Revert "MDL-34257 quiz 'secure' mode: PAGE initialisation order issues."
[moodle.git] / mod / quiz / review.php
CommitLineData
83192608 1<?php
b2607ccc
TH
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
ee1fb969 17/**
f63a4ff2 18 * This page prints a review of a particular quiz attempt
19 *
b2607ccc
TH
20 * It is used either by the student whose attempts this is, after the attempt,
21 * or by a teacher reviewing another's attempt during or afterwards.
22 *
34b7d838
TH
23 * @package mod_quiz
24 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
f63a4ff2 26 */
29d5d0b4 27
ba643847 28
b2607ccc
TH
29require_once(dirname(__FILE__) . '/../../config.php');
30require_once($CFG->dirroot . '/mod/quiz/locallib.php');
31require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
32
33$attemptid = required_param('attempt', PARAM_INT);
a361ff56
TH
34$page = optional_param('page', 0, PARAM_INT);
35$showall = optional_param('showall', 0, PARAM_BOOL);
b2607ccc
TH
36
37$url = new moodle_url('/mod/quiz/review.php', array('attempt'=>$attemptid));
38if ($page !== 0) {
39 $url->param('page', $page);
40}
41if ($showall !== 0) {
42 $url->param('showall', $showall);
43}
44$PAGE->set_url($url);
45
46$attemptobj = quiz_attempt::create($attemptid);
a361ff56 47$page = $attemptobj->force_page_number_into_range($page);
b2607ccc
TH
48
49// Check login.
50require_login($attemptobj->get_course(), false, $attemptobj->get_cm());
51$attemptobj->check_review_capability();
52
53// Create an object to manage all the other (non-roles) access rules.
54$accessmanager = $attemptobj->get_access_manager(time());
55$options = $attemptobj->get_display_options(true);
56
8032cd79
TH
57// Check permissions.
58if ($attemptobj->is_own_attempt()) {
b2607ccc 59 if (!$attemptobj->is_finished()) {
45e5fbe1 60 redirect($attemptobj->attempt_url(null, $page));
d755b0f5 61
8032cd79 62 } else if (!$options->attempt) {
d755b0f5
TH
63 $accessmanager->back_to_view_page($PAGE->get_renderer('mod_quiz'),
64 $attemptobj->cannot_review_message());
83192608 65 }
8032cd79
TH
66
67} else if (!$attemptobj->is_review_allowed()) {
68 throw new moodle_quiz_exception($attemptobj->get_quizobj(), 'noreviewattempt');
b2607ccc
TH
69}
70
71// Load the questions and states needed by this page.
72if ($showall) {
73 $questionids = $attemptobj->get_slots();
74} else {
75 $questionids = $attemptobj->get_slots($page);
76}
77
78// Save the flag states, if they are being changed.
cbe87543
DL
79if ($options->flags == question_display_options::EDITABLE && optional_param('savingflags', false,
80 PARAM_BOOL)) {
b2607ccc
TH
81 require_sesskey();
82 $attemptobj->save_question_flags();
918776f4 83 redirect($attemptobj->review_url(null, $page, $showall));
b2607ccc
TH
84}
85
86// Log this review.
87add_to_log($attemptobj->get_courseid(), 'quiz', 'review', 'review.php?attempt=' .
88 $attemptobj->get_attemptid(), $attemptobj->get_quizid(), $attemptobj->get_cmid());
89
9e83f3d1 90// Work out appropriate title and whether blocks should be shown.
b2607ccc
TH
91if ($attemptobj->is_preview_user() && $attemptobj->is_own_attempt()) {
92 $strreviewtitle = get_string('reviewofpreview', 'quiz');
93 navigation_node::override_active_url($attemptobj->start_attempt_url());
94
95} else {
96 $strreviewtitle = get_string('reviewofattempt', 'quiz', $attemptobj->get_attempt_number());
97 if (empty($attemptobj->get_quiz()->showblocks) && !$attemptobj->is_preview_user()) {
98 $PAGE->blocks->show_only_fake_blocks();
f62040ed 99 }
b2607ccc
TH
100}
101
9e83f3d1 102// Set up the page header.
b2607ccc 103$headtags = $attemptobj->get_html_head_contributions($page, $showall);
d755b0f5
TH
104$PAGE->set_title(format_string($attemptobj->get_quiz_name()));
105$PAGE->set_heading($attemptobj->get_course()->fullname);
4abc5a1a 106$accessmanager->setup_attempt_page($PAGE);
b2607ccc 107
9e83f3d1 108// Summary table start. ============================================================================
b2607ccc
TH
109
110// Work out some time-related things.
111$attempt = $attemptobj->get_attempt();
112$quiz = $attemptobj->get_quiz();
113$overtime = 0;
114
b39b5d77 115if ($attempt->state == quiz_attempt::FINISHED) {
b2607ccc 116 if ($timetaken = ($attempt->timefinish - $attempt->timestart)) {
b3782c71 117 if ($quiz->timelimit && $timetaken > ($quiz->timelimit + 60)) {
b2607ccc
TH
118 $overtime = $timetaken - $quiz->timelimit;
119 $overtime = format_time($overtime);
56ed242b 120 }
b2607ccc 121 $timetaken = format_time($timetaken);
ee1fb969 122 } else {
b2607ccc 123 $timetaken = "-";
99a1bf3d 124 }
b2607ccc
TH
125} else {
126 $timetaken = get_string('unfinished', 'quiz');
127}
128
3a5da40b 129// Prepare summary informat about the whole attempt.
b3782c71 130$summarydata = array();
b2607ccc
TH
131if (!$attemptobj->get_quiz()->showuserpicture && $attemptobj->get_userid() != $USER->id) {
132 // If showuserpicture is true, the picture is shown elsewhere, so don't repeat it.
133 $student = $DB->get_record('user', array('id' => $attemptobj->get_userid()));
b3782c71
TH
134 $usrepicture = new user_picture($student);
135 $usrepicture->courseid = $attemptobj->get_courseid();
136 $summarydata['user'] = array(
137 'title' => $usrepicture,
138 'content' => new action_link(new moodle_url('/user/view.php', array(
139 'id' => $student->id, 'course' => $attemptobj->get_courseid())),
140 fullname($student, true)),
141 );
b2607ccc 142}
b39b5d77 143
b2607ccc 144if ($attemptobj->has_capability('mod/quiz:viewreports')) {
918776f4 145 $attemptlist = $attemptobj->links_to_other_attempts($attemptobj->review_url(null, $page,
cbe87543 146 $showall));
b2607ccc 147 if ($attemptlist) {
b3782c71
TH
148 $summarydata['attemptlist'] = array(
149 'title' => get_string('attempts', 'quiz'),
150 'content' => $attemptlist,
151 );
29d5d0b4 152 }
b2607ccc
TH
153}
154
b3782c71
TH
155// Timing information.
156$summarydata['startedon'] = array(
157 'title' => get_string('startedon', 'quiz'),
158 'content' => userdate($attempt->timestart),
159);
b2607ccc 160
b39b5d77
TH
161$summarydata['state'] = array(
162 'title' => get_string('attemptstate', 'quiz'),
163 'content' => quiz_attempt::state_name($attempt->state),
164);
165
166if ($attempt->state == quiz_attempt::FINISHED) {
b3782c71
TH
167 $summarydata['completedon'] = array(
168 'title' => get_string('completedon', 'quiz'),
169 'content' => userdate($attempt->timefinish),
170 );
171 $summarydata['timetaken'] = array(
172 'title' => get_string('timetaken', 'quiz'),
b2817f80 173 'content' => $timetaken,
b3782c71
TH
174 );
175}
b2607ccc 176
b3782c71
TH
177if (!empty($overtime)) {
178 $summarydata['overdue'] = array(
179 'title' => get_string('overdue', 'quiz'),
98754195 180 'content' => $overtime,
b3782c71
TH
181 );
182}
9c22b42e 183
b3782c71
TH
184// Show marks (if the user is allowed to see marks at the moment).
185$grade = quiz_rescale_grade($attempt->sumgrades, $quiz, false);
186if ($options->marks >= question_display_options::MARK_AND_MAX && quiz_has_grades($quiz)) {
4fc3d7e5 187
be18f589 188 if ($attempt->state != quiz_attempt::FINISHED) {
b3782c71
TH
189 $summarydata['grade'] = array(
190 'title' => get_string('grade', 'quiz'),
191 'content' => get_string('attemptstillinprogress', 'quiz'),
192 );
193
194 } else if (is_null($grade)) {
195 $summarydata['grade'] = array(
196 'title' => get_string('grade', 'quiz'),
197 'content' => quiz_format_grade($quiz, $grade),
198 );
199
200 } else {
201 // Show raw marks only if they are different from the grade (like on the view page).
202 if ($quiz->grade != $quiz->sumgrades) {
f39cf78c 203 $a = new stdClass();
b3782c71
TH
204 $a->grade = quiz_format_grade($quiz, $attempt->sumgrades);
205 $a->maxgrade = quiz_format_grade($quiz, $quiz->sumgrades);
206 $summarydata['marks'] = array(
207 'title' => get_string('marks', 'quiz'),
208 'content' => get_string('outofshort', 'quiz', $a),
209 );
b2607ccc 210 }
b2607ccc 211
b3782c71
TH
212 // Now the scaled grade.
213 $a = new stdClass();
214 $a->grade = html_writer::tag('b', quiz_format_grade($quiz, $grade));
215 $a->maxgrade = quiz_format_grade($quiz, $quiz->grade);
216 if ($quiz->grade != 100) {
217 $a->percent = html_writer::tag('b', format_float(
218 $attempt->sumgrades * 100 / $quiz->sumgrades, 0));
219 $formattedgrade = get_string('outofpercent', 'quiz', $a);
220 } else {
221 $formattedgrade = get_string('outof', 'quiz', $a);
222 }
223 $summarydata['grade'] = array(
224 'title' => get_string('grade', 'quiz'),
225 'content' => $formattedgrade,
226 );
f39cf78c 227 }
b2607ccc
TH
228}
229
b3782c71
TH
230// Feedback if there is any, and the user is allowed to see it now.
231$feedback = $attemptobj->get_overall_feedback($grade);
232if ($options->overallfeedback && $feedback) {
233 $summarydata['feedback'] = array(
234 'title' => get_string('feedback', 'quiz'),
235 'content' => $feedback,
236 );
b2607ccc
TH
237}
238
9e83f3d1 239// Summary table end. ==============================================================================
b2607ccc 240
b2607ccc 241if ($showall) {
b3782c71 242 $slots = $attemptobj->get_slots();
b2607ccc
TH
243 $lastpage = true;
244} else {
b3782c71 245 $slots = $attemptobj->get_slots($page);
b2607ccc
TH
246 $lastpage = $attemptobj->is_last_page($page);
247}
b2607ccc 248
b3782c71 249$output = $PAGE->get_renderer('mod_quiz');
b2607ccc 250
b3782c71
TH
251// Arrange for the navigation to be displayed.
252$navbc = $attemptobj->get_navigation_panel($output, 'quiz_review_nav_panel', $page, $showall);
34b037de
TH
253$regions = $PAGE->blocks->get_regions();
254$PAGE->blocks->add_fake_block($navbc, reset($regions));
b3782c71
TH
255
256echo $output->review_page($attemptobj, $slots, $page, $showall, $lastpage, $options, $summarydata);