MDL-14741: load editor automatically, from footer/after page is loaded.
[moodle.git] / mod / quiz / review.php
CommitLineData
d1290cec 1<?php // $Id$
ee1fb969 2/**
f63a4ff2 3 * This page prints a review of a particular quiz attempt
4 *
4fc3d7e5 5 * @author Martin Dougiamas and many others.
f63a4ff2 6 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
7 * @package quiz
8 */
29d5d0b4 9
4fc3d7e5 10 require_once(dirname(__FILE__) . '/../../config.php');
c52c62d1 11 require_once($CFG->dirroot . '/mod/quiz/locallib.php');
29d5d0b4 12
4fc3d7e5 13 $attemptid = required_param('attempt', PARAM_INT);
14 $page = optional_param('page', 0, PARAM_INT);
ee1fb969 15 $showall = optional_param('showall', 0, PARAM_BOOL);
29d5d0b4 16
4fc3d7e5 17 $attemptobj = new quiz_attempt($attemptid);
18
19/// Check login.
20 require_login($attemptobj->get_courseid(), false, $attemptobj->get_cm());
77ed3ba5 21
29d5d0b4 22
c52c62d1 23/// Create an object to manage all the other (non-roles) access rules.
4fc3d7e5 24 $accessmanager = $attemptobj->get_access_manager(time());
25 $options = $attemptobj->get_review_options();
c52c62d1 26
27/// Work out if this is a student viewing their own attempt/teacher previewing,
28/// or someone with 'mod/quiz:viewreports' reviewing someone elses attempt.
4fc3d7e5 29 $reviewofownattempt = $attemptobj->get_userid() == $USER->id &&
30 (!$attemptobj->is_preview_user() || $attemptobj->is_preview());
c52c62d1 31
32/// Permissions checks for normal users who do not have quiz:viewreports capability.
4fc3d7e5 33 if (!$attemptobj->has_capability('mod/quiz:viewreports')) {
c52c62d1 34 /// Can't review during the attempt - send them back to the attempt page.
4fc3d7e5 35 if (!$attemptobj->is_finished()) {
36 redirect($attemptobj->attempt_url(0, $page));
29d5d0b4 37 }
c52c62d1 38 /// Can't review other users' attempts.
39 if (!$reviewofownattempt) {
40 quiz_error($quiz, 'reviewnotallowed');
41 }
42 /// Can't review unless Students may review -> Responses option is turned on.
a4faed69 43 if (!$options->responses) {
4fc3d7e5 44 $accessmanager->back_to_view_page($attemptobj->is_preview_user(),
c52c62d1 45 $accessmanager->cannot_review_message($options));
34283aa8 46 }
29d5d0b4 47 }
48
c52c62d1 49/// Log this review.
4fc3d7e5 50 add_to_log($attemptobj->get_courseid(), 'quiz', 'review', 'review.php?attempt=' .
51 $attemptobj->get_attemptid(), $attemptobj->get_quizid(), $attemptobj->get_cmid());
29d5d0b4 52
4fc3d7e5 53/// load the questions and states needed by this page.
c52c62d1 54 if ($showall) {
4fc3d7e5 55 $questionids = $attemptobj->get_question_ids();
c52c62d1 56 } else {
4fc3d7e5 57 $questionids = $attemptobj->get_question_ids($page);
58 }
59 $attemptobj->load_questions($questionids);
60 $attemptobj->load_question_states($questionids);
2d05b472 61
38e179a4 62/// Work out appropriate title.
4fc3d7e5 63 if ($attemptobj->is_preview_user() && $reviewofownattempt) {
38e179a4 64 $strreviewtitle = get_string('reviewofpreview', 'quiz');
65 } else {
b9b3aa94 66 $strreviewtitle = get_string('reviewofattempt', 'quiz', $attemptobj->get_attempt_number());
38e179a4 67 }
68
c52c62d1 69/// Print the page header
4fc3d7e5 70 $headtags = $attemptobj->get_html_head_contributions($page);
71 if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) {
c52c62d1 72 $accessmanager->setup_secure_page($course->shortname.': '.format_string($quiz->name), $headtags);
ee1fb969 73 } else {
4fc3d7e5 74 print_header_simple(format_string($attemptobj->get_quiz_name()), '', $attemptobj->navigation($strreviewtitle),
75 '', $headtags, true, $attemptobj->update_module_button());
ee1fb969 76 }
b7f35820 77 echo '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>'; // for overlib
78
c52c62d1 79/// Print tabs if they should be there.
4fc3d7e5 80 if ($attemptobj->is_preview_user()) {
c52c62d1 81 if ($reviewofownattempt) {
0a5b58af 82 $currenttab = 'preview';
83 } else {
84 $currenttab = 'reports';
85 $mode = '';
86 }
ee1fb969 87 include('tabs.php');
ee1fb969 88 }
c52c62d1 89
90/// Print heading.
38e179a4 91 print_heading(format_string($quiz->name));
4fc3d7e5 92 if ($attemptobj->is_preview_user() && $reviewofownattempt) {
78e7a3dd 93 $attemptobj->print_restart_preview_button();
99a1bf3d 94 }
38e179a4 95 print_heading($strreviewtitle);
99a1bf3d 96
baef998b 97/// Print the navigation panel in a left column.
98 print_container_start();
99 echo '<div id="left-column">';
100 $attemptobj->print_navigation_panel('quiz_review_nav_panel', $page);
101 echo '</div>';
102 print_container_end();
103
104/// Start the main column.
105 echo '<div id="middle-column">';
106 print_container_start();
107 echo skip_main_destination();
ad1a74e0 108
4fc3d7e5 109/// Summary table start ============================================================================
110
9c22b42e 111/// Work out some time-related things.
4fc3d7e5 112 $attempt = $attemptobj->get_attempt();
113 $quiz = $attemptobj->get_quiz();
114 $timelimit = $quiz->timelimit * 60;
235987c5 115 $overtime = 0;
d4961620 116
ee1fb969 117 if ($attempt->timefinish) {
118 if ($timetaken = ($attempt->timefinish - $attempt->timestart)) {
119 if($timelimit && $timetaken > ($timelimit + 60)) {
120 $overtime = $timetaken - $timelimit;
121 $overtime = format_time($overtime);
122 }
123 $timetaken = format_time($timetaken);
124 } else {
125 $timetaken = "-";
d4961620 126 }
29d5d0b4 127 } else {
ee1fb969 128 $timetaken = get_string('unfinished', 'quiz');
29d5d0b4 129 }
9c22b42e 130
131/// Print summary table about the whole attempt.
132/// First we assemble all the rows that are appopriate to the current situation in
133/// an array, then later we only output the table if there are any rows to show.
134 $rows = array();
b9b3aa94 135 if ($attemptobj->get_userid() <> $USER->id) {
136 $student = $DB->get_record('user', array('id' => $attemptobj->get_userid()));
137 $picture = print_user_picture($student, $attemptobj->get_courseid(), $student->picture, false, true);
9c22b42e 138 $rows[] = '<tr><th scope="row" class="cell">' . $picture . '</th><td class="cell"><a href="' .
b9b3aa94 139 $CFG->wwwroot . '/user/view.php?id=' . $student->id . '&amp;course=' . $attemptobj->get_courseid() . '">' .
9c22b42e 140 fullname($student, true) . '</a></td></tr>';
76cacec8 141 }
9c22b42e 142 if (has_capability('mod/quiz:viewreports', $context) &&
9cf4a18b 143 count($attempts = $DB->get_records_select('quiz_attempts', "quiz = ? AND userid = ?", array($quiz->id, $attempt->userid), 'attempt ASC')) > 1) {
9c22b42e 144 /// List of all this user's attempts for people who can see reports.
9c22b42e 145 $attemptlist = array();
ee1fb969 146 foreach ($attempts as $at) {
9c22b42e 147 if ($at->id == $attempt->id) {
148 $attemptlist[] = '<strong>' . $at->attempt . '</strong>';
149 } else {
4fc3d7e5 150 $attemptlist[] = '<a href="' . $attemptobj->review_url(0, $page, $showall, $at->id) .
151 '">' . $at->attempt . '</a>';
9c22b42e 152 }
ee1fb969 153 }
9c22b42e 154 $rows[] = '<tr><th scope="row" class="cell">' . get_string('attempts', 'quiz') .
155 '</th><td class="cell">' . implode(', ', $attemptlist) . '</td></tr>';
ee1fb969 156 }
157
9c22b42e 158/// Timing information.
159 $rows[] = '<tr><th scope="row" class="cell">' . get_string('startedon', 'quiz') .
160 '</th><td class="cell">' . userdate($attempt->timestart) . '</td></tr>';
ee1fb969 161 if ($attempt->timefinish) {
9c22b42e 162 $rows[] = '<tr><th scope="row" class="cell">' . get_string('completedon', 'quiz') . '</th><td class="cell">' .
163 userdate($attempt->timefinish) . '</td></tr>';
164 $rows[] = '<tr><th scope="row" class="cell">' . get_string('timetaken', 'quiz') . '</th><td class="cell">' .
165 $timetaken . '</td></tr>';
ee1fb969 166 }
3a00dbfd 167 if (!empty($overtime)) {
9c22b42e 168 $rows[] = '<tr><th scope="row" class="cell">' . get_string('overdue', 'quiz') . '</th><td class="cell">' . $overtime . '</td></tr>';
d4961620 169 }
9c22b42e 170
171/// Show scores (if the user is allowed to see scores at the moment).
172 $grade = quiz_rescale_grade($attempt->sumgrades, $quiz);
15db443c 173 if ($options->scores) {
174 if ($quiz->grade and $quiz->sumgrades) {
175 if($overtime) {
176 $result->sumgrades = "0";
177 $result->grade = "0.0";
178 }
77ed3ba5 179
9c22b42e 180 /// Show raw marks only if they are different from the grade (like on the view page.
181 if ($quiz->grade != $quiz->sumgrades) {
182 $a = new stdClass;
183 $a->grade = round($attempt->sumgrades, $CFG->quiz_decimalpoints);
184 $a->maxgrade = $quiz->sumgrades;
185 $rows[] = '<tr><th scope="row" class="cell">' . get_string('marks', 'quiz') . '</th><td class="cell">' .
186 get_string('outofshort', 'quiz', $a) . '</td></tr>';
187 }
188
189 /// Now the scaled grade.
3b48ba9d 190 $a = new stdClass;
9c22b42e 191 $a->grade = '<b>' . $grade . '</b>';
3b48ba9d 192 $a->maxgrade = $quiz->grade;
9c22b42e 193 $a->percent = '<b>' . round(($attempt->sumgrades/$quiz->sumgrades)*100, 0) . '</b>';
194 $rows[] = '<tr><th scope="row" class="cell">' . get_string('grade') . '</th><td class="cell">' .
195 get_string('outofpercent', 'quiz', $a) . '</td></tr>';
d4961620 196 }
ee1fb969 197 }
9c22b42e 198
199/// Feedback if there is any, and the user is allowed to see it now.
200 $feedback = quiz_feedback_for_grade($grade, $attempt->quiz);
77ed3ba5 201 if ($options->overallfeedback && $feedback) {
9c22b42e 202 $rows[] = '<tr><th scope="row" class="cell">' . get_string('feedback', 'quiz') .
203 '</th><td class="cell">' . $feedback . '</td></tr>';
204 }
205
206/// Now output the summary table, if there are any rows to be shown.
207 if (!empty($rows)) {
208 echo '<table class="generaltable generalbox quizreviewsummary"><tbody>', "\n";
209 echo implode("\n", $rows);
210 echo "\n</tbody></table>\n";
9bc2d82a 211 }
212
4fc3d7e5 213/// Summary table end ==============================================================================
214
ee1fb969 215/// Print all the questions
4fc3d7e5 216 if ($showall) {
baef998b 217 $thispage = 'all';
218 $lastpage = true;
219 } else {
220 $thispage = $page;
221 $lastpage = $attemptobj->is_last_page($page);
ee1fb969 222 }
baef998b 223 foreach ($attemptobj->get_question_ids($thispage) as $id) {
4fc3d7e5 224 $attemptobj->print_question($id);
29d5d0b4 225 }
226
baef998b 227/// Print a link to the next page.
228 echo '<div class="submitbtns">';
229 if ($lastpage) {
4fc3d7e5 230 $accessmanager->print_finish_review_link($attemptobj->is_preview_user());
baef998b 231 } else {
232 link_arrow_right(get_string('next'), $attemptobj->review_url(0, $page + 1));
ee1fb969 233 }
baef998b 234 echo "</div>";
235
236 // End middle column.
237 print_container_end();
238 echo '</div>';
239
240 echo '</div>';
241 echo '<div class="clearer"></div>';
29d5d0b4 242
baef998b 243 // Finish the page
4fc3d7e5 244 if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) {
c52c62d1 245 print_footer('empty');
246 } else {
ee1fb969 247 print_footer($course);
248 }
29d5d0b4 249?>