Proyectos de Subversion Moodle

Rev

Rev 727 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 727 Rev 1441
Línea 43... Línea 43...
43
 * @package   mod_quiz
43
 * @package   mod_quiz
44
 * @category  output
44
 * @category  output
45
 * @copyright 2011 The Open University
45
 * @copyright 2011 The Open University
46
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
47
 */
47
 */
48
class renderer extends plugin_renderer_base
48
class renderer extends plugin_renderer_base {
49
{
-
 
50
    /**
49
    /**
51
     * Builds the review page
50
     * Builds the review page
52
     *
51
     *
53
     * @param quiz_attempt $attemptobj an instance of quiz_attempt.
52
     * @param quiz_attempt $attemptobj an instance of quiz_attempt.
54
     * @param array $slots of slots to be displayed.
53
     * @param array $slots of slots to be displayed.
Línea 58... Línea 57...
58
     * @param display_options $displayoptions instance of display_options.
57
     * @param display_options $displayoptions instance of display_options.
59
     * @param attempt_summary_information|array $summarydata summary information about the attempt.
58
     * @param attempt_summary_information|array $summarydata summary information about the attempt.
60
     *      Passing an array is deprecated.
59
     *      Passing an array is deprecated.
61
     * @return string HTML to display.
60
     * @return string HTML to display.
62
     */
61
     */
63
    public function review_page(
62
    public function review_page(quiz_attempt $attemptobj, $slots, $page, $showall,
64
        quiz_attempt $attemptobj,
-
 
65
        $slots,
-
 
66
        $page,
-
 
67
        $showall,
-
 
68
        $lastpage,
-
 
69
        display_options $displayoptions,
63
            $lastpage, display_options $displayoptions, $summarydata) {
70
        $summarydata
-
 
71
    ) {
-
 
72
        if (is_array($summarydata)) {
64
        if (is_array($summarydata)) {
73
            debugging(
-
 
74
                'Since Moodle 4.4, $summarydata passed to review_page should be a attempt_summary_information.',
65
            debugging('Since Moodle 4.4, $summarydata passed to review_page should be a attempt_summary_information.',
75
                DEBUG_DEVELOPER
66
                DEBUG_DEVELOPER);
76
            );
-
 
77
            $summarydata = $this->filter_review_summary_table($summarydata, $page);
67
            $summarydata = $this->filter_review_summary_table($summarydata, $page);
78
            $summarydata = attempt_summary_information::create_from_legacy_array($summarydata);
68
            $summarydata = attempt_summary_information::create_from_legacy_array($summarydata);
79
        }
69
        }
Línea 80... Línea 70...
80
 
70
 
81
        $output = '';
71
        $output = '';
82
        $output .= $this->header();
72
        $output .= $this->header();
83
        $output .= $this->review_attempt_summary($summarydata, $page);
73
        $output .= $this->review_attempt_summary($summarydata, $page);
84
        $output .= $this->review_form(
-
 
85
            $page,
-
 
86
            $showall,
-
 
87
            $displayoptions,
74
        $output .= $this->review_form($page, $showall, $displayoptions,
88
            $this->questions($attemptobj, true, $slots, $page, $showall, $displayoptions),
75
                $this->questions($attemptobj, true, $slots, $page, $showall, $displayoptions),
89
            $attemptobj
-
 
Línea 90... Línea 76...
90
        );
76
                $attemptobj);
91
 
77
 
92
        $output .= $this->review_next_navigation($attemptobj, $page, $lastpage, $showall);
78
        $output .= $this->review_next_navigation($attemptobj, $page, $lastpage, $showall);
93
        $output .= $this->footer();
79
        $output .= $this->footer();
Línea 103... Línea 89...
103
     * @param display_options $displayoptions instance of display_options.
89
     * @param display_options $displayoptions instance of display_options.
104
     * @param attempt_summary_information|array $summarydata summary information about the attempt.
90
     * @param attempt_summary_information|array $summarydata summary information about the attempt.
105
     *      Passing an array is deprecated.
91
     *      Passing an array is deprecated.
106
     * @return string HTML to display.
92
     * @return string HTML to display.
107
     */
93
     */
108
    public function review_question_page(
94
    public function review_question_page(quiz_attempt $attemptobj, $slot, $seq,
109
        quiz_attempt $attemptobj,
-
 
110
        $slot,
-
 
111
        $seq,
-
 
112
        display_options $displayoptions,
95
            display_options $displayoptions, $summarydata) {
113
        $summarydata
-
 
114
    ) {
-
 
115
        if (is_array($summarydata)) {
96
        if (is_array($summarydata)) {
116
            debugging(
-
 
117
                'Since Moodle 4.4, $summarydata passed to review_question_page should be a attempt_summary_information.',
97
            debugging('Since Moodle 4.4, $summarydata passed to review_question_page should be a attempt_summary_information.',
118
                DEBUG_DEVELOPER
98
                DEBUG_DEVELOPER);
119
            );
-
 
120
            $summarydata = attempt_summary_information::create_from_legacy_array($summarydata);
99
            $summarydata = attempt_summary_information::create_from_legacy_array($summarydata);
121
        }
100
        }
Línea 122... Línea 101...
122
 
101
 
123
        $output = '';
102
        $output = '';
Línea 140... Línea 119...
140
     *
119
     *
141
     * @param quiz_attempt $attemptobj an instance of quiz_attempt.
120
     * @param quiz_attempt $attemptobj an instance of quiz_attempt.
142
     * @param string $message Why the review is not allowed.
121
     * @param string $message Why the review is not allowed.
143
     * @return string html to output.
122
     * @return string html to output.
144
     */
123
     */
145
    public function review_question_not_allowed(quiz_attempt $attemptobj, $message)
124
    public function review_question_not_allowed(quiz_attempt $attemptobj, $message) {
146
    {
-
 
147
        $output = '';
125
        $output = '';
148
        $output .= $this->header();
126
        $output .= $this->header();
149
        $output .= $this->heading(format_string(
127
        $output .= $this->heading(format_string($attemptobj->get_quiz_name(), true,
150
            $attemptobj->get_quiz_name(),
-
 
151
            true,
-
 
152
            ["context" => $attemptobj->get_quizobj()->get_context()]
128
                ["context" => $attemptobj->get_quizobj()->get_context()]));
153
        ));
-
 
154
        $output .= $this->notification($message);
129
        $output .= $this->notification($message);
155
        $output .= $this->close_window_button();
130
        $output .= $this->close_window_button();
156
        $output .= $this->footer();
131
        $output .= $this->footer();
157
        return $output;
132
        return $output;
158
    }
133
    }
Línea 196... Línea 171...
196
     * @param array $summarydata contains row data for table
171
     * @param array $summarydata contains row data for table
197
     * @param int $page the current page number
172
     * @param int $page the current page number
198
     * @return array updated version of the $summarydata array.
173
     * @return array updated version of the $summarydata array.
199
     * @deprecated since Moodle 4.4. Replaced by filter_review_attempt_summary.
174
     * @deprecated since Moodle 4.4. Replaced by filter_review_attempt_summary.
200
     */
175
     */
201
    protected function filter_review_summary_table($summarydata, $page)
176
    protected function filter_review_summary_table($summarydata, $page) {
202
    {
-
 
203
        debugging('filter_review_summary_table() is deprecated. Replaced by filter_review_attempt_summary().', DEBUG_DEVELOPER);
177
        debugging('filter_review_summary_table() is deprecated. Replaced by filter_review_attempt_summary().', DEBUG_DEVELOPER);
204
        if ($page == 0) {
178
        if ($page == 0) {
205
            return $summarydata;
179
            return $summarydata;
206
        }
180
        }
Línea 221... Línea 195...
221
     * @param array $summarydata contains row data for table
195
     * @param array $summarydata contains row data for table
222
     * @param int $page contains the current page number
196
     * @param int $page contains the current page number
223
     * @return string HTML to display.
197
     * @return string HTML to display.
224
     * @deprecated since Moodle 4.4. Replaced by review_attempt_summary.
198
     * @deprecated since Moodle 4.4. Replaced by review_attempt_summary.
225
     */
199
     */
226
    public function review_summary_table($summarydata, $page)
200
    public function review_summary_table($summarydata, $page) {
227
    {
-
 
228
        debugging('review_summary_table() is deprecated. Please use review_attempt_summary() instead.', DEBUG_DEVELOPER);
201
        debugging('review_summary_table() is deprecated. Please use review_attempt_summary() instead.', DEBUG_DEVELOPER);
229
        $summarydata = $this->filter_review_summary_table($summarydata, $page);
202
        $summarydata = $this->filter_review_summary_table($summarydata, $page);
230
        $this->render(attempt_summary_information::create_from_legacy_array($summarydata));
203
        $this->render(attempt_summary_information::create_from_legacy_array($summarydata));
231
    }
204
    }
Línea 238... Línea 211...
238
     * @param array $slots array of integers relating to questions
211
     * @param array $slots array of integers relating to questions
239
     * @param int $page current page number
212
     * @param int $page current page number
240
     * @param bool $showall if true shows attempt on single page
213
     * @param bool $showall if true shows attempt on single page
241
     * @param display_options $displayoptions instance of display_options
214
     * @param display_options $displayoptions instance of display_options
242
     */
215
     */
243
    public function questions(
-
 
244
        quiz_attempt $attemptobj,
216
    public function questions(quiz_attempt $attemptobj, $reviewing, $slots, $page, $showall,
245
        $reviewing,
-
 
246
        $slots,
-
 
247
        $page,
-
 
248
        $showall,
-
 
249
        display_options $displayoptions
217
            display_options $displayoptions) {
250
    ) {
-
 
251
        $output = '';
218
        $output = '';
252
        foreach ($slots as $slot) {
219
        foreach ($slots as $slot) {
253
            $output .= $attemptobj->render_question(
220
            $output .= $attemptobj->render_question($slot, $reviewing, $this,
254
                $slot,
-
 
255
                $reviewing,
-
 
256
                $this,
-
 
257
                $attemptobj->review_url($slot, $page, $showall)
221
                    $attemptobj->review_url($slot, $page, $showall));
258
            );
-
 
259
        }
222
        }
260
        return $output;
223
        return $output;
261
    }
224
    }
Línea 262... Línea 225...
262
 
225
 
Línea 268... Línea 231...
268
     * @param display_options $displayoptions instance of display_options
231
     * @param display_options $displayoptions instance of display_options
269
     * @param string $content the rendered display of each question
232
     * @param string $content the rendered display of each question
270
     * @param quiz_attempt $attemptobj instance of quiz_attempt
233
     * @param quiz_attempt $attemptobj instance of quiz_attempt
271
     * @return string HTML to display.
234
     * @return string HTML to display.
272
     */
235
     */
273
    public function review_form($page, $showall, $displayoptions, $content, $attemptobj)
236
    public function review_form($page, $showall, $displayoptions, $content, $attemptobj) {
274
    {
-
 
275
        if ($displayoptions->flags != question_display_options::EDITABLE) {
237
        if ($displayoptions->flags != question_display_options::EDITABLE) {
276
            return $content;
238
            return $content;
277
        }
239
        }
Línea 278... Línea 240...
278
 
240
 
279
        $this->page->requires->js_init_call(
-
 
280
            'M.mod_quiz.init_review_form',
-
 
281
            null,
-
 
282
            false,
241
        $this->page->requires->js_init_call('M.mod_quiz.init_review_form', null, false,
283
            quiz_get_js_module()
-
 
Línea 284... Línea 242...
284
        );
242
                quiz_get_js_module());
285
 
243
 
286
        $output = '';
-
 
287
        $output .= html_writer::start_tag('form', ['action' => $attemptobj->review_url(
-
 
288
            null,
-
 
289
            $page,
244
        $output = '';
290
            $showall
245
        $output .= html_writer::start_tag('form', ['action' => $attemptobj->review_url(null,
291
        ), 'method' => 'post', 'class' => 'questionflagsaveform']);
246
                $page, $showall), 'method' => 'post', 'class' => 'questionflagsaveform']);
292
        $output .= html_writer::start_tag('div');
247
        $output .= html_writer::start_tag('div');
293
        $output .= $content;
-
 
294
        $output .= html_writer::empty_tag('input', [
-
 
295
            'type' => 'hidden',
248
        $output .= $content;
296
            'name' => 'sesskey',
-
 
297
            'value' => sesskey()
249
        $output .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'sesskey',
298
        ]);
250
                'value' => sesskey()]);
299
        $output .= html_writer::start_tag('div', ['class' => 'submitbtns']);
-
 
300
        $output .= html_writer::empty_tag('input', [
251
        $output .= html_writer::start_tag('div', ['class' => 'submitbtns']);
301
            'type' => 'submit',
-
 
302
            'class' => 'questionflagsavebutton btn btn-secondary',
252
        $output .= html_writer::empty_tag('input', ['type' => 'submit',
303
            'name' => 'savingflags',
-
 
304
            'value' => get_string('saveflags', 'question')
253
                'class' => 'questionflagsavebutton btn btn-secondary', 'name' => 'savingflags',
305
        ]);
254
                'value' => get_string('saveflags', 'question')]);
306
        $output .= html_writer::end_tag('div');
255
        $output .= html_writer::end_tag('div');
Línea 307... Línea 256...
307
        $output .= html_writer::end_tag('div');
256
        $output .= html_writer::end_tag('div');
Línea 313... Línea 262...
313
    /**
262
    /**
314
     * Returns either a link or button.
263
     * Returns either a link or button.
315
     *
264
     *
316
     * @param quiz_attempt $attemptobj instance of quiz_attempt
265
     * @param quiz_attempt $attemptobj instance of quiz_attempt
317
     */
266
     */
318
    public function finish_review_link(quiz_attempt $attemptobj)
267
    public function finish_review_link(quiz_attempt $attemptobj) {
319
    {
-
 
320
        $url = $attemptobj->view_url();
268
        $url = $attemptobj->view_url();
Línea 321... Línea 269...
321
 
269
 
322
        if ($attemptobj->get_access_manager(time())->attempt_must_be_in_popup()) {
-
 
323
            $this->page->requires->js_init_call(
270
        if ($attemptobj->get_access_manager(time())->attempt_must_be_in_popup()) {
324
                'M.mod_quiz.secure_window.init_close_button',
-
 
325
                [$url->out(false)],
-
 
326
                false,
271
            $this->page->requires->js_init_call('M.mod_quiz.secure_window.init_close_button',
327
                quiz_get_js_module()
-
 
328
            );
272
                    [$url->out(false)], false, quiz_get_js_module());
329
            return html_writer::empty_tag('input', [
-
 
330
                'type' => 'button',
273
            return html_writer::empty_tag('input', ['type' => 'button',
331
                'value' => get_string('finishreview', 'quiz'),
274
                    'value' => get_string('finishreview', 'quiz'),
332
                'id' => 'secureclosebutton',
275
                    'id' => 'secureclosebutton',
333
                'class' => 'mod_quiz-next-nav btn btn-primary'
276
                    'class' => 'mod_quiz-next-nav btn btn-primary']);
334
            ]);
277
 
335
        } else {
-
 
336
            return html_writer::link(
-
 
337
                $url,
278
        } else {
338
                get_string('finishreview', 'quiz'),
279
            return html_writer::link($url, get_string('finishreview', 'quiz'),
339
                ['class' => 'mod_quiz-next-nav']
-
 
340
            );
280
                    ['class' => 'mod_quiz-next-nav']);
341
        }
281
        }
Línea 342... Línea 282...
342
    }
282
    }
343
 
283
 
Línea 353... Línea 293...
353
     * @param bool|null $showall if true, the URL will be to review the entire attempt on one page,
293
     * @param bool|null $showall if true, the URL will be to review the entire attempt on one page,
354
     *      and $page will be ignored. If null, a sensible default will be chosen.
294
     *      and $page will be ignored. If null, a sensible default will be chosen.
355
     *
295
     *
356
     * @return string HTML fragment.
296
     * @return string HTML fragment.
357
     */
297
     */
358
    public function review_next_navigation(quiz_attempt $attemptobj, $page, $lastpage, $showall = null)
298
    public function review_next_navigation(quiz_attempt $attemptobj, $page, $lastpage, $showall = null) {
359
    {
-
 
360
        $nav = '';
299
        $nav = '';
361
        if ($page > 0) {
300
        if ($page > 0) {
362
            $nav .= link_arrow_left(
-
 
363
                get_string('navigateprevious', 'quiz'),
301
            $nav .= link_arrow_left(get_string('navigateprevious', 'quiz'),
364
                $attemptobj->review_url(null, $page - 1, $showall),
302
                    $attemptobj->review_url(null, $page - 1, $showall), false, 'mod_quiz-prev-nav');
365
                false,
-
 
366
                'mod_quiz-prev-nav'
-
 
367
            );
-
 
368
        }
303
        }
369
        if ($lastpage) {
304
        if ($lastpage) {
370
            $nav .= $this->finish_review_link($attemptobj);
305
            $nav .= $this->finish_review_link($attemptobj);
371
        } else {
306
        } else {
372
            $nav .= link_arrow_right(
-
 
373
                get_string('navigatenext', 'quiz'),
307
            $nav .= link_arrow_right(get_string('navigatenext', 'quiz'),
374
                $attemptobj->review_url(null, $page + 1, $showall),
308
                    $attemptobj->review_url(null, $page + 1, $showall), false, 'mod_quiz-next-nav');
375
                false,
-
 
376
                'mod_quiz-next-nav'
-
 
377
            );
-
 
378
        }
309
        }
379
        return html_writer::tag('div', $nav, ['class' => 'submitbtns']);
310
        return html_writer::tag('div', $nav, ['class' => 'submitbtns']);
380
    }
311
    }
Línea 381... Línea 312...
381
 
312
 
Línea 384... Línea 315...
384
     *
315
     *
385
     * @param quiz_attempt $attemptobj instance of quiz_attempt
316
     * @param quiz_attempt $attemptobj instance of quiz_attempt
386
     * @param int $timenow timestamp to use as 'now'.
317
     * @param int $timenow timestamp to use as 'now'.
387
     * @return string HTML content.
318
     * @return string HTML content.
388
     */
319
     */
389
    public function countdown_timer(quiz_attempt $attemptobj, $timenow)
320
    public function countdown_timer(quiz_attempt $attemptobj, $timenow) {
390
    {
-
 
Línea 391... Línea 321...
391
 
321
 
392
        $timeleft = $attemptobj->get_time_left_display($timenow);
322
        $timeleft = $attemptobj->get_time_left_display($timenow);
393
        if ($timeleft !== false) {
323
        if ($timeleft !== false) {
394
            $ispreview = $attemptobj->is_preview();
324
            $ispreview = $attemptobj->is_preview();
Línea 407... Línea 337...
407
    /**
337
    /**
408
     * Create a preview link
338
     * Create a preview link
409
     *
339
     *
410
     * @param moodle_url $url URL to restart the attempt.
340
     * @param moodle_url $url URL to restart the attempt.
411
     */
341
     */
412
    public function restart_preview_button($url)
342
    public function restart_preview_button($url) {
413
    {
-
 
414
        return $this->single_button($url, get_string('startnewpreview', 'quiz'));
343
        return $this->single_button($url, get_string('startnewpreview', 'quiz'));
415
    }
344
    }
Línea 416... Línea 345...
416
 
345
 
417
    /**
346
    /**
418
     * Outputs the navigation block panel
347
     * Outputs the navigation block panel
419
     *
348
     *
420
     * @param navigation_panel_base $panel
349
     * @param navigation_panel_base $panel
421
     */
350
     */
422
    public function navigation_panel(navigation_panel_base $panel)
-
 
Línea 423... Línea 351...
423
    {
351
    public function navigation_panel(navigation_panel_base $panel) {
424
 
352
 
425
        $output = '';
353
        $output = '';
426
        $userpicture = $panel->user_picture();
354
        $userpicture = $panel->user_picture();
427
        if ($userpicture) {
355
        if ($userpicture) {
428
            $fullname = fullname($userpicture->user);
356
            $fullname = fullname($userpicture->user);
429
            if ($userpicture->size) {
357
            if ($userpicture->size) {
430
                $fullname = html_writer::div($fullname);
-
 
431
            }
-
 
432
            $output .= html_writer::tag(
358
                $fullname = html_writer::div($fullname);
433
                'div',
359
            }
434
                $this->render($userpicture) . $fullname,
-
 
435
                ['id' => 'user-picture', 'class' => 'clearfix']
360
            $output .= html_writer::tag('div', $this->render($userpicture) . $fullname,
436
            );
361
                    ['id' => 'user-picture', 'class' => 'clearfix']);
Línea 437... Línea 362...
437
        }
362
        }
438
        $output .= $panel->render_before_button_bits($this);
363
        $output .= $panel->render_before_button_bits($this);
439
 
364
 
440
        $bcc = $panel->get_button_container_class();
365
        $bcc = $panel->get_button_container_class();
441
        $output .= html_writer::start_tag('div', ['class' => "qn_buttons clearfix $bcc"]);
366
        $output .= html_writer::start_tag('div', ['class' => "qn_buttons clearfix $bcc"]);
442
        foreach ($panel->get_question_buttons() as $button) {
367
        foreach ($panel->get_question_buttons() as $button) {
Línea 443... Línea -...
443
            $output .= $this->render($button);
-
 
444
        }
-
 
445
        $output .= html_writer::end_tag('div');
368
            $output .= $this->render($button);
446
 
369
        }
447
        $output .= html_writer::tag(
-
 
Línea 448... Línea 370...
448
            'div',
370
        $output .= html_writer::end_tag('div');
449
            $panel->render_end_bits($this),
-
 
450
            ['class' => 'othernav']
-
 
451
        );
-
 
452
 
371
 
453
        $this->page->requires->js_init_call(
-
 
Línea 454... Línea 372...
454
            'M.mod_quiz.nav.init',
372
        $output .= html_writer::tag('div', $panel->render_end_bits($this),
455
            null,
373
                ['class' => 'othernav']);
Línea 456... Línea 374...
456
            false,
374
 
457
            quiz_get_js_module()
375
        $this->page->requires->js_init_call('M.mod_quiz.nav.init', null, false,
458
        );
376
                quiz_get_js_module());
459
 
377
 
460
        return $output;
378
        return $output;
461
    }
379
    }
462
 
380
 
463
    /**
-
 
464
     * Display a quiz navigation button.
381
    /**
465
     *
382
     * Display a quiz navigation button.
Línea 466... Línea 383...
466
     * @param navigation_question_button $button
383
     *
467
     * @return string HTML fragment.
384
     * @param navigation_question_button $button
Línea 495... Línea 412...
495
 
412
 
496
        $a = new stdClass();
413
        $a = new stdClass();
497
        $a->number = s($button->number);
414
        $a->number = s($button->number);
498
        $a->attributes = implode(' ', $extrainfo);
415
        $a->attributes = implode(' ', $extrainfo);
499
        $tagcontents = html_writer::tag('span', '', ['class' => 'thispageholder']) .
416
        $tagcontents = html_writer::tag('span', '', ['class' => 'thispageholder']) .
500
            html_writer::tag('span', '', ['class' => 'trafficlight']) .
417
                html_writer::tag('span', '', ['class' => 'trafficlight']) .
501
            get_string($qnostring, 'quiz', $a);
-
 
502
        $tagattributes = [
418
                get_string($qnostring, 'quiz', $a);
503
            'class' => implode(' ', $classes),
-
 
504
            'id' => $button->id,
-
 
505
            'title' => $tooltip,
419
        $tagattributes = ['class' => implode(' ', $classes), 'id' => $button->id,
506
            'data-quiz-page' => $button->page
-
 
Línea 507... Línea 420...
507
        ];
420
                'title' => $tooltip, 'data-quiz-page' => $button->page];
508
 
421
 
509
        if ($button->url) {
422
        if ($button->url) {
510
            return html_writer::link($button->url, $tagcontents, $tagattributes);
423
            return html_writer::link($button->url, $tagcontents, $tagattributes);
Línea 517... Línea 430...
517
     * Display a quiz navigation heading.
430
     * Display a quiz navigation heading.
518
     *
431
     *
519
     * @param navigation_section_heading $heading the heading.
432
     * @param navigation_section_heading $heading the heading.
520
     * @return string HTML fragment.
433
     * @return string HTML fragment.
521
     */
434
     */
522
    protected function render_navigation_section_heading(navigation_section_heading $heading)
435
    protected function render_navigation_section_heading(navigation_section_heading $heading) {
523
    {
-
 
524
        if (empty($heading->heading)) {
436
        if (empty($heading->heading)) {
525
            $headingtext = get_string('sectionnoname', 'quiz');
437
            $headingtext = get_string('sectionnoname', 'quiz');
526
            $class = ' dimmed_text';
438
            $class = ' dimmed_text';
527
        } else {
439
        } else {
528
            $headingtext = $heading->heading;
440
            $headingtext = $heading->heading;
Línea 536... Línea 448...
536
     *
448
     *
537
     * @param links_to_other_attempts $links
449
     * @param links_to_other_attempts $links
538
     * @return string HTML fragment.
450
     * @return string HTML fragment.
539
     */
451
     */
540
    protected function render_links_to_other_attempts(
452
    protected function render_links_to_other_attempts(
541
        links_to_other_attempts $links
453
            links_to_other_attempts $links) {
542
    ) {
-
 
543
        $attemptlinks = [];
454
        $attemptlinks = [];
544
        foreach ($links->links as $attempt => $url) {
455
        foreach ($links->links as $attempt => $url) {
545
            if (!$url) {
456
            if (!$url) {
546
                $attemptlinks[] = html_writer::tag('strong', $attempt);
457
                $attemptlinks[] = html_writer::tag('strong', $attempt);
547
            } else {
458
            } else {
Línea 562... Línea 473...
562
     * having this renderer method allows themes to override the default rendering.
473
     * having this renderer method allows themes to override the default rendering.
563
     *
474
     *
564
     * @param grade_out_of $grade
475
     * @param grade_out_of $grade
565
     * @return string HTML to output.
476
     * @return string HTML to output.
566
     */
477
     */
567
    protected function render_grade_out_of(grade_out_of $grade): string
478
    protected function render_grade_out_of(grade_out_of $grade): string {
568
    {
-
 
569
        return get_string(
-
 
570
            $grade->get_string_key(),
479
        return get_string($grade->get_string_key(), 'quiz',
571
            'quiz',
-
 
572
            $grade->style_formatted_values($grade->get_formatted_values())
480
                $grade->style_formatted_values($grade->get_formatted_values()));
573
        );
-
 
574
    }
481
    }
Línea 575... Línea 482...
575
 
482
 
576
    /**
483
    /**
577
     * Render the 'start attempt' page.
484
     * Render the 'start attempt' page.
Línea 581... Línea 488...
581
     *
488
     *
582
     * @param \mod_quiz\quiz_settings $quizobj
489
     * @param \mod_quiz\quiz_settings $quizobj
583
     * @param preflight_check_form $mform
490
     * @param preflight_check_form $mform
584
     * @return string
491
     * @return string
585
     */
492
     */
586
    public function start_attempt_page(quiz_settings $quizobj, preflight_check_form $mform)
493
    public function start_attempt_page(quiz_settings $quizobj, preflight_check_form $mform) {
587
    {
-
 
588
        $output = '';
494
        $output = '';
589
        $output .= $this->header();
495
        $output .= $this->header();
590
        $output .= $this->during_attempt_tertiary_nav($quizobj->view_url());
496
        $output .= $this->during_attempt_tertiary_nav($quizobj->view_url());
591
        $output .= $this->heading(format_string(
497
        $output .= $this->heading(format_string($quizobj->get_quiz_name(), true,
592
            $quizobj->get_quiz_name(),
-
 
593
            true,
-
 
594
            ["context" => $quizobj->get_context()]
498
                ["context" => $quizobj->get_context()]));
595
        ));
-
 
596
        $output .= $this->quiz_intro($quizobj->get_quiz(), $quizobj->get_cm());
499
        $output .= $this->quiz_intro($quizobj->get_quiz(), $quizobj->get_cm());
597
        $output .= $mform->render();
500
        $output .= $mform->render();
598
        $output .= $this->footer();
501
        $output .= $this->footer();
599
        return $output;
502
        return $output;
600
    }
503
    }
Línea 609... Línea 512...
609
     * @param array $slots Contains an array of integers that relate to questions
512
     * @param array $slots Contains an array of integers that relate to questions
610
     * @param int $id The ID of an attempt
513
     * @param int $id The ID of an attempt
611
     * @param int $nextpage The number of the next page
514
     * @param int $nextpage The number of the next page
612
     * @return string HTML to output.
515
     * @return string HTML to output.
613
     */
516
     */
614
    public function attempt_page(
517
    public function attempt_page($attemptobj, $page, $accessmanager, $messages, $slots, $id,
615
        $attemptobj,
-
 
616
        $page,
-
 
617
        $accessmanager,
-
 
618
        $messages,
-
 
619
        $slots,
-
 
620
        $id,
-
 
621
        $nextpage
518
            $nextpage) {
622
    ) {
-
 
623
        $output = '';
519
        $output = '';
624
        $output .= $this->header();
520
        $output .= $this->header();
625
        $output .= $this->during_attempt_tertiary_nav($attemptobj->view_url());
521
        $output .= $this->during_attempt_tertiary_nav($attemptobj->view_url());
626
        $output .= $this->quiz_notices($messages);
522
        $output .= $this->quiz_notices($messages);
627
        $output .= $this->countdown_timer($attemptobj, time());
523
        $output .= $this->countdown_timer($attemptobj, time());
Línea 634... Línea 530...
634
     * Render the tertiary navigation for pages during the attempt.
530
     * Render the tertiary navigation for pages during the attempt.
635
     *
531
     *
636
     * @param string|moodle_url $quizviewurl url of the view.php page for this quiz.
532
     * @param string|moodle_url $quizviewurl url of the view.php page for this quiz.
637
     * @return string HTML to output.
533
     * @return string HTML to output.
638
     */
534
     */
639
    public function during_attempt_tertiary_nav($quizviewurl): string
535
    public function during_attempt_tertiary_nav($quizviewurl): string {
640
    {
-
 
641
        $output = '';
536
        $output = '';
642
        $output .= html_writer::start_div('container-fluid tertiary-navigation');
537
        $output .= html_writer::start_div('tertiary-navigation');
643
        $output .= html_writer::start_div('row');
538
        $output .= html_writer::start_div('row');
644
        $output .= html_writer::start_div('navitem');
539
        $output .= html_writer::start_div('navitem');
645
        $output .= html_writer::link(
540
        $output .= html_writer::link($quizviewurl, get_string('back'),
646
            $quizviewurl,
-
 
647
            get_string('back'),
-
 
648
            ['class' => 'btn btn-secondary']
541
                ['class' => 'btn btn-secondary']);
649
        );
-
 
650
        $output .= html_writer::end_div();
542
        $output .= html_writer::end_div();
651
        $output .= html_writer::end_div();
543
        $output .= html_writer::end_div();
652
        $output .= html_writer::end_div();
544
        $output .= html_writer::end_div();
653
        return $output;
545
        return $output;
654
    }
546
    }
Línea 656... Línea 548...
656
    /**
548
    /**
657
     * Returns any notices.
549
     * Returns any notices.
658
     *
550
     *
659
     * @param array $messages
551
     * @param array $messages
660
     */
552
     */
661
    public function quiz_notices($messages)
553
    public function quiz_notices($messages) {
662
    {
-
 
663
        if (!$messages) {
554
        if (!$messages) {
664
            return '';
555
            return '';
665
        }
556
        }
666
        return $this->notification(
557
        return $this->notification(
667
            html_writer::tag('p', get_string('accessnoticesheader', 'quiz')) . $this->access_messages($messages),
558
                html_writer::tag('p', get_string('accessnoticesheader', 'quiz')) . $this->access_messages($messages),
668
            'warning',
559
                'warning',
669
            false
560
                false
670
        );
561
        );
671
    }
562
    }
Línea 672... Línea 563...
672
 
563
 
673
    /**
564
    /**
Línea 677... Línea 568...
677
     * @param int $page Current page number
568
     * @param int $page Current page number
678
     * @param array $slots Array of integers relating to questions
569
     * @param array $slots Array of integers relating to questions
679
     * @param int $id ID of the attempt
570
     * @param int $id ID of the attempt
680
     * @param int $nextpage Next page number
571
     * @param int $nextpage Next page number
681
     */
572
     */
682
    public function attempt_form($attemptobj, $page, $slots, $id, $nextpage)
573
    public function attempt_form($attemptobj, $page, $slots, $id, $nextpage) {
683
    {
-
 
684
        $output = '';
574
        $output = '';
Línea 685... Línea 575...
685
 
575
 
686
        // Start the form.
576
        // Start the form.
687
        $output .= html_writer::start_tag(
-
 
688
            'form',
-
 
689
            [
-
 
690
                'action' => new moodle_url(
577
        $output .= html_writer::start_tag('form',
691
                    $attemptobj->processattempt_url(),
578
                ['action' => new moodle_url($attemptobj->processattempt_url(),
692
                    ['cmid' => $attemptobj->get_cmid()]
-
 
693
                ),
-
 
694
                'method' => 'post',
579
                        ['cmid' => $attemptobj->get_cmid()]), 'method' => 'post',
695
                'enctype' => 'multipart/form-data',
-
 
696
                'accept-charset' => 'utf-8',
580
                        'enctype' => 'multipart/form-data', 'accept-charset' => 'utf-8',
697
                'id' => 'responseform'
-
 
698
            ]
-
 
699
        );
581
                        'id' => 'responseform']);
Línea 700... Línea 582...
700
        $output .= html_writer::start_tag('div');
582
        $output .= html_writer::start_tag('div');
701
 
583
 
702
        // Print all the questions.
584
        // Print all the questions.
703
        foreach ($slots as $slot) {
-
 
704
            $output .= $attemptobj->render_question(
-
 
705
                $slot,
-
 
706
                false,
585
        foreach ($slots as $slot) {
707
                $this,
-
 
708
                $attemptobj->attempt_url($slot, $page)
586
            $output .= $attemptobj->render_question($slot, false, $this,
Línea 709... Línea 587...
709
            );
587
                    $attemptobj->attempt_url($slot, $page));
710
        }
588
        }
Línea 711... Línea 589...
711
 
589
 
712
        $navmethod = $attemptobj->get_quiz()->navmethod;
590
        $navmethod = $attemptobj->get_quiz()->navmethod;
713
        $output .= $this->attempt_navigation_buttons($page, $attemptobj->is_last_page($page), $navmethod);
-
 
714
 
-
 
715
        // Some hidden fields to track what is going on.
591
        $output .= $this->attempt_navigation_buttons($page, $attemptobj->is_last_page($page), $navmethod);
716
        $output .= html_writer::empty_tag('input', [
-
 
717
            'type' => 'hidden',
592
 
718
            'name' => 'attempt',
-
 
719
            'value' => $attemptobj->get_attemptid()
-
 
720
        ]);
-
 
721
        $output .= html_writer::empty_tag('input', [
593
        // Some hidden fields to track what is going on.
722
            'type' => 'hidden',
-
 
723
            'name' => 'thispage',
594
        $output .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'attempt',
724
            'value' => $page,
-
 
725
            'id' => 'followingpage'
-
 
726
        ]);
595
                'value' => $attemptobj->get_attemptid()]);
727
        $output .= html_writer::empty_tag('input', [
-
 
728
            'type' => 'hidden',
596
        $output .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'thispage',
729
            'name' => 'nextpage',
-
 
730
            'value' => $nextpage
597
                'value' => $page, 'id' => 'followingpage']);
731
        ]);
-
 
732
        $output .= html_writer::empty_tag('input', [
-
 
733
            'type' => 'hidden',
-
 
734
            'name' => 'timeup',
598
        $output .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'nextpage',
735
            'value' => '0',
-
 
736
            'id' => 'timeup'
-
 
737
        ]);
599
                'value' => $nextpage]);
738
        $output .= html_writer::empty_tag('input', [
-
 
739
            'type' => 'hidden',
600
        $output .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'timeup',
740
            'name' => 'sesskey',
-
 
741
            'value' => sesskey()
601
                'value' => '0', 'id' => 'timeup']);
742
        ]);
-
 
743
        $output .= html_writer::empty_tag('input', [
-
 
744
            'type' => 'hidden',
-
 
Línea 745... Línea 602...
745
            'name' => 'mdlscrollto',
602
        $output .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'sesskey',
746
            'value' => '',
603
                'value' => sesskey()]);
747
            'id' => 'mdlscrollto'
604
        $output .= html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'mdlscrollto',
748
        ]);
605
                'value' => '', 'id' => 'mdlscrollto']);
749
 
-
 
750
        // Add a hidden field with questionids. Do this at the end of the form, so
-
 
751
        // if you navigate before the form has finished loading, it does not wipe all
606
 
752
        // the student's answers.
-
 
Línea 753... Línea 607...
753
        $output .= html_writer::empty_tag('input', [
607
        // Add a hidden field with questionids. Do this at the end of the form, so
754
            'type' => 'hidden',
608
        // if you navigate before the form has finished loading, it does not wipe all
755
            'name' => 'slots',
609
        // the student's answers.
Línea 771... Línea 625...
771
     * @param int $page the page number. Starts at 0 for the first page.
625
     * @param int $page the page number. Starts at 0 for the first page.
772
     * @param bool $lastpage is this the last page in the quiz?
626
     * @param bool $lastpage is this the last page in the quiz?
773
     * @param string $navmethod Optional quiz attribute, 'free' (default) or 'sequential'
627
     * @param string $navmethod Optional quiz attribute, 'free' (default) or 'sequential'
774
     * @return string HTML fragment.
628
     * @return string HTML fragment.
775
     */
629
     */
776
    protected function attempt_navigation_buttons($page, $lastpage, $navmethod = 'free')
630
    protected function attempt_navigation_buttons($page, $lastpage, $navmethod = 'free') {
777
    {
-
 
778
        $output = '';
631
        $output = '';
Línea 779... Línea 632...
779
 
632
 
780
        $output .= html_writer::start_tag('div', ['class' => 'submitbtns']);
633
        $output .= html_writer::start_tag('div', ['class' => 'submitbtns']);
781
        if ($page > 0 && $navmethod == 'free') {
634
        if ($page > 0 && $navmethod == 'free') {
782
            $output .= html_writer::empty_tag('input', [
-
 
783
                'type' => 'submit',
-
 
784
                'name' => 'previous',
635
            $output .= html_writer::empty_tag('input', ['type' => 'submit', 'name' => 'previous',
785
                'value' => get_string('navigateprevious', 'quiz'),
-
 
786
                'class' => 'mod_quiz-prev-nav btn btn-secondary',
636
                    'value' => get_string('navigateprevious', 'quiz'), 'class' => 'mod_quiz-prev-nav btn btn-secondary',
787
                'id' => 'mod_quiz-prev-nav'
-
 
788
            ]);
637
                    'id' => 'mod_quiz-prev-nav']);
789
            $this->page->requires->js_call_amd('core_form/submit', 'init', ['mod_quiz-prev-nav']);
638
            $this->page->requires->js_call_amd('core_form/submit', 'init', ['mod_quiz-prev-nav']);
790
        }
639
        }
791
        if ($lastpage) {
640
        if ($lastpage) {
792
            $nextlabel = get_string('endtest', 'quiz');
641
            $nextlabel = get_string('endtest', 'quiz');
793
        } else {
642
        } else {
794
            $nextlabel = get_string('navigatenext', 'quiz');
643
            $nextlabel = get_string('navigatenext', 'quiz');
795
        }
644
        }
796
        $output .= html_writer::empty_tag('input', [
-
 
797
            'type' => 'submit',
-
 
798
            'name' => 'next',
-
 
799
            'value' => $nextlabel,
645
        $output .= html_writer::empty_tag('input', ['type' => 'submit', 'name' => 'next',
800
            'class' => 'mod_quiz-next-nav btn btn-primary',
-
 
801
            'id' => 'mod_quiz-next-nav'
-
 
802
        ]);
646
                'value' => $nextlabel, 'class' => 'mod_quiz-next-nav btn btn-primary', 'id' => 'mod_quiz-next-nav']);
803
        $output .= html_writer::end_tag('div');
647
        $output .= html_writer::end_tag('div');
Línea 804... Línea 648...
804
        $this->page->requires->js_call_amd('core_form/submit', 'init', ['mod_quiz-next-nav']);
648
        $this->page->requires->js_call_amd('core_form/submit', 'init', ['mod_quiz-next-nav']);
805
 
649
 
Línea 811... Línea 655...
811
     *
655
     *
812
     * @param int $slot the number of the slot to generate the button for.
656
     * @param int $slot the number of the slot to generate the button for.
813
     * @param bool $disabled if true, output the button disabled.
657
     * @param bool $disabled if true, output the button disabled.
814
     * @return string HTML fragment.
658
     * @return string HTML fragment.
815
     */
659
     */
816
    public function redo_question_button($slot, $disabled)
660
    public function redo_question_button($slot, $disabled) {
817
    {
-
 
818
        $attributes = [
-
 
819
            'type' => 'submit',
-
 
820
            'name' => 'redoslot' . $slot,
661
        $attributes = ['type' => 'submit', 'name' => 'redoslot' . $slot,
821
            'value' => get_string('redoquestion', 'quiz'),
662
                'value' => get_string('redoquestion', 'quiz'),
822
            'class' => 'mod_quiz-redo_question_button btn btn-secondary',
663
                'class' => 'mod_quiz-redo_question_button btn btn-secondary',
823
            'id' => 'redoslot' . $slot . '-submit',
664
                'id' => 'redoslot' . $slot . '-submit',
824
            'data-savescrollposition' => 'true',
665
                'data-savescrollposition' => 'true',
825
        ];
666
            ];
826
        if ($disabled) {
667
        if ($disabled) {
827
            $attributes['disabled'] = 'disabled';
668
            $attributes['disabled'] = 'disabled';
828
        } else {
669
        } else {
829
            $this->page->requires->js_call_amd('core_question/question_engine', 'initSubmitButton', [$attributes['id']]);
670
            $this->page->requires->js_call_amd('core_question/question_engine', 'initSubmitButton', [$attributes['id']]);
830
        }
671
        }
Línea 835... Línea 676...
835
     * Initialise the JavaScript required to initialise the countdown timer.
676
     * Initialise the JavaScript required to initialise the countdown timer.
836
     *
677
     *
837
     * @param int $timerstartvalue time remaining, in seconds.
678
     * @param int $timerstartvalue time remaining, in seconds.
838
     * @param bool $ispreview true if this is a preview attempt.
679
     * @param bool $ispreview true if this is a preview attempt.
839
     */
680
     */
840
    public function initialise_timer($timerstartvalue, $ispreview)
681
    public function initialise_timer($timerstartvalue, $ispreview) {
841
    {
-
 
842
        $options = [$timerstartvalue, (bool) $ispreview];
682
        $options = [$timerstartvalue, (bool) $ispreview];
843
        $this->page->requires->js_init_call('M.mod_quiz.timer.init', $options, false, quiz_get_js_module());
683
        $this->page->requires->js_init_call('M.mod_quiz.timer.init', $options, false, quiz_get_js_module());
844
    }
684
    }
Línea 845... Línea 685...
845
 
685
 
Línea 849... Línea 689...
849
     *
689
     *
850
     * @param moodle_url $url the URL to redirect the parent window to.
690
     * @param moodle_url $url the URL to redirect the parent window to.
851
     * @param string $message message to display before closing the window. (optional)
691
     * @param string $message message to display before closing the window. (optional)
852
     * @return string HTML to output.
692
     * @return string HTML to output.
853
     */
693
     */
854
    public function close_attempt_popup($url, $message = '')
694
    public function close_attempt_popup($url, $message = '') {
855
    {
-
 
856
        $output = '';
695
        $output = '';
857
        $output .= $this->header();
696
        $output .= $this->header();
858
        $output .= $this->box_start();
697
        $output .= $this->box_start();
Línea 859... Línea 698...
859
 
698
 
Línea 863... Línea 702...
863
            $delay = 5;
702
            $delay = 5;
864
        } else {
703
        } else {
865
            $output .= html_writer::tag('p', get_string('pleaseclose', 'quiz'));
704
            $output .= html_writer::tag('p', get_string('pleaseclose', 'quiz'));
866
            $delay = 0;
705
            $delay = 0;
867
        }
706
        }
868
        $this->page->requires->js_init_call(
707
        $this->page->requires->js_init_call('M.mod_quiz.secure_window.close',
869
            'M.mod_quiz.secure_window.close',
-
 
870
            [$url->out(false), $delay],
708
            [$url->out(false), $delay], false, quiz_get_js_module());
871
            false,
-
 
872
            quiz_get_js_module()
-
 
873
        );
-
 
Línea 874... Línea 709...
874
 
709
 
875
        $output .= $this->box_end();
710
        $output .= $this->box_end();
876
        $output .= $this->footer();
711
        $output .= $this->footer();
877
        return $output;
712
        return $output;
Línea 881... Línea 716...
881
     * Print each message in an array, surrounded by <p>, </p> tags.
716
     * Print each message in an array, surrounded by <p>, </p> tags.
882
     *
717
     *
883
     * @param array $messages the array of message strings.
718
     * @param array $messages the array of message strings.
884
     * @return string HTML to output.
719
     * @return string HTML to output.
885
     */
720
     */
886
    public function access_messages($messages)
721
    public function access_messages($messages) {
887
    {
-
 
888
        $output = '';
722
        $output = '';
889
        foreach ($messages as $message) {
723
        foreach ($messages as $message) {
890
            $output .= html_writer::tag('p', $message, ['class' => 'text-left']);
724
            $output .= html_writer::tag('p', $message, ['class' => 'text-start']);
891
        }
725
        }
892
        return $output;
726
        return $output;
893
    }
727
    }
Línea 894... Línea 728...
894
 
728
 
Línea 899... Línea 733...
899
     * Create the summary page
733
     * Create the summary page
900
     *
734
     *
901
     * @param quiz_attempt $attemptobj
735
     * @param quiz_attempt $attemptobj
902
     * @param display_options $displayoptions
736
     * @param display_options $displayoptions
903
     */
737
     */
904
    public function summary_page($attemptobj, $displayoptions)
738
    public function summary_page($attemptobj, $displayoptions) {
905
    {
-
 
906
        $output = '';
739
        $output = '';
907
        $output .= $this->header();
740
        $output .= $this->header();
908
        $output .= $this->during_attempt_tertiary_nav($attemptobj->view_url());
741
        $output .= $this->during_attempt_tertiary_nav($attemptobj->view_url());
909
        $output .= $this->heading(format_string($attemptobj->get_quiz_name()));
742
        $output .= $this->heading(format_string($attemptobj->get_quiz_name()));
910
        $output .= $this->heading(get_string('summaryofattempt', 'quiz'), 3);
743
        $output .= $this->heading(get_string('summaryofattempt', 'quiz'), 3);
Línea 918... Línea 751...
918
     * Generates the table of summarydata
751
     * Generates the table of summarydata
919
     *
752
     *
920
     * @param quiz_attempt $attemptobj
753
     * @param quiz_attempt $attemptobj
921
     * @param display_options $displayoptions
754
     * @param display_options $displayoptions
922
     */
755
     */
923
    public function summary_table($attemptobj, $displayoptions)
756
    public function summary_table($attemptobj, $displayoptions) {
924
    {
-
 
925
        // Prepare the summary table header.
757
        // Prepare the summary table header.
926
        $table = new html_table();
758
        $table = new html_table();
927
        $table->attributes['class'] = 'generaltable quizsummaryofattempt boxaligncenter';
759
        $table->attributes['class'] = 'generaltable quizsummaryofattempt boxaligncenter';
928
        $table->head = [get_string('question', 'quiz'), get_string('status', 'quiz')];
760
        $table->head = [get_string('question', 'quiz'), get_string('status', 'quiz')];
929
        $table->align = ['left', 'left'];
761
        $table->align = ['left', 'left'];
Línea 969... Línea 801...
969
 
801
 
970
            // Real question, show it.
802
            // Real question, show it.
971
            $flag = '';
803
            $flag = '';
972
            if ($attemptobj->is_question_flagged($slot)) {
804
            if ($attemptobj->is_question_flagged($slot)) {
973
                // Quiz has custom JS manipulating these image tags - so we can't use the pix_icon method here.
-
 
974
                $flag = html_writer::empty_tag('img', [
805
                // Quiz has custom JS manipulating these image tags - so we can't use the pix_icon method here.
975
                    'src' => $this->image_url('i/flagged'),
806
                $flag = html_writer::empty_tag('img', ['src' => $this->image_url('i/flagged'),
976
                    'alt' => get_string('flagged', 'question'),
-
 
977
                    'class' => 'questionflag icon-post'
-
 
978
                ]);
807
                    'alt' => get_string('flagged', 'question'), 'class' => 'questionflag icon ms-2']);
979
            }
808
            }
980
            if ($attemptobj->can_navigate_to($slot)) {
-
 
981
                $row = [
-
 
982
                    html_writer::link(
809
            if ($attemptobj->can_navigate_to($slot)) {
983
                        $attemptobj->attempt_url($slot),
810
                $row = [html_writer::link($attemptobj->attempt_url($slot),
984
                        $attemptobj->get_question_number($slot) . $flag
-
 
985
                    ),
811
                        $attemptobj->get_question_number($slot) . $flag),
986
                    $attemptobj->get_question_status($slot, $displayoptions->correctness)
-
 
987
                ];
812
                        $attemptobj->get_question_status($slot, $displayoptions->correctness)];
988
            } else {
-
 
989
                $row = [
813
            } else {
990
                    $attemptobj->get_question_number($slot) . $flag,
814
                $row = [$attemptobj->get_question_number($slot) . $flag,
991
                    $attemptobj->get_question_status($slot, $displayoptions->correctness)
-
 
992
                ];
815
                        $attemptobj->get_question_status($slot, $displayoptions->correctness)];
993
            }
816
            }
994
            if ($markscolumn) {
817
            if ($markscolumn) {
995
                $row[] = $attemptobj->get_question_mark($slot);
818
                $row[] = $attemptobj->get_question_mark($slot);
996
            }
819
            }
997
            $table->data[] = $row;
820
            $table->data[] = $row;
998
            $table->rowclasses[] = 'quizsummary' . $slot . ' ' . $attemptobj->get_question_state_class(
-
 
999
                $slot,
821
            $table->rowclasses[] = 'quizsummary' . $slot . ' ' . $attemptobj->get_question_state_class(
1000
                $displayoptions->correctness
-
 
1001
            );
822
                            $slot, $displayoptions->correctness);
Línea 1002... Línea 823...
1002
        }
823
        }
1003
 
824
 
1004
        // Print the summary table.
825
        // Print the summary table.
Línea 1008... Línea 829...
1008
    /**
829
    /**
1009
     * Creates any controls the page should have.
830
     * Creates any controls the page should have.
1010
     *
831
     *
1011
     * @param quiz_attempt $attemptobj
832
     * @param quiz_attempt $attemptobj
1012
     */
833
     */
1013
    public function summary_page_controls($attemptobj)
834
    public function summary_page_controls($attemptobj) {
1014
    {
-
 
1015
        $output = '';
835
        $output = '';
Línea 1016... Línea 836...
1016
 
836
 
1017
        // Return to place button.
837
        // Return to place button.
1018
        if ($attemptobj->get_state() == quiz_attempt::IN_PROGRESS) {
838
        if ($attemptobj->get_state() == quiz_attempt::IN_PROGRESS) {
1019
            $button = new single_button(
839
            $button = new single_button(
1020
                new moodle_url($attemptobj->attempt_url(null, $attemptobj->get_currentpage())),
840
                    new moodle_url($attemptobj->attempt_url(null, $attemptobj->get_currentpage())),
1021
                get_string('returnattempt', 'quiz')
-
 
1022
            );
841
                    get_string('returnattempt', 'quiz'));
1023
            $output .= $this->container($this->container(
-
 
1024
                $this->render($button),
-
 
1025
                'controls'
842
            $output .= $this->container($this->container($this->render($button),
1026
            ), 'submitbtns mdl-align');
843
                    'controls'), 'submitbtns mdl-align');
Línea 1027... Línea 844...
1027
        }
844
        }
1028
 
845
 
1029
        // Finish attempt button.
846
        // Finish attempt button.
1030
        $options = [
847
        $options = [
1031
            'attempt' => $attemptobj->get_attemptid(),
848
                'attempt' => $attemptobj->get_attemptid(),
1032
            'finishattempt' => 1,
849
                'finishattempt' => 1,
1033
            'timeup' => 0,
850
                'timeup' => 0,
1034
            'slots' => '',
851
                'slots' => '',
1035
            'cmid' => $attemptobj->get_cmid(),
852
                'cmid' => $attemptobj->get_cmid(),
Línea 1036... Línea 853...
1036
            'sesskey' => sesskey(),
853
                'sesskey' => sesskey(),
1037
        ];
854
        ];
1038
 
855
 
1039
        $button = new single_button(
-
 
1040
            new moodle_url($attemptobj->processattempt_url(), $options),
856
        $button = new single_button(
1041
            get_string('submitallandfinish', 'quiz')
857
                new moodle_url($attemptobj->processattempt_url(), $options),
1042
        );
858
                get_string('submitallandfinish', 'quiz'));
1043
        $button->class = 'btn-finishattempt';
859
        $button->class = 'btn-finishattempt';
1044
        $button->formid = 'frm-finishattempt';
860
        $button->formid = 'frm-finishattempt';
Línea 1054... Línea 870...
1054
 
870
 
1055
        $duedate = $attemptobj->get_due_date();
871
        $duedate = $attemptobj->get_due_date();
1056
        $message = '';
872
        $message = '';
1057
        if ($attemptobj->get_state() == quiz_attempt::OVERDUE) {
873
        if ($attemptobj->get_state() == quiz_attempt::OVERDUE) {
-
 
874
            $message = get_string('overduemustbesubmittedby', 'quiz', userdate($duedate));
1058
            $message = get_string('overduemustbesubmittedby', 'quiz', userdate($duedate));
875
 
1059
        } else {
876
        } else {
1060
            if ($duedate) {
877
            if ($duedate) {
1061
                $message = get_string('mustbesubmittedby', 'quiz', userdate($duedate));
878
                $message = get_string('mustbesubmittedby', 'quiz', userdate($duedate));
1062
            }
879
            }
Línea 1063... Línea 880...
1063
        }
880
        }
1064
 
881
 
1065
        $output .= $this->countdown_timer($attemptobj, time());
-
 
1066
        $output .= $this->container($message . $this->container(
-
 
1067
            $this->render($button),
882
        $output .= $this->countdown_timer($attemptobj, time());
Línea 1068... Línea 883...
1068
            'controls'
883
        $output .= $this->container($message . $this->container(
1069
        ), 'submitbtns mdl-align');
884
                        $this->render($button), 'controls'), 'submitbtns mdl-align');
Línea 1070... Línea 885...
1070
 
885
 
Línea 1082... Línea 897...
1082
     * @param stdClass $cm the course_module settings row from the database.
897
     * @param stdClass $cm the course_module settings row from the database.
1083
     * @param context_module $context the quiz context.
898
     * @param context_module $context the quiz context.
1084
     * @param view_page $viewobj
899
     * @param view_page $viewobj
1085
     * @return string HTML to display
900
     * @return string HTML to display
1086
     */
901
     */
1087
    public function view_page($course, $quiz, $cm, $context, $viewobj)
902
    public function view_page($course, $quiz, $cm, $context, $viewobj) {
1088
    {
-
 
1089
        $output = '';
903
        $output = '';
Línea 1090... Línea 904...
1090
 
904
 
1091
        $output .= $this->view_page_tertiary_nav($viewobj);
905
        $output .= $this->view_page_tertiary_nav($viewobj);
1092
        $output .= $this->view_information($quiz, $cm, $context, $viewobj->infomessages);
906
        $output .= $this->view_information($quiz, $cm, $context, $viewobj->infomessages);
Línea 1100... Línea 914...
1100
     * Render the tertiary navigation for the view page.
914
     * Render the tertiary navigation for the view page.
1101
     *
915
     *
1102
     * @param view_page $viewobj the information required to display the view page.
916
     * @param view_page $viewobj the information required to display the view page.
1103
     * @return string HTML to output.
917
     * @return string HTML to output.
1104
     */
918
     */
1105
    public function view_page_tertiary_nav(view_page $viewobj): string
919
    public function view_page_tertiary_nav(view_page $viewobj): string {
1106
    {
-
 
1107
        $content = '';
920
        $content = '';
Línea 1108... Línea 921...
1108
 
921
 
1109
        if ($viewobj->buttontext) {
922
        if ($viewobj->buttontext) {
1110
            $attemptbtn = $this->start_attempt_button(
-
 
1111
                $viewobj->buttontext,
-
 
1112
                $viewobj->startattempturl,
923
            $attemptbtn = $this->start_attempt_button($viewobj->buttontext,
1113
                $viewobj->preflightcheckform,
924
                    $viewobj->startattempturl, $viewobj->preflightcheckform,
1114
                $viewobj->popuprequired,
-
 
1115
                $viewobj->popupoptions
-
 
1116
            );
925
                    $viewobj->popuprequired, $viewobj->popupoptions);
1117
            $content .= $attemptbtn;
926
            $content .= html_writer::div($attemptbtn, 'navitem');
Línea 1118... Línea 927...
1118
        }
927
        }
1119
 
-
 
1120
        if ($viewobj->canedit && !$viewobj->quizhasquestions) {
-
 
1121
            $content .= html_writer::link(
928
 
1122
                $viewobj->editurl,
929
        if ($viewobj->canedit && !$viewobj->quizhasquestions) {
1123
                get_string('addquestion', 'quiz'),
930
            $addquestionbutton = html_writer::link($viewobj->editurl, get_string('addquestion', 'quiz'),
1124
                ['class' => 'btn btn-secondary']
931
                    ['class' => 'btn btn-secondary']);
Línea 1125... Línea 932...
1125
            );
932
            $content .= html_writer::div($addquestionbutton, 'navitem');
1126
        }
933
        }
1127
 
934
 
1128
        if ($content) {
935
        if ($content) {
1129
            return html_writer::div(html_writer::div($content, 'row'), 'container-fluid tertiary-navigation');
936
            return html_writer::div(html_writer::div($content, 'd-flex'), 'tertiary-navigation');
1130
        } else {
937
        } else {
Línea 1137... Línea 944...
1137
     * at the end of the review page.
944
     * at the end of the review page.
1138
     *
945
     *
1139
     * @param view_page $viewobj the information required to display the view page.
946
     * @param view_page $viewobj the information required to display the view page.
1140
     * @return string HTML to output.
947
     * @return string HTML to output.
1141
     */
948
     */
1142
    public function view_page_buttons(view_page $viewobj)
949
    public function view_page_buttons(view_page $viewobj) {
1143
    {
-
 
1144
        $output = '';
950
        $output = '';
Línea 1145... Línea 951...
1145
 
951
 
1146
        if (!$viewobj->quizhasquestions) {
952
        if (!$viewobj->quizhasquestions) {
1147
            $output .= html_writer::div(
953
            $output .= html_writer::div(
1148
                $this->notification(get_string('noquestions', 'quiz'), 'warning', false),
954
                    $this->notification(get_string('noquestions', 'quiz'), 'warning', false),
1149
                'text-left mb-3'
-
 
1150
            );
955
                    'text-start mb-3');
1151
        }
956
        }
Línea 1152... Línea 957...
1152
        $output .= $this->access_messages($viewobj->preventmessages);
957
        $output .= $this->access_messages($viewobj->preventmessages);
1153
 
958
 
1154
        if ($viewobj->showbacktocourse) {
-
 
1155
            $output .= $this->single_button(
959
        if ($viewobj->showbacktocourse) {
1156
                $viewobj->backtocourseurl,
-
 
1157
                get_string('backtocourse', 'quiz'),
960
            $output .= $this->single_button($viewobj->backtocourseurl,
1158
                'get',
-
 
1159
                ['class' => 'continuebutton']
961
                    get_string('backtocourse', 'quiz'), 'get',
Línea 1160... Línea 962...
1160
            );
962
                    ['class' => 'continuebutton']);
1161
        }
963
        }
Línea 1171... Línea 973...
1171
     * @param preflight_check_form|null $preflightcheckform deprecated.
973
     * @param preflight_check_form|null $preflightcheckform deprecated.
1172
     * @param bool $popuprequired whether the attempt needs to be opened in a pop-up.
974
     * @param bool $popuprequired whether the attempt needs to be opened in a pop-up.
1173
     * @param array $popupoptions the options to use if we are opening a popup.
975
     * @param array $popupoptions the options to use if we are opening a popup.
1174
     * @return string HTML fragment.
976
     * @return string HTML fragment.
1175
     */
977
     */
1176
    public function start_attempt_button(
978
    public function start_attempt_button($buttontext, moodle_url $url,
1177
        $buttontext,
-
 
1178
        moodle_url $url,
-
 
1179
        preflight_check_form $preflightcheckform = null,
979
            ?preflight_check_form $preflightcheckform = null,
1180
        $popuprequired = false,
980
            $popuprequired = false, $popupoptions = null) {
1181
        $popupoptions = null
-
 
1182
    ) {
-
 
Línea 1183... Línea 981...
1183
 
981
 
1184
        $button = new single_button($url, $buttontext, 'post', single_button::BUTTON_PRIMARY);
982
        $button = new single_button($url, $buttontext, 'post', single_button::BUTTON_PRIMARY);
1185
        $button->class .= ' quizstartbuttondiv';
983
        $button->class .= ' quizstartbuttondiv';
1186
        if ($popuprequired) {
984
        if ($popuprequired) {
Línea 1191... Línea 989...
1191
        if ($popuprequired && $popupoptions) {
989
        if ($popuprequired && $popupoptions) {
1192
            $action = new popup_action('click', $url, 'popup', $popupoptions);
990
            $action = new popup_action('click', $url, 'popup', $popupoptions);
1193
            $popupjsoptions = $action->get_js_options();
991
            $popupjsoptions = $action->get_js_options();
1194
        }
992
        }
Línea 1195... Línea 993...
1195
 
993
 
1196
        $this->page->requires->js_call_amd(
-
 
1197
            'mod_quiz/preflightcheck',
-
 
1198
            'init',
-
 
1199
            [
994
        $this->page->requires->js_call_amd('mod_quiz/preflightcheck', 'init',
1200
                '.quizstartbuttondiv [type=submit]',
-
 
1201
                get_string('startattempt', 'quiz'),
995
                ['.quizstartbuttondiv [type=submit]', get_string('startattempt', 'quiz'),
1202
                '#mod_quiz_preflight_form',
-
 
1203
                $popupjsoptions
-
 
1204
            ]
-
 
Línea 1205... Línea 996...
1205
        );
996
                        '#mod_quiz_preflight_form', $popupjsoptions]);
1206
 
997
 
Línea 1207... Línea 998...
1207
        return $this->render($button) . ($preflightcheckform ? $preflightcheckform->render() : '');
998
        return $this->render($button) . ($preflightcheckform ? $preflightcheckform->render() : '');
Línea 1215... Línea 1006...
1215
     * @param moodle_url $editurl URL of the edit quiz page.
1006
     * @param moodle_url $editurl URL of the edit quiz page.
1216
     * @return string HTML to output.
1007
     * @return string HTML to output.
1217
     *
1008
     *
1218
     * @deprecated since Moodle 4.0 MDL-71915 - please do not use this function any more.
1009
     * @deprecated since Moodle 4.0 MDL-71915 - please do not use this function any more.
1219
     */
1010
     */
1220
    public function no_questions_message($canedit, $editurl)
1011
    public function no_questions_message($canedit, $editurl) {
1221
    {
-
 
1222
        debugging('no_questions_message() is deprecated, please use generate_no_questions_message() instead.', DEBUG_DEVELOPER);
1012
        debugging('no_questions_message() is deprecated, please use generate_no_questions_message() instead.', DEBUG_DEVELOPER);
Línea 1223... Línea 1013...
1223
 
1013
 
1224
        $output = html_writer::start_tag('div', ['class' => 'card text-center mb-3']);
1014
        $output = html_writer::start_tag('div', ['class' => 'card text-center mb-3']);
Línea 1242... Línea 1032...
1242
     * @param stdClass $cm the course_module settings row from the database.
1032
     * @param stdClass $cm the course_module settings row from the database.
1243
     * @param context_module $context the quiz context.
1033
     * @param context_module $context the quiz context.
1244
     * @param array $messages Array containing any messages
1034
     * @param array $messages Array containing any messages
1245
     * @param view_page $viewobj
1035
     * @param view_page $viewobj
1246
     */
1036
     */
1247
    public function view_page_guest($course, $quiz, $cm, $context, $messages, $viewobj)
1037
    public function view_page_guest($course, $quiz, $cm, $context, $messages, $viewobj) {
1248
    {
-
 
1249
        $output = '';
1038
        $output = '';
1250
        $output .= $this->view_page_tertiary_nav($viewobj);
1039
        $output .= $this->view_page_tertiary_nav($viewobj);
1251
        $output .= $this->view_information($quiz, $cm, $context, $messages);
1040
        $output .= $this->view_information($quiz, $cm, $context, $messages);
1252
        $guestno = html_writer::tag('p', get_string('guestsno', 'quiz'));
1041
        $guestno = html_writer::tag('p', get_string('guestsno', 'quiz'));
1253
        $liketologin = html_writer::tag('p', get_string('liketologin'));
1042
        $liketologin = html_writer::tag('p', get_string('liketologin'));
Línea 1264... Línea 1053...
1264
     * @param stdClass $cm the course_module settings row from the database.
1053
     * @param stdClass $cm the course_module settings row from the database.
1265
     * @param context_module $context the quiz context.
1054
     * @param context_module $context the quiz context.
1266
     * @param array $messages Array containing any messages
1055
     * @param array $messages Array containing any messages
1267
     * @param view_page $viewobj
1056
     * @param view_page $viewobj
1268
     */
1057
     */
1269
    public function view_page_notenrolled($course, $quiz, $cm, $context, $messages, $viewobj)
1058
    public function view_page_notenrolled($course, $quiz, $cm, $context, $messages, $viewobj) {
1270
    {
-
 
1271
        global $CFG;
1059
        global $CFG;
1272
        $output = '';
1060
        $output = '';
1273
        $output .= $this->view_page_tertiary_nav($viewobj);
1061
        $output .= $this->view_page_tertiary_nav($viewobj);
1274
        $output .= $this->view_information($quiz, $cm, $context, $messages);
1062
        $output .= $this->view_information($quiz, $cm, $context, $messages);
1275
        $youneedtoenrol = html_writer::tag('p', get_string('youneedtoenrol', 'quiz'));
1063
        $youneedtoenrol = html_writer::tag('p', get_string('youneedtoenrol', 'quiz'));
1276
        $button = html_writer::tag(
1064
        $button = html_writer::tag('p',
1277
            'p',
-
 
1278
            $this->continue_button($CFG->wwwroot . '/course/view.php?id=' . $course->id)
1065
                $this->continue_button($CFG->wwwroot . '/course/view.php?id=' . $course->id));
1279
        );
-
 
1280
        $output .= $this->box($youneedtoenrol . "\n\n" . $button . "\n", 'generalbox', 'notice');
1066
        $output .= $this->box($youneedtoenrol . "\n\n" . $button . "\n", 'generalbox', 'notice');
1281
        return $output;
1067
        return $output;
1282
    }
1068
    }
Línea 1283... Línea 1069...
1283
 
1069
 
Línea 1289... Línea 1075...
1289
     * @param context $context the quiz context.
1075
     * @param context $context the quiz context.
1290
     * @param array $messages any access messages that should be described.
1076
     * @param array $messages any access messages that should be described.
1291
     * @param bool $quizhasquestions does quiz has questions added.
1077
     * @param bool $quizhasquestions does quiz has questions added.
1292
     * @return string HTML to output.
1078
     * @return string HTML to output.
1293
     */
1079
     */
1294
    public function view_information($quiz, $cm, $context, $messages, bool $quizhasquestions = false)
1080
    public function view_information($quiz, $cm, $context, $messages, bool $quizhasquestions = false) {
1295
    {
-
 
1296
        $output = '';
1081
        $output = '';
Línea 1297... Línea 1082...
1297
 
1082
 
1298
        // Output any access messages.
1083
        // Output any access messages.
1299
        if ($messages) {
1084
        if ($messages) {
1300
            $output .= $this->box($this->access_messages($messages), 'quizinfo');
1085
            $output .= $this->box($this->access_messages($messages), 'quizinfo');
Línea 1301... Línea 1086...
1301
        }
1086
        }
1302
 
1087
 
1303
        // Show number of attempts summary to those who can view reports.
1088
        // Show number of attempts summary to those who can view reports.
1304
        if (has_capability('mod/quiz:viewreports', $context)) {
-
 
1305
            if ($strattemptnum = $this->quiz_attempt_summary_link_to_reports(
-
 
1306
                $quiz,
1089
        if (has_capability('mod/quiz:viewreports', $context)) {
1307
                $cm,
-
 
1308
                $context
1090
            if ($strattemptnum = $this->quiz_attempt_summary_link_to_reports($quiz, $cm,
1309
            )) {
-
 
1310
                $output .= html_writer::tag(
-
 
1311
                    'div',
1091
                    $context)) {
1312
                    $strattemptnum,
-
 
1313
                    ['class' => 'quizattemptcounts']
1092
                $output .= html_writer::tag('div', $strattemptnum,
1314
                );
1093
                        ['class' => 'quizattemptcounts']);
Línea 1315... Línea 1094...
1315
            }
1094
            }
1316
        }
1095
        }
Línea 1329... Línea 1108...
1329
     *
1108
     *
1330
     * @param stdClass $quiz the quiz settings.
1109
     * @param stdClass $quiz the quiz settings.
1331
     * @param stdClass $cm the course_module object.
1110
     * @param stdClass $cm the course_module object.
1332
     * @return string HTML to output.
1111
     * @return string HTML to output.
1333
     */
1112
     */
1334
    public function quiz_intro($quiz, $cm)
1113
    public function quiz_intro($quiz, $cm) {
1335
    {
-
 
1336
        if (html_is_blank($quiz->intro)) {
1114
        if (html_is_blank($quiz->intro)) {
1337
            return '';
1115
            return '';
1338
        }
1116
        }
Línea 1339... Línea 1117...
1339
 
1117
 
1340
        return $this->box(format_module_intro('quiz', $quiz, $cm->id), 'generalbox', 'intro');
1118
        return $this->box(format_module_intro('quiz', $quiz, $cm->id), 'generalbox', 'intro');
Línea 1341... Línea 1119...
1341
    }
1119
    }
1342
 
1120
 
1343
    /**
1121
    /**
1344
     * Generates the table heading.
1122
     * Generates the table heading.
1345
     */
-
 
1346
    public function view_table_heading()
1123
     */
1347
    {
1124
    public function view_table_heading() {
Línea 1348... Línea 1125...
1348
        return $this->heading(get_string('summaryofattempts', 'quiz'), 3);
1125
        return $this->heading(get_string('summaryofattempts', 'quiz'), 3);
1349
    }
1126
    }
Línea 1354... Línea 1131...
1354
     * @param stdClass $quiz the quiz settings.
1131
     * @param stdClass $quiz the quiz settings.
1355
     * @param context_module $context the quiz context.
1132
     * @param context_module $context the quiz context.
1356
     * @param view_page $viewobj
1133
     * @param view_page $viewobj
1357
     * @deprecated Since 4.4 please use the {@see list_of_attempts} renderable instead.
1134
     * @deprecated Since 4.4 please use the {@see list_of_attempts} renderable instead.
1358
     */
1135
     */
1359
    public function view_table($quiz, $context, $viewobj)
1136
    public function view_table($quiz, $context, $viewobj) {
1360
    {
-
 
1361
        debugging('view_table has been deprecated since 4.4 please use the list_of_attempts renderable instead.');
1137
        debugging('view_table has been deprecated since 4.4 please use the list_of_attempts renderable instead.');
1362
        if (!$viewobj->attempts) {
1138
        if (!$viewobj->attempts) {
1363
            return '';
1139
            return '';
1364
        }
1140
        }
Línea 1379... Línea 1155...
1379
        $table->head[] = get_string('attemptstate', 'quiz');
1155
        $table->head[] = get_string('attemptstate', 'quiz');
1380
        $table->align[] = 'left';
1156
        $table->align[] = 'left';
1381
        $table->size[] = '';
1157
        $table->size[] = '';
1382
        if ($viewobj->markcolumn) {
1158
        if ($viewobj->markcolumn) {
1383
            $table->head[] = get_string('marks', 'quiz') . ' / ' .
1159
            $table->head[] = get_string('marks', 'quiz') . ' / ' .
1384
                quiz_format_grade($quiz, $quiz->sumgrades);
1160
                    quiz_format_grade($quiz, $quiz->sumgrades);
1385
            $table->align[] = 'center';
1161
            $table->align[] = 'center';
1386
            $table->size[] = '';
1162
            $table->size[] = '';
1387
        }
1163
        }
1388
        if ($viewobj->gradecolumn) {
1164
        if ($viewobj->gradecolumn) {
1389
            $table->head[] = get_string('gradenoun') . ' / ' .
1165
            $table->head[] = get_string('gradenoun') . ' / ' .
1390
                quiz_format_grade($quiz, $quiz->grade);
1166
                    quiz_format_grade($quiz, $quiz->grade);
1391
            $table->align[] = 'center';
1167
            $table->align[] = 'center';
1392
            $table->size[] = '';
1168
            $table->size[] = '';
1393
        }
1169
        }
1394
        if ($viewobj->canreviewmine) {
1170
        if ($viewobj->canreviewmine) {
1395
            $table->head[] = get_string('review', 'quiz');
1171
            $table->head[] = get_string('review', 'quiz');
Línea 1417... Línea 1193...
1417
            }
1193
            }
Línea 1418... Línea 1194...
1418
 
1194
 
Línea 1419... Línea 1195...
1419
            $row[] = $this->attempt_state($attemptobj);
1195
            $row[] = $this->attempt_state($attemptobj);
1420
 
-
 
1421
            if ($viewobj->markcolumn) {
1196
 
1422
                if (
1197
            if ($viewobj->markcolumn) {
1423
                    $attemptoptions->marks >= question_display_options::MARK_AND_MAX &&
-
 
1424
                    $attemptobj->is_finished()
1198
                if ($attemptoptions->marks >= question_display_options::MARK_AND_MAX &&
1425
                ) {
1199
                        $attemptobj->is_finished()) {
1426
                    $row[] = quiz_format_grade($quiz, $attemptobj->get_sum_marks());
1200
                    $row[] = quiz_format_grade($quiz, $attemptobj->get_sum_marks());
1427
                } else {
1201
                } else {
1428
                    $row[] = '';
1202
                    $row[] = '';
Línea 1429... Línea 1203...
1429
                }
1203
                }
1430
            }
1204
            }
Línea 1431... Línea 1205...
1431
 
1205
 
1432
            // Outside the if because we may be showing feedback but not grades.
-
 
1433
            $attemptgrade = quiz_rescale_grade($attemptobj->get_sum_marks(), $quiz, false);
1206
            // Outside the if because we may be showing feedback but not grades.
1434
 
1207
            $attemptgrade = quiz_rescale_grade($attemptobj->get_sum_marks(), $quiz, false);
1435
            if ($viewobj->gradecolumn) {
-
 
Línea 1436... Línea 1208...
1436
                if (
1208
 
1437
                    $attemptoptions->marks >= question_display_options::MARK_AND_MAX &&
-
 
1438
                    $attemptobj->is_finished()
1209
            if ($viewobj->gradecolumn) {
1439
                ) {
1210
                if ($attemptoptions->marks >= question_display_options::MARK_AND_MAX &&
1440
 
1211
                        $attemptobj->is_finished()) {
1441
                    // Highlight the highest grade if appropriate.
1212
 
1442
                    if (
1213
                    // Highlight the highest grade if appropriate.
1443
                        $viewobj->overallstats && !$attemptobj->is_preview()
-
 
1444
                        && $viewobj->numattempts > 1 && !is_null($viewobj->mygrade)
1214
                    if ($viewobj->overallstats && !$attemptobj->is_preview()
1445
                        && $attemptobj->get_state() == quiz_attempt::FINISHED
1215
                            && $viewobj->numattempts > 1 && !is_null($viewobj->mygrade)
Línea 1446... Línea 1216...
1446
                        && $attemptgrade == $viewobj->mygrade
1216
                            && $attemptobj->get_state() == quiz_attempt::FINISHED
1447
                        && $quiz->grademethod == QUIZ_GRADEHIGHEST
1217
                            && $attemptgrade == $viewobj->mygrade
1448
                    ) {
1218
                            && $quiz->grademethod == QUIZ_GRADEHIGHEST) {
1449
                        $table->rowclasses[$attemptobj->get_attempt_number()] = 'bestrow';
1219
                        $table->rowclasses[$attemptobj->get_attempt_number()] = 'bestrow';
1450
                    }
1220
                    }
Línea 1451... Línea 1221...
1451
 
1221
 
1452
                    $row[] = quiz_format_grade($quiz, $attemptgrade);
1222
                    $row[] = quiz_format_grade($quiz, $attemptgrade);
1453
                } else {
-
 
1454
                    $row[] = '';
1223
                } else {
1455
                }
-
 
1456
            }
-
 
1457
 
1224
                    $row[] = '';
Línea 1458... Línea 1225...
1458
            if ($viewobj->canreviewmine) {
1225
                }
1459
                $row[] = $viewobj->accessmanager->make_review_link(
1226
            }
1460
                    $attemptobj->get_attempt(),
1227
 
Línea 1488... Línea 1255...
1488
     * Generate a brief textual description of the current state of an attempt.
1255
     * Generate a brief textual description of the current state of an attempt.
1489
     *
1256
     *
1490
     * @param quiz_attempt $attemptobj the attempt
1257
     * @param quiz_attempt $attemptobj the attempt
1491
     * @return string the appropriate lang string to describe the state.
1258
     * @return string the appropriate lang string to describe the state.
1492
     */
1259
     */
1493
    public function attempt_state($attemptobj)
1260
    public function attempt_state($attemptobj) {
1494
    {
-
 
1495
        switch ($attemptobj->get_state()) {
1261
        switch ($attemptobj->get_state()) {
1496
            case quiz_attempt::IN_PROGRESS:
1262
            case quiz_attempt::IN_PROGRESS:
1497
                return get_string('stateinprogress', 'quiz');
1263
                return get_string('stateinprogress', 'quiz');
Línea 1498... Línea 1264...
1498
 
1264
 
1499
            case quiz_attempt::OVERDUE:
1265
            case quiz_attempt::OVERDUE:
1500
                return get_string('stateoverdue', 'quiz') . html_writer::tag(
-
 
1501
                    'span',
-
 
1502
                    get_string(
1266
                return get_string('stateoverdue', 'quiz') . html_writer::tag('span',
1503
                        'stateoverduedetails',
-
 
1504
                        'quiz',
1267
                                get_string('stateoverduedetails', 'quiz',
1505
                        userdate($attemptobj->get_due_date())
-
 
1506
                    ),
1268
                                        userdate($attemptobj->get_due_date())),
1507
                    ['class' => 'statedetails']
-
 
Línea 1508... Línea 1269...
1508
                );
1269
                                ['class' => 'statedetails']);
1509
 
1270
 
1510
            case quiz_attempt::FINISHED:
-
 
1511
                return get_string('statefinished', 'quiz') . html_writer::tag(
-
 
1512
                    'span',
1271
            case quiz_attempt::FINISHED:
1513
                    get_string(
-
 
1514
                        'statefinisheddetails',
1272
                return get_string('statefinished', 'quiz') . html_writer::tag('span',
1515
                        'quiz',
-
 
1516
                        userdate($attemptobj->get_submitted_date())
1273
                                get_string('statefinisheddetails', 'quiz',
1517
                    ),
-
 
Línea 1518... Línea 1274...
1518
                    ['class' => 'statedetails']
1274
                                        userdate($attemptobj->get_submitted_date())),
1519
                );
1275
                                ['class' => 'statedetails']);
Línea 1520... Línea 1276...
1520
 
1276
 
Línea 1533... Línea 1289...
1533
     * @param context_module $context The quiz context.
1289
     * @param context_module $context The quiz context.
1534
     * @param stdClass|cm_info $cm The course module information.
1290
     * @param stdClass|cm_info $cm The course module information.
1535
     * @param view_page $viewobj
1291
     * @param view_page $viewobj
1536
     * @return string HTML to display.
1292
     * @return string HTML to display.
1537
     */
1293
     */
1538
    public function view_result_info($quiz, $context, $cm, $viewobj)
1294
    public function view_result_info($quiz, $context, $cm, $viewobj) {
1539
    {
-
 
1540
        $output = '';
1295
        $output = '';
1541
        if (!$viewobj->numattempts && !$viewobj->gradecolumn && is_null($viewobj->mygrade)) {
1296
        if (!$viewobj->numattempts && !$viewobj->gradecolumn && is_null($viewobj->mygrade)) {
1542
            return $output;
1297
            return $output;
1543
        }
1298
        }
1544
        $resultinfo = '';
1299
        $resultinfo = '';
Línea 1559... Línea 1314...
1559
            }
1314
            }
1560
        }
1315
        }
Línea 1561... Línea 1316...
1561
 
1316
 
Línea 1562... Línea -...
1562
        if ($viewobj->mygradeoverridden) {
-
 
1563
 
-
 
1564
            $resultinfo .= html_writer::tag(
1317
        if ($viewobj->mygradeoverridden) {
1565
                'p',
1318
 
1566
                get_string('overriddennotice', 'grades'),
-
 
1567
                ['class' => 'overriddennotice']
1319
            $resultinfo .= html_writer::tag('p', get_string('overriddennotice', 'grades'),
1568
            ) . "\n";
1320
                            ['class' => 'overriddennotice']) . "\n";
1569
        }
1321
        }
1570
        if ($viewobj->gradebookfeedback) {
1322
        if ($viewobj->gradebookfeedback) {
1571
            $resultinfo .= $this->heading(get_string('comment', 'quiz'), 3);
1323
            $resultinfo .= $this->heading(get_string('comment', 'quiz'), 3);
1572
            $resultinfo .= html_writer::div($viewobj->gradebookfeedback, 'quizteacherfeedback') . "\n";
1324
            $resultinfo .= html_writer::div($viewobj->gradebookfeedback, 'quizteacherfeedback') . "\n";
1573
        }
1325
        }
1574
        if ($viewobj->feedbackcolumn) {
1326
        if ($viewobj->feedbackcolumn) {
1575
            $resultinfo .= $this->heading(get_string('overallfeedback', 'quiz'), 3);
1327
            $resultinfo .= $this->heading(get_string('overallfeedback', 'quiz'), 3);
1576
            $resultinfo .= html_writer::div(
1328
            $resultinfo .= html_writer::div(
1577
                quiz_feedback_for_grade($viewobj->mygrade, $quiz, $context),
-
 
1578
                'quizgradefeedback'
1329
                            quiz_feedback_for_grade($viewobj->mygrade, $quiz, $context),
Línea 1579... Línea 1330...
1579
            ) . "\n";
1330
                            'quizgradefeedback') . "\n";
1580
        }
1331
        }
1581
 
1332
 
Línea 1592... Línea 1343...
1592
     * @param moodle_url $url of the target page.
1343
     * @param moodle_url $url of the target page.
1593
     * @param bool $reviewinpopup whether a pop-up is required.
1344
     * @param bool $reviewinpopup whether a pop-up is required.
1594
     * @param array $popupoptions options to pass to the popup_action constructor.
1345
     * @param array $popupoptions options to pass to the popup_action constructor.
1595
     * @return string HTML to output.
1346
     * @return string HTML to output.
1596
     */
1347
     */
1597
    public function review_link($url, $reviewinpopup, $popupoptions)
1348
    public function review_link($url, $reviewinpopup, $popupoptions) {
1598
    {
-
 
1599
        if ($reviewinpopup) {
1349
        if ($reviewinpopup) {
1600
            $button = new single_button($url, get_string('review', 'quiz'));
1350
            $button = new single_button($url, get_string('review', 'quiz'));
1601
            $button->add_action(new popup_action('click', $url, 'quizpopup', $popupoptions));
1351
            $button->add_action(new popup_action('click', $url, 'quizpopup', $popupoptions));
1602
            return $this->render($button);
1352
            return $this->render($button);
-
 
1353
 
1603
        } else {
1354
        } else {
1604
            return html_writer::link(
-
 
1605
                $url,
-
 
1606
                get_string('review', 'quiz'),
1355
            return html_writer::link($url, get_string('review', 'quiz'),
1607
                ['title' => get_string('reviewthisattempt', 'quiz')]
1356
                    ['title' => get_string('reviewthisattempt', 'quiz')]);
1608
            );
-
 
1609
        }
1357
        }
1610
    }
1358
    }
Línea 1611... Línea 1359...
1611
 
1359
 
1612
    /**
1360
    /**
1613
     * Displayed where there might normally be a review link, to explain why the
1361
     * Displayed where there might normally be a review link, to explain why the
1614
     * review is not available at this time.
1362
     * review is not available at this time.
1615
     *
1363
     *
1616
     * @param string $message optional message explaining why the review is not possible.
1364
     * @param string $message optional message explaining why the review is not possible.
1617
     * @return string HTML to output.
1365
     * @return string HTML to output.
1618
     */
1366
     */
1619
    public function no_review_message($message)
-
 
1620
    {
1367
    public function no_review_message($message) {
1621
        return html_writer::nonempty_tag(
-
 
1622
            'span',
-
 
1623
            $message,
1368
        return html_writer::nonempty_tag('span', $message,
1624
            ['class' => 'noreviewmessage']
-
 
1625
        );
1369
                ['class' => 'noreviewmessage']);
Línea 1626... Línea 1370...
1626
    }
1370
    }
1627
 
1371
 
1628
    /**
1372
    /**
Línea 1636... Línea 1380...
1636
     *      instead of 'Attempts: 0'.
1380
     *      instead of 'Attempts: 0'.
1637
     * @param int $currentgroup if there is a concept of current group where this method is being
1381
     * @param int $currentgroup if there is a concept of current group where this method is being
1638
     *      called (e.g. a report) pass it in here. Default 0 which means no current group.
1382
     *      called (e.g. a report) pass it in here. Default 0 which means no current group.
1639
     * @return string HTML fragment for the link.
1383
     * @return string HTML fragment for the link.
1640
     */
1384
     */
1641
    public function quiz_attempt_summary_link_to_reports(
1385
    public function quiz_attempt_summary_link_to_reports($quiz, $cm, $context,
1642
        $quiz,
-
 
1643
        $cm,
-
 
1644
        $context,
-
 
1645
        $returnzero = false,
1386
            $returnzero = false, $currentgroup = 0) {
1646
        $currentgroup = 0
-
 
1647
    ) {
-
 
1648
        global $CFG;
1387
        global $CFG;
1649
        $summary = quiz_num_attempt_summary($quiz, $cm, $returnzero, $currentgroup);
1388
        $summary = quiz_num_attempt_summary($quiz, $cm, $returnzero, $currentgroup);
1650
        if (!$summary) {
1389
        if (!$summary) {
1651
            return '';
1390
            return '';
1652
        }
1391
        }
Línea 1653... Línea 1392...
1653
 
1392
 
1654
        require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
1393
        require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
1655
        $url = new moodle_url('/mod/quiz/report.php', [
-
 
1656
            'id' => $cm->id,
1394
        $url = new moodle_url('/mod/quiz/report.php', [
1657
            'mode' => quiz_report_default_report($context)
-
 
1658
        ]);
1395
                'id' => $cm->id, 'mode' => quiz_report_default_report($context)]);
1659
        return html_writer::link($url, $summary);
1396
        return html_writer::link($url, $summary);
Línea 1660... Línea 1397...
1660
    }
1397
    }
1661
 
1398
 
Línea 1665... Línea 1402...
1665
     * @param stdClass $quiz the quiz settings.
1402
     * @param stdClass $quiz the quiz settings.
1666
     * @param cm_info|stdClass $cm the cm object.
1403
     * @param cm_info|stdClass $cm the cm object.
1667
     * @param int $currentgroup currently selected group, if there is one.
1404
     * @param int $currentgroup currently selected group, if there is one.
1668
     * @return string HTML fragment for the link.
1405
     * @return string HTML fragment for the link.
1669
     */
1406
     */
1670
    public function quiz_override_summary_links(stdClass $quiz, cm_info|stdClass $cm, $currentgroup = 0): string
1407
    public function quiz_override_summary_links(stdClass $quiz, cm_info|stdClass $cm, $currentgroup = 0): string {
1671
    {
-
 
Línea 1672... Línea 1408...
1672
 
1408
 
1673
        $baseurl = new moodle_url('/mod/quiz/overrides.php', ['cmid' => $cm->id]);
1409
        $baseurl = new moodle_url('/mod/quiz/overrides.php', ['cmid' => $cm->id]);
Línea 1674... Línea 1410...
1674
        $counts = quiz_override_summary($quiz, $cm, $currentgroup);
1410
        $counts = quiz_override_summary($quiz, $cm, $currentgroup);
1675
 
1411
 
1676
        $links = [];
-
 
1677
        if ($counts['group']) {
1412
        $links = [];
1678
            $links[] = html_writer::link(
1413
        if ($counts['group']) {
1679
                new moodle_url($baseurl, ['mode' => 'group']),
-
 
1680
                get_string('overridessummarygroup', 'quiz', $counts['group'])
1414
            $links[] = html_writer::link(new moodle_url($baseurl, ['mode' => 'group']),
1681
            );
1415
                    get_string('overridessummarygroup', 'quiz', $counts['group']));
1682
        }
-
 
1683
        if ($counts['user']) {
1416
        }
1684
            $links[] = html_writer::link(
1417
        if ($counts['user']) {
1685
                new moodle_url($baseurl, ['mode' => 'user']),
-
 
1686
                get_string('overridessummaryuser', 'quiz', $counts['user'])
1418
            $links[] = html_writer::link(new moodle_url($baseurl, ['mode' => 'user']),
Línea 1687... Línea 1419...
1687
            );
1419
                    get_string('overridessummaryuser', 'quiz', $counts['user']));
1688
        }
1420
        }
1689
 
1421
 
Línea 1713... Línea 1445...
1713
     * @param \core\chart_base $chart The chart.
1445
     * @param \core\chart_base $chart The chart.
1714
     * @param string $title The title to display above the graph.
1446
     * @param string $title The title to display above the graph.
1715
     * @param array $attrs extra container html attributes.
1447
     * @param array $attrs extra container html attributes.
1716
     * @return string HTML of the graph.
1448
     * @return string HTML of the graph.
1717
     */
1449
     */
1718
    public function chart(\core\chart_base $chart, $title, $attrs = [])
1450
    public function chart(\core\chart_base $chart, $title, $attrs = []) {
1719
    {
-
 
1720
        return $this->heading($title, 3) . html_writer::tag(
1451
        return $this->heading($title, 3) . html_writer::tag('div',
1721
            'div',
-
 
1722
            $this->render($chart),
-
 
1723
            array_merge(['class' => 'graph'], $attrs)
1452
                        $this->render($chart), array_merge(['class' => 'graph'], $attrs));
1724
        );
-
 
1725
    }
1453
    }
Línea 1726... Línea 1454...
1726
 
1454
 
1727
    /**
1455
    /**
1728
     * Output a graph, or a message saying that GD is required.
1456
     * Output a graph, or a message saying that GD is required.
1729
     *
1457
     *
1730
     * @param moodle_url $url the URL of the graph.
1458
     * @param moodle_url $url the URL of the graph.
1731
     * @param string $title the title to display above the graph.
1459
     * @param string $title the title to display above the graph.
1732
     * @return string HTML of the graph.
1460
     * @return string HTML of the graph.
1733
     */
1461
     */
1734
    public function graph(moodle_url $url, $title)
-
 
1735
    {
1462
    public function graph(moodle_url $url, $title) {
Línea 1736... Línea 1463...
1736
        $graph = html_writer::empty_tag('img', ['src' => $url, 'alt' => $title]);
1463
        $graph = html_writer::empty_tag('img', ['src' => $url, 'alt' => $title]);
1737
 
1464
 
Línea 1738... Línea 1465...
1738
        return $this->heading($title, 3) . html_writer::tag('div', $graph, ['class' => 'graph']);
1465
        return $this->heading($title, 3) . html_writer::tag('div', $graph, ['class' => 'graph']);
1739
    }
1466
    }
1740
 
1467
 
1741
    /**
1468
    /**
1742
     * Output the connection warning messages, which are initially hidden, and
1469
     * Output the connection warning messages, which are initially hidden, and
1743
     * only revealed by JavaScript if necessary.
-
 
1744
     */
1470
     * only revealed by JavaScript if necessary.
1745
    public function connection_warning()
1471
     */
1746
    {
1472
    public function connection_warning() {
1747
        $options = ['filter' => false, 'newlines' => false];
1473
        $options = ['filter' => false, 'newlines' => false];
1748
        $warning = format_text(get_string('connectionerror', 'quiz'), FORMAT_MARKDOWN, $options);
-
 
1749
        $ok = format_text(get_string('connectionok', 'quiz'), FORMAT_MARKDOWN, $options);
-
 
1750
        return html_writer::tag(
1474
        $warning = format_text(get_string('connectionerror', 'quiz'), FORMAT_MARKDOWN, $options);
1751
            'div',
-
 
1752
            $warning,
1475
        $ok = format_text(get_string('connectionok', 'quiz'), FORMAT_MARKDOWN, $options);
1753
            ['id' => 'connection-error', 'style' => 'display: none;', 'role' => 'alert']
1476
        return html_writer::tag('div', $warning,
Línea 1754... Línea 1477...
1754
        ) .
1477
                        ['id' => 'connection-error', 'style' => 'display: none;', 'role' => 'alert']) .
1755
            html_writer::tag('div', $ok, ['id' => 'connection-ok', 'style' => 'display: none;', 'role' => 'alert']);
1478
                html_writer::tag('div', $ok, ['id' => 'connection-ok', 'style' => 'display: none;', 'role' => 'alert']);
1756
    }
1479
    }
1757
 
1480
 
1758
    /**
1481
    /**
1759
     * Deprecated version of render_links_to_other_attempts.
1482
     * Deprecated version of render_links_to_other_attempts.
1760
     *
1483
     *
1761
     * @param links_to_other_attempts $links
1484
     * @param links_to_other_attempts $links
1762
     * @return string HTML fragment.
1485
     * @return string HTML fragment.
1763
     * @deprecated since Moodle 4.2. Please use render_links_to_other_attempts instead.
-
 
1764
     * @todo MDL-76612 Final deprecation in Moodle 4.6
1486
     * @deprecated since Moodle 4.2. Please use render_links_to_other_attempts instead.
1765
     */
1487
     * @todo MDL-76612 Final deprecation in Moodle 4.6
Línea 1766... Línea 1488...
1766
    protected function render_mod_quiz_links_to_other_attempts(links_to_other_attempts $links)
1488
     */
1767
    {
1489
    protected function render_mod_quiz_links_to_other_attempts(links_to_other_attempts $links) {
Línea 1774... Línea 1496...
1774
     * @param navigation_question_button $button
1496
     * @param navigation_question_button $button
1775
     * @return string HTML fragment.
1497
     * @return string HTML fragment.
1776
     * @deprecated since Moodle 4.2. Please use render_links_to_other_attempts instead.
1498
     * @deprecated since Moodle 4.2. Please use render_links_to_other_attempts instead.
1777
     * @todo MDL-76612 Final deprecation in Moodle 4.6
1499
     * @todo MDL-76612 Final deprecation in Moodle 4.6
1778
     */
1500
     */
1779
    protected function render_quiz_nav_question_button(navigation_question_button $button)
1501
    protected function render_quiz_nav_question_button(navigation_question_button $button) {
1780
    {
-
 
1781
        return $this->render_navigation_question_button($button);
1502
        return $this->render_navigation_question_button($button);
1782
    }
1503
    }
Línea 1783... Línea 1504...
1783
 
1504
 
1784
    /**
1505
    /**
Línea 1787... Línea 1508...
1787
     * @param navigation_section_heading $heading the heading.
1508
     * @param navigation_section_heading $heading the heading.
1788
     * @return string HTML fragment.
1509
     * @return string HTML fragment.
1789
     * @deprecated since Moodle 4.2. Please use render_links_to_other_attempts instead.
1510
     * @deprecated since Moodle 4.2. Please use render_links_to_other_attempts instead.
1790
     * @todo MDL-76612 Final deprecation in Moodle 4.6
1511
     * @todo MDL-76612 Final deprecation in Moodle 4.6
1791
     */
1512
     */
1792
    protected function render_quiz_nav_section_heading(navigation_section_heading $heading)
1513
    protected function render_quiz_nav_section_heading(navigation_section_heading $heading) {
1793
    {
-
 
1794
        return $this->render_navigation_section_heading($heading);
1514
        return $this->render_navigation_section_heading($heading);
1795
    }
1515
    }
1796
}
1516
}