Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
// This file is part of Moodle - http://moodle.org/
4
//
5
// Moodle is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// Moodle is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17
 
18
/**
19
 * Workshop module renderering methods are defined here
20
 *
21
 * @package    mod_workshop
22
 * @copyright  2009 David Mudrak <david.mudrak@gmail.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
defined('MOODLE_INTERNAL') || die();
27
 
28
/**
29
 * Workshop module renderer class
30
 *
31
 * @copyright 2009 David Mudrak <david.mudrak@gmail.com>
32
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
33
 */
34
class mod_workshop_renderer extends plugin_renderer_base {
35
 
36
    ////////////////////////////////////////////////////////////////////////////
37
    // External API - methods to render workshop renderable components
38
    ////////////////////////////////////////////////////////////////////////////
39
 
40
    /**
41
     * Renders the tertiary nav for the allocation pages
42
     *
43
     * @param \mod_workshop\output\actionbar $actionbar
44
     * @return bool|string the rendered output
45
     */
46
    public function render_allocation_menu(\mod_workshop\output\actionbar $actionbar): string {
47
        return $this->render_from_template('mod_workshop/action_bar', $actionbar->export_for_template($this));
48
    }
49
 
50
    /**
51
     * Renders workshop message
52
     *
53
     * @param workshop_message $message to display
54
     * @return string html code
55
     */
56
    protected function render_workshop_message(workshop_message $message) {
57
 
58
        $text   = $message->get_message();
59
        $url    = $message->get_action_url();
60
        $label  = $message->get_action_label();
61
 
62
        if (empty($text) and empty($label)) {
63
            return '';
64
        }
65
 
66
        switch ($message->get_type()) {
67
        case workshop_message::TYPE_OK:
68
            $sty = 'ok';
69
            break;
70
        case workshop_message::TYPE_ERROR:
71
            $sty = 'error';
72
            break;
73
        default:
74
            $sty = 'info';
75
        }
76
 
77
        $o = html_writer::tag('span', $message->get_message());
78
 
79
        if (!is_null($url) and !is_null($label)) {
80
            $o .= $this->output->single_button($url, $label, 'get');
81
        }
82
 
83
        return $this->output->container($o, array('message', $sty));
84
    }
85
 
86
 
87
    /**
88
     * Renders full workshop submission
89
     *
90
     * @param workshop_submission $submission
91
     * @return string HTML
92
     */
93
    protected function render_workshop_submission(workshop_submission $submission) {
94
        global $CFG;
95
 
96
        $o  = '';    // output HTML code
97
        $anonymous = $submission->is_anonymous();
98
        $classes = 'submission-full';
99
        if ($anonymous) {
100
            $classes .= ' anonymous';
101
        }
102
        $o .= $this->output->container_start($classes);
103
        $o .= $this->output->container_start('header');
104
 
105
        $title = format_string($submission->title);
106
 
107
        if ($this->page->url != $submission->url) {
108
            $title = html_writer::link($submission->url, $title);
109
        }
110
 
111
        $o .= $this->output->heading($title, 3, 'title');
112
 
113
        if (!$anonymous) {
114
            $author = new stdclass();
115
            $additionalfields = explode(',', implode(',', \core_user\fields::get_picture_fields()));
116
            $author = username_load_fields_from_object($author, $submission, 'author', $additionalfields);
117
            $userpic            = $this->output->user_picture($author, array('courseid' => $this->page->course->id, 'size' => 64));
118
            $userurl            = new moodle_url('/user/view.php',
119
                                            array('id' => $author->id, 'course' => $this->page->course->id));
120
            $a                  = new stdclass();
121
            $a->name            = fullname($author);
122
            $a->url             = $userurl->out();
123
            $byfullname         = get_string('byfullname', 'workshop', $a);
124
            $oo  = $this->output->container($userpic, 'picture');
125
            $oo .= $this->output->container($byfullname, 'fullname');
126
 
127
            $o .= $this->output->container($oo, 'author');
128
        }
129
 
130
        $created = get_string('userdatecreated', 'workshop', userdate($submission->timecreated));
131
        $o .= $this->output->container($created, 'userdate created');
132
 
133
        if ($submission->timemodified > $submission->timecreated) {
134
            $modified = get_string('userdatemodified', 'workshop', userdate($submission->timemodified));
135
            $o .= $this->output->container($modified, 'userdate modified');
136
        }
137
 
138
        $o .= $this->output->container_end(); // end of header
139
 
140
        $content = file_rewrite_pluginfile_urls($submission->content, 'pluginfile.php', $this->page->context->id,
141
                                                        'mod_workshop', 'submission_content', $submission->id);
142
        $content = format_text($content, $submission->contentformat, array('overflowdiv'=>true));
143
        if (!empty($content)) {
144
            if (!empty($CFG->enableplagiarism)) {
145
                require_once($CFG->libdir.'/plagiarismlib.php');
146
                $content .= plagiarism_get_links(array('userid' => $submission->authorid,
147
                    'content' => $submission->content,
148
                    'cmid' => $this->page->cm->id,
149
                    'course' => $this->page->course));
150
            }
151
        }
152
        $o .= $this->output->container($content, 'content');
153
 
154
        $o .= $this->helper_submission_attachments($submission->id, 'html');
155
 
156
        $o .= $this->output->container_end(); // end of submission-full
157
 
158
        return $o;
159
    }
160
 
161
    /**
162
     * Renders short summary of the submission
163
     *
164
     * @param workshop_submission_summary $summary
165
     * @return string text to be echo'ed
166
     */
167
    protected function render_workshop_submission_summary(workshop_submission_summary $summary) {
168
 
169
        $o  = '';    // output HTML code
170
        $anonymous = $summary->is_anonymous();
171
        $classes = 'submission-summary';
172
 
173
        if ($anonymous) {
174
            $classes .= ' anonymous';
175
        }
176
 
177
        $gradestatus = '';
178
 
179
        if ($summary->status == 'notgraded') {
180
            $classes    .= ' notgraded';
181
            $gradestatus = $this->output->container(get_string('nogradeyet', 'workshop'), 'grade-status');
182
 
183
        } else if ($summary->status == 'graded') {
184
            $classes    .= ' graded';
185
            $gradestatus = $this->output->container(get_string('alreadygraded', 'workshop'), 'grade-status');
186
        }
187
 
188
        $o .= $this->output->container_start($classes);  // main wrapper
189
        $o .= html_writer::link($summary->url, format_string($summary->title), array('class' => 'title'));
190
 
191
        if (!$anonymous) {
192
            $author             = new stdClass();
193
            $additionalfields = explode(',', implode(',', \core_user\fields::get_picture_fields()));
194
            $author = username_load_fields_from_object($author, $summary, 'author', $additionalfields);
195
            $userpic            = $this->output->user_picture($author, array('courseid' => $this->page->course->id, 'size' => 35));
196
            $userurl            = new moodle_url('/user/view.php',
197
                                            array('id' => $author->id, 'course' => $this->page->course->id));
198
            $a                  = new stdClass();
199
            $a->name            = fullname($author);
200
            $a->url             = $userurl->out();
201
            $byfullname         = get_string('byfullname', 'workshop', $a);
202
 
203
            $oo  = $this->output->container($userpic, 'picture');
204
            $oo .= $this->output->container($byfullname, 'fullname');
205
            $o  .= $this->output->container($oo, 'author');
206
        }
207
 
208
        $created = get_string('userdatecreated', 'workshop', userdate($summary->timecreated));
209
        $o .= $this->output->container($created, 'userdate created');
210
 
211
        if ($summary->timemodified > $summary->timecreated) {
212
            $modified = get_string('userdatemodified', 'workshop', userdate($summary->timemodified));
213
            $o .= $this->output->container($modified, 'userdate modified');
214
        }
215
 
216
        $o .= $gradestatus;
217
        $o .= $this->output->container_end(); // end of the main wrapper
218
        return $o;
219
    }
220
 
221
    /**
222
     * Renders full workshop example submission
223
     *
224
     * @param workshop_example_submission $example
225
     * @return string HTML
226
     */
227
    protected function render_workshop_example_submission(workshop_example_submission $example) {
228
 
229
        $o  = '';    // output HTML code
230
        $classes = 'submission-full example';
231
        $o .= $this->output->container_start($classes);
232
        $o .= $this->output->container_start('header');
233
        $o .= $this->output->container(format_string($example->title), array('class' => 'title'));
234
        $o .= $this->output->container_end(); // end of header
235
 
236
        $content = file_rewrite_pluginfile_urls($example->content, 'pluginfile.php', $this->page->context->id,
237
                                                        'mod_workshop', 'submission_content', $example->id);
238
        $content = format_text($content, $example->contentformat, array('overflowdiv'=>true));
239
        $o .= $this->output->container($content, 'content');
240
 
241
        $o .= $this->helper_submission_attachments($example->id, 'html');
242
 
243
        $o .= $this->output->container_end(); // end of submission-full
244
 
245
        return $o;
246
    }
247
 
248
    /**
249
     * Renders short summary of the example submission
250
     *
251
     * @param workshop_example_submission_summary $summary
252
     * @return string text to be echo'ed
253
     */
254
    protected function render_workshop_example_submission_summary(workshop_example_submission_summary $summary) {
255
 
256
        $o  = '';    // output HTML code
257
 
258
        // wrapping box
259
        $o .= $this->output->box_start('generalbox example-summary ' . $summary->status);
260
 
261
        // title
262
        $o .= $this->output->container_start('example-title');
263
        $o .= html_writer::link($summary->url, format_string($summary->title), array('class' => 'title'));
264
 
265
        if ($summary->editable) {
266
            $o .= $this->output->action_icon($summary->editurl, new pix_icon('i/edit', get_string('edit')));
267
        }
268
        $o .= $this->output->container_end();
269
 
270
        // additional info
271
        if ($summary->status == 'notgraded') {
272
            $o .= $this->output->container(get_string('nogradeyet', 'workshop'), 'example-info nograde');
273
        } else {
274
            $o .= $this->output->container(get_string('gradeinfo', 'workshop' , $summary->gradeinfo), 'example-info grade');
275
        }
276
 
277
        // button to assess
278
        $button = new single_button($summary->assessurl, $summary->assesslabel, 'get');
279
        $o .= $this->output->container($this->output->render($button), 'example-actions');
280
 
281
        // end of wrapping box
282
        $o .= $this->output->box_end();
283
 
284
        return $o;
285
    }
286
 
287
    /**
288
     * Renders the user plannner tool
289
     *
290
     * @param workshop_user_plan $plan prepared for the user
291
     * @return string html code to be displayed
292
     */
293
    protected function render_workshop_user_plan(workshop_user_plan $plan) {
294
        $o  = '';    // Output HTML code.
295
        $numberofphases = count($plan->phases);
296
        $o .= html_writer::start_tag('div', array(
297
            'class' => 'userplan',
298
            'aria-labelledby' => 'mod_workshop-userplanheading',
299
            'aria-describedby' => 'mod_workshop-userplanaccessibilitytitle',
300
        ));
301
        $o .= html_writer::span(get_string('userplanaccessibilitytitle', 'workshop', $numberofphases),
302
            'accesshide', array('id' => 'mod_workshop-userplanaccessibilitytitle'));
303
        $o .= html_writer::link('#mod_workshop-userplancurrenttasks', get_string('userplanaccessibilityskip', 'workshop'),
304
            array('class' => 'accesshide'));
305
        foreach ($plan->phases as $phasecode => $phase) {
306
            $o .= html_writer::start_tag('dl', array('class' => 'phase'));
307
            $actions = '';
308
 
309
            if ($phase->active) {
310
                // Mark the section as the current one.
311
                $icon = $this->output->pix_icon('i/marked', '');
312
                $actions .= get_string('userplancurrentphase', 'workshop').' '.$icon;
313
 
314
            } else {
315
                // Display a control widget to switch to the given phase or mark the phase as the current one.
316
                foreach ($phase->actions as $action) {
317
                    if ($action->type === 'switchphase') {
318
                        if ($phasecode == workshop::PHASE_ASSESSMENT && $plan->workshop->phase == workshop::PHASE_SUBMISSION
319
                                && $plan->workshop->phaseswitchassessment) {
320
                            $icon = new pix_icon('i/scheduled', get_string('switchphaseauto', 'mod_workshop'));
321
                        } else {
322
                            $icon = new pix_icon('i/marker', get_string('switchphase'.$phasecode, 'mod_workshop'));
323
                        }
324
                        $actions .= $this->output->action_icon($action->url, $icon, null, null, true);
325
                    }
326
                }
327
            }
328
 
329
            if (!empty($actions)) {
330
                $actions = $this->output->container($actions, 'actions');
331
            }
332
            $classes = 'phase' . $phasecode;
333
            if ($phase->active) {
334
                $title = html_writer::span($phase->title, 'phasetitle', ['id' => 'mod_workshop-userplancurrenttasks']);
335
                $classes .= ' active';
336
            } else {
337
                $title = html_writer::span($phase->title, 'phasetitle');
338
                $classes .= ' nonactive';
339
            }
340
            $o .= html_writer::start_tag('dt', array('class' => $classes));
341
            $o .= $this->output->container($title . $actions);
342
            $o .= html_writer::start_tag('dd', array('class' => $classes. ' phasetasks'));
343
            $o .= $this->helper_user_plan_tasks($phase->tasks);
344
            $o .= html_writer::end_tag('dd');
345
            $o .= html_writer::end_tag('dl');
346
        }
347
        $o .= html_writer::end_tag('div');
348
        return $o;
349
    }
350
 
351
    /**
352
     * Renders the result of the submissions allocation process
353
     *
354
     * @param workshop_allocation_result $result as returned by the allocator's init() method
355
     * @return string HTML to be echoed
356
     */
357
    protected function render_workshop_allocation_result(workshop_allocation_result $result) {
358
        global $CFG;
359
 
360
        $status = $result->get_status();
361
 
362
        if (is_null($status) or $status == workshop_allocation_result::STATUS_VOID) {
363
            debugging('Attempt to render workshop_allocation_result with empty status', DEBUG_DEVELOPER);
364
            return '';
365
        }
366
 
367
        switch ($status) {
368
        case workshop_allocation_result::STATUS_FAILED:
369
            if ($message = $result->get_message()) {
370
                $message = new workshop_message($message, workshop_message::TYPE_ERROR);
371
            } else {
372
                $message = new workshop_message(get_string('allocationerror', 'workshop'), workshop_message::TYPE_ERROR);
373
            }
374
            break;
375
 
376
        case workshop_allocation_result::STATUS_CONFIGURED:
377
            if ($message = $result->get_message()) {
378
                $message = new workshop_message($message, workshop_message::TYPE_INFO);
379
            } else {
380
                $message = new workshop_message(get_string('allocationconfigured', 'workshop'), workshop_message::TYPE_INFO);
381
            }
382
            break;
383
 
384
        case workshop_allocation_result::STATUS_EXECUTED:
385
            if ($message = $result->get_message()) {
386
                $message = new workshop_message($message, workshop_message::TYPE_OK);
387
            } else {
388
                $message = new workshop_message(get_string('allocationdone', 'workshop'), workshop_message::TYPE_OK);
389
            }
390
            break;
391
 
392
        default:
393
            throw new coding_exception('Unknown allocation result status', $status);
394
        }
395
 
396
        // start with the message
397
        $o = $this->render($message);
398
 
399
        // display the details about the process if available
400
        $logs = $result->get_logs();
401
        if (is_array($logs) and !empty($logs)) {
402
            $o .= html_writer::start_tag('ul', array('class' => 'allocation-init-results'));
403
            foreach ($logs as $log) {
404
                if ($log->type == 'debug' and !$CFG->debugdeveloper) {
405
                    // display allocation debugging messages for developers only
406
                    continue;
407
                }
408
                $class = $log->type;
409
                if ($log->indent) {
410
                    $class .= ' indent';
411
                }
412
                $o .= html_writer::tag('li', $log->message, array('class' => $class)).PHP_EOL;
413
            }
414
            $o .= html_writer::end_tag('ul');
415
        }
416
 
417
        return $o;
418
    }
419
 
420
    /**
421
     * Renders the workshop grading report
422
     *
423
     * @param workshop_grading_report $gradingreport
424
     * @return string html code
425
     */
426
    protected function render_workshop_grading_report(workshop_grading_report $gradingreport) {
427
 
428
        $data       = $gradingreport->get_data();
429
        $options    = $gradingreport->get_options();
430
        $grades     = $data->grades;
431
        $userinfo   = $data->userinfo;
432
 
433
        if (empty($grades)) {
434
            return $this->output->notification(get_string('nothingtodisplay'), 'info', false);
435
        }
436
 
437
        $table = new html_table();
438
        $table->attributes['class'] = 'grading-report table-striped table-hover';
439
 
440
        $sortbyfirstname = $this->helper_sortable_heading(get_string('firstname'), 'firstname', $options->sortby, $options->sorthow);
441
        $sortbylastname = $this->helper_sortable_heading(get_string('lastname'), 'lastname', $options->sortby, $options->sorthow);
442
        if (self::fullname_format() == 'lf') {
443
            $sortbyname = $sortbylastname . ' / ' . $sortbyfirstname;
444
        } else {
445
            $sortbyname = $sortbyfirstname . ' / ' . $sortbylastname;
446
        }
447
 
448
        $sortbysubmisstiontitle = $this->helper_sortable_heading(get_string('submission', 'workshop'), 'submissiontitle',
449
                $options->sortby, $options->sorthow);
450
        $sortbysubmisstionlastmodified = $this->helper_sortable_heading(get_string('submissionlastmodified', 'workshop'),
451
                'submissionmodified', $options->sortby, $options->sorthow);
452
        $sortbysubmisstion = $sortbysubmisstiontitle . ' / ' . $sortbysubmisstionlastmodified;
453
 
454
        $table->head = array();
455
        $table->head[] = $sortbyname;
456
        $table->head[] = $sortbysubmisstion;
457
 
458
        // If we are in submission phase ignore the following headers (columns).
459
        if ($options->workshopphase != workshop::PHASE_SUBMISSION) {
460
            $table->head[] = $this->helper_sortable_heading(get_string('receivedgrades', 'workshop'));
461
            if ($options->showsubmissiongrade) {
462
                $table->head[] = $this->helper_sortable_heading(get_string('submissiongradeof', 'workshop', $data->maxgrade),
463
                        'submissiongrade', $options->sortby, $options->sorthow);
464
            }
465
            $table->head[] = $this->helper_sortable_heading(get_string('givengrades', 'workshop'));
466
            if ($options->showgradinggrade) {
467
                $table->head[] = $this->helper_sortable_heading(get_string('gradinggradeof', 'workshop', $data->maxgradinggrade),
468
                        'gradinggrade', $options->sortby, $options->sorthow);
469
            }
470
        }
471
        $table->rowclasses  = array();
472
        $table->colclasses  = array();
473
        $table->data        = array();
474
 
475
        foreach ($grades as $participant) {
476
            $numofreceived  = count($participant->reviewedby);
477
            $numofgiven     = count($participant->reviewerof);
478
            $published      = $participant->submissionpublished;
479
 
480
            // compute the number of <tr> table rows needed to display this participant
481
            if ($numofreceived > 0 and $numofgiven > 0) {
482
                $numoftrs       = workshop::lcm($numofreceived, $numofgiven);
483
                $spanreceived   = $numoftrs / $numofreceived;
484
                $spangiven      = $numoftrs / $numofgiven;
485
            } elseif ($numofreceived == 0 and $numofgiven > 0) {
486
                $numoftrs       = $numofgiven;
487
                $spanreceived   = $numoftrs;
488
                $spangiven      = $numoftrs / $numofgiven;
489
            } elseif ($numofreceived > 0 and $numofgiven == 0) {
490
                $numoftrs       = $numofreceived;
491
                $spanreceived   = $numoftrs / $numofreceived;
492
                $spangiven      = $numoftrs;
493
            } else {
494
                $numoftrs       = 1;
495
                $spanreceived   = 1;
496
                $spangiven      = 1;
497
            }
498
 
499
            for ($tr = 0; $tr < $numoftrs; $tr++) {
500
                $row = new html_table_row();
501
                if ($published) {
502
                    $row->attributes['class'] = 'published';
503
                }
504
                // column #1 - participant - spans over all rows
505
                if ($tr == 0) {
506
                    $cell = new html_table_cell();
507
                    $cell->text = $this->helper_grading_report_participant($participant, $userinfo);
508
                    $cell->rowspan = $numoftrs;
509
                    $cell->attributes['class'] = 'participant';
510
                    $row->cells[] = $cell;
511
                }
512
                // column #2 - submission - spans over all rows
513
                if ($tr == 0) {
514
                    $cell = new html_table_cell();
515
                    $cell->text = $this->helper_grading_report_submission($participant);
516
                    $cell->rowspan = $numoftrs;
517
                    $cell->attributes['class'] = 'submission';
518
                    $row->cells[] = $cell;
519
                }
520
 
521
                // If we are in submission phase ignore the following columns.
522
                if ($options->workshopphase == workshop::PHASE_SUBMISSION) {
523
                    $table->data[] = $row;
524
                    continue;
525
                }
526
 
527
                // column #3 - received grades
528
                if ($tr % $spanreceived == 0) {
529
                    $idx = intval($tr / $spanreceived);
530
                    $assessment = self::array_nth($participant->reviewedby, $idx);
531
                    $cell = new html_table_cell();
532
                    $cell->text = $this->helper_grading_report_assessment($assessment, $options->showreviewernames, $userinfo,
533
                            get_string('gradereceivedfrom', 'workshop'));
534
                    $cell->rowspan = $spanreceived;
535
                    $cell->attributes['class'] = 'receivedgrade';
536
                    if (is_null($assessment) or is_null($assessment->grade)) {
537
                        $cell->attributes['class'] .= ' null';
538
                    } else {
539
                        $cell->attributes['class'] .= ' notnull';
540
                    }
541
                    $row->cells[] = $cell;
542
                }
543
                // column #4 - total grade for submission
544
                if ($options->showsubmissiongrade and $tr == 0) {
545
                    $cell = new html_table_cell();
546
                    $cell->text = $this->helper_grading_report_grade($participant->submissiongrade, $participant->submissiongradeover);
547
                    $cell->rowspan = $numoftrs;
548
                    $cell->attributes['class'] = 'submissiongrade';
549
                    $row->cells[] = $cell;
550
                }
551
                // column #5 - given grades
552
                if ($tr % $spangiven == 0) {
553
                    $idx = intval($tr / $spangiven);
554
                    $assessment = self::array_nth($participant->reviewerof, $idx);
555
                    $cell = new html_table_cell();
556
                    $cell->text = $this->helper_grading_report_assessment($assessment, $options->showauthornames, $userinfo,
557
                            get_string('gradegivento', 'workshop'));
558
                    $cell->rowspan = $spangiven;
559
                    $cell->attributes['class'] = 'givengrade';
560
                    if (is_null($assessment) or is_null($assessment->grade)) {
561
                        $cell->attributes['class'] .= ' null';
562
                    } else {
563
                        $cell->attributes['class'] .= ' notnull';
564
                    }
565
                    $row->cells[] = $cell;
566
                }
567
                // column #6 - total grade for assessment
568
                if ($options->showgradinggrade and $tr == 0) {
569
                    $cell = new html_table_cell();
570
                    $cell->text = $this->helper_grading_report_grade($participant->gradinggrade);
571
                    $cell->rowspan = $numoftrs;
572
                    $cell->attributes['class'] = 'gradinggrade';
573
                    $row->cells[] = $cell;
574
                }
575
 
576
                $table->data[] = $row;
577
            }
578
        }
579
 
580
        return html_writer::table($table);
581
    }
582
 
583
    /**
584
     * Renders the feedback for the author of the submission
585
     *
586
     * @param workshop_feedback_author $feedback
587
     * @return string HTML
588
     */
589
    protected function render_workshop_feedback_author(workshop_feedback_author $feedback) {
590
        return $this->helper_render_feedback($feedback);
591
    }
592
 
593
    /**
594
     * Renders the feedback for the reviewer of the submission
595
     *
596
     * @param workshop_feedback_reviewer $feedback
597
     * @return string HTML
598
     */
599
    protected function render_workshop_feedback_reviewer(workshop_feedback_reviewer $feedback) {
600
        return $this->helper_render_feedback($feedback);
601
    }
602
 
603
    /**
604
     * Helper method to rendering feedback
605
     *
606
     * @param workshop_feedback_author|workshop_feedback_reviewer $feedback
607
     * @return string HTML
608
     */
609
    private function helper_render_feedback($feedback) {
610
 
611
        $o  = '';    // output HTML code
612
        $o .= $this->output->container_start('feedback feedbackforauthor');
613
        $o .= $this->output->container_start('header');
614
        $o .= $this->output->heading(get_string('feedbackby', 'workshop', s(fullname($feedback->get_provider()))), 3, 'title');
615
 
616
        $userpic = $this->output->user_picture($feedback->get_provider(), array('courseid' => $this->page->course->id, 'size' => 32));
617
        $o .= $this->output->container($userpic, 'picture');
618
        $o .= $this->output->container_end(); // end of header
619
 
620
        $content = format_text($feedback->get_content(), $feedback->get_format(), array('overflowdiv' => true));
621
        $o .= $this->output->container($content, 'content');
622
 
623
        $o .= $this->output->container_end();
624
 
625
        return $o;
626
    }
627
 
628
    /**
629
     * Renders the full assessment
630
     *
631
     * @param workshop_assessment $assessment
632
     * @return string HTML
633
     */
634
    protected function render_workshop_assessment(workshop_assessment $assessment) {
635
 
636
        $o = ''; // output HTML code
637
        $anonymous = is_null($assessment->reviewer);
638
        $classes = 'assessment-full';
639
        if ($anonymous) {
640
            $classes .= ' anonymous';
641
        }
642
 
643
        $o .= $this->output->container_start($classes);
644
        $o .= $this->output->container_start('header');
645
 
646
        if (!empty($assessment->title)) {
647
            $title = s($assessment->title);
648
        } else {
649
            $title = get_string('assessment', 'workshop');
650
        }
651
        if (($assessment->url instanceof moodle_url) and ($this->page->url != $assessment->url)) {
652
            $o .= $this->output->container(html_writer::link($assessment->url, $title), 'title');
653
        } else {
654
            $o .= $this->output->container($title, 'title');
655
        }
656
 
657
        if (!$anonymous) {
658
            $reviewer   = $assessment->reviewer;
659
            $userpic    = $this->output->user_picture($reviewer, array('courseid' => $this->page->course->id, 'size' => 32));
660
 
661
            $userurl    = new moodle_url('/user/view.php',
662
                                       array('id' => $reviewer->id, 'course' => $this->page->course->id));
663
            $a          = new stdClass();
664
            $a->name    = fullname($reviewer);
665
            $a->url     = $userurl->out();
666
            $byfullname = get_string('assessmentby', 'workshop', $a);
667
            $oo         = $this->output->container($userpic, 'picture');
668
            $oo        .= $this->output->container($byfullname, 'fullname');
669
 
670
            $o .= $this->output->container($oo, 'reviewer');
671
        }
672
 
673
        if (is_null($assessment->realgrade)) {
674
            $o .= $this->output->container(
675
                get_string('notassessed', 'workshop'),
676
                'grade nograde'
677
            );
678
        } else {
679
            $a              = new stdClass();
680
            $a->max         = $assessment->maxgrade;
681
            $a->received    = $assessment->realgrade;
682
            $o .= $this->output->container(
683
                get_string('gradeinfo', 'workshop', $a),
684
                'grade'
685
            );
686
 
687
            if (!is_null($assessment->weight) and $assessment->weight != 1) {
688
                $o .= $this->output->container(
689
                    get_string('weightinfo', 'workshop', $assessment->weight),
690
                    'weight'
691
                );
692
            }
693
        }
694
 
695
        $o .= $this->output->container_start('actions');
696
        foreach ($assessment->actions as $action) {
697
            $o .= $this->output->single_button($action->url, $action->label, $action->method);
698
        }
699
        $o .= $this->output->container_end(); // actions
700
 
701
        $o .= $this->output->container_end(); // header
702
 
703
        if (!is_null($assessment->form)) {
704
            $o .= print_collapsible_region_start('assessment-form-wrapper', uniqid('workshop-assessment'),
705
                    get_string('assessmentform', 'workshop'), 'workshop-viewlet-assessmentform-collapsed', false, true);
706
            $o .= $this->output->container(self::moodleform($assessment->form), 'assessment-form');
707
            $o .= print_collapsible_region_end(true);
708
 
709
            if (!$assessment->form->is_editable()) {
710
                $o .= $this->overall_feedback($assessment);
711
            }
712
        }
713
 
714
        $o .= $this->output->container_end(); // main wrapper
715
 
716
        return $o;
717
    }
718
 
719
    /**
720
     * Renders the assessment of an example submission
721
     *
722
     * @param workshop_example_assessment $assessment
723
     * @return string HTML
724
     */
725
    protected function render_workshop_example_assessment(workshop_example_assessment $assessment) {
726
        return $this->render_workshop_assessment($assessment);
727
    }
728
 
729
    /**
730
     * Renders the reference assessment of an example submission
731
     *
732
     * @param workshop_example_reference_assessment $assessment
733
     * @return string HTML
734
     */
735
    protected function render_workshop_example_reference_assessment(workshop_example_reference_assessment $assessment) {
736
        return $this->render_workshop_assessment($assessment);
737
    }
738
 
739
    /**
740
     * Renders the overall feedback for the author of the submission
741
     *
742
     * @param workshop_assessment $assessment
743
     * @return string HTML
744
     */
745
    protected function overall_feedback(workshop_assessment $assessment) {
746
 
747
        $content = $assessment->get_overall_feedback_content();
748
 
749
        if ($content === false) {
750
            return '';
751
        }
752
 
753
        $o = '';
754
 
755
        if (!is_null($content)) {
756
            $o .= $this->output->container($content, 'content');
757
        }
758
 
759
        $attachments = $assessment->get_overall_feedback_attachments();
760
 
761
        if (!empty($attachments)) {
762
            $o .= $this->output->container_start('attachments');
763
            $images = '';
764
            $files = '';
765
            foreach ($attachments as $attachment) {
766
                $icon = $this->output->pix_icon(file_file_icon($attachment), get_mimetype_description($attachment),
767
                    'moodle', array('class' => 'icon'));
768
                $link = html_writer::link($attachment->fileurl, $icon.' '.substr($attachment->filepath.$attachment->filename, 1));
769
                if (file_mimetype_in_typegroup($attachment->mimetype, 'web_image')) {
770
                    $preview = html_writer::empty_tag('img', array('src' => $attachment->previewurl, 'alt' => '', 'class' => 'preview'));
771
                    $preview = html_writer::tag('a', $preview, array('href' => $attachment->fileurl));
772
                    $images .= $this->output->container($preview);
773
                } else {
774
                    $files .= html_writer::tag('li', $link, array('class' => $attachment->mimetype));
775
                }
776
            }
777
            if ($images) {
778
                $images = $this->output->container($images, 'images');
779
            }
780
 
781
            if ($files) {
782
                $files = html_writer::tag('ul', $files, array('class' => 'files'));
783
            }
784
 
785
            $o .= $images.$files;
786
            $o .= $this->output->container_end();
787
        }
788
 
789
        if ($o === '') {
790
            return '';
791
        }
792
 
793
        $o = $this->output->box($o, 'overallfeedback');
794
        $o = print_collapsible_region($o, 'overall-feedback-wrapper', uniqid('workshop-overall-feedback'),
795
                get_string('overallfeedback', 'workshop'), 'workshop-viewlet-overallfeedback-collapsed', false, true);
796
 
797
        return $o;
798
    }
799
 
800
    /**
801
     * Renders a perpage selector for workshop listings
802
     *
803
     * The scripts using this have to define the $PAGE->url prior to calling this
804
     * and deal with eventually submitted value themselves.
805
     *
806
     * @param int $current current value of the perpage parameter
807
     * @return string HTML
808
     */
809
    public function perpage_selector($current=10) {
810
 
811
        $options = array();
812
        foreach (array(10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 1000) as $option) {
813
            if ($option != $current) {
814
                $options[$option] = $option;
815
            }
816
        }
817
        $select = new single_select($this->page->url, 'perpage', $options, '', array('' => get_string('showingperpagechange', 'mod_workshop')));
818
        $select->label = get_string('showingperpage', 'mod_workshop', $current);
819
        $select->method = 'post';
820
 
821
        return $this->output->container($this->output->render($select), 'perpagewidget');
822
    }
823
 
824
    /**
825
     * Render the initials bars for workshop.
826
     *
827
     * @param workshop $workshop the current workshop of initial bars.
828
     * @param moodle_url $url base URL object.
829
     * @return string HTML.
830
     */
831
    public function initials_bars(workshop $workshop, moodle_url $url): string {
832
        $ifirst = $workshop->get_initial_first();
833
        $ilast = $workshop->get_initial_last();
834
 
835
        $html = $this->output->initials_bar($ifirst, 'firstinitial', get_string('firstname'), 'ifirst', $url);
836
        $html .= $this->output->initials_bar($ilast, 'lastinitial', get_string('lastname'), 'ilast', $url);
837
        return $html;
838
    }
839
 
840
    /**
841
     * Renders the user's final grades
842
     *
843
     * @param workshop_final_grades $grades with the info about grades in the gradebook
844
     * @return string HTML
845
     */
846
    protected function render_workshop_final_grades(workshop_final_grades $grades) {
847
 
848
        $out = html_writer::start_tag('div', array('class' => 'finalgrades'));
849
 
850
        if (!empty($grades->submissiongrade)) {
851
            $cssclass = 'grade submissiongrade';
852
            if ($grades->submissiongrade->hidden) {
853
                $cssclass .= ' hiddengrade';
854
            }
855
            $out .= html_writer::tag(
856
                'div',
857
                html_writer::tag('div', get_string('submissiongrade', 'mod_workshop'), array('class' => 'gradetype')) .
858
                html_writer::tag('div', $grades->submissiongrade->str_long_grade, array('class' => 'gradevalue')),
859
                array('class' => $cssclass)
860
            );
861
        }
862
 
863
        if (!empty($grades->assessmentgrade)) {
864
            $cssclass = 'grade assessmentgrade';
865
            if ($grades->assessmentgrade->hidden) {
866
                $cssclass .= ' hiddengrade';
867
            }
868
            $out .= html_writer::tag(
869
                'div',
870
                html_writer::tag('div', get_string('gradinggrade', 'mod_workshop'), array('class' => 'gradetype')) .
871
                html_writer::tag('div', $grades->assessmentgrade->str_long_grade, array('class' => 'gradevalue')),
872
                array('class' => $cssclass)
873
            );
874
        }
875
 
876
        $out .= html_writer::end_tag('div');
877
 
878
        return $out;
879
    }
880
 
881
    ////////////////////////////////////////////////////////////////////////////
882
    // Internal rendering helper methods
883
    ////////////////////////////////////////////////////////////////////////////
884
 
885
    /**
886
     * Renders a list of files attached to the submission
887
     *
888
     * If format==html, then format a html string. If format==text, then format a text-only string.
889
     * Otherwise, returns html for non-images and html to display the image inline.
890
     *
891
     * @param int $submissionid submission identifier
892
     * @param string format the format of the returned string - html|text
893
     * @return string formatted text to be echoed
894
     */
895
    protected function helper_submission_attachments($submissionid, $format = 'html') {
896
        global $CFG;
897
        require_once($CFG->libdir.'/filelib.php');
898
 
899
        $fs     = get_file_storage();
900
        $ctx    = $this->page->context;
901
        $files  = $fs->get_area_files($ctx->id, 'mod_workshop', 'submission_attachment', $submissionid);
902
 
903
        $outputimgs     = '';   // images to be displayed inline
904
        $outputfiles    = '';   // list of attachment files
905
 
906
        foreach ($files as $file) {
907
            if ($file->is_directory()) {
908
                continue;
909
            }
910
 
911
            $filepath   = $file->get_filepath();
912
            $filename   = $file->get_filename();
913
            $fileurl    = moodle_url::make_pluginfile_url($ctx->id, 'mod_workshop', 'submission_attachment',
914
                            $submissionid, $filepath, $filename, true);
915
            $embedurl   = moodle_url::make_pluginfile_url($ctx->id, 'mod_workshop', 'submission_attachment',
916
                            $submissionid, $filepath, $filename, false);
917
            $embedurl   = new moodle_url($embedurl, array('preview' => 'bigthumb'));
918
            $type       = $file->get_mimetype();
919
            $image      = $this->output->pix_icon(file_file_icon($file), get_mimetype_description($file), 'moodle', array('class' => 'icon'));
920
 
921
            $linkhtml   = html_writer::link($fileurl, $image . substr($filepath, 1) . $filename);
922
            $linktxt    = "$filename [$fileurl]";
923
 
924
            if ($format == 'html') {
925
                if (file_mimetype_in_typegroup($type, 'web_image')) {
926
                    $preview     = html_writer::empty_tag('img', array('src' => $embedurl, 'alt' => '', 'class' => 'preview'));
927
                    $preview     = html_writer::tag('a', $preview, array('href' => $fileurl));
928
                    $outputimgs .= $this->output->container($preview);
929
 
930
                } else {
931
                    $outputfiles .= html_writer::tag('li', $linkhtml, array('class' => $type));
932
                }
933
 
934
            } else if ($format == 'text') {
935
                $outputfiles .= $linktxt . PHP_EOL;
936
            }
937
 
938
            if (!empty($CFG->enableplagiarism)) {
939
                require_once($CFG->libdir.'/plagiarismlib.php');
940
                $outputfiles .= plagiarism_get_links(array('userid' => $file->get_userid(),
941
                    'file' => $file,
942
                    'cmid' => $this->page->cm->id,
943
                    'course' => $this->page->course->id));
944
            }
945
        }
946
 
947
        if ($format == 'html') {
948
            if ($outputimgs) {
949
                $outputimgs = $this->output->container($outputimgs, 'images');
950
            }
951
 
952
            if ($outputfiles) {
953
                $outputfiles = html_writer::tag('ul', $outputfiles, array('class' => 'files'));
954
            }
955
 
956
            return $this->output->container($outputimgs . $outputfiles, 'attachments');
957
 
958
        } else {
959
            return $outputfiles;
960
        }
961
    }
962
 
963
    /**
964
     * Renders the tasks for the single phase in the user plan
965
     *
966
     * @param stdClass $tasks
967
     * @return string html code
968
     */
969
    protected function helper_user_plan_tasks(array $tasks) {
970
        $out = '';
971
        foreach ($tasks as $taskcode => $task) {
972
            $classes = '';
973
            $accessibilitytext = '';
974
            $icon = null;
975
            if ($task->completed === true) {
976
                $classes .= ' completed';
977
                $accessibilitytext .= get_string('taskdone', 'workshop') . ' ';
978
            } else if ($task->completed === false) {
979
                $classes .= ' fail';
980
                $accessibilitytext .= get_string('taskfail', 'workshop') . ' ';
981
            } else if ($task->completed === 'info') {
982
                $classes .= ' info';
983
                $accessibilitytext .= get_string('taskinfo', 'workshop') . ' ';
984
            } else {
985
                $accessibilitytext .= get_string('tasktodo', 'workshop') . ' ';
986
            }
987
            if (is_null($task->link)) {
988
                $title = html_writer::tag('span', $accessibilitytext, array('class' => 'accesshide'));
989
                $title .= $task->title;
990
            } else {
991
                $title = html_writer::tag('span', $accessibilitytext, array('class' => 'accesshide'));
992
                $title .= html_writer::link($task->link, $task->title);
993
            }
994
            $title = $this->output->container($title, 'title');
995
            $details = $this->output->container($task->details, 'details');
996
            $out .= html_writer::tag('li', $title . $details, array('class' => $classes));
997
        }
998
        if ($out) {
999
            $out = html_writer::tag('ul', $out, array('class' => 'tasks'));
1000
        }
1001
        return $out;
1002
    }
1003
 
1004
    /**
1005
     * Renders a text with icons to sort by the given column
1006
     *
1007
     * This is intended for table headings.
1008
     *
1009
     * @param string $text    The heading text
1010
     * @param string $sortid  The column id used for sorting
1011
     * @param string $sortby  Currently sorted by (column id)
1012
     * @param string $sorthow Currently sorted how (ASC|DESC)
1013
     *
1014
     * @return string
1015
     */
1016
    protected function helper_sortable_heading($text, $sortid=null, $sortby=null, $sorthow=null) {
1017
 
1018
        $out = html_writer::tag('span', $text, array('class'=>'text'));
1019
 
1020
        if (!is_null($sortid)) {
1021
            if ($sortby !== $sortid or $sorthow !== 'ASC') {
1022
                $url = new moodle_url($this->page->url);
1023
                $url->params(array('sortby' => $sortid, 'sorthow' => 'ASC'));
1024
                $out .= $this->output->action_icon($url, new pix_icon('t/sort_asc', get_string('sortasc', 'workshop')),
1025
                    null, array('class' => 'iconsort sort asc'));
1026
            }
1027
            if ($sortby !== $sortid or $sorthow !== 'DESC') {
1028
                $url = new moodle_url($this->page->url);
1029
                $url->params(array('sortby' => $sortid, 'sorthow' => 'DESC'));
1030
                $out .= $this->output->action_icon($url, new pix_icon('t/sort_desc', get_string('sortdesc', 'workshop')),
1031
                    null, array('class' => 'iconsort sort desc'));
1032
            }
1033
        }
1034
        return $out;
1035
}
1036
 
1037
    /**
1038
     * @param stdClass $participant
1039
     * @param array $userinfo
1040
     * @return string
1041
     */
1042
    protected function helper_grading_report_participant(stdclass $participant, array $userinfo) {
1043
        $userid = $participant->userid;
1044
        $out  = $this->output->user_picture($userinfo[$userid], array('courseid' => $this->page->course->id, 'size' => 35));
1045
        $out .= html_writer::tag('span', fullname($userinfo[$userid]));
1046
 
1047
        return $out;
1048
    }
1049
 
1050
    /**
1051
     * @param stdClass $participant
1052
     * @return string
1053
     */
1054
    protected function helper_grading_report_submission(stdclass $participant) {
1055
        global $CFG;
1056
 
1057
        if (is_null($participant->submissionid)) {
1058
            $out = $this->output->container(get_string('nosubmissionfound', 'workshop'), 'info');
1059
        } else {
1060
            $url = new moodle_url('/mod/workshop/submission.php',
1061
                                  array('cmid' => $this->page->context->instanceid, 'id' => $participant->submissionid));
1062
            $out = html_writer::link($url, format_string($participant->submissiontitle), array('class'=>'title'));
1063
 
1064
            $lastmodified = get_string('userdatemodified', 'workshop', userdate($participant->submissionmodified));
1065
            $out .= html_writer::tag('div', $lastmodified, array('class' => 'lastmodified'));
1066
        }
1067
 
1068
        return $out;
1069
    }
1070
 
1071
    /**
1072
     * @todo Highlight the nulls
1073
     * @param stdClass|null $assessment
1074
     * @param bool $shownames
1075
     * @param string $separator between the grade and the reviewer/author
1076
     * @return string
1077
     */
1078
    protected function helper_grading_report_assessment($assessment, $shownames, array $userinfo, $separator) {
1079
        global $CFG;
1080
 
1081
        if (is_null($assessment)) {
1082
            return get_string('nullgrade', 'workshop');
1083
        }
1084
        $a = new stdclass();
1085
        $a->grade = is_null($assessment->grade) ? get_string('nullgrade', 'workshop') : $assessment->grade;
1086
        $a->gradinggrade = is_null($assessment->gradinggrade) ? get_string('nullgrade', 'workshop') : $assessment->gradinggrade;
1087
        $a->weight = $assessment->weight;
1088
        // grrr the following logic should really be handled by a future language pack feature
1089
        if (is_null($assessment->gradinggradeover)) {
1090
            if ($a->weight == 1) {
1091
                $grade = get_string('formatpeergrade', 'workshop', $a);
1092
            } else {
1093
                $grade = get_string('formatpeergradeweighted', 'workshop', $a);
1094
            }
1095
        } else {
1096
            $a->gradinggradeover = $assessment->gradinggradeover;
1097
            if ($a->weight == 1) {
1098
                $grade = get_string('formatpeergradeover', 'workshop', $a);
1099
            } else {
1100
                $grade = get_string('formatpeergradeoverweighted', 'workshop', $a);
1101
            }
1102
        }
1103
        $url = new moodle_url('/mod/workshop/assessment.php',
1104
                              array('asid' => $assessment->assessmentid));
1105
        $grade = html_writer::link($url, $grade, array('class'=>'grade'));
1106
 
1107
        if ($shownames) {
1108
            $userid = $assessment->userid;
1109
            $name   = $this->output->user_picture($userinfo[$userid], array('courseid' => $this->page->course->id, 'size' => 16));
1110
            $name  .= html_writer::tag('span', fullname($userinfo[$userid]), array('class' => 'fullname'));
1111
            $name   = $separator . html_writer::tag('span', $name, array('class' => 'user'));
1112
        } else {
1113
            $name   = '';
1114
        }
1115
 
1116
        return $this->output->container($grade . $name, 'assessmentdetails');
1117
    }
1118
 
1119
    /**
1120
     * Formats the aggreagated grades
1121
     */
1122
    protected function helper_grading_report_grade($grade, $over=null) {
1123
        $a = new stdclass();
1124
        $a->grade = is_null($grade) ? get_string('nullgrade', 'workshop') : $grade;
1125
        if (is_null($over)) {
1126
            $text = get_string('formataggregatedgrade', 'workshop', $a);
1127
        } else {
1128
            $a->over = is_null($over) ? get_string('nullgrade', 'workshop') : $over;
1129
            $text = get_string('formataggregatedgradeover', 'workshop', $a);
1130
        }
1131
        return $text;
1132
    }
1133
 
1134
    ////////////////////////////////////////////////////////////////////////////
1135
    // Static helpers
1136
    ////////////////////////////////////////////////////////////////////////////
1137
 
1138
    /**
1139
     * Helper method dealing with the fact we can not just fetch the output of moodleforms
1140
     *
1141
     * @param moodleform $mform
1142
     * @return string HTML
1143
     */
1144
    protected static function moodleform(moodleform $mform) {
1145
 
1146
        ob_start();
1147
        $mform->display();
1148
        $o = ob_get_contents();
1149
        ob_end_clean();
1150
 
1151
        return $o;
1152
    }
1153
 
1154
    /**
1155
     * Helper function returning the n-th item of the array
1156
     *
1157
     * @param array $a
1158
     * @param int   $n from 0 to m, where m is th number of items in the array
1159
     * @return mixed the $n-th element of $a
1160
     */
1161
    protected static function array_nth(array $a, $n) {
1162
        $keys = array_keys($a);
1163
        if ($n < 0 or $n > count($keys) - 1) {
1164
            return null;
1165
        }
1166
        $key = $keys[$n];
1167
        return $a[$key];
1168
    }
1169
 
1170
    /**
1171
     * Tries to guess the fullname format set at the site
1172
     *
1173
     * @return string fl|lf
1174
     */
1175
    protected static function fullname_format() {
1176
        $fake = new stdclass(); // fake user
1177
        $fake->lastname = 'LLLL';
1178
        $fake->firstname = 'FFFF';
1179
        $fullname = get_string('fullnamedisplay', '', $fake);
1180
        if (strpos($fullname, 'LLLL') < strpos($fullname, 'FFFF')) {
1181
            return 'lf';
1182
        } else {
1183
            return 'fl';
1184
        }
1185
    }
1186
 
1187
    /**
1188
     * Generates the action buttons.
1189
     *
1190
     * @param workshop $workshop The current workshop.
1191
     * @param workshop_user_plan $userplan An individual workshop plan for the user.
1192
     * @return string HTML to display.
1193
     */
1194
    public function render_action_buttons(workshop $workshop, workshop_user_plan $userplan): string {
1195
        global $USER;
1196
        $output = '';
1197
 
1198
        switch ($workshop->phase) {
1199
            case workshop::PHASE_SUBMISSION:
1200
                // Does the user have to assess examples before submitting their own work?
1201
                $examplesmust = ($workshop->useexamples && $workshop->examplesmode == workshop::EXAMPLES_BEFORE_SUBMISSION);
1202
 
1203
                // Is the assessment of example submissions considered finished?
1204
                $examplesdone = has_capability('mod/workshop:manageexamples', $workshop->context);
1205
 
1206
                if ($workshop->assessing_examples_allowed() && has_capability('mod/workshop:submit', $workshop->context) &&
1207
                    !has_capability('mod/workshop:manageexamples', $workshop->context)) {
1208
                    $examples = $userplan->get_examples();
1209
                    $left = 0;
1210
                    // Make sure the current user has all examples allocated.
1211
                    foreach ($examples as $exampleid => $example) {
1212
                        if (is_null($example->grade)) {
1213
                            $left++;
1214
                            break;
1215
                        }
1216
                    }
1217
                    if ($left > 0 && $workshop->examplesmode != workshop::EXAMPLES_VOLUNTARY) {
1218
                        $examplesdone = false;
1219
                    } else {
1220
                        $examplesdone = true;
1221
                    }
1222
                }
1223
 
1224
                if (has_capability('mod/workshop:submit', $this->page->context) && (!$examplesmust || $examplesdone)) {
1225
                    if (!$workshop->get_submission_by_author($USER->id)) {
1226
                        $btnurl = new moodle_url($workshop->submission_url(), ['edit' => 'on']);
1227
                        $btntxt = get_string('createsubmission', 'workshop');
1228
                        $output .= $this->single_button($btnurl, $btntxt, 'get', ['type' => single_button::BUTTON_PRIMARY]);
1229
                    }
1230
                }
1231
                break;
1232
 
1233
            case workshop::PHASE_ASSESSMENT:
1234
                if (has_capability('mod/workshop:submit', $this->page->context)) {
1235
                    if (!$workshop->get_submission_by_author($USER->id)) {
1236
                        if ($workshop->creating_submission_allowed($USER->id)) {
1237
                            $btnurl = new moodle_url($workshop->submission_url(), ['edit' => 'on']);
1238
                            $btntxt = get_string('createsubmission', 'workshop');
1239
                            $output .= $this->single_button($btnurl, $btntxt, 'get', ['type' => single_button::BUTTON_PRIMARY]);
1240
                        }
1241
                    }
1242
                }
1243
        }
1244
 
1245
        return $output;
1246
    }
1247
 
1248
    /**
1249
     * Generates the view page.
1250
     *
1251
     * @param workshop $workshop The current workshop.
1252
     * @param workshop_user_plan $userplan An individual workshop plan for the user.
1253
     * @param string $currentphasetitle The current phase title.
1254
     * @param int $page The current page (for the pagination).
1255
     * @param string $sortby Lastname|firstname|submissiontitle|submissiongrade|gradinggrade.
1256
     * @param string $sorthow ASC|DESC.
1257
     * @return string HTML to display.
1258
     */
1259
    public function view_page(workshop $workshop, workshop_user_plan $userplan, string $currentphasetitle,
1260
            int $page, string $sortby, string $sorthow): string {
1261
        $output = '';
1262
 
1263
        $output .= $this->render_action_buttons($workshop, $userplan);
11 efrain 1264
        $output .= $this->heading(format_string($currentphasetitle), 2, null, 'mod_workshop-userplanheading');
1 efrain 1265
        $output .= $this->render($userplan);
1266
        $output .= $this->view_submissions_report($workshop, $userplan, $page, $sortby, $sorthow);
1267
 
1268
        return $output;
1269
    }
1270
 
1271
    /**
1272
     * Generates the submission report.
1273
     *
1274
     * @param workshop $workshop The current workshop.
1275
     * @param workshop_user_plan $userplan An individual workshop plan for the user.
1276
     * @param int $page The current page (for the pagination).
1277
     * @param string $sortby Lastname|firstname|submissiontitle|submissiongrade|gradinggrade.
1278
     * @param string $sorthow ASC|DESC.
1279
     * @return string HTML to display.
1280
     */
1281
    public function view_submissions_report(workshop $workshop, workshop_user_plan $userplan,
1282
            int $page, string $sortby, string $sorthow): string {
1283
        global $USER;
1284
        $output = '';
1285
 
1286
        switch ($workshop->phase) {
1287
            case workshop::PHASE_SETUP:
1288
                if (trim($workshop->intro)) {
1289
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-intro', get_string('introduction', 'workshop'),
1290
                        'workshop-viewlet-intro-collapsed', false, true);
1291
                    $output .= $this->box(format_module_intro('workshop', $workshop, $workshop->cm->id), 'generalbox');
1292
                    $output .= print_collapsible_region_end(true);
1293
                }
1294
                if ($workshop->useexamples && has_capability('mod/workshop:manageexamples', $this->page->context)) {
1295
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-allexamples',
1296
                        get_string('examplesubmissions', 'workshop'), 'workshop-viewlet-allexamples-collapsed', false, true);
1297
                    $output .= $this->box_start('generalbox examples');
1298
                    if ($workshop->grading_strategy_instance()->form_ready()) {
1299
                        if (!$examples = $workshop->get_examples_for_manager()) {
1300
                            $output .= $this->container(get_string('noexamples', 'workshop'), 'noexamples');
1301
                        }
1302
                        foreach ($examples as $example) {
1303
                            $summary = $workshop->prepare_example_summary($example);
1304
                            $summary->editable = true;
1305
                            $output .= $this->render($summary);
1306
                        }
1307
                        $aurl = new moodle_url($workshop->exsubmission_url(0), ['edit' => 'on']);
1308
                        $output .= $this->single_button($aurl, get_string('exampleadd', 'workshop'), 'get');
1309
                    } else {
1310
                        $output .= $this->container(get_string('noexamplesformready', 'workshop'));
1311
                    }
1312
                    $output .= $this->box_end();
1313
                    $output .= print_collapsible_region_end(true);
1314
                }
1315
                break;
1316
            case workshop::PHASE_SUBMISSION:
1317
                $examplesmust = ($workshop->useexamples && $workshop->examplesmode == workshop::EXAMPLES_BEFORE_SUBMISSION);
1318
                $examplesdone = has_capability('mod/workshop:manageexamples', $workshop->context);
1319
                if (trim($workshop->instructauthors)) {
1320
                    $instructions = file_rewrite_pluginfile_urls($workshop->instructauthors,
1321
                        'pluginfile.php', $this->page->context->id,
1322
                        'mod_workshop', 'instructauthors', null, workshop::instruction_editors_options($this->page->context));
1323
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-instructauthors',
1324
                        get_string('instructauthors', 'workshop'),
1325
                        'workshop-viewlet-instructauthors-collapsed', false, true);
1326
                    $output .= $this->box(format_text($instructions, $workshop->instructauthorsformat, ['overflowdiv' => true]),
1327
                        ['generalbox', 'instructions']);
1328
                    $output .= print_collapsible_region_end(true);
1329
                }
