From b2607ccc19828f07094b2c8e3438913dc4d5ba1b Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Wed, 9 Feb 2011 16:56:44 +0000 Subject: [PATCH] MDL-20636 Now the quiz review page works. --- mod/quiz/accessrules.php | 6 +- mod/quiz/attemptlib.php | 14 +- mod/quiz/db/install.xml | 4 +- mod/quiz/index.php | 14 +- mod/quiz/lang/en/quiz.php | 6 +- mod/quiz/lib.php | 10 +- mod/quiz/locallib.php | 2 +- mod/quiz/report/overview/report.php | 2 +- mod/quiz/review.php | 472 +++++++++++++++------------- mod/quiz/summary.php | 2 +- question/todo/diffstat.txt | 3 +- 11 files changed, 280 insertions(+), 255 deletions(-) diff --git a/mod/quiz/accessrules.php b/mod/quiz/accessrules.php index 98cbbcc6328..eaec86e1c36 100644 --- a/mod/quiz/accessrules.php +++ b/mod/quiz/accessrules.php @@ -166,8 +166,8 @@ class quiz_access_manager { /** * Do any of the rules mean that this student will no be allowed any further attempts at this - * quiz. Used, for example, to change the label by the grade displayed on the view page from - * 'your current score is' to 'your final score is'. + * quiz. Used, for example, to change the label by the grade displayed on the view page from + * 'your current grade is' to 'your final grade is'. * * @param integer $numattempts the number of previous attempts this user has made. * @param object $lastattempt information about the user's last completed attempt. @@ -484,7 +484,7 @@ abstract class quiz_access_rule_base { /** * If this rule can determine that this user will never be allowed another attempt at * this quiz, then return true. This is used so we can know whether to display a - * final score on the view page. This will only be called if there is not a currently + * final grade on the view page. This will only be called if there is not a currently * active attempt for this user. * @param integer $numattempts the number of previous attempts this user has made. * @param object $lastattempt information about the user's last completed attempt. diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index 6d512052c0e..ff753664095 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -33,9 +33,6 @@ if (!defined('MOODLE_INTERNAL')) { } -// TODO get_question_score -> mark - - /** * Class for quiz exceptions. Just saves a couple of arguments on the * constructor for a moodle_exception. @@ -557,6 +554,15 @@ class quiz_attempt { (!$this->is_preview_user() || $this->attempt->preview); } + /** + * Get the overall feedback corresponding to a particular mark. + * @param $grade a particular grade. + */ + public function get_overall_feedback($grade) { + return quiz_feedback_for_grade($grade, $this->get_quiz(), + $this->quizobj->get_context(), $this->get_cm()); + } + /** * Wrapper round the has_capability funciton that automatically passes in the quiz context. */ @@ -713,7 +719,7 @@ class quiz_attempt { * @param integer $slot the number used to identify this question within this attempt. * @return string the formatted grade, to the number of decimal places specified by the quiz. */ - public function get_question_score($slot) { + public function get_question_mark($slot) { return quiz_format_question_grade($this->get_quiz(), $this->quba->get_question_mark($slot)); } diff --git a/mod/quiz/db/install.xml b/mod/quiz/db/install.xml index dc9f2cc7abf..6da1a3affae 100644 --- a/mod/quiz/db/install.xml +++ b/mod/quiz/db/install.xml @@ -17,7 +17,7 @@ - + @@ -102,7 +102,7 @@ - +
diff --git a/mod/quiz/index.php b/mod/quiz/index.php index 22e12290421..5c584451b12 100644 --- a/mod/quiz/index.php +++ b/mod/quiz/index.php @@ -86,9 +86,9 @@ array_push($headings, get_string('feedback', 'quiz')); array_push($align, 'left'); } - $showing = 'scores'; // default + $showing = 'grades'; // default - $scores = $DB->get_records_sql_menu(' + $grades = $DB->get_records_sql_menu(' SELECT qg.quiz, qg.grade FROM {quiz_grades} qg JOIN {quiz} q ON q.id = qg.quiz @@ -140,22 +140,22 @@ // fields set to make the following call work. $data[] = quiz_attempt_summary_link_to_reports($quiz, $cm, $context); - } else if ($showing == 'scores') { + } else if ($showing == 'grades') { // Grade and feedback. $attempts = quiz_get_user_attempts($quiz->id, $USER->id, 'all'); list($someoptions, $alloptions) = quiz_get_combined_reviewoptions($quiz, $attempts, $context); $grade = ''; $feedback = ''; - if ($quiz->grade && array_key_exists($quiz->id, $scores)) { - if ($alloptions->scores) { + if ($quiz->grade && array_key_exists($quiz->id, grades)) { + if ($alloptions->marks) { $a = new stdClass; - $a->grade = quiz_format_grade($quiz, $scores[$quiz->id]); + $a->grade = quiz_format_grade($quiz, grades[$quiz->id]); $a->maxgrade = quiz_format_grade($quiz, $quiz->grade); $grade = get_string('outofshort', 'quiz', $a); } if ($alloptions->overallfeedback) { - $feedback = quiz_feedback_for_grade($scores[$quiz->id], $quiz, $context, $cm); + $feedback = quiz_feedback_for_grade(grades[$quiz->id], $quiz, $context, $cm); } } $data[] = $grade; diff --git a/mod/quiz/lang/en/quiz.php b/mod/quiz/lang/en/quiz.php index 2284f917d99..274a84a0e2f 100644 --- a/mod/quiz/lang/en/quiz.php +++ b/mod/quiz/lang/en/quiz.php @@ -218,7 +218,7 @@ $string['daysavailable'] = 'Days available'; $string['decimaldigits'] = 'Decimal digits in grades'; $string['decimalformat'] = 'decimals'; $string['decimalplaces'] = 'Decimal places in grades'; -$string['decimalplaces_help'] = 'This setting specifies the number of digits shown after the decimal point when displaying scores or grades. It only effects the display of grades, not the grades stored in the database, nor the internal calculations, which are carried out to full accuracy.'; +$string['decimalplaces_help'] = 'This setting specifies the number of digits shown after the decimal point when displaying grades or grades. It only effects the display of grades, not the grades stored in the database, nor the internal calculations, which are carried out to full accuracy.'; $string['decimalplacesquestion'] = 'Decimal places in question grades'; $string['decimalplacesquestion_help'] = 'This setting specifies the number of digits shown after the decimal point when displaying the grades for individual questions.'; $string['decimalpoints'] = 'Decimal points'; @@ -314,8 +314,8 @@ $string['feedbackerrororder'] = 'Feedback grade boundaries must be in order, hig $string['file'] = 'File'; $string['fileformat'] = 'File format'; $string['fillcorrect'] = 'Fill with correct'; -$string['filloutnumericalanswer'] = 'You provide at least one possible answer and tolerance. The first matching answer will be used to determine the score and feedback. If you supply some feedback with no answer at the end, that will be shown to students whose response is not matched by any of the other answers.'; -$string['filloutoneanswer'] = 'You must provide at least one possible answer. Answers left blank will not be used. \'*\' can be used as a wildcard to match any characters. The first matching answer will be used to determine the score and feedback.'; +$string['filloutnumericalanswer'] = 'You provide at least one possible answer and tolerance. The first matching answer will be used to determine the grade and feedback. If you supply some feedback with no answer at the end, that will be shown to students whose response is not matched by any of the other answers.'; +$string['filloutoneanswer'] = 'You must provide at least one possible answer. Answers left blank will not be used. \'*\' can be used as a wildcard to match any characters. The first matching answer will be used to determine the grade and feedback.'; $string['filloutthreequestions'] = 'You must provide at least three questions with matching answers. You can provide extra wrong answers by giving an answer with a blank question. Entries where both the question and the answer are blank will be ignored.'; $string['fillouttwochoices'] = 'You must fill out at least two choices. Choices left blank will not be used.'; $string['finishattemptdots'] = 'Finish attempt...'; diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index ed7c2f4e3fa..1b632e26411 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -326,7 +326,7 @@ function quiz_get_best_grade($quiz, $userid) { global $DB; $grade = $DB->get_field('quiz_grades', 'grade', array('quiz' => $quiz->id, 'userid' => $userid)); - // Need to detect errors/no result, without catching 0 scores. + // Need to detect errors/no result, without catching 0 grades. if ($grade === false) { return null; } @@ -599,10 +599,10 @@ function quiz_grade_item_update($quiz, $grades = NULL) { } /* description by TJ: -1/ If the quiz is set to not show scores while the quiz is still open, and is set to show scores after +1/ If the quiz is set to not show grades while the quiz is still open, and is set to show grades after the quiz is closed, then create the grade_item with a show-after date that is the quiz close date. -2/ If the quiz is set to not show scores at either of those times, create the grade_item as hidden. -3/ If the quiz is set to show scores, create the grade_item visible. +2/ If the quiz is set to not show grades at either of those times, create the grade_item as hidden. +3/ If the quiz is set to show grades, create the grade_item visible. */ $openreviewoptions = mod_quiz_display_options::make_from_quiz($quiz, mod_quiz_display_options::LATER_WHILE_OPEN); @@ -812,7 +812,7 @@ function quiz_get_recent_mod_activity(&$activities, &$index, $timestart, $tmpactivity->content->attemptid = $attempt->id; $tmpactivity->content->attempt = $attempt->attempt; - if (quiz_has_grades($quiz) && $options->scores) { + if (quiz_has_grades($quiz) && $options->marks) { $tmpactivity->content->sumgrades = quiz_format_grade($quiz, $attempt->sumgrades); $tmpactivity->content->maxgrade = quiz_format_grade($quiz, $quiz->sumgrades); } else { diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index a469509c563..f2d44b69c14 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -508,7 +508,7 @@ function quiz_update_all_attempt_sumgrades($quiz) { } /** - * The quiz grade is the score that student's results are marked out of. When it + * The quiz grade is the maximum that student's results are marked out of. When it * changes, the corresponding data in quiz_grades and quiz_feedback needs to be * rescaled. After calling this function, you probably need to call * quiz_update_all_attempt_sumgrades, quiz_update_all_final_grades and diff --git a/mod/quiz/report/overview/report.php b/mod/quiz/report/overview/report.php index 0ef2a32f7e5..b6c7ffbccef 100644 --- a/mod/quiz/report/overview/report.php +++ b/mod/quiz/report/overview/report.php @@ -21,7 +21,7 @@ class quiz_overview_report extends quiz_default_report { $this->context = get_context_instance(CONTEXT_MODULE, $cm->id); - // Work out some display options - whether there is feedback, and whether scores should be shown. + // Work out some display options - whether there is feedback, and whether grades should be shown. $hasfeedback = quiz_has_feedback($quiz); $fakeattempt = new stdClass(); $fakeattempt->preview = false; diff --git a/mod/quiz/review.php b/mod/quiz/review.php index 7c81f5c8d12..212fde71631 100644 --- a/mod/quiz/review.php +++ b/mod/quiz/review.php @@ -1,257 +1,275 @@ . + /** * This page prints a review of a particular quiz attempt * - * @author Martin Dougiamas and many others. - * @license http://www.gnu.org/copyleft/gpl.html GNU Public License - * @package quiz + * It is used either by the student whose attempts this is, after the attempt, + * or by a teacher reviewing another's attempt during or afterwards. + * + * @package mod + * @subpackage quiz + * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com} + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ - require_once(dirname(__FILE__) . '/../../config.php'); - require_once($CFG->dirroot . '/mod/quiz/locallib.php'); - require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php'); +require_once(dirname(__FILE__) . '/../../config.php'); +require_once($CFG->dirroot . '/mod/quiz/locallib.php'); +require_once($CFG->dirroot . '/mod/quiz/report/reportlib.php'); - $attemptid = required_param('attempt', PARAM_INT); - $page = optional_param('page', 0, PARAM_INT); - $showall = optional_param('showall', 0, PARAM_BOOL); +$attemptid = required_param('attempt', PARAM_INT); +$page = optional_param('page', 0, PARAM_INT); +$showall = optional_param('showall', 0, PARAM_BOOL); - $url = new moodle_url('/mod/quiz/review.php', array('attempt'=>$attemptid)); - if ($page !== 0) { - $url->param('page', $page); +$url = new moodle_url('/mod/quiz/review.php', array('attempt'=>$attemptid)); +if ($page !== 0) { + $url->param('page', $page); +} +if ($showall !== 0) { + $url->param('showall', $showall); +} +$PAGE->set_url($url); + +$attemptobj = quiz_attempt::create($attemptid); + +// Check login. +require_login($attemptobj->get_course(), false, $attemptobj->get_cm()); +$attemptobj->check_review_capability(); + +// Create an object to manage all the other (non-roles) access rules. +$accessmanager = $attemptobj->get_access_manager(time()); +$options = $attemptobj->get_display_options(true); + +// Permissions checks for normal users who do not have quiz:viewreports capability. +if (!$attemptobj->has_capability('mod/quiz:viewreports')) { + // Can't review other users' attempts. + if (!$attemptobj->is_own_attempt()) { + throw new moodle_quiz_exception($attemptobj->get_quizobj(), 'notyourattempt'); } - if ($showall !== 0) { - $url->param('showall', $showall); + // Can't review during the attempt - send them back to the attempt page. + if (!$attemptobj->is_finished()) { + redirect($attemptobj->attempt_url(0, $page)); } - $PAGE->set_url($url); - - $attemptobj = quiz_attempt::create($attemptid); - -/// Check login. - require_login($attemptobj->get_course(), false, $attemptobj->get_cm()); - $attemptobj->check_review_capability(); - -/// Create an object to manage all the other (non-roles) access rules. - $accessmanager = $attemptobj->get_access_manager(time()); - $options = $attemptobj->get_review_options(); - -/// Permissions checks for normal users who do not have quiz:viewreports capability. - if (!$attemptobj->has_capability('mod/quiz:viewreports')) { - /// Can't review other users' attempts. - if (!$attemptobj->is_own_attempt()) { - quiz_error($attemptobj->get_quiz(), 'notyourattempt'); - } - /// Can't review during the attempt - send them back to the attempt page. - if (!$attemptobj->is_finished()) { - redirect($attemptobj->attempt_url(0, $page)); - } - /// Can't review unless Students may review -> Responses option is turned on. - if (!$options->responses) { - $accessmanager->back_to_view_page($attemptobj->is_preview_user(), - $accessmanager->cannot_review_message($options)); - } + // Can't review unless Students may review -> Responses option is turned on. + if (!$options->attempt) { + $accessmanager->back_to_view_page($attemptobj->is_preview_user(), + $accessmanager->cannot_review_message($attemptobj->get_attempt_state())); } +} -/// Load the questions and states needed by this page. - if ($showall) { - $questionids = $attemptobj->get_question_ids(); +// Load the questions and states needed by this page. +if ($showall) { + $questionids = $attemptobj->get_slots(); +} else { + $questionids = $attemptobj->get_slots($page); +} + +// Save the flag states, if they are being changed. +if ($options->flags == question_display_options::EDITABLE && optional_param('savingflags', false, PARAM_BOOL)) { + require_sesskey(); + $attemptobj->save_question_flags(); + redirect($attemptobj->review_url(0, $page, $showall)); +} + +// Log this review. +add_to_log($attemptobj->get_courseid(), 'quiz', 'review', 'review.php?attempt=' . + $attemptobj->get_attemptid(), $attemptobj->get_quizid(), $attemptobj->get_cmid()); + +// Work out appropriate title and whether blocks should be shown +if ($attemptobj->is_preview_user() && $attemptobj->is_own_attempt()) { + $strreviewtitle = get_string('reviewofpreview', 'quiz'); + navigation_node::override_active_url($attemptobj->start_attempt_url()); + +} else { + $strreviewtitle = get_string('reviewofattempt', 'quiz', $attemptobj->get_attempt_number()); + if (empty($attemptobj->get_quiz()->showblocks) && !$attemptobj->is_preview_user()) { + $PAGE->blocks->show_only_fake_blocks(); + } +} + +// Arrange for the navigation to be displayed. +$navbc = $attemptobj->get_navigation_panel('quiz_review_nav_panel', $page, $showall); +$firstregion = reset($PAGE->blocks->get_regions()); +$PAGE->blocks->add_fake_block($navbc, $firstregion); + +// Print the page header +$headtags = $attemptobj->get_html_head_contributions($page, $showall); +if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) { + $accessmanager->setup_secure_page($attemptobj->get_course()->shortname.': '.format_string($attemptobj->get_quiz_name()), $headtags); +} elseif ($accessmanager->safebrowser_required($attemptobj->is_preview_user())) { + $PAGE->set_title($attemptobj->get_course()->shortname . ': '.format_string($attemptobj->get_quiz_name())); + $PAGE->set_heading($attemptobj->get_course()->fullname); + $PAGE->set_cacheable(false); + echo $OUTPUT->header(); +} else { + $PAGE->navbar->add($strreviewtitle); + $PAGE->set_title(format_string($attemptobj->get_quiz_name())); + $PAGE->set_heading($attemptobj->get_course()->fullname); + echo $OUTPUT->header(); +} + +// Print heading. +if ($attemptobj->is_preview_user() && $attemptobj->is_own_attempt()) { + $attemptobj->print_restart_preview_button(); +} +echo $OUTPUT->heading($strreviewtitle); + +// Summary table start ============================================================================ + +// Work out some time-related things. +$attempt = $attemptobj->get_attempt(); +$quiz = $attemptobj->get_quiz(); +$overtime = 0; + +if ($attempt->timefinish) { + if ($timetaken = ($attempt->timefinish - $attempt->timestart)) { + if($quiz->timelimit && $timetaken > ($quiz->timelimit + 60)) { + $overtime = $timetaken - $quiz->timelimit; + $overtime = format_time($overtime); + } + $timetaken = format_time($timetaken); } else { - $questionids = $attemptobj->get_question_ids($page); + $timetaken = "-"; } - $attemptobj->load_questions($questionids); - $attemptobj->load_question_states($questionids); +} else { + $timetaken = get_string('unfinished', 'quiz'); +} -/// Save the flag states, if they are being changed. - if ($options->flags == QUESTION_FLAGSEDITABLE && optional_param('savingflags', false, PARAM_BOOL)) { - require_sesskey(); - $formdata = data_submitted(); - - question_save_flags($formdata, $attemptid, $questionids); - redirect($attemptobj->review_url(0, $page, $showall)); +// 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(); +if (!$attemptobj->get_quiz()->showuserpicture && $attemptobj->get_userid() != $USER->id) { + // If showuserpicture is true, the picture is shown elsewhere, so don't repeat it. + $student = $DB->get_record('user', array('id' => $attemptobj->get_userid())); + $picture = $OUTPUT->user_picture($student, array('courseid'=>$attemptobj->get_courseid())); + $rows[] = ''; +} +if ($attemptobj->has_capability('mod/quiz:viewreports')) { + $attemptlist = $attemptobj->links_to_other_attempts($attemptobj->review_url(0, $page, $showall)); + if ($attemptlist) { + $rows[] = ''; } +} -/// Log this review. - add_to_log($attemptobj->get_courseid(), 'quiz', 'review', 'review.php?attempt=' . - $attemptobj->get_attemptid(), $attemptobj->get_quizid(), $attemptobj->get_cmid()); +// Timing information. +$rows[] = ''; +if ($attempt->timefinish) { + $rows[] = ''; + $rows[] = ''; +} +if (!empty($overtime)) { + $rows[] = ''; +} -/// Work out appropriate title and whether blocks should be shown - if ($attemptobj->is_preview_user() && $attemptobj->is_own_attempt()) { - // Normal blocks - $strreviewtitle = get_string('reviewofpreview', 'quiz'); - navigation_node::override_active_url($attemptobj->start_attempt_url()); +// Show marks (if the user is allowed to see marks at the moment). +$grade = quiz_rescale_grade($attempt->sumgrades, $quiz, false); +if ($options->marks && quiz_has_grades($quiz)) { + + if (!$attempt->timefinish) { + $rows[] = ''; + + } else if (is_null($grade)) { + $rows[] = ''; } else { - $strreviewtitle = get_string('reviewofattempt', 'quiz', $attemptobj->get_attempt_number()); - if (empty($attemptobj->get_quiz()->showblocks) && !$attemptobj->is_preview_user()) { - // Only show pretend blocks - $PAGE->blocks->show_only_fake_blocks(); - } - } - - // Initialise the JavaScript. - $headtags = $attemptobj->get_html_head_contributions($page); - - // Arrange for the navigation to be displayed. - $navbc = $attemptobj->get_navigation_panel('quiz_review_nav_panel', $page, $showall); - $firstregion = reset($PAGE->blocks->get_regions()); - $PAGE->blocks->add_fake_block($navbc, $firstregion); - -/// Print the page header - $headtags = $attemptobj->get_html_head_contributions($page); - if ($accessmanager->securewindow_required($attemptobj->is_preview_user())) { - $accessmanager->setup_secure_page($attemptobj->get_course()->shortname.': '.format_string($attemptobj->get_quiz_name()), $headtags); - } elseif ($accessmanager->safebrowser_required($attemptobj->is_preview_user())) { - $PAGE->set_title($attemptobj->get_course()->shortname . ': '.format_string($attemptobj->get_quiz_name())); - $PAGE->set_heading($attemptobj->get_course()->fullname); - $PAGE->set_cacheable(false); - echo $OUTPUT->header(); - } else { - $PAGE->navbar->add($strreviewtitle); - $PAGE->set_title(format_string($attemptobj->get_quiz_name())); - $PAGE->set_heading($attemptobj->get_course()->fullname); - echo $OUTPUT->header(); - } - -/// Print heading. - if ($attemptobj->is_preview_user() && $attemptobj->is_own_attempt()) { - $attemptobj->print_restart_preview_button(); - } - echo $OUTPUT->heading($strreviewtitle); - -/// Summary table start ============================================================================ - -/// Work out some time-related things. - $attempt = $attemptobj->get_attempt(); - $quiz = $attemptobj->get_quiz(); - $overtime = 0; - - if ($attempt->timefinish) { - if ($timetaken = ($attempt->timefinish - $attempt->timestart)) { - if($quiz->timelimit && $timetaken > ($quiz->timelimit + 60)) { - $overtime = $timetaken - $quiz->timelimit; - $overtime = format_time($overtime); - } - $timetaken = format_time($timetaken); - } else { - $timetaken = "-"; - } - } else { - $timetaken = get_string('unfinished', 'quiz'); - } - -/// 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(); - if (!$attemptobj->get_quiz()->showuserpicture && $attemptobj->get_userid() <> $USER->id) { - /// If showuserpicture is true, the picture is shown elsewhere, so don't repeat it. - $student = $DB->get_record('user', array('id' => $attemptobj->get_userid())); - $picture = $OUTPUT->user_picture($student, array('courseid'=>$attemptobj->get_courseid())); - $rows[] = ''; - } - if ($attemptobj->has_capability('mod/quiz:viewreports')) { - $attemptlist = $attemptobj->links_to_other_attempts($attemptobj->review_url(0, $page, $showall)); - if ($attemptlist) { - $rows[] = ''; - } - } - -/// Timing information. - $rows[] = ''; - if ($attempt->timefinish) { - $rows[] = ''; - $rows[] = ''; - } - if (!empty($overtime)) { - $rows[] = ''; - } - -/// Show scores (if the user is allowed to see scores at the moment). - $grade = quiz_rescale_grade($attempt->sumgrades, $quiz, false); - if ($options->scores) { - if (quiz_has_grades($quiz)) { - if($overtime) { - $result->sumgrades = "0"; - $result->grade = "0.0"; - } - - /// Show raw marks only if they are different from the grade (like on the view page. - if ($quiz->grade != $quiz->sumgrades) { - $a = new stdClass; - $a->grade = quiz_format_grade($quiz, $attempt->sumgrades); - $a->maxgrade = quiz_format_grade($quiz, $quiz->sumgrades); - $rows[] = ''; - } - - /// Now the scaled grade. + // Show raw marks only if they are different from the grade (like on the view page). + if ($quiz->grade != $quiz->sumgrades) { $a = new stdClass; - $a->grade = '' . quiz_format_grade($quiz, $grade) . ''; - $a->maxgrade = quiz_format_grade($quiz, $quiz->grade); - $a->percent = '' . round(($attempt->sumgrades/$quiz->sumgrades)*100, 0) . ''; - $rows[] = ''; + $a->grade = quiz_format_grade($quiz, $attempt->sumgrades); + $a->maxgrade = quiz_format_grade($quiz, $quiz->sumgrades); + $rows[] = ''; } + + // Now the scaled grade. + $a = new stdClass; + $a->grade = '' . quiz_format_grade($quiz, $grade) . ''; + $a->maxgrade = quiz_format_grade($quiz, $quiz->grade); + if ($quiz->grade != 100) { + $a->percent = '' . round($attempt->sumgrades * 100 / $quiz->sumgrades, 0) . ''; + $formattedgrade = get_string('outofpercent', 'quiz', $a); + } else { + $formattedgrade = get_string('outof', 'quiz', $a); + } + $rows[] = ''; } +} -/// Feedback if there is any, and the user is allowed to see it now. - $feedback = $attemptobj->get_overall_feedback($grade); - if ($options->overallfeedback && $feedback) { - $rows[] = ''; - } +// Feedback if there is any, and the user is allowed to see it now. +$feedback = $attemptobj->get_overall_feedback($grade); +if ($options->overallfeedback && $feedback) { + $rows[] = ''; +} -/// Now output the summary table, if there are any rows to be shown. - if (!empty($rows)) { - echo '
' . $picture . '' . + fullname($student, true) . '
' . get_string('attempts', 'quiz') . + '' . $attemptlist . '
' . get_string('startedon', 'quiz') . + '' . userdate($attempt->timestart) . '
' . get_string('completedon', 'quiz') . '' . + userdate($attempt->timefinish) . '
' . get_string('timetaken', 'quiz') . '' . + $timetaken . '
' . get_string('overdue', 'quiz') . '' . $overtime . '
' . get_string('grade') . '' . + get_string('attemptstillinprogress', 'quiz') . '
' . get_string('grade') . '' . + quiz_format_grade($quiz, $grade) . '
' . $picture . '' . - fullname($student, true) . '
' . get_string('attempts', 'quiz') . - '' . $attemptlist . '
' . get_string('startedon', 'quiz') . - '' . userdate($attempt->timestart) . '
' . get_string('completedon', 'quiz') . '' . - userdate($attempt->timefinish) . '
' . get_string('timetaken', 'quiz') . '' . - $timetaken . '
' . get_string('overdue', 'quiz') . '' . $overtime . '
' . get_string('marks', 'quiz') . '' . - get_string('outofshort', 'quiz', $a) . '
' . get_string('grade') . '' . - get_string('outofpercent', 'quiz', $a) . '
' . get_string('marks', 'quiz') . '' . + get_string('outofshort', 'quiz', $a) . '
' . get_string('grade') . '' . + $formattedgrade . '
' . get_string('feedback', 'quiz') . - '' . $feedback . '
' . get_string('feedback', 'quiz') . + '' . $feedback . '
', "\n"; - echo implode("\n", $rows); - echo "\n
\n"; - } +// Now output the summary table, if there are any rows to be shown. +if (!empty($rows)) { + echo '', "\n"; + echo implode("\n", $rows); + echo "\n
\n"; +} -/// Summary table end ============================================================================== +// Summary table end ============================================================================== -/// Form for saving flags if necessary. - if ($options->flags == QUESTION_FLAGSEDITABLE) { - echo '
'; - echo ''; - } +// Form for saving flags if necessary. +if ($options->flags == question_display_options::EDITABLE) { + echo '
'; + echo ''; +} -/// Print all the questions. - if ($showall) { - $thispage = 'all'; - $lastpage = true; - } else { - $thispage = $page; - $lastpage = $attemptobj->is_last_page($page); - } - foreach ($attemptobj->get_question_ids($thispage) as $id) { - $attemptobj->print_question($id, true, $attemptobj->review_url($id, $page, $showall)); - } +// Print all the questions. +if ($showall) { + $thispage = 'all'; + $lastpage = true; +} else { + $thispage = $page; + $lastpage = $attemptobj->is_last_page($page); +} +foreach ($attemptobj->get_slots($thispage) as $slot) { + echo $attemptobj->render_question($slot, true, $attemptobj->review_url($slot, $page, $showall)); +} -/// Close form if we opened it. - if ($options->flags == QUESTION_FLAGSEDITABLE) { - echo '
' . "\n" . - '' . - "
\n" . - "\n
\n"; - $PAGE->requires->js_init_call('M.mod_quiz.init_review_form', null, false, quiz_get_js_module()); - } - -/// Print a link to the next page. - echo '
'; - if ($lastpage) { - $accessmanager->print_finish_review_link($attemptobj->is_preview_user()); - } else { - echo link_arrow_right(get_string('next'), s($attemptobj->review_url(0, $page + 1))); - } - echo "
"; - - echo $OUTPUT->footer(); +// Close form if we opened it. +if ($options->flags == question_display_options::EDITABLE) { + echo '
' . "\n" . + '' . + "
\n" . + "\n
\n"; + $PAGE->requires->js_init_call('M.mod_quiz.init_review_form', null, false, quiz_get_js_module()); +} +// Print a link to the next page. +echo '
'; +if ($lastpage) { + $accessmanager->print_finish_review_link($attemptobj->is_preview_user()); +} else { + echo link_arrow_right(get_string('next'), $attemptobj->review_url(0, $page + 1)); +} +echo '
'; +echo $OUTPUT->footer(); diff --git a/mod/quiz/summary.php b/mod/quiz/summary.php index ffb531acd32..fe6ac184879 100644 --- a/mod/quiz/summary.php +++ b/mod/quiz/summary.php @@ -127,7 +127,7 @@ foreach ($slots as $slot) { $attemptobj->get_question_number($slot) . $flag . '', $attemptobj->get_question_status($slot, $displayoptions->correctness)); if ($markscolumn) { - $row[] = $attemptobj->get_question_score($slot); + $row[] = $attemptobj->get_question_mark($slot); } $table->data[] = $row; } diff --git a/question/todo/diffstat.txt b/question/todo/diffstat.txt index ca20439b047..b3d3f268105 100644 --- a/question/todo/diffstat.txt +++ b/question/todo/diffstat.txt @@ -100,9 +100,10 @@ DONE mod/quiz/protect_js.php | 56 - mod/quiz/quiz.js | 355 ++- mod/quiz/restorelib.php | 113 +- mod/quiz/restorelibpre15.php | 41 +- - mod/quiz/review.php | 520 ++-- +DONE mod/quiz/review.php | 520 ++-- DONE mod/quiz/reviewoptions.html | 124 +- mod/quiz/reviewquestion.php | 267 +- + mod/quiz/settingslib.php DONE mod/quiz/simpletest/testaccessrules.php | 518 ++++ DONE mod/quiz/simpletest/testlib.php | 58 + DONE mod/quiz/simpletest/testlocallib.php | 76 +