mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 17:06:53 +02:00
MDL-64609 gradebook: Prevent infinite loop in regrading
This commit is contained in:
parent
4c6ae316d8
commit
85fec2b605
2 changed files with 51 additions and 2 deletions
|
@ -1191,6 +1191,7 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null,
|
||||||
$failed = 0;
|
$failed = 0;
|
||||||
|
|
||||||
while (count($finalids) < count($gids)) { // work until all grades are final or error found
|
while (count($finalids) < count($gids)) { // work until all grades are final or error found
|
||||||
|
$count = 0;
|
||||||
foreach ($gids as $gid) {
|
foreach ($gids as $gid) {
|
||||||
if (in_array($gid, $finalids)) {
|
if (in_array($gid, $finalids)) {
|
||||||
continue; // already final
|
continue; // already final
|
||||||
|
@ -1245,7 +1246,7 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null,
|
||||||
if ($updateddependencies === false) {
|
if ($updateddependencies === false) {
|
||||||
// If no direct descendants are marked as updated, then we don't need to update this grade item. We then mark it
|
// If no direct descendants are marked as updated, then we don't need to update this grade item. We then mark it
|
||||||
// as final.
|
// as final.
|
||||||
|
$count++;
|
||||||
$finalids[] = $gid;
|
$finalids[] = $gid;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1264,6 +1265,7 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null,
|
||||||
} else {
|
} else {
|
||||||
$grade_items[$gid]->needsupdate = 0;
|
$grade_items[$gid]->needsupdate = 0;
|
||||||
}
|
}
|
||||||
|
$count++;
|
||||||
$finalids[] = $gid;
|
$finalids[] = $gid;
|
||||||
$updatedids[] = $gid;
|
$updatedids[] = $gid;
|
||||||
|
|
||||||
|
@ -1273,7 +1275,7 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count($finalids) == 0) {
|
if ($count == 0) {
|
||||||
$failed++;
|
$failed++;
|
||||||
} else {
|
} else {
|
||||||
$failed = 0;
|
$failed = 0;
|
||||||
|
|
|
@ -104,4 +104,51 @@ class core_gradelib_testcase extends advanced_testcase {
|
||||||
// Confirm grade letter was deleted.
|
// Confirm grade letter was deleted.
|
||||||
$this->assertEquals(0, $DB->count_records('grade_letters'));
|
$this->assertEquals(0, $DB->count_records('grade_letters'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the function grade_regrade_final_grades().
|
||||||
|
*/
|
||||||
|
public function test_grade_regrade_final_grades() {
|
||||||
|
global $DB;
|
||||||
|
|
||||||
|
$this->resetAfterTest();
|
||||||
|
|
||||||
|
// Setup some basics.
|
||||||
|
$course = $this->getDataGenerator()->create_course();
|
||||||
|
$user = $this->getDataGenerator()->create_user();
|
||||||
|
$this->getDataGenerator()->enrol_user($user->id, $course->id, 'student');
|
||||||
|
|
||||||
|
// We need two grade items.
|
||||||
|
$params = ['idnumber' => 'g1', 'courseid' => $course->id];
|
||||||
|
$g1 = new grade_item($this->getDataGenerator()->create_grade_item($params));
|
||||||
|
unset($params['idnumber']);
|
||||||
|
$g2 = new grade_item($this->getDataGenerator()->create_grade_item($params));
|
||||||
|
|
||||||
|
$category = new grade_category($this->getDataGenerator()->create_grade_category($params));
|
||||||
|
$catitem = $category->get_grade_item();
|
||||||
|
|
||||||
|
// Now set a calculation.
|
||||||
|
$catitem->set_calculation('=[[g1]]');
|
||||||
|
|
||||||
|
$catitem->update();
|
||||||
|
|
||||||
|
// Everything needs updating.
|
||||||
|
$this->assertEquals(4, $DB->count_records('grade_items', ['courseid' => $course->id, 'needsupdate' => 1]));
|
||||||
|
|
||||||
|
grade_regrade_final_grades($course->id);
|
||||||
|
|
||||||
|
// See that everything has been updated.
|
||||||
|
$this->assertEquals(0, $DB->count_records('grade_items', ['courseid' => $course->id, 'needsupdate' => 1]));
|
||||||
|
|
||||||
|
$g1->delete();
|
||||||
|
|
||||||
|
// Now there is one that needs updating.
|
||||||
|
$this->assertEquals(1, $DB->count_records('grade_items', ['courseid' => $course->id, 'needsupdate' => 1]));
|
||||||
|
|
||||||
|
// This can cause an infinite loop if things go... poorly.
|
||||||
|
grade_regrade_final_grades($course->id);
|
||||||
|
|
||||||
|
// Now because of the failure, two things need updating.
|
||||||
|
$this->assertEquals(2, $DB->count_records('grade_items', ['courseid' => $course->id, 'needsupdate' => 1]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue