From fd32dbfa1de464b3d08f6dbf55428085938627f3 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 3 May 2012 22:33:36 +0100 Subject: [PATCH] MDL-32633 quiz editing: recreate grade item when max changed from 0 --- mod/quiz/locallib.php | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index 03fabcd7fd2..a5306ad14c5 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -461,28 +461,33 @@ function quiz_set_grade($newgrade, $quiz) { return true; } + $oldgrade = $quiz->grade; + $quiz->grade = $newgrade; + // Use a transaction, so that on those databases that support it, this is safer. $transaction = $DB->start_delegated_transaction(); // Update the quiz table. $DB->set_field('quiz', 'grade', $newgrade, array('id' => $quiz->instance)); - // Rescaling the other data is only possible if the old grade was non-zero. - if ($quiz->grade > 1e-7) { - global $CFG; + if ($oldgrade < 1) { + // If the old grade was zero, we cannot rescale, we have to recompute. + // We also recompute if the old grade was too small to avoid underflow problems. + quiz_update_all_final_grades($quiz); - $factor = $newgrade/$quiz->grade; - $quiz->grade = $newgrade; - - // Update the quiz_grades table. + } else { + // We can rescale the grades efficiently. $timemodified = time(); $DB->execute(" UPDATE {quiz_grades} SET grade = ? * grade, timemodified = ? WHERE quiz = ? - ", array($factor, $timemodified, $quiz->id)); + ", array($newgrade/$oldgrade, $timemodified, $quiz->id)); + } + if ($oldgrade > 1e-7) { // Update the quiz_feedback table. + $factor = $newgrade/$oldgrade; $DB->execute(" UPDATE {quiz_feedback} SET mingrade = ? * mingrade, maxgrade = ? * maxgrade @@ -490,7 +495,7 @@ function quiz_set_grade($newgrade, $quiz) { ", array($factor, $factor, $quiz->id)); } - // update grade item and send all grades to gradebook + // Update grade item and send all grades to gradebook. quiz_grade_item_update($quiz); quiz_update_grades($quiz);