1330
 
1331
                if ($workshop->assessing_examples_allowed()
1332
                    && has_capability('mod/workshop:submit', $workshop->context)
1333
                    && !has_capability('mod/workshop:manageexamples', $workshop->context)) {
1334
                    $examples = $userplan->get_examples();
1335
                    $total = count($examples);
1336
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-examples',
1337
                        get_string('exampleassessments', 'workshop'),
1338
                        'workshop-viewlet-examples-collapsed', $examplesdone, true);
1339
                    $output .= $this->box_start('generalbox exampleassessments');
1340
                    if ($total == 0) {
1341
                        $output .= $this->heading(get_string('noexamples', 'workshop'), 3);
1342
                    } else {
1343
                        foreach ($examples as $example) {
1344
                            $summary = $workshop->prepare_example_summary($example);
1345
                            $output .= $this->render($summary);
1346
                        }
1347
                    }
1348
                    $output .= $this->box_end();
1349
                    $output .= print_collapsible_region_end(true);
1350
                }
1351
 
1352
                if (has_capability('mod/workshop:submit', $this->page->context) && (!$examplesmust || $examplesdone)) {
1353
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-ownsubmission',
1354
                        get_string('yoursubmission', 'workshop'),
1355
                        'workshop-viewlet-ownsubmission-collapsed', false, true);
