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