MDL-32633 quiz editing: recreate grade item when max changed from 0
[moodle.git] / mod / quiz / locallib.php
index a18a7a2..f535e9b 100644 (file)
@@ -471,28 +471,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;
-
-        $factor = $newgrade/$quiz->grade;
-        $quiz->grade = $newgrade;
+    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);
 
-        // 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