1356
                    $output .= $this->box_start('generalbox ownsubmission');
1357
                    if ($submission = $workshop->get_submission_by_author($USER->id)) {
1358
                        $output .= $this->render($workshop->prepare_submission_summary($submission, true));
1359
                    } else {
1360
                        $output .= $this->container(get_string('noyoursubmission', 'workshop'));
1361
                    }
1362
 
1363
                    $output .= $this->box_end();
1364
                    $output .= print_collapsible_region_end(true);
1365
                }
1366
 
1367
                if (has_capability('mod/workshop:viewallsubmissions', $this->page->context)) {
1368
                    $groupmode = groups_get_activity_groupmode($workshop->cm);
1369
                    $groupid = groups_get_activity_group($workshop->cm, true);
1370
 
1371
                    if ($groupmode == SEPARATEGROUPS && !has_capability('moodle/site:accessallgroups', $workshop->context)) {
1372
                        $allowedgroups = groups_get_activity_allowed_groups($workshop->cm);
1373
                        if (empty($allowedgroups)) {
1374
                            $output .= $this->container(get_string('groupnoallowed', 'mod_workshop'), 'groupwidget error');
1375
                            break;
1376
                        }
1377
                        if (!in_array($groupid, array_keys($allowedgroups))) {
1378
                            $output .= $this->container(get_string('groupnotamember', 'core_group'), 'groupwidget error');
1379
                            break;
1380
                        }
1381
                    }
1382
 
1383
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-allsubmissions',
1384
                        get_string('submissionsreport', 'workshop'),
1385
                        'workshop-viewlet-allsubmissions-collapsed', false, true);
