MDL-13845 rewritten rounding in grades classes again - rounding done also before storage into db so that we can compare the values properly and skip db updates if possible + some more optimisations
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
+30
-20
@@ -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');
|
||||
}
|
||||
|
||||
|
||||
+27
-3
@@ -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));
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user