]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-13845 rewritten rounding in grades classes again - rounding done also before...
authorskodak <skodak>
Wed, 12 Mar 2008 19:45:17 +0000 (19:45 +0000)
committerskodak <skodak>
Wed, 12 Mar 2008 19:45:17 +0000 (19:45 +0000)
grade/edit/tree/grade.php
lib/grade/grade_category.php
lib/grade/grade_grade.php
lib/grade/grade_item.php
lib/gradelib.php

index 52f027ce874e4baecfd70eeec49c0c9bbc25c0c8..4e5e28696aa93efc2486f17abc013f46fe5c7ba7 100644 (file)
@@ -217,6 +217,9 @@ if ($mform->is_cancelled()) {
         } else {
             $grade_grade->set_locktime($data->locktime); //set_lock may reset locktime
             $grade_grade->set_locked($data->locked, false, true);
+            // reload grade in case it was regraded from activity
+            $grade_grade = new grade_grade(array('userid'=>$data->userid, 'itemid'=>$grade_item->id), true);
+            $grade_grade->grade_item =& $grade_item; // no db fetching
         }
     }
 
index 114d3195aad379eeba71bd18a9ab5578ea4a07c2..d678c1a9da7335c3f35eb55defb40498fe242e46 100644 (file)
@@ -571,7 +571,7 @@ class grade_category extends grade_object {
         }
 
         // update in db if changed