1386
 
1387
                    $perpage = get_user_preferences('workshop_perpage', 10);
1388
                    $data = $workshop->prepare_grading_report_data($USER->id, $groupid, $page, $perpage, $sortby, $sorthow);
1389
                    if ($data) {
1390
                        $countparticipants = $workshop->count_participants();
1391
                        $countsubmissions = $workshop->count_submissions(array_keys($data->grades), $groupid);
1392
                        $a = new stdClass();
1393
                        $a->submitted = $countsubmissions;
1394
                        $a->notsubmitted = $data->totalcount - $countsubmissions;
1395
 
1396
                        $output .= html_writer::tag('div', get_string('submittednotsubmitted', 'workshop', $a));
1397
 
1398
                        $output .= $this->container(
1399
                            groups_print_activity_menu($workshop->cm, $this->page->url, true), 'groupwidget');
1400
 
1401
                        // Prepare the paging bar.
1402
                        $baseurl = new moodle_url($this->page->url, ['sortby' => $sortby, 'sorthow' => $sorthow]);
1403
                        $pagingbar = new paging_bar($data->totalcount, $page, $perpage, $baseurl, 'page');
1404
 
1405
                        // Populate the display options for the submissions report.
1406
                        $reportopts = new stdclass();
1407
                        $reportopts->showauthornames = has_capability('mod/workshop:viewauthornames', $workshop->context);
1408
                        $reportopts->showreviewernames = has_capability('mod/workshop:viewreviewernames', $workshop->context);
1409
                        $reportopts->sortby = $sortby;
1410
                        $reportopts->sorthow = $sorthow;
1411
                        $reportopts->showsubmissiongrade = false;
1412
                        $reportopts->showgradinggrade = false;
1413
                        $reportopts->workshopphase = $workshop->phase;
1414
                        $output .= $this->initials_bars($workshop, $baseurl);
1415
                        $output .= $this->render($pagingbar);
1416
                        $output .= $this->render(new workshop_grading_report($data, $reportopts));
1417
                        $output .= $this->render($pagingbar);
1418
                        $output .= $this->perpage_selector($perpage);
1419
                    } else {
1420
                        $output .= html_writer::tag('div', get_string('nothingfound', 'workshop'),
1421
                            'info', false);
1422
                    }
