diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index 22dba91fac0..385832d3d3d 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -418,10 +418,17 @@ class quiz_attempt { * @param object $quiz the quiz object for this attempt and user. * @param object $cm the course_module object for this quiz. * @param object $course the row from the course table for the course we belong to. + * @param bool $loadquestions (optional) if true, the default, load all the details + * of the state of each question. Else just set up the basic details of the attempt. */ - public function __construct($attempt, $quiz, $cm, $course) { + public function __construct($attempt, $quiz, $cm, $course, $loadquestions = true) { $this->attempt = $attempt; $this->quizobj = new quiz($quiz, $cm, $course); + + if (!$loadquestions) { + return; + } + $this->quba = question_engine::load_questions_usage_by_activity($this->attempt->uniqueid); $this->determine_layout(); $this->number_questions(); diff --git a/mod/quiz/grade.php b/mod/quiz/grade.php index dd2b22cbebc..9334731706f 100644 --- a/mod/quiz/grade.php +++ b/mod/quiz/grade.php @@ -30,23 +30,63 @@ require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php'); $id = required_param('id', PARAM_INT); +$userid = optional_param('userid', 0, PARAM_INT); -if (!$cm = get_coursemodule_from_id('quiz', $id)) { - print_error('invalidcoursemodule'); -} -if (!$quiz = $DB->get_record('quiz', array('id' => $cm->instance))) { - print_error('invalidquizid'); -} -if (!$course = $DB->get_record('course', array('id' => $quiz->course))) { - print_error('coursemisconf'); -} - +$cm = get_coursemodule_from_id('quiz', $id, 0, false, MUST_EXIST); +$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); +$quiz = $DB->get_record('quiz', array('id' => $cm->instance), '*', MUST_EXIST); require_login($course, false, $cm); -$reportlist = quiz_report_list(get_context_instance(CONTEXT_MODULE, $cm->id)); -if (!empty($reportlist)) { - redirect(new moodle_url('/mod/quiz/report.php', array( - 'id' => $cm->id, 'mode' => reset($reportlist)))); -} else { - redirect(new moodle_url('/mod/quiz/view.php', array('id' => $cm->id))); +$reportlist = quiz_report_list(context_module::instance($cm->id)); +if (empty($reportlist) || $userid == $USER->id) { + // If the user cannot see reports, or can see reports but is looking + // at their own grades, redirect them to the view.php page. + // (The looking at their own grades case is unlikely, since users who + // appear in the gradebook are unlikely to be able to see quiz reports, + // but it is possible.) + redirect(new moodle_url('/mod/quiz/view.php', array('id' => $cm->id))); } + +// Now we know the user is interested in reports. If they are interested in a +// specific other user, try to send them to the most appropriate attempt review page. +if ($userid) { + + // Work out which attempt is most significant from a grading point of view. + $attempts = quiz_get_user_attempts($quiz->id, $userid, 'finished'); + $attempt = null; + switch ($quiz->grademethod) { + case QUIZ_ATTEMPTFIRST: + $attempt = reset($attempts); + break; + + case QUIZ_ATTEMPTLAST: + case QUIZ_GRADEAVERAGE: + $attempt = end($attempts); + break; + + case QUIZ_GRADEHIGHEST: + $maxmark = 0; + foreach ($attempts as $at) { + // >=, since we want to most recent relevant attempt. + if ((float) $at->sumgrades >= $maxmark) { + $maxmark = $at->sumgrades; + $attempt = $at; + } + } + break; + } + + // If the user can review the relevant attempt, redirect to it. + if ($attempt) { + $attemptobj = new quiz_attempt($attempt, $quiz, $cm, $course, false); + if ($attemptobj->is_review_allowed()) { + redirect($attemptobj->review_url()); + } + } + + // Otherwise, fall thorugh to the generic case. +} + +// Send the user to the first report they can see. +redirect(new moodle_url('/mod/quiz/report.php', array( + 'id' => $cm->id, 'mode' => reset($reportlist))));