This commit is contained in:
Víctor Déniz 2022-06-14 10:03:22 +01:00
commit 5481e7999c
2 changed files with 74 additions and 1 deletions

View file

@ -718,6 +718,14 @@ class grade_grade extends grade_object {
protected static function flatten_dependencies_array(&$dependson, &$dependencydepth) { protected static function flatten_dependencies_array(&$dependson, &$dependencydepth) {
// Flatten the nested dependencies - this will handle recursion bombs because it removes duplicates. // Flatten the nested dependencies - this will handle recursion bombs because it removes duplicates.
$somethingchanged = true; $somethingchanged = true;
// First of all, delete any incorrect (not array or individual null) dependency, they aren't welcome.
// TODO: Maybe we should report about this happening, it shouldn't if all dependencies are correct and consistent.
foreach ($dependson as $itemid => $depends) {
$depends = is_array($depends) ? $depends : []; // Only arrays are accepted.
$dependson[$itemid] = array_filter($depends, function($val) { // Only not-null values are accepted.
return !is_null($val);
});
}
while ($somethingchanged) { while ($somethingchanged) {
$somethingchanged = false; $somethingchanged = false;
@ -725,7 +733,7 @@ class grade_grade extends grade_object {
// Make a copy so we can tell if it changed. // Make a copy so we can tell if it changed.
$before = $dependson[$itemid]; $before = $dependson[$itemid];
foreach ($depends as $subitemid => $subdepends) { foreach ($depends as $subitemid => $subdepends) {
$dependson[$itemid] = array_unique(array_merge($depends, $dependson[$subdepends])); $dependson[$itemid] = array_unique(array_merge($depends, $dependson[$subdepends] ?? []));
sort($dependson[$itemid], SORT_NUMERIC); sort($dependson[$itemid], SORT_NUMERIC);
} }
if ($before != $dependson[$itemid]) { if ($before != $dependson[$itemid]) {

View file

@ -196,6 +196,11 @@ class core_grade_grade_testcase extends grade_base_testcase {
$this->assertTrue($grade->is_hidden()); $this->assertTrue($grade->is_hidden());
} }
/**
* Test grade_grade::flatten_dependencies_array()
*
* @covers \grade_grade::flatten_dependencies_array()
*/
public function test_flatten_dependencies() { public function test_flatten_dependencies() {
// First test a simple normal case. // First test a simple normal case.
$a = array(1 => array(2, 3), 2 => array(), 3 => array(4), 4 => array()); $a = array(1 => array(2, 3), 2 => array(), 3 => array(4), 4 => array());
@ -231,6 +236,66 @@ class core_grade_grade_testcase extends grade_base_testcase {
test_grade_grade_flatten_dependencies_array::test_flatten_dependencies_array($a, $b); test_grade_grade_flatten_dependencies_array::test_flatten_dependencies_array($a, $b);
$this->assertSame($expecteda, $a); $this->assertSame($expecteda, $a);
// Missing first level dependency.
$a = array(1 => array(2, 3), 3 => array(4), 4 => array());
$b = array();
$expecteda = array(1 => array(2, 3, 4), 3 => array(4), 4 => array());
$expectedb = array(1 => 1);
test_grade_grade_flatten_dependencies_array::test_flatten_dependencies_array($a, $b);
$this->assertSame($expecteda, $a);
$this->assertSame($expectedb, $b);
// Missing 2nd level dependency.
$a = array(1 => array(2, 3), 2 => array(), 3 => array(4));
$b = array();
$expecteda = array(1 => array(2, 3, 4), 2 => array(), 3 => array(4));
$expectedb = array(1 => 1);
test_grade_grade_flatten_dependencies_array::test_flatten_dependencies_array($a, $b);
$this->assertSame($expecteda, $a);
$this->assertSame($expectedb, $b);
// Null first level dependency.
$a = array(1 => array(2, null), 2 => array(3), 3 => array(4), 4 => array());
$b = array();
$expecteda = array(1 => array(2, 3, 4), 2 => array(3, 4), 3 => array(4), 4 => array());
$expectedb = array(1 => 2, 2 => 1);
test_grade_grade_flatten_dependencies_array::test_flatten_dependencies_array($a, $b);
$this->assertSame($expecteda, $a);
$this->assertSame($expectedb, $b);
// Null 2nd level dependency.
$a = array(1 => array(2, 3), 2 => array(), 3 => array(4), 4 => array(null));
$b = array();
$expecteda = array(1 => array(2, 3, 4), 2 => array(), 3 => array(4), 4 => array());
$expectedb = array(1 => 1);
test_grade_grade_flatten_dependencies_array::test_flatten_dependencies_array($a, $b);
$this->assertSame($expecteda, $a);
$this->assertSame($expectedb, $b);
// Straight null dependency.
$a = array(1 => array(2, 3), 2 => array(), 3 => array(4), 4 => null);
$b = array();
$expecteda = array(1 => array(2, 3, 4), 2 => array(), 3 => array(4), 4 => array());
$expectedb = array(1 => 1);
test_grade_grade_flatten_dependencies_array::test_flatten_dependencies_array($a, $b);
$this->assertSame($expecteda, $a);
$this->assertSame($expectedb, $b);
// Also incorrect non-array dependency.
$a = array(1 => array(2, 3), 2 => array(), 3 => array(4), 4 => 23);
$b = array();
$expecteda = array(1 => array(2, 3, 4), 2 => array(), 3 => array(4), 4 => array());
$expectedb = array(1 => 1);
test_grade_grade_flatten_dependencies_array::test_flatten_dependencies_array($a, $b);
$this->assertSame($expecteda, $a);
$this->assertSame($expectedb, $b);
} }
public function test_grade_grade_min_max() { public function test_grade_grade_min_max() {