1423
                    $output .= print_collapsible_region_end(true);
1424
                }
1425
                break;
1426
 
1427
            case workshop::PHASE_ASSESSMENT:
1428
 
1429
                $ownsubmissionexists = null;
1430
                if (has_capability('mod/workshop:submit', $this->page->context)) {
1431
                    if ($ownsubmission = $workshop->get_submission_by_author($USER->id)) {
1432
                        $output .= print_collapsible_region_start('', 'workshop-viewlet-ownsubmission',
1433
                            get_string('yoursubmission', 'workshop'),
1434
                            'workshop-viewlet-ownsubmission-collapsed', true, true);
1435
                        $output .= $this->box_start('generalbox ownsubmission');
1436
                        $output .= $this->render($workshop->prepare_submission_summary($ownsubmission, true));
1437
                        $ownsubmissionexists = true;
1438
                    } else {
1439
                        $output .= print_collapsible_region_start('', 'workshop-viewlet-ownsubmission',
1440
                            get_string('yoursubmission', 'workshop'),
1441
                            'workshop-viewlet-ownsubmission-collapsed', false, true);
1442
                        $output .= $this->box_start('generalbox ownsubmission');
1443
                        $output .= $this->container(get_string('noyoursubmission', 'workshop'));
1444
                        $ownsubmissionexists = false;
1445
                    }
1446
 
1447
                    $output .= $this->box_end();
1448
                    $output .= print_collapsible_region_end(true);
1449
                }
