2004-09-12 17:34:35 +00:00
|
|
|
<?php // $Id$
|
2005-05-06 06:24:04 +00:00
|
|
|
/**
|
2007-11-07 15:26:37 +00:00
|
|
|
* This page prints a review of a particular quiz attempt
|
|
|
|
*
|
2008-07-08 17:47:57 +00:00
|
|
|
* @author Martin Dougiamas and many others.
|
2007-11-07 15:26:37 +00:00
|
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
|
|
|
* @package quiz
|
|
|
|
*/
|
2003-07-24 05:18:00 +00:00
|
|
|
|
2008-07-08 17:47:57 +00:00
|
|
|
require_once(dirname(__FILE__) . '/../../config.php');
|
2008-03-07 12:33:07 +00:00
|
|
|
require_once($CFG->dirroot . '/mod/quiz/locallib.php');
|
2008-11-25 12:11:27 +00:00
|
|
|
require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php');
|
2003-07-24 05:18:00 +00:00
|
|
|
|
2008-07-08 17:47:57 +00:00
|
|
|
$attemptid = required_param('attempt', PARAM_INT);
|
|
|
|
$page = optional_param('page', 0, PARAM_INT);
|
2005-05-06 06:24:04 +00:00
|
|
|
$showall = optional_param('showall', 0, PARAM_BOOL);
|
2003-07-24 05:18:00 +00:00
|
|
|
|
2008-07-08 17:47:57 +00:00
|
|
|
$attemptobj = new quiz_attempt($attemptid);
|
|
|
|
|
|
|
|
/// Check login.
|
|
|
|
require_login($attemptobj->get_courseid(), false, $attemptobj->get_cm());
|
2009-01-14 07:08:02 +00:00
|
|
|
$attemptobj->check_review_capability();
|
2006-12-22 12:52:13 +00:00
|
|
|
|
2008-03-07 12:33:07 +00:00
|
|
|
/// Create an object to manage all the other (non-roles) access rules.
|
2008-07-08 17:47:57 +00:00
|
|
|
$accessmanager = $attemptobj->get_access_manager(time());
|
|
|
|
$options = $attemptobj->get_review_options();
|
2008-03-07 12:33:07 +00:00
|
|
|
|
|
|
|
/// Permissions checks for normal users who do not have quiz:viewreports capability.
|
2008-07-08 17:47:57 +00:00
|
|
|
if (!$attemptobj->has_capability('mod/quiz:viewreports')) {
|
2009-07-22 09:25:46 +00:00
|
|
|
/// Can't review other users' attempts.
|
|
|
|
if (!$attemptobj->is_own_attempt()) {
|
|
|
|
quiz_error($attemptobj->get_quiz(), 'notyourattempt');
|
|
|
|
}
|
2008-03-07 12:33:07 +00:00
|
|
|
/// Can't review during the attempt - send them back to the attempt page.
|
2008-07-08 17:47:57 +00:00
|
|
|
if (!$attemptobj->is_finished()) {
|
|
|
|
redirect($attemptobj->attempt_url(0, $page));
|
2003-07-24 05:18:00 +00:00
|
|
|
}
|
2008-03-07 12:33:07 +00:00
|
|
|
/// Can't review unless Students may review -> Responses option is turned on.
|
2007-09-21 16:01:40 +00:00
|
|
|
if (!$options->responses) {
|
2008-07-08 17:47:57 +00:00
|
|
|
$accessmanager->back_to_view_page($attemptobj->is_preview_user(),
|
2008-03-07 12:33:07 +00:00
|
|
|
$accessmanager->cannot_review_message($options));
|
2005-01-02 07:15:19 +00:00
|
|
|
}
|
2003-07-24 05:18:00 +00:00
|
|
|
}
|
|
|
|
|
2008-09-03 08:32:29 +00:00
|
|
|
/// Load the questions and states needed by this page.
|
2008-03-07 12:33:07 +00:00
|
|
|
if ($showall) {
|
2008-07-08 17:47:57 +00:00
|
|
|
$questionids = $attemptobj->get_question_ids();
|
2008-03-07 12:33:07 +00:00
|
|
|
} else {
|
2008-07-08 17:47:57 +00:00
|
|
|
$questionids = $attemptobj->get_question_ids($page);
|
|
|
|
}
|
|
|
|
$attemptobj->load_questions($questionids);
|
|
|
|
$attemptobj->load_question_states($questionids);
|
2007-04-24 17:32:21 +00:00
|
|
|
|
2008-09-03 08:32:29 +00:00
|
|
|
/// Save the flag states, if they are being changed.
|
|
|
|
if ($options->flags == QUESTION_FLAGSEDITABLE && optional_param('savingflags', false, PARAM_BOOL)) {
|
|
|
|
confirm_sesskey();
|
|
|
|
$formdata = data_submitted();
|
|
|
|
|
|
|
|
question_save_flags($formdata, $attemptid, $questionids);
|
|
|
|
redirect($attemptobj->review_url(0, $page, $showall));
|
|
|
|
}
|
|
|
|
|
2008-07-15 15:30:39 +00:00
|
|
|
/// Log this review.
|
|
|
|
add_to_log($attemptobj->get_courseid(), 'quiz', 'review', 'review.php?attempt=' .
|
|
|
|
$attemptobj->get_attemptid(), $attemptobj->get_quizid(), $attemptobj->get_cmid());
|
|
|
|
|
2007-10-12 15:55:49 +00:00
|
|
|
/// Work out appropriate title.
|
2008-07-15 15:30:39 +00:00
|
|
|
if ($attemptobj->is_preview_user() && $attemptobj->is_own_attempt()) {
|
2007-10-12 15:55:49 +00:00
|
|
|
$strreviewtitle = get_string('reviewofpreview', 'quiz');
|
|
|
|
} else {
|
2008-07-10 17:23:56 +00:00
|
|
|
$strreviewtitle = get_string('reviewofattempt', 'quiz', $attemptobj->get_attempt_number());
|
2007-10-12 15:55:49 +00:00
|
|
|
}
|
|
|
|
|
2009-07-09 07:35:03 +00:00
|
|
|
/// Arrange for the navigation to be displayed.
|
2009-07-23 09:20:33 +00:00
|
|
|
$navbc = $attemptobj->get_navigation_panel('quiz_review_nav_panel', $page, $showall);
|
2009-07-09 07:35:03 +00:00
|
|
|
$firstregion = reset($PAGE->blocks->get_regions());
|
|
|
|
$PAGE->blocks->add_pretend_block($navbc, $firstregion);
|
|
|
|
|
2008-03-07 12:33:07 +00:00
|
|
|
/// Print the page header
|
2008-07-08 17:47:57 +00:00
|
|
|
$headtags = $attemptobj->get_html_head_contributions($page);
|
|
|
|
if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) {
|
2009-01-06 05:19:15 +00:00
|
|
|
$accessmanager->setup_secure_page($attemptobj->get_course()->shortname.': '.format_string($attemptobj->get_quiz_name()), $headtags);
|
2005-05-06 06:24:04 +00:00
|
|
|
} else {
|
2008-07-08 17:47:57 +00:00
|
|
|
print_header_simple(format_string($attemptobj->get_quiz_name()), '', $attemptobj->navigation($strreviewtitle),
|
|
|
|
'', $headtags, true, $attemptobj->update_module_button());
|
2005-05-06 06:24:04 +00:00
|
|
|
}
|
2004-05-16 03:14:03 +00:00
|
|
|
echo '<div id="overDiv" style="position:absolute; visibility:hidden; z-index:1000;"></div>'; // for overlib
|
|
|
|
|
2008-03-07 12:33:07 +00:00
|
|
|
/// Print tabs if they should be there.
|
2008-07-08 17:47:57 +00:00
|
|
|
if ($attemptobj->is_preview_user()) {
|
2008-07-15 15:30:39 +00:00
|
|
|
if ($attemptobj->is_own_attempt()) {
|
2006-04-05 05:53:18 +00:00
|
|
|
$currenttab = 'preview';
|
|
|
|
} else {
|
|
|
|
$currenttab = 'reports';
|
|
|
|
$mode = '';
|
|
|
|
}
|
2005-05-06 06:24:04 +00:00
|
|
|
include('tabs.php');
|
|
|
|
}
|
2008-03-07 12:33:07 +00:00
|
|
|
|
|
|
|
/// Print heading.
|
2008-07-15 15:30:39 +00:00
|
|
|
if ($attemptobj->is_preview_user() && $attemptobj->is_own_attempt()) {
|
2008-07-08 16:33:47 +00:00
|
|
|
$attemptobj->print_restart_preview_button();
|
2007-07-06 16:37:06 +00:00
|
|
|
}
|
2007-10-12 15:55:49 +00:00
|
|
|
print_heading($strreviewtitle);
|
2007-07-06 16:37:06 +00:00
|
|
|
|
2008-07-08 17:47:57 +00:00
|
|
|
/// Summary table start ============================================================================
|
|
|
|
|
2008-05-15 15:32:43 +00:00
|
|
|
/// Work out some time-related things.
|
2008-07-08 17:47:57 +00:00
|
|
|
$attempt = $attemptobj->get_attempt();
|
|
|
|
$quiz = $attemptobj->get_quiz();
|
2004-08-05 05:27:18 +00:00
|
|
|
$overtime = 0;
|
2004-07-25 22:17:24 +00:00
|
|
|
|
2005-05-06 06:24:04 +00:00
|
|
|
if ($attempt->timefinish) {
|
|
|
|
if ($timetaken = ($attempt->timefinish - $attempt->timestart)) {
|
quiz settings: MDL-18485 Improve quiz settings form
* Reorder form fields to group things more logically.
** and on the corresponding admin page too.
* Set some options to be 'Advanced' by default:
** Apply penalties.
** Each attempt builds on the last.
** Decimal places for question grades.
** The five 'Extra restrictions on attempts' settings. (password, etc.)
* Admins can still change this to suit their institiution at Administration > Plugins > Activity modules > Quiz.
* These new defaults are applied if the admin had not previously set any fields to be advanced.
* Disable some filds when they are not applicable:
** Grading method, if num attempts = 1
** Penaly scheme, if adaptive mode = no
** Each attempt builds of last, if num attempts = 1
** Review after quiz closed options, if no close date.
** Delay between 1st and 2nd attempts, if num attempts = 1
** Delay between later attempts, if num attempts < 3
* Convert quiz.timelimit to be in seconds, for consistency, and ready for the new duration field type (MDL 18500).
** Including ensuring that backup and restore is backwards compatible.
* MDL-5537 New setting, questiondecimalpoints, so, for example, you can show the quiz grade as an integer, but have fractional question grades.
** There is a 'Same as overall decimal points' option, which is the default.
* Improve some field labels.
* Make corresponding changes in the help files.
2009-03-10 08:39:51 +00:00
|
|
|
if($quiz->timelimit && $timetaken > ($quiz->timelimit + 60)) {
|
|
|
|
$overtime = $timetaken - $quiz->timelimit;
|
2005-05-06 06:24:04 +00:00
|
|
|
$overtime = format_time($overtime);
|
|
|
|
}
|
|
|
|
$timetaken = format_time($timetaken);
|
|
|
|
} else {
|
|
|
|
$timetaken = "-";
|
2004-07-25 22:17:24 +00:00
|
|
|
}
|
2003-07-24 05:18:00 +00:00
|
|
|
} else {
|
2005-05-06 06:24:04 +00:00
|
|
|
$timetaken = get_string('unfinished', 'quiz');
|
2003-07-24 05:18:00 +00:00
|
|
|
}
|
2008-05-15 15:32:43 +00:00
|
|
|
|
|
|
|
/// Print summary table about the whole attempt.
|
|
|
|
/// First we assemble all the rows that are appopriate to the current situation in
|
|
|
|
/// an array, then later we only output the table if there are any rows to show.
|
|
|
|
$rows = array();
|
2009-01-07 06:32:13 +00:00
|
|
|
if (!$attemptobj->get_quiz()->showuserpicture && $attemptobj->get_userid() <> $USER->id) {
|
|
|
|
/// If showuserpicture is true, the picture is shown elsewhere, so don't repeat it.
|
2008-07-10 17:23:56 +00:00
|
|
|
$student = $DB->get_record('user', array('id' => $attemptobj->get_userid()));
|
|
|
|
$picture = print_user_picture($student, $attemptobj->get_courseid(), $student->picture, false, true);
|
2008-05-15 15:32:43 +00:00
|
|
|
$rows[] = '<tr><th scope="row" class="cell">' . $picture . '</th><td class="cell"><a href="' .
|
2008-07-10 17:23:56 +00:00
|
|
|
$CFG->wwwroot . '/user/view.php?id=' . $student->id . '&course=' . $attemptobj->get_courseid() . '">' .
|
2008-05-15 15:32:43 +00:00
|
|
|
fullname($student, true) . '</a></td></tr>';
|
2005-01-08 20:06:00 +00:00
|
|
|
}
|
2008-07-15 15:30:39 +00:00
|
|
|
if ($attemptobj->has_capability('mod/quiz:viewreports')) {
|
|
|
|
$attemptlist = $attemptobj->links_to_other_attempts($attemptobj->review_url(0, $page, $showall));
|
|
|
|
if ($attemptlist) {
|
|
|
|
$rows[] = '<tr><th scope="row" class="cell">' . get_string('attempts', 'quiz') .
|
|
|
|
'</th><td class="cell">' . $attemptlist . '</td></tr>';
|
2005-05-06 06:24:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-15 15:32:43 +00:00
|
|
|
/// Timing information.
|
|
|
|
$rows[] = '<tr><th scope="row" class="cell">' . get_string('startedon', 'quiz') .
|
|
|
|
'</th><td class="cell">' . userdate($attempt->timestart) . '</td></tr>';
|
2005-05-06 06:24:04 +00:00
|
|
|
if ($attempt->timefinish) {
|
2008-05-15 15:32:43 +00:00
|
|
|
$rows[] = '<tr><th scope="row" class="cell">' . get_string('completedon', 'quiz') . '</th><td class="cell">' .
|
|
|
|
userdate($attempt->timefinish) . '</td></tr>';
|
|
|
|
$rows[] = '<tr><th scope="row" class="cell">' . get_string('timetaken', 'quiz') . '</th><td class="cell">' .
|
|
|
|
$timetaken . '</td></tr>';
|
2005-05-06 06:24:04 +00:00
|
|
|
}
|
2004-08-04 07:04:11 +00:00
|
|
|
if (!empty($overtime)) {
|
2008-05-15 15:32:43 +00:00
|
|
|
$rows[] = '<tr><th scope="row" class="cell">' . get_string('overdue', 'quiz') . '</th><td class="cell">' . $overtime . '</td></tr>';
|
2004-07-25 22:17:24 +00:00
|
|
|
}
|
2008-05-15 15:32:43 +00:00
|
|
|
|
|
|
|
/// Show scores (if the user is allowed to see scores at the moment).
|
|
|
|
$grade = quiz_rescale_grade($attempt->sumgrades, $quiz);
|
2006-04-18 22:50:04 +00:00
|
|
|
if ($options->scores) {
|
2008-09-23 07:18:15 +00:00
|
|
|
if (quiz_has_grades($quiz)) {
|
2006-04-18 22:50:04 +00:00
|
|
|
if($overtime) {
|
|
|
|
$result->sumgrades = "0";
|
|
|
|
$result->grade = "0.0";
|
|
|
|
}
|
2006-12-22 12:52:13 +00:00
|
|
|
|
2008-05-15 15:32:43 +00:00
|
|
|
/// Show raw marks only if they are different from the grade (like on the view page.
|
|
|
|
if ($quiz->grade != $quiz->sumgrades) {
|
|
|
|
$a = new stdClass;
|
2008-08-15 06:42:38 +00:00
|
|
|
$a->grade = quiz_format_grade($quiz, $attempt->sumgrades);
|
|
|
|
$a->maxgrade = quiz_format_grade($quiz, $attempt->sumgrades);
|
2008-05-15 15:32:43 +00:00
|
|
|
$rows[] = '<tr><th scope="row" class="cell">' . get_string('marks', 'quiz') . '</th><td class="cell">' .
|
|
|
|
get_string('outofshort', 'quiz', $a) . '</td></tr>';
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Now the scaled grade.
|
2006-07-24 14:40:48 +00:00
|
|
|
$a = new stdClass;
|
2008-05-15 15:32:43 +00:00
|
|
|
$a->grade = '<b>' . $grade . '</b>';
|
2008-08-15 06:42:38 +00:00
|
|
|
$a->maxgrade = quiz_format_grade($quiz, $quiz->grade);
|
2008-05-15 15:32:43 +00:00
|
|
|
$a->percent = '<b>' . round(($attempt->sumgrades/$quiz->sumgrades)*100, 0) . '</b>';
|
|
|
|
$rows[] = '<tr><th scope="row" class="cell">' . get_string('grade') . '</th><td class="cell">' .
|
|
|
|
get_string('outofpercent', 'quiz', $a) . '</td></tr>';
|
2004-07-25 22:17:24 +00:00
|
|
|
}
|
2005-05-06 06:24:04 +00:00
|
|
|
}
|
2008-05-15 15:32:43 +00:00
|
|
|
|
|
|
|
/// Feedback if there is any, and the user is allowed to see it now.
|
|
|
|
$feedback = quiz_feedback_for_grade($grade, $attempt->quiz);
|
2006-12-22 12:52:13 +00:00
|
|
|
if ($options->overallfeedback && $feedback) {
|
2008-05-15 15:32:43 +00:00
|
|
|
$rows[] = '<tr><th scope="row" class="cell">' . get_string('feedback', 'quiz') .
|
|
|
|
'</th><td class="cell">' . $feedback . '</td></tr>';
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Now output the summary table, if there are any rows to be shown.
|
|
|
|
if (!empty($rows)) {
|
|
|
|
echo '<table class="generaltable generalbox quizreviewsummary"><tbody>', "\n";
|
|
|
|
echo implode("\n", $rows);
|
|
|
|
echo "\n</tbody></table>\n";
|
2005-07-07 18:34:12 +00:00
|
|
|
}
|
|
|
|
|
2008-07-08 17:47:57 +00:00
|
|
|
/// Summary table end ==============================================================================
|
|
|
|
|
2008-09-03 08:32:29 +00:00
|
|
|
/// Form for saving flags if necessary.
|
|
|
|
if ($options->flags == QUESTION_FLAGSEDITABLE) {
|
2009-07-22 09:49:48 +00:00
|
|
|
echo '<form action="' . s($attemptobj->review_url(0, $page, $showall)) .
|
2008-09-03 08:32:29 +00:00
|
|
|
'" method="post"><div>';
|
|
|
|
echo '<input type="hidden" name="sesskey" value="' . sesskey() . '" />';
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Print all the questions.
|
2008-07-08 17:47:57 +00:00
|
|
|
if ($showall) {
|
2008-07-14 15:40:24 +00:00
|
|
|
$thispage = 'all';
|
|
|
|
$lastpage = true;
|
|
|
|
} else {
|
|
|
|
$thispage = $page;
|
|
|
|
$lastpage = $attemptobj->is_last_page($page);
|
2005-05-06 06:24:04 +00:00
|
|
|
}
|
2008-07-14 15:40:24 +00:00
|
|
|
foreach ($attemptobj->get_question_ids($thispage) as $id) {
|
2008-12-10 06:26:47 +00:00
|
|
|
$attemptobj->print_question($id, true, $attemptobj->review_url($id, $page, $showall));
|
2003-07-24 05:18:00 +00:00
|
|
|
}
|
|
|
|
|
2008-09-03 08:32:29 +00:00
|
|
|
/// Close form if we opened it.
|
|
|
|
if ($options->flags == QUESTION_FLAGSEDITABLE) {
|
|
|
|
echo '<div class="submitbtns">' . "\n" .
|
|
|
|
'<input type="submit" id="savingflagssubmit" name="savingflags" value="' .
|
|
|
|
get_string('saveflags', 'question') . '" />' .
|
|
|
|
"</div>\n" .
|
2008-09-26 10:49:31 +00:00
|
|
|
"\n</div></form>\n";
|
ajaxlib/require_js: MDL-16693 $PAGE->requires->... deprecates require_js etc.
There is a new implementation of require_js in lib/deprecatedlib.php,
based on $PAGE->requires.
There were a few other recently introduced functions in lib/weblib.php,
namely print_js_call, print_delayed_js_call, print_js_config and
standard_js_config. These have been removed, since they were never in
a stable branch, and all the places that used them have been changed
to use the newer $PAGE->requires->... methods.
get_require_js_code is also gone, and the evil places that were calling
it, even though it is an internal function, have been fixed.
Also, I made some minor improvements to the code I committed yesterday
for MDL-16695.
All that remains is to update all the places in core code that are
still using require_js.
(This commit also fixes the problem where the admin tree would not
start with the right categories expanded.)
2009-06-12 12:13:07 +00:00
|
|
|
$PAGE->requires->js_function_call('question_flag_changer.init_flag_save_form', array('savingflagssubmit'));
|
2008-09-03 08:32:29 +00:00
|
|
|
}
|
|
|
|
|
2008-07-14 15:40:24 +00:00
|
|
|
/// Print a link to the next page.
|
|
|
|
echo '<div class="submitbtns">';
|
|
|
|
if ($lastpage) {
|
2008-07-08 17:47:57 +00:00
|
|
|
$accessmanager->print_finish_review_link($attemptobj->is_preview_user());
|
2008-07-14 15:40:24 +00:00
|
|
|
} else {
|
2009-07-23 09:20:33 +00:00
|
|
|
echo link_arrow_right(get_string('next'), s($attemptobj->review_url(0, $page + 1)));
|
2005-05-06 06:24:04 +00:00
|
|
|
}
|
2008-07-14 15:40:24 +00:00
|
|
|
echo "</div>";
|
|
|
|
|
|
|
|
// Finish the page
|
2008-07-08 17:47:57 +00:00
|
|
|
if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) {
|
2008-03-07 12:33:07 +00:00
|
|
|
print_footer('empty');
|
|
|
|
} else {
|
2009-01-06 05:19:15 +00:00
|
|
|
print_footer($attemptobj->get_course());
|
2005-05-06 06:24:04 +00:00
|
|
|
}
|
2003-07-24 05:18:00 +00:00
|
|
|
?>
|