Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
/**
18
 * Completion Progress block renderer.
19
 *
20
 * @package    block_completion_progress
21
 * @copyright  2016 Michael de Raadt
22
 * @copyright  2020 Jonathon Fowler <fowlerj@usq.edu.au>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
namespace block_completion_progress\output;
27
 
28
use block_completion_progress\completion_progress;
29
use block_completion_progress\defaults;
30
use plugin_renderer_base;
31
use html_writer;
32
 
33
/**
34
 * Completion Progress block renderer.
35
 *
36
 * @package    block_completion_progress
37
 * @copyright  2020 Jonathon Fowler <fowlerj@usq.edu.au>
38
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
39
 */
40
class renderer extends plugin_renderer_base {
41
    /**
42
     * Generate a progress bar.
43
     * @param completion_progress $progress
44
     * @return string HTML
45
     */
46
    public function render_completion_progress(completion_progress $progress) {
47
        global $CFG, $USER;
48
 
49
        $activities = $progress->get_visible_activities();
50
        $completions = $progress->get_completions();
51
        $config = $progress->get_block_config();
52
        $userid = $progress->get_user()->id;
53
        $courseid = $progress->get_course()->id;
54
        $instance = $progress->get_block_instance()->id;
55
        $simple = $progress->is_simple_bar();
56
 
57
        $content = '';
58
        $now = time();
59
        $usingrtl = right_to_left();
60
        $numactivities = count($activities);
61
 
62
        if ($simple && $numactivities == 0) {
63
            return get_string('no_visible_activities_message', 'block_completion_progress');
64
        }
65
 
66
        $alternatelinks = array(
67
            'assign' => array(
68
                'url' => '/mod/assign/view.php?id=:cmid&action=grade&userid=:userid',
69
                'capability' => 'mod/assign:grade',
70
            ),
71
            'feedback' => array(
72
                // Breaks if anonymous feedback is collected.
73
                'url' => '/mod/feedback/show_entries.php?id=:cmid&do_show=showoneentry&userid=:userid',
74
                'capability' => 'mod/feedback:viewreports',
75
            ),
76
            'lesson' => array(
77
                'url' => '/mod/lesson/report.php?id=:cmid&action=reportdetail&userid=:userid',
78
                'capability' => 'mod/lesson:viewreports',
79
            ),
80
            'quiz' => array(
81
                'url' => '/mod/quiz/report.php?id=:cmid&mode=overview',
82
                'capability' => 'mod/quiz:viewreports',
83
            ),
84
        );
85
 
86
        // Get relevant block instance settings or use defaults.
87
        if (get_config('block_completion_progress', 'forceiconsinbar') == 0) {
88
            $useicons = $config->progressBarIcons ?? defaults::PROGRESSBARICONS;
89
        } else {
90
            $useicons = true;
91
        }
92
        if (($defaultlongbars = get_config('block_completion_progress', 'defaultlongbars')) === false) {
93
            $defaultlongbars = defaults::LONGBARS;
94
        }
95
        $orderby = $config->orderby ?? defaults::ORDERBY;
96
        $longbars = $config->longbars ?? $defaultlongbars;
97
        $displaynow = $orderby == completion_progress::ORDERBY_TIME;
98
        $showpercentage = $config->showpercentage ?? defaults::SHOWPERCENTAGE;
99
 
100
        $rowoptions = array('style' => '');
101
        $cellsoptions = array('style' => '');
102
        $barclasses = array('barRow');
103
 
104
        $content .= html_writer::start_div('barContainer', ['data-instanceid' => $instance]);
105
 
106
        // Determine the segment width.
107
        $wrapafter = get_config('block_completion_progress', 'wrapafter') ?: defaults::WRAPAFTER;
108
        if ($wrapafter <= 1) {
109
            $wrapafter = 1;
110
        }
111
        if ($longbars == 'wrap' && $numactivities <= $wrapafter) {
112
            $longbars = 'squeeze';
113
        }
114
        if ($longbars == 'wrap') {
115
            $rows = ceil($numactivities / $wrapafter);
116
            if ($rows <= 1) {
117
                $rows = 1;
118
            }
119
            $cellsoptions['style'] = 'flex-basis: calc(100% / ' . ceil($numactivities / $rows) . ');';
120
            $displaynow = false;
121
        }
122
        if ($longbars == 'scroll') {
123
            $leftpoly = html_writer::tag('polygon', '', array('points' => '30,0 0,15 30,30', 'class' => 'triangle-polygon'));
124
            $rightpoly = html_writer::tag('polygon', '', array('points' => '0,0 30,15 0,30', 'class' => 'triangle-polygon'));
125
            $content .= html_writer::tag('svg', $leftpoly, array('class' => 'left-arrow-svg', 'height' => '30', 'width' => '30'));
126
            $content .= html_writer::tag('svg', $rightpoly, array('class' => 'right-arrow-svg', 'height' => '30', 'width' => '30'));
127
        }
128
        $barclasses[] = 'barMode' . ucfirst($longbars);
129
        if ($useicons) {
130
            $barclasses[] = 'barWithIcons';
131
        }
132
 
133
        // Determine where to put the NOW indicator.
134
        $nowpos = -1;
135
        if ($orderby == 'orderbytime' && $longbars != 'wrap' && $displaynow && !$simple) {
136
            $barclasses[] = 'barWithNow';
137
 
138
            // Find where to put now arrow.
139
            $nowpos = 0;
140
            while ($nowpos < $numactivities && $now > $activities[$nowpos]->expected && $activities[$nowpos]->expected != 0) {
141
                $nowpos++;
142
            }
143
            $nowstring = get_string('now_indicator', 'block_completion_progress');
144
            $leftarrowimg = $this->pix_icon('left', $nowstring, 'block_completion_progress', array('class' => 'nowicon'));
145
            $rightarrowimg = $this->pix_icon('right', $nowstring, 'block_completion_progress', array('class' => 'nowicon'));
146
        }
147
 
148
        // Determine links to activities.
149
        for ($i = 0; $i < $numactivities; $i++) {
150
            if ($userid != $USER->id &&
151
                array_key_exists($activities[$i]->type, $alternatelinks) &&
152
                has_capability($alternatelinks[$activities[$i]->type]['capability'], $activities[$i]->context)
153
            ) {
154
                $substitutions = array(
155
                    '/:courseid/' => $courseid,
156
                    '/:eventid/'  => $activities[$i]->instance,
157
                    '/:cmid/'     => $activities[$i]->id,
158
                    '/:userid/'   => $userid,
159
                );
160
                $link = $alternatelinks[$activities[$i]->type]['url'];
161
                $link = preg_replace(array_keys($substitutions), array_values($substitutions), $link);
162
                $activities[$i]->link = $CFG->wwwroot.$link;
163
            } else {
164
                $activities[$i]->link = $activities[$i]->url;
165
            }
166
        }
167
 
168
        // Start progress bar.
169
        $content .= html_writer::start_div(implode(' ', $barclasses), $rowoptions);
170
        $content .= html_writer::start_div('barRowCells', $cellsoptions);
171
        $counter = 1;
172
        foreach ($activities as $activity) {
173
            $complete = $completions[$activity->id] ?? null;
174
 
175
            // A cell in the progress bar.
176
            $cellcontent = '';
177
            $celloptions = array(
178
                'class' => 'progressBarCell',
179
                'data-info-ref' => 'progressBarInfo'.$instance.'-'.$userid.'-'.$activity->id,
180
            );
181
            if ($complete === 'submitted') {
182
                $celloptions['class'] .= ' submittedNotComplete';
183
 
184
            } else if ($complete == COMPLETION_COMPLETE || $complete == COMPLETION_COMPLETE_PASS) {
185
                $celloptions['class'] .= ' completed';
186
 
187
            } else if (
188
                $complete == COMPLETION_COMPLETE_FAIL ||
189
                (!isset($config->orderby) || $config->orderby == 'orderbytime') &&
190
                (isset($activity->expected) && $activity->expected > 0 && $activity->expected < $now)
191
            ) {
192
                $celloptions['class'] .= ' notCompleted';
193
 
194
            } else {
195
                $celloptions['class'] .= ' futureNotCompleted';
196
            }
197
            if (empty($activity->link)) {
198
                $celloptions['data-haslink'] = 'false';
199
            } else if (!empty($activity->available) || $simple) {
200
                $celloptions['data-haslink'] = 'true';
201
            } else if (!empty($activity->link)) {
202
                $celloptions['data-haslink'] = 'not-allowed';
203
            }
204
 
205
            // Place the NOW indicator.
206
            if ($nowpos >= 0) {
207
                if ($nowpos == 0 && $counter == 1) {
208
                    $nowcontent = $usingrtl ? $rightarrowimg.$nowstring : $leftarrowimg.$nowstring;
209
                    $cellcontent .= html_writer::div($nowcontent, 'nowDiv firstNow');
210
                } else if ($nowpos == $counter) {
211
                    if ($nowpos < $numactivities / 2) {
212
                        $nowcontent = $usingrtl ? $rightarrowimg.$nowstring : $leftarrowimg.$nowstring;
213
                        $cellcontent .= html_writer::div($nowcontent, 'nowDiv firstHalfNow');
214
                    } else {
215
                        $nowcontent = $usingrtl ? $nowstring.$leftarrowimg : $nowstring.$rightarrowimg;
216
                        $cellcontent .= html_writer::div($nowcontent, 'nowDiv lastHalfNow');
217
                    }
218
                }
219
            }
220
 
221
            $counter++;
222
            $content .= html_writer::div($cellcontent, null, $celloptions);
223
        }
224
        $content .= html_writer::end_div(); // ... barRowCells
225
        $content .= html_writer::end_div(); // ... $barclasses
226
        $content .= html_writer::end_div(); // ... barContainer
227
 
228
        // Add the percentage below the progress bar.
229
        if ($showpercentage && !$simple) {
230
            $progress = $progress->get_percentage();
231
            $percentagecontent = get_string('progress', 'block_completion_progress').': '.$progress.'%';
232
            $percentageoptions = array('class' => 'progressPercentage');
233
            $content .= html_writer::tag('div', $percentagecontent, $percentageoptions);
234
        }
235
 
236
        // Add the info box below the table.
237
        $divoptions = array('class' => 'progressEventInfo',
238
                            'id' => 'progressBarInfo'.$instance.'-'.$userid.'-info');
239
        $content .= html_writer::start_tag('div', $divoptions);
240
        if (!$simple) {
241
            $content .= get_string('mouse_over_prompt', 'block_completion_progress');
242
            $content .= ' ';
243
            $attributes = array (
244
                'class' => 'accesshide progressShowAllInfo',
245
            );
246
            $content .= html_writer::link('#', get_string('showallinfo', 'block_completion_progress'), $attributes);
247
        }
248
        $content .= html_writer::end_tag('div');
249
 
250
        // Add hidden divs for activity information.
251
        $strincomplete = get_string('completion-n', 'completion');
252
        $strcomplete = get_string('completed', 'completion');
253
        $strpassed = get_string('completion-pass', 'completion');
254
        $strfailed = get_string('completion-fail', 'completion');
255
        $strsubmitted = get_string('submitted', 'block_completion_progress');
256
        $strdateformat = get_string('strftimedate', 'langconfig');
257
        $strtimeexpected = get_string('time_expected', 'block_completion_progress');
258
 
259
        foreach ($activities as $activity) {
260
            $completed = $completions[$activity->id] ?? null;
261
            $divoptions = array('class' => 'progressEventInfo',
262
                                'id' => 'progressBarInfo'.$instance.'-'.$userid.'-'.$activity->id,
263
                                'style' => 'display: none;');
264
            $content .= html_writer::start_tag('div', $divoptions);
265
 
266
            $text = '';
267
            $text .= html_writer::empty_tag('img',
268
                    array('src' => $activity->icon, 'class' => 'moduleIcon', 'alt' => '', 'role' => 'presentation'));
269
            $text .= $activity->name;
270
            if (!empty($activity->link) && (!empty($activity->available) || $simple)) {
271
                $attrs = ['class' => 'action_link'];
272
                if (!empty($activity->onclick)) {
273
                    $attrs['onclick'] = $activity->onclick;
274
                }
275
                $content .= $this->action_link($activity->link, $text, null, $attrs);
276
            } else {
277
                $content .= $text;
278
            }
279
            $content .= html_writer::empty_tag('br');
280
            $altattribute = '';
281
            if ($completed == COMPLETION_COMPLETE) {
282
                $content .= $strcomplete.'&nbsp;';
283
                $icon = 'tick';
284
                $altattribute = $strcomplete;
285
            } else if ($completed == COMPLETION_COMPLETE_PASS) {
286
                $content .= $strpassed.'&nbsp;';
287
                $icon = 'tick';
288
                $altattribute = $strpassed;
289
            } else if ($completed == COMPLETION_COMPLETE_FAIL) {
290
                $content .= $strfailed.'&nbsp;';
291
                $icon = 'cross';
292
                $altattribute = $strfailed;
293
            } else {
294
                $content .= $strincomplete .'&nbsp;';
295
                $icon = 'cross';
296
                $altattribute = $strincomplete;
297
                if ($completed === 'submitted') {
298
                    $content .= '(' . $strsubmitted . ')&nbsp;';
299
                    $altattribute .= '(' . $strsubmitted . ')';
300
                }
301
            }
302
            $content .= $this->pix_icon($icon, $altattribute, 'block_completion_progress', array('class' => 'iconInInfo'));
303
            $content .= html_writer::empty_tag('br');
304
            if ($activity->expected != 0) {
305
                $content .= html_writer::start_tag('div', array('class' => 'expectedBy'));
306
                $content .= $strtimeexpected.': ';
307
                $content .= userdate($activity->expected, $strdateformat, $CFG->timezone);
308
                $content .= html_writer::end_tag('div');
309
            }
310
            $content .= html_writer::end_tag('div');
311
        }
312
 
313
        return $content;
314
    }
315
}