diff --git a/mod/quiz/accessrules.php b/mod/quiz/accessrules.php index 98cbbcc6328fb..eaec86e1c36bc 100644 --- a/mod/quiz/accessrules.php +++ b/mod/quiz/accessrules.php @@ -166,8 +166,8 @@ public function prevent_access() { /** * 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 @@ public function description() { /** * 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 6d512052c0e0b..ff753664095ca 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -33,9 +33,6 @@ } -// 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 @@ public function is_own_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 @@ public function get_question_status($slot, $showcorrectness) { * @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 dc9f2cc7abf04..6da1a3affaeda 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 22e122904212e..5c584451b125b 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 2284f917d9901..274a84a0e2f20 100644 --- a/mod/quiz/lang/en/quiz.php +++ b/mod/quiz/lang/en/quiz.php @@ -218,7 +218,7 @@ $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['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 ed7c2f4e3fa5d..1b632e264117d 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 a469509c563c0..f2d44b69c1438 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 0ef2a32f7e55e..b6c7ffbccef4a 100644 --- a/mod/quiz/report/overview/report.php +++ b/mod/quiz/report/overview/report.php @@ -21,7 +21,7 @@ function display($quiz, $cm, $course) { $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 7c81f5c8d1252..212fde716313f 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'); - - $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); - } - if ($showall !== 0) { - $url->param('showall', $showall); +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); + +$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'); } - $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 during the attempt - send them back to the attempt page. + if (!$attemptobj->is_finished()) { + redirect($attemptobj->attempt_url(0, $page)); } - -/// Load the questions and states needed by this page. - if ($showall) { - $questionids = $attemptobj->get_question_ids(); - } else { - $questionids = $attemptobj->get_question_ids($page); + // 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())); } - $attemptobj->load_questions($questionids); - $attemptobj->load_question_states($questionids); - -/// 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)); +} + +// 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(); } - -/// 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()) { - // Normal blocks - $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()) { - // Only show pretend blocks - $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); } - } - - // 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(); + $timetaken = format_time($timetaken); } 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(); + $timetaken = "-"; } - 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'); +} 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 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[] = ''; -/// 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. + } else { + // 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[] = ''; } - } - -/// 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('feedback', 'quiz') . - '' . $feedback . '
', "\n"; - echo implode("\n", $rows); - echo "\n
\n"; - } - -/// Summary table end ============================================================================== -/// Form for saving flags if necessary. - if ($options->flags == QUESTION_FLAGSEDITABLE) { - 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)); - } - -/// 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))); + // 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[] = '' . get_string('grade') . '' . + $formattedgrade . ''; } - echo "
"; - - echo $OUTPUT->footer(); - +} + +// 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[] = '' . get_string('feedback', 'quiz') . + '' . $feedback . ''; +} + +// 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 ============================================================================== + +// 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_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_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 ffb531acd32c7..fe6ac1848791f 100644 --- a/mod/quiz/summary.php +++ b/mod/quiz/summary.php @@ -127,7 +127,7 @@ $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 ca20439b047ab..b3d3f26810527 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 +