1450
 
1451
                if (has_capability('mod/workshop:viewallassessments', $this->page->context)) {
1452
                    $perpage = get_user_preferences('workshop_perpage', 10);
1453
                    $groupid = groups_get_activity_group($workshop->cm, true);
1454
                    $data = $workshop->prepare_grading_report_data($USER->id, $groupid, $page, $perpage, $sortby, $sorthow);
1455
                    if ($data) {
1456
                        $showauthornames = has_capability('mod/workshop:viewauthornames', $workshop->context);
1457
                        $showreviewernames = has_capability('mod/workshop:viewreviewernames', $workshop->context);
1458
 
1459
                        // Prepare paging bar.
1460
                        $baseurl = new moodle_url($this->page->url, ['sortby' => $sortby, 'sorthow' => $sorthow]);
1461
                        $pagingbar = new paging_bar($data->totalcount, $page, $perpage, $baseurl, 'page');
1462
 
1463
                        // Grading report display options.
1464
                        $reportopts = new stdclass();
1465
                        $reportopts->showauthornames = $showauthornames;
1466
                        $reportopts->showreviewernames = $showreviewernames;
1467
                        $reportopts->sortby = $sortby;
1468
                        $reportopts->sorthow = $sorthow;
1469
                        $reportopts->showsubmissiongrade = false;
1470
                        $reportopts->showgradinggrade = false;
1471
                        $reportopts->workshopphase = $workshop->phase;
1472
 
1473
                        $output .= print_collapsible_region_start('', 'workshop-viewlet-gradereport',
1474
                            get_string('gradesreport', 'workshop'),
1475
                            'workshop-viewlet-gradereport-collapsed', false, true);
1476
                        $output .= $this->box_start('generalbox gradesreport');
1477
                        $output .= $this->container(groups_print_activity_menu($workshop->cm,
1478
                            $this->page->url, true), 'groupwidget');
1479
                        $output .= $this->initials_bars($workshop, $baseurl);
1480
                        $output .= $this->render($pagingbar);
1481
                        $output .= $this->render(new workshop_grading_report($data, $reportopts));
1482
                        $output .= $this->render($pagingbar);
1483
                        $output .= $this->perpage_selector($perpage);
1484
                        $output .= $this->box_end();
1485
                        $output .= print_collapsible_region_end(true);
1486
                    }
1487
                }
