diff --git a/grade/edit/letter/index.php b/grade/edit/letter/index.php index 19743672f9d..00fb110d8b9 100644 --- a/grade/edit/letter/index.php +++ b/grade/edit/letter/index.php @@ -137,7 +137,7 @@ if (!$edit) { } $letters = array(); - for($i=1; $i<$num+1; $i++) { + for ($i=1; $i < $num+1; $i++) { $gradelettername = 'gradeletter'.$i; $gradeboundaryname = 'gradeboundary'.$i; @@ -146,33 +146,52 @@ if (!$edit) { if ($letter == '') { continue; } + + $boundary = floatval($data->$gradeboundaryname); + if ($boundary < 0 || $boundary > 100) { + continue; // Skip if out of range. + } + // The keys need to be strings so floats are not truncated. - $letters[strval($data->$gradeboundaryname)] = $letter; + $letters[number_format($boundary, 5)] = $letter; } } - krsort($letters, SORT_NUMERIC); - $old_ids = array(); - if ($records = $DB->get_records('grade_letters', array('contextid' => $context->id), 'lowerboundary ASC', 'id')) { - $old_ids = array_keys($records); + $pool = array(); + if ($records = $DB->get_records('grade_letters', array('contextid' => $context->id), 'lowerboundary ASC')) { + foreach ($records as $r) { + // Will re-use the lowerboundary to avoid duplicate during the update process. + $pool[number_format($r->lowerboundary, 5)] = $r; + } } - foreach($letters as $boundary=>$letter) { + foreach ($letters as $boundary => $letter) { $record = new stdClass(); $record->letter = $letter; $record->lowerboundary = $boundary; $record->contextid = $context->id; - if ($old_id = array_pop($old_ids)) { - $record->id = $old_id; + if (isset($pool[$boundary])) { + // Re-use the existing boundary to avoid key constraint. + if ($letter != $pool[$boundary]->letter) { + // The letter has been assigned to another boundary, we update it. + $record->id = $pool[$boundary]->id; + $DB->update_record('grade_letters', $record); + } + unset($pool[$boundary]); // Remove the letter from the pool. + } else if ($candidate = array_pop($pool)) { + // The boundary is new, we update a random record from the pool. + $record->id = $candidate->id; $DB->update_record('grade_letters', $record); } else { + // No records were found, this must be a new letter. $DB->insert_record('grade_letters', $record); } } - foreach($old_ids as $old_id) { - $DB->delete_records('grade_letters', array('id' => $old_id)); + // Delete the unused records. + foreach($pool as $leftover) { + $DB->delete_records('grade_letters', array('id' => $leftover->id)); } redirect($returnurl);