-        if (grade_floatval($grade->finalgrade) !== grade_floatval($oldfinalgrade)) {
+        if (grade_floats_different($grade->finalgrade, $oldfinalgrade)) {
             $grade->update('aggregation');
         }
 
@@ -732,7 +732,7 @@ class grade_category extends grade_object {
         $grade->finalgrade = bounded_number($this->grade_item->grademin, $sum, $this->grade_item->grademax);
 
         // update in db if changed
-        if (grade_floatval($grade->finalgrade) !== grade_floatval($oldfinalgrade)) {
+        if (grade_floats_different($grade->finalgrade, $oldfinalgrade)) {
             $grade->update('aggregation');
         }
 
index 7c72ef4bcc15079c145e85ad5d92660bebdab79d..5c291c7d5a73cf346f6b01388cf6f5283f23929e 100644 (file)
@@ -366,8 +366,8 @@ class grade_grade extends grade_object {
             $this->locked = 0;
             $this->update();
 
-            if ($refresh) {
-                //refresh when unlocking
+            if ($refresh and !$this->is_overridden()) {
+                //refresh when unlocking and not overridden
                 $this->grade_item->refresh_grades($this->userid);
             }
 
@@ -719,5 +719,19 @@ class grade_grade extends grade_object {
         $this->timecreated = $this->timemodified = time(); 
         return parent::insert($source);
     }
+
+    /**
+     * In addition to update() as defined in grade_object rounds the float numbers using php function,
+     * the reason is we need to compare the db value with computed number to skip updates if possible.
+     * @param string $source from where was the object inserted (mod/forum, manual, etc.)
+     * @return boolean success
+     */
+    function update($source=null) {
+        $this->rawgrade    = grade_floatval($this->rawgrade);
+        $this->finalgrade  = grade_floatval($this->finalgrade);
+        $this->rawgrademin = grade_floatval($this->rawgrademin);
+        $this->rawgrademax = grade_floatval($this->rawgrademax);
+        return parent::update($source);
+    }
 }
 ?>
index 0eb79ec9158bee12c5a219139d4d4193551a4580..c4a11fbf8d7b19a84b938f4dcd93506235666dcf 100644 (file)
@@ -245,7 +245,8 @@ class grade_item extends grade_object {
 
     /**
      * In addition to update() as defined in grade_object, handle the grade_outcome and grade_scale objects.
-     * Force regrading if necessary
+     * Force regrading if necessary, rounds the float numbers using php function,
+     * the reason is we need to compare the db value with computed number to skip regrading if possible.
      * @param string $source from where was the object inserted (mod/forum, manual, etc.)
      * @return boolean success
      */
@@ -267,6 +268,12 @@ class grade_item extends grade_object {
 
         $this->timemodified = time();
 
+        $this->grademin        = grade_floatval($this->grademin);
+        $this->grademax        = grade_floatval($this->grademax);
+        $this->multfactor      = grade_floatval($this->multfactor);
+        $this->plusfactor      = grade_floatval($this->plusfactor);
+        $this->aggregationcoef = grade_floatval($this->aggregationcoef);
+
         return parent::update($source);
     }
 
@@ -286,14 +293,14 @@ class grade_item extends grade_object {
         $calculationdiff = $db_item->calculation != $this->calculation;
         $categorydiff    = $db_item->categoryid  != $this->categoryid;
         $gradetypediff   = $db_item->gradetype   != $this->gradetype;
-        $grademindiff    = $db_item->grademin    != $this->grademin;
         $scaleiddiff     = $db_item->scaleid     != $this->scaleid;
         $outcomeiddiff   = $db_item->outcomeid   != $this->outcomeid;
         $locktimediff    = $db_item->locktime    != $this->locktime;
-        $grademaxdiff    = grade_floatval($db_item->grademax)        !== grade_floatval($this->grademax);
-        $multfactordiff  = grade_floatval($db_item->multfactor)      !== grade_floatval($this->multfactor);
-        $plusfactordiff  = grade_floatval($db_item->plusfactor)      !== grade_floatval($this->plusfactor);
-        $acoefdiff       = grade_floatval($db_item->aggregationcoef) !== grade_floatval($this->aggregationcoef);
+        $grademindiff    = grade_floats_different($db_item->grademin,        $this->grademin);
+        $grademaxdiff    = grade_floats_different($db_item->grademax,        $this->grademax);
+        $multfactordiff  = grade_floats_different($db_item->multfactor,      $this->multfactor);
+        $plusfactordiff  = grade_floats_different($db_item->plusfactor,      $this->plusfactor);
+        $acoefdiff       = grade_floats_different($db_item->aggregationcoef, $this->aggregationcoef);
 
         $needsupdatediff = !$db_item->needsupdate &&  $this->needsupdate;    // force regrading only if setting the flag first time
         $lockeddiff      = !empty($db_item->locked) && empty($this->locked); // force regrading only when unlocking
@@ -683,7 +690,7 @@ class grade_item extends grade_object {
 
                 $grade->finalgrade = $this->adjust_raw_grade($grade->rawgrade, $grade->rawgrademin, $grade->rawgrademax);
 
-                if (grade_floatval($grade_record->finalgrade) !== grade_floatval($grade->finalgrade)) {
+                if (grade_floats_different($grade_record->finalgrade, $grade->finalgrade)) {
                     if (!$grade->update('system')) {
                         $result = "Internal error updating final grade";
                     }
@@ -965,7 +972,7 @@ class grade_item extends grade_object {
          */
 
         // first detect if we need to change calculation formula from [[idnumber]] to ##giXXX## (after backup, etc.)
-        if (!$this->calculation_normalized and strpos('[[', $this->calculation) !== 0) {
+        if (!$this->calculation_normalized and strpos('[[', $this->calculation) !== false) {
             $this->set_calculation($this->calculation);
         }
 
@@ -1126,6 +1133,9 @@ class grade_item extends grade_object {
      * @return void
      */
     function set_sortorder($sortorder) {
+        if ($this->sortorder == $sortorder) {
+            return;
+        } 
         $this->sortorder = $sortorder;
         $this->update();
     }
@@ -1393,9 +1403,9 @@ class grade_item extends grade_object {
             $grade->timemodified = time(); // overridden flag might take over, but anyway
             $result = (boolean)$grade->insert($source);
 
-        } else if (grade_floatval($grade->finalgrade)     !== grade_floatval($oldgrade->finalgrade)
-                or grade_floatval($grade->feedback)       !== grade_floatval($oldgrade->feedback)
-                or grade_floatval($grade->feedbackformat) !== grade_floatval($oldgrade->feedbackformat)) {
+        } else if (grade_floats_different($grade->finalgrade, $oldgrade->finalgrade)
+                or $grade->feedback       !== $oldgrade->feedback
+                or $grade->feedbackformat != $oldgrade->feedbackformat) {
             $grade->timemodified = time(); // overridden flag might take over, but anyway
             $result = $grade->update($source);
         } else {
@@ -1505,7 +1515,7 @@ class grade_item extends grade_object {
         }
 
         // do we have comment from teacher?
-        if ($feedback !== false) {
+        if ($feedback !== false and !$grade->is_overridden()) {
             $grade->feedback       = $feedback;
             $grade->feedbackformat = $feedbackformat;
         }
@@ -1522,13 +1532,13 @@ class grade_item extends grade_object {
         if (empty($grade->id)) {
             $result = (boolean)$grade->insert($source);
 
-        } else if (grade_floatval($grade->finalgrade)     !== grade_floatval($oldgrade->finalgrade)
-                or grade_floatval($grade->rawgrade)       !== grade_floatval($oldgrade->rawgrade)
-                or grade_floatval($grade->rawgrademin)    !== grade_floatval($oldgrade->rawgrademin)
-                or grade_floatval($grade->rawgrademax)    !== grade_floatval($oldgrade->rawgrademax)
-                or grade_floatval($grade->rawscaleid)     !== grade_floatval($oldgrade->rawscaleid)
-                or grade_floatval($grade->feedback)       !== grade_floatval($oldgrade->feedback)
-                or grade_floatval($grade->feedbackformat) !== grade_floatval($oldgrade->feedbackformat)) {
+        } else if (grade_floats_different($grade->finalgrade,  $oldgrade->finalgrade)
+                or grade_floats_different($grade->rawgrade,    $oldgrade->rawgrade)
+                or grade_floats_different($grade->rawgrademin, $oldgrade->rawgrademin)
+                or grade_floats_different($grade->rawgrademax, $oldgrade->rawgrademax)
+                or $grade->rawscaleid     != $oldgrade->rawscaleid
+                or $grade->feedback       !== $oldgrade->feedback
+                or $grade->feedbackformat != $oldgrade->feedbackformat) {
             $result = $grade->update($source);
         } else {
             return $result;
@@ -1699,7 +1709,7 @@ class grade_item extends grade_object {
         }
 
         // update in db if changed
-        if (grade_floatval($grade->finalgrade) !== grade_floatval($oldfinalgrade)) {
+        if (grade_floats_different($grade->finalgrade, $oldfinalgrade)) {
             $grade->update('compute');
         }
 
index b3c993fd0397dbe9fea37f2a5b4f02b07f0ba823..145db5ce0d8e73a79498ac432c4ee716e5eda0be 100644 (file)
@@ -67,6 +67,8 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
 
     // only following grade_item properties can be changed in this function
     $allowed = array('itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted', 'hidden');
+    // list of 10,5 numeric fields
+    $floats  = array('grademin', 'grademax', 'multfactor', 'plusfactor');
 
     // grade item identification
     $params = compact('courseid', 'itemtype', 'itemmodule', 'iteminstance', 'itemnumber');
@@ -143,9 +145,17 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
                     // ignore it
                     continue;
                 }
-                if ($grade_item->{$k} != $v) {
-                    $grade_item->{$k} = $v;
-                    $update = true;
+                if (in_array($k, $floats)) {
+                    if (grade_floats_different($grade_item->{$k}, $v)) {
+                        $grade_item->{$k} = $v;
+                        $update = true;
+                    }
+                    
+                } else {
+                    if ($grade_item->{$k} != $v) {
+                        $grade_item->{$k} = $v;
+                        $update = true;
+                    }
                 }
             }
             if ($update) {
@@ -1254,6 +1264,20 @@ function grade_floatval($number) {
         return null;
     }
     // we must round to 5 digits to get the same precision as in 10,5 db fields
+    // note: db rounding for 10,5 is different from php round() function
     return round($number, 5);
 }
+
+/**
+ * Compare two float numbers safely. Uses 5 decimals php precision. Nulls accepted too.
+ * Used for skipping of db updates
+ * @param float $f1
+ * @param float $f2
+ * @return true if different
+ */
+function grade_floats_different($f1, $f2) {
+    // note: db rounding for 10,5 is different from php round() function
+    return (grade_floatval($f1) !== grade_floatval($f2));
+}
+
 ?>