1488
                if (trim($workshop->instructreviewers)) {
1489
                    $instructions = file_rewrite_pluginfile_urls($workshop->instructreviewers,
1490
                        'pluginfile.php', $this->page->context->id,
1491
                        'mod_workshop', 'instructreviewers', null, workshop::instruction_editors_options($this->page->context));
1492
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-instructreviewers',
1493
                        get_string('instructreviewers', 'workshop'),
1494
                        'workshop-viewlet-instructreviewers-collapsed', false, true);
1495
                    $output .= $this->box(format_text($instructions, $workshop->instructreviewersformat,
1496
                        ['overflowdiv' => true]), ['generalbox', 'instructions']);
1497
                    $output .= print_collapsible_region_end(true);
1498
                }
1499
 
1500
                // Does the user have to assess examples before assessing other's work?
1501
                $examplesmust = ($workshop->useexamples && $workshop->examplesmode == workshop::EXAMPLES_BEFORE_ASSESSMENT);
1502
 
1503
                // Is the assessment of example submissions considered finished?
1504
                $examplesdone = has_capability('mod/workshop:manageexamples', $workshop->context);
1505
 
1506
                // Can the examples be assessed?
1507
                $examplesavailable = true;
1508
 
1509
                if (!$examplesdone && $examplesmust && ($ownsubmissionexists === false)) {
1510
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-examplesfail',
1511
                        get_string('exampleassessments', 'workshop'),
1512
                        'workshop-viewlet-examplesfail-collapsed', false, true);
1513
                    $output .= $this->box(get_string('exampleneedsubmission', 'workshop'));
1514
                    $output .= print_collapsible_region_end(true);
1515
                    $examplesavailable = false;
1516
                }
1517
 
1518
                if ($workshop->assessing_examples_allowed()
1519
                    && has_capability('mod/workshop:submit', $workshop->context)
1520
                    && !has_capability('mod/workshop:manageexamples', $workshop->context)
1521
                    && $examplesavailable) {
1522
                    $examples = $userplan->get_examples();
1523
                    $total = count($examples);
1524
                    $left = 0;
1525
                    // Make sure the current user has all examples allocated.
1526
                    foreach ($examples as $exampleid => $example) {
1527
                        if (is_null($example->assessmentid)) {
1528
                            $examples[$exampleid]->assessmentid = $workshop->add_allocation($example, $USER->id, 0);
1529
                        }
1530
                        if (is_null($example->grade)) {
1531
                            $left++;
1532
                        }
1533
                    }
1534
                    if ($left > 0 && $workshop->examplesmode != workshop::EXAMPLES_VOLUNTARY) {
1535
                        $examplesdone = false;
1536
                    } else {
1537
                        $examplesdone = true;
1538
                    }
1539
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-examples',
1540
                        get_string('exampleassessments', 'workshop'),
1541
                        'workshop-viewlet-examples-collapsed', $examplesdone, true);
1542
                    $output .= $this->box_start('generalbox exampleassessments');
1543
                    if ($total == 0) {
1544
                        $output .= $this->heading(get_string('noexamples', 'workshop'), 3);
1545
                    } else {
1546
                        foreach ($examples as $example) {
1547
                            $summary = $workshop->prepare_example_summary($example);
1548
                            $output .= $this->render($summary);
1549
                        }
1550
                    }
1551
                    $output .= $this->box_end();
1552
                    $output .= print_collapsible_region_end(true);
1553
                }
1554
                if (!$examplesmust || $examplesdone) {
1555
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-assignedassessments',
1556
                        get_string('assignedassessments', 'workshop'),
1557
                        'workshop-viewlet-assignedassessments-collapsed', false, true);
1558
                    if (!$assessments = $workshop->get_assessments_by_reviewer($USER->id)) {
1559
                        $output .= $this->box_start('generalbox assessment-none');
1560
                        $output .= $this->notification(get_string('assignedassessmentsnone', 'workshop'));
1561
                        $output .= $this->box_end();
1562
                    } else {
1563
                        $shownames = has_capability('mod/workshop:viewauthornames', $this->page->context);
1564
                        foreach ($assessments as $assessment) {
1565
                            $submission = new stdClass();
1566
                            $submission->id = $assessment->submissionid;
1567
                            $submission->title = $assessment->submissiontitle;
1568
                            $submission->timecreated = $assessment->submissioncreated;
1569
                            $submission->timemodified = $assessment->submissionmodified;
1570
                            $userpicturefields = explode(',', implode(',', \core_user\fields::get_picture_fields()));
1571
                            foreach ($userpicturefields as $userpicturefield) {
1572
                                $prefixedusernamefield = 'author' . $userpicturefield;
1573
                                $submission->$prefixedusernamefield = $assessment->$prefixedusernamefield;
1574
                            }
1575
 
1576
                            // Transform the submission object into renderable component.
1577
                            $submission = $workshop->prepare_submission_summary($submission, $shownames);
1578
 
1579
                            if (is_null($assessment->grade)) {
1580
                                $submission->status = 'notgraded';
1581
                                $class = ' notgraded';
1582
                                $buttontext = get_string('assess', 'workshop');
1583
                            } else {
1584
                                $submission->status = 'graded';
1585
                                $class = ' graded';
1586
                                $buttontext = get_string('reassess', 'workshop');
1587
                            }
1588
 
1589
                            $output .= $this->box_start('generalbox assessment-summary' . $class);
1590
                            $output .= $this->render($submission);
1591
                            $aurl = $workshop->assess_url($assessment->id);
1592
                            $output .= $this->single_button($aurl, $buttontext, 'get');
1593
                            $output .= $this->box_end();
1594
                        }
1595
                    }
1596
                    $output .= print_collapsible_region_end(true);
1597
                }
1598
                break;
1599
            case workshop::PHASE_EVALUATION:
1600
                if (has_capability('mod/workshop:viewallassessments', $this->page->context)) {
1601
                    $perpage = get_user_preferences('workshop_perpage', 10);
1602
                    $groupid = groups_get_activity_group($workshop->cm, true);
1603
                    $data = $workshop->prepare_grading_report_data($USER->id, $groupid, $page, $perpage, $sortby, $sorthow);
1604
                    if ($data) {
1605
                        $showauthornames = has_capability('mod/workshop:viewauthornames', $workshop->context);
1606
                        $showreviewernames = has_capability('mod/workshop:viewreviewernames', $workshop->context);
1607
 
1608
                        if (has_capability('mod/workshop:overridegrades', $this->page->context)) {
1609
                            // Print a drop-down selector to change the current evaluation method.
1610
                            $selector = new single_select($this->page->url, 'eval', workshop::available_evaluators_list(),
1611
                                $workshop->evaluation, false, 'evaluationmethodchooser');
1612
                            $selector->set_label(get_string('evaluationmethod', 'mod_workshop'));
1613
                            $selector->set_help_icon('evaluationmethod', 'mod_workshop');
1614
                            $selector->method = 'post';
1615
                            $output .= $this->render($selector);
1616
                            // Load the grading evaluator.
1617
                            $evaluator = $workshop->grading_evaluation_instance();
1618
                            $form = $evaluator->get_settings_form(new moodle_url($workshop->aggregate_url(),
1619
                                compact('sortby', 'sorthow', 'page')));
1620
                            $form->display();
1621
                        }
1622
 
1623
                        // Prepare paging bar.
1624
                        $baseurl = new moodle_url($this->page->url, ['sortby' => $sortby, 'sorthow' => $sorthow]);
1625
                        $pagingbar = new paging_bar($data->totalcount, $page, $perpage, $baseurl, 'page');
1626
 
1627
                        // Grading report display options.
1628
                        $reportopts = new stdclass();
1629
                        $reportopts->showauthornames = $showauthornames;
1630
                        $reportopts->showreviewernames = $showreviewernames;
1631
                        $reportopts->sortby = $sortby;
1632
                        $reportopts->sorthow = $sorthow;
1633
                        $reportopts->showsubmissiongrade = true;
1634
                        $reportopts->showgradinggrade = true;
1635
                        $reportopts->workshopphase = $workshop->phase;
1636
 
1637
                        $output .= print_collapsible_region_start('', 'workshop-viewlet-gradereport',
1638
                            get_string('gradesreport', 'workshop'),
1639
                            'workshop-viewlet-gradereport-collapsed', false, true);
1640
                        $output .= $this->box_start('generalbox gradesreport');
1641
                        $output .= $this->container(groups_print_activity_menu($workshop->cm,
1642
                            $this->page->url, true), 'groupwidget');
1643
                        $output .= $this->initials_bars($workshop, $baseurl);
1644
                        $output .= $this->render($pagingbar);
1645
                        $output .= $this->render(new workshop_grading_report($data, $reportopts));
1646
                        $output .= $this->render($pagingbar);
1647
                        $output .= $this->perpage_selector($perpage);
1648
                        $output .= $this->box_end();
1649
                        $output .= print_collapsible_region_end(true);
1650
                    }
1651
                }
1652
                if (has_capability('mod/workshop:overridegrades', $workshop->context)) {
1653
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-cleargrades', get_string('toolbox', 'workshop'),
1654
                        'workshop-viewlet-cleargrades-collapsed', true, true);
1655
                    $output .= $this->box_start('generalbox toolbox');
1656
 
1657
                    // Clear aggregated grades.
1658
                    $url = new moodle_url($workshop->toolbox_url('clearaggregatedgrades'));
1659
                    $btn = new single_button($url, get_string('clearaggregatedgrades', 'workshop'), 'post');
1660
                    $btn->add_confirm_action(get_string('clearaggregatedgradesconfirm', 'workshop'));
1661
                    $output .= $this->container_start('toolboxaction');
1662
                    $output .= $this->render($btn);
1663
                    $output .= $this->help_icon('clearaggregatedgrades', 'workshop');
1664
                    $output .= $this->container_end();
1665
                    // Clear assessments.
1666
                    $url = new moodle_url($workshop->toolbox_url('clearassessments'));
1667
                    $btn = new single_button($url, get_string('clearassessments', 'workshop'), 'post');
1668
                    $btn->add_confirm_action(get_string('clearassessmentsconfirm', 'workshop'));
1669
                    $output .= $this->container_start('toolboxaction');
1670
                    $output .= $this->render($btn);
1671
                    $output .= $this->help_icon('clearassessments', 'workshop');
1672
 
1673
                    $output .= $this->output->pix_icon('i/risk_dataloss', get_string('riskdatalossshort', 'admin'));
1674
                    $output .= $this->container_end();
1675
 
1676
                    $output .= $this->box_end();
1677
                    $output .= print_collapsible_region_end(true);
1678
                }
1679
                if (has_capability('mod/workshop:submit', $this->page->context)) {
1680
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-ownsubmission',
1681
                        get_string('yoursubmission', 'workshop'),
1682
                        'workshop-viewlet-ownsubmission-collapsed', false, true);
1683
                    $output .= $this->box_start('generalbox ownsubmission');
1684
                    if ($submission = $workshop->get_submission_by_author($USER->id)) {
1685
                        $output .= $this->render($workshop->prepare_submission_summary($submission, true));
1686
                    } else {
1687
                        $output .= $this->container(get_string('noyoursubmission', 'workshop'));
1688
                    }
1689
                    $output .= $this->box_end();
1690
                    $output .= print_collapsible_region_end(true);
1691
                }
1692
                if ($assessments = $workshop->get_assessments_by_reviewer($USER->id)) {
1693
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-assignedassessments',
1694
                        get_string('assignedassessments', 'workshop'),
1695
                        'workshop-viewlet-assignedassessments-collapsed', false, true);
1696
                    $shownames = has_capability('mod/workshop:viewauthornames', $this->page->context);
1697
                    foreach ($assessments as $assessment) {
1698
                        $submission = new stdclass();
1699
                        $submission->id = $assessment->submissionid;
1700
                        $submission->title = $assessment->submissiontitle;
1701
                        $submission->timecreated = $assessment->submissioncreated;
1702
                        $submission->timemodified = $assessment->submissionmodified;
1703
                        $userpicturefields = explode(',', implode(',', \core_user\fields::get_picture_fields()));
1704
                        foreach ($userpicturefields as $userpicturefield) {
1705
                            $prefixedusernamefield = 'author' . $userpicturefield;
1706
                            $submission->$prefixedusernamefield = $assessment->$prefixedusernamefield;
1707
                        }
1708
 
1709
                        if (is_null($assessment->grade)) {
1710
                            $class = ' notgraded';
1711
                            $submission->status = 'notgraded';
1712
                            $buttontext = get_string('assess', 'workshop');
1713
                        } else {
1714
                            $class = ' graded';
1715
                            $submission->status = 'graded';
1716
                            $buttontext = get_string('reassess', 'workshop');
1717
                        }
1718
                        $output .= $this->box_start('generalbox assessment-summary' . $class);
1719
                        $output .= $this->render($workshop->prepare_submission_summary($submission, $shownames));
1720
                        $output .= $this->box_end();
1721
                    }
1722
                    $output .= print_collapsible_region_end(true);
1723
                }
1724
                break;
1725
            case workshop::PHASE_CLOSED:
1726
                if (trim($workshop->conclusion)) {
1727
                    $conclusion = file_rewrite_pluginfile_urls($workshop->conclusion, 'pluginfile.php', $workshop->context->id,
1728
                        'mod_workshop', 'conclusion', null, workshop::instruction_editors_options($workshop->context));
1729
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-conclusion',
1730
                        get_string('conclusion', 'workshop'),
1731
                        'workshop-viewlet-conclusion-collapsed', false, true);
1732
                    $output .= $this->box(format_text($conclusion, $workshop->conclusionformat, ['overflowdiv' => true]),
1733
                        ['generalbox', 'conclusion']);
1734
                    $output .= print_collapsible_region_end(true);
1735
                }
1736
                $finalgrades = $workshop->get_gradebook_grades($USER->id);
1737
                if (!empty($finalgrades)) {
1738
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-yourgrades',
1739
                        get_string('yourgrades', 'workshop'),
1740
                        'workshop-viewlet-yourgrades-collapsed', false, true);
1741
                    $output .= $this->box_start('generalbox grades-yourgrades');
1742
                    $output .= $this->render($finalgrades);
1743
                    $output .= $this->box_end();
1744
                    $output .= print_collapsible_region_end(true);
1745
                }
1746
                if (has_capability('mod/workshop:viewallassessments', $this->page->context)) {
1747
                    $perpage = get_user_preferences('workshop_perpage', 10);
1748
                    $groupid = groups_get_activity_group($workshop->cm, true);
1749
                    $data = $workshop->prepare_grading_report_data($USER->id, $groupid, $page, $perpage, $sortby, $sorthow);
1750
                    if ($data) {
1751
                        $showauthornames = has_capability('mod/workshop:viewauthornames', $workshop->context);
1752
                        $showreviewernames = has_capability('mod/workshop:viewreviewernames', $workshop->context);
1753
 
1754
                        // Prepare paging bar.
1755
                        $baseurl = new moodle_url($this->page->url, ['sortby' => $sortby, 'sorthow' => $sorthow]);
1756
                        $pagingbar = new paging_bar($data->totalcount, $page, $perpage, $baseurl, 'page');
1757
 
1758
                        // Grading report display options.
1759
                        $reportopts = new stdclass();
1760
                        $reportopts->showauthornames = $showauthornames;
1761
                        $reportopts->showreviewernames = $showreviewernames;
1762
                        $reportopts->sortby = $sortby;
1763
                        $reportopts->sorthow = $sorthow;
1764
                        $reportopts->showsubmissiongrade = true;
1765
                        $reportopts->showgradinggrade = true;
1766
                        $reportopts->workshopphase = $workshop->phase;
1767
 
1768
                        $output .= print_collapsible_region_start('', 'workshop-viewlet-gradereport',
1769
                            get_string('gradesreport', 'workshop'),
1770
                            'workshop-viewlet-gradereport-collapsed', false, true);
1771
                        $output .= $this->box_start('generalbox gradesreport');
1772
                        $output .= $this->container(groups_print_activity_menu($workshop->cm,
1773
                            $this->page->url, true), 'groupwidget');
1774
                        $output .= $this->initials_bars($workshop, $baseurl);
1775
                        $output .= $this->render($pagingbar);
1776
                        $output .= $this->render(new workshop_grading_report($data, $reportopts));
1777
                        $output .= $this->render($pagingbar);
1778
                        $output .= $this->perpage_selector($perpage);
1779
                        $output .= $this->box_end();
1780
                        $output .= print_collapsible_region_end(true);
1781
                    }
1782
                }
1783
                if (has_capability('mod/workshop:submit', $this->page->context)) {
1784
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-ownsubmission',
1785
                        get_string('yoursubmissionwithassessments', 'workshop'),
1786
                        'workshop-viewlet-ownsubmission-collapsed', false, true);
1787
                    $output .= $this->box_start('generalbox ownsubmission');
1788
                    if ($submission = $workshop->get_submission_by_author($USER->id)) {
1789
                        $output .= $this->render($workshop->prepare_submission_summary($submission, true));
1790
                    } else {
1791
                        $output .= $this->container(get_string('noyoursubmission', 'workshop'));
1792
                    }
1793
                    $output .= $this->box_end();
1794
 
1795
                    if (!empty($submission->gradeoverby) && strlen(trim($submission->feedbackauthor)) > 0) {
1796
                        $output .= $this->render(new workshop_feedback_author($submission));
1797
                    }
1798
 
1799
                    $output .= print_collapsible_region_end(true);
1800
                }
1801
                if (has_capability('mod/workshop:viewpublishedsubmissions', $workshop->context)) {
1802
                    $shownames = has_capability('mod/workshop:viewauthorpublished', $workshop->context);
1803
                    if ($submissions = $workshop->get_published_submissions()) {
1804
                        $output .= print_collapsible_region_start('', 'workshop-viewlet-publicsubmissions',
1805
                            get_string('publishedsubmissions', 'workshop'),
1806
                            'workshop-viewlet-publicsubmissions-collapsed', false, true);
1807
                        foreach ($submissions as $submission) {
1808
                            $output .= $this->box_start('generalbox submission-summary');
1809
                            $output .= $this->render($workshop->prepare_submission_summary($submission, $shownames));
1810
                            $output .= $this->box_end();
1811
                        }
1812
                        $output .= print_collapsible_region_end();
1813
                    }
1814
                }
1815
                if ($assessments = $workshop->get_assessments_by_reviewer($USER->id)) {
1816
                    $output .= print_collapsible_region_start('', 'workshop-viewlet-assignedassessments',
1817
                        get_string('assignedassessments', 'workshop'),
1818
                        'workshop-viewlet-assignedassessments-collapsed', false, true);
1819
                    $shownames = has_capability('mod/workshop:viewauthornames', $this->page->context);
1820
                    foreach ($assessments as $assessment) {
1821
                        $submission = new stdclass();
1822
                        $submission->id = $assessment->submissionid;
1823
                        $submission->title = $assessment->submissiontitle;
1824
                        $submission->timecreated = $assessment->submissioncreated;
1825
                        $submission->timemodified = $assessment->submissionmodified;
1826
                        $userpicturefields = explode(',', implode(',', \core_user\fields::get_picture_fields()));
1827
                        foreach ($userpicturefields as $userpicturefield) {
1828
                            $prefixedusernamefield = 'author' . $userpicturefield;
1829
                            $submission->$prefixedusernamefield = $assessment->$prefixedusernamefield;
1830
                        }
1831
 
1832
                        if (is_null($assessment->grade)) {
1833
                            $class = ' notgraded';
1834
                            $submission->status = 'notgraded';
1835
                            $buttontext = get_string('assess', 'workshop');
1836
                        } else {
1837
                            $class = ' graded';
1838
                            $submission->status = 'graded';
1839
                            $buttontext = get_string('reassess', 'workshop');
1840
                        }
1841
                        $output .= $this->box_start('generalbox assessment-summary' . $class);
1842
                        $output .= $this->render($workshop->prepare_submission_summary($submission, $shownames));
1843
                        $output .= $this->box_end();
1844
 
1845
                        if (!empty($assessment->feedbackreviewer) && strlen(trim($assessment->feedbackreviewer)) > 0) {
1846
                            $output .= $this->render(new workshop_feedback_reviewer($assessment));
1847
                        }
1848
                    }
1849
                    $output .= print_collapsible_region_end(true);
1850
                }
1851
                break;
1852
            default:
1853
        }
1854
 
1855
        return $output;
1856
    }
1857
}