From 92a66edf7a04988557407e176a4fe3cc5e1d6a58 Mon Sep 17 00:00:00 2001 From: nicolasconnault Date: Tue, 22 May 2007 04:38:20 +0000 Subject: [PATCH] MDL-9506 Implemented grade_tree->update_db, fixed bugs in grade_category etc... --- lib/grade/grade_category.php | 6 -- lib/grade/grade_tree.php | 117 ++++++++++++++++++--- .../grade/simpletest/testgradecategory.php | 23 ++-- lib/simpletest/grade/simpletest/testgradetree.php | 36 ++++++- 4 files changed, 145 insertions(+), 37 deletions(-) diff --git a/lib/grade/grade_category.php b/lib/grade/grade_category.php index 8b7b55041..5ffb84531 100644 --- a/lib/grade/grade_category.php +++ b/lib/grade/grade_category.php @@ -720,7 +720,6 @@ class grade_category extends grade_object { * Sets this category as the parent for the given children. * A number of constraints are necessary: * - The children must all be of the same type and at the same level - * - The children must be consecutive (no gap between them), this assumes they have been correctly ordered previously * - The children cannot already be top categories * - The children cannot already have a top category * @param array $children An array of fully instantiated grade_category OR grade_item objects @@ -732,17 +731,12 @@ class grade_category extends grade_object { // Check type and sortorder of first child $first_child = current($children); $first_child_type = get_class($first_child); - $first_child_sortorder = $first_child->get_sortorder(); foreach ($children as $child) { if (get_class($child) != $first_child_type) { debugging("Violated constraint: Attempted to set a category as a parent over children of 2 different types."); return false; } - if ($child->get_sortorder() != $first_child_sortorder++) { - debugging("Violated constraint: Attempted to set a category as a parent over children which were not consecutively arranged (gaps exist)."); - return false; - } if (grade_tree::get_element_type($child) == 'topcat') { debugging("Violated constraint: Attempted to set a category over children which are already top categories."); return false; diff --git a/lib/grade/grade_tree.php b/lib/grade/grade_tree.php index 8ae217bd4..7d7c97a71 100644 --- a/lib/grade/grade_tree.php +++ b/lib/grade/grade_tree.php @@ -226,7 +226,7 @@ class grade_tree { return false; } - $this->need_delete[] = $element->element['object']; + $this->need_delete[$element->element['object']->id] = $element->element['object']; return true; } else { @@ -316,7 +316,7 @@ class grade_tree { return false; } - $this->need_insert[] = $new_element; + $this->need_insert[$new_element->element['object']->id] = $new_element->element['object']; return true; } @@ -365,7 +365,8 @@ class grade_tree { /** * One at a time, re-assigns new sort orders for every element in the tree, starting * with a base number. - * @return boolean; + * @return array A debugging array which shows the progression of variables throughout this method. This is very useful + * to identify problems and implement new functionality. */ function renumber($starting_sortorder=NULL) { $sortorder = $starting_sortorder; @@ -379,44 +380,100 @@ class grade_tree { } $newtree = array(); + $topcatsortorder = 0; + $debug = array(); foreach ($this->tree_array as $topcat) { $sortorder++; + $subcatsortorder = 0; + + $debug[] = array('sortorder' => $sortorder, + 'need_update' => $this->need_update, + 'line' => __LINE__); + if (!empty($topcat['children'])) { $topcatsortorder = $sortorder; + $debug[] = array('sortorder' => $sortorder, + 'topcatsortorder' => $topcatsortorder, + 'need_update' => $this->need_update, + 'line' => __LINE__); + foreach ($topcat['children'] as $subcat) { $sortorder++; + $debug[] = array('sortorder' => $sortorder, + 'topcatsortorder' => $topcatsortorder, + 'need_update' => $this->need_update, + 'line' => __LINE__); + if (!empty($subcat['children'])) { $subcatsortorder = $sortorder; + + $debug[] = array('sortorder' => $sortorder, + 'topcatsortorder' => $topcatsortorder, + 'subcatsortorder' => $subcatsortorder, + 'need_update' => $this->need_update, + 'line' => __LINE__); + foreach ($subcat['children'] as $item) { $sortorder++; + + $debug[] = array('sortorder' => $sortorder, + 'topcatsortorder' => $topcatsortorder, + 'subcatsortorder' => $subcatsortorder, + 'need_update' => $this->need_update, + 'line' => __LINE__); + $newtree[$topcatsortorder]['children'][$subcatsortorder]['children'][$sortorder] = $item; + if ($sortorder != $item['object']->sortorder) { - $this->need_update[$item['object']->sortorder] = $sortorder; + $this->need_update[$item['object']->id] = array('old_sortorder' => $item['object']->sortorder, 'new_sortorder' => $sortorder); + $debug[] = array('sortorder' => $sortorder, + 'topcatsortorder' => $topcatsortorder, + 'subcatsortorder' => $subcatsortorder, + 'need_update' => $this->need_update, + 'line' => __LINE__); + } } $newtree[$topcatsortorder]['children'][$subcatsortorder]['object'] = $subcat['object']; + $newsortorder = $subcatsortorder; } else { $newtree[$topcatsortorder]['children'][$sortorder] = $subcat; + $newsortorder = $sortorder; } - - if ($sortorder != $subcat['object']->sortorder) { - $this->need_update[$subcat['object']->sortorder] = $sortorder; + + if ($newsortorder != $subcat['object']->sortorder) { + $this->need_update[$subcat['object']->id] = array('old_sortorder' => $subcat['object']->sortorder, 'new_sortorder' => $newsortorder); + $debug[] = array('sortorder' => $sortorder, + 'topcatsortorder' => $topcatsortorder, + 'subcatsortorder' => $subcatsortorder, + 'need_update' => $this->need_update, + 'line' => __LINE__); + } } $newtree[$topcatsortorder]['object'] = $topcat['object']; + $newsortorder = $topcatsortorder; } else { - $newtree[$sortorder] = $topcat; + $newsortorder = $sortorder; + $newtree[$sortorder] = $topcat; } - - if ($sortorder != $topcat['object']->sortorder) { - $this->need_update[$topcat['object']->sortorder] = $sortorder; + + if ($newsortorder != $topcat['object']->sortorder) { + $this->need_update[$topcat['object']->id] = array('old_sortorder' => $topcat['object']->sortorder, 'new_sortorder' => $newsortorder); + $debug[] = array('sortorder' => $sortorder, + 'topcatsortorder' => $topcatsortorder, + 'subcatsortorder' => $subcatsortorder, + 'need_update' => $this->need_update, + 'line' => __LINE__); + } } + $this->tree_array = $newtree; unset($this->first_sortorder); $this->build_tree_filled(); - return true; + return $debug; } /** @@ -719,4 +776,40 @@ class grade_tree { return true; } + + /** + * Performs any delete, insert or update queries required, depending on the objects + * stored in $this->need_update, need_insert and need_delete. + * @return boolean Success or Failure + */ + function update_db() { + // Perform deletions first + foreach ($this->need_delete as $id => $object) { + // If an item is both in the delete AND insert arrays, it must be an existing object that only needs updating, so ignore it. + if (empty($this->need_insert[$id])) { + if (!$object->delete()) { + debugging("Could not delete object from DB."); + } + } + } + + foreach ($this->need_insert as $id => $object) { + if (empty($this->need_delete[$id])) { + if (!$object->insert()) { + debugging("Could not insert object into DB."); + } + } + } + + $this->need_delete = array(); + $this->need_insert = array(); + + foreach ($this->need_update as $id => $sortorders) { + if (!set_field('grade_items', 'sortorder', $sortorders['new_sortorder'], 'id', $id)) { + debugging("Could not update the grade_item's sortorder in DB."); + } + } + + $this->need_update = array(); + } } diff --git a/lib/simpletest/grade/simpletest/testgradecategory.php b/lib/simpletest/grade/simpletest/testgradecategory.php index d792f8dfd..7e30f213c 100755 --- a/lib/simpletest/grade/simpletest/testgradecategory.php +++ b/lib/simpletest/grade/simpletest/testgradecategory.php @@ -200,10 +200,10 @@ class grade_category_test extends gradelib_test { $aggregated_grades = $category->aggregate_grades($grade_sets); $this->assertEqual(200, count($aggregated_grades)); - $this->assertWithinMargin($aggregated_grades[rand(0, count($aggregated_grades))]->gradevalue, 0, 100); - $this->assertWithinMargin($aggregated_grades[rand(0, count($aggregated_grades))]->gradevalue, 0, 100); - $this->assertWithinMargin($aggregated_grades[rand(0, count($aggregated_grades))]->gradevalue, 0, 100); - $this->assertWithinMargin($aggregated_grades[rand(0, count($aggregated_grades))]->gradevalue, 0, 100); + $this->assertWithinMargin($aggregated_grades[rand(1, count($aggregated_grades) - 1)]->gradevalue, 0, 100); + $this->assertWithinMargin($aggregated_grades[rand(1, count($aggregated_grades) - 1)]->gradevalue, 0, 100); + $this->assertWithinMargin($aggregated_grades[rand(1, count($aggregated_grades) - 1)]->gradevalue, 0, 100); + $this->assertWithinMargin($aggregated_grades[rand(1, count($aggregated_grades) - 1)]->gradevalue, 0, 100); } function generate_random_raw_grade($item, $userid) { @@ -222,7 +222,7 @@ class grade_category_test extends gradelib_test { global $CFG; $debuglevel = $CFG->debug; - // There are 4 constraints which, if violated, should return false and trigger a debugging message. Test each of them + // There are 3 constraints which, if violated, should return false and trigger a debugging message. Test each of them $grade_category = new grade_category(); $grade_category->fullname = 'new topcategory'; $grade_category->courseid = $this->courseid; @@ -238,22 +238,13 @@ class grade_category_test extends gradelib_test { $this->assertFalse($grade_category->set_as_parent(array($child1, $child2))); $CFG->debug = $debuglevel; - // 2. Non-consecutive children - $child1 = new grade_item(); - $child2 = new grade_item(); - $child1->sortorder = 1; - $child2->sortorder = 3; - $CFG->debug = 2; - $this->assertFalse($grade_category->set_as_parent(array($child1, $child2))); - $CFG->debug = $debuglevel; - - // 3. Child is a top category + // 2. Child is a top category $child1 = new grade_category($this->grade_categories[0]); $CFG->debug = 2; $this->assertFalse($grade_category->set_as_parent(array($child1))); $CFG->debug = $debuglevel; - // 4. Child already has a top category + // 3. Child already has a top category $child1 = new grade_item($this->grade_items[0]); $CFG->debug = 2; $this->assertFalse($grade_category->set_as_parent(array($child1))); diff --git a/lib/simpletest/grade/simpletest/testgradetree.php b/lib/simpletest/grade/simpletest/testgradetree.php index 6927f761d..7d079c2c9 100644 --- a/lib/simpletest/grade/simpletest/testgradetree.php +++ b/lib/simpletest/grade/simpletest/testgradetree.php @@ -97,6 +97,17 @@ class grade_tree_test extends gradelib_test { $this->assertFalse(empty($tree->tree_array[8]['children'][1])); $this->assertEqual('unittestgradeitem2', $tree->tree_array[8]['children'][1]['object']->itemname); $tree->renumber(); + + // Check need_? fields + $this->assertFalse(empty($tree->need_update)); + $this->assertFalse(empty($tree->need_insert)); + $this->assertFalse(empty($tree->need_delete)); + $this->assertEqual(6, count($tree->need_update)); + $this->assertEqual(1, count($tree->need_delete)); + $this->assertEqual(1, count($tree->need_insert)); + $this->assertEqual($this->grade_items[1]->itemname, $tree->need_delete[$this->grade_items[1]->id]->itemname); + $this->assertEqual($this->grade_items[1]->itemname, $tree->need_insert[$this->grade_items[1]->id]->itemname); + $this->assertFalse(empty($tree->tree_array[1]['children'][4]['children'][5])); $this->assertEqual('unittestgradeitem3', $tree->tree_array[1]['children'][4]['children'][5]['object']->itemname); @@ -162,6 +173,7 @@ class grade_tree_test extends gradelib_test { $tree1 = $tree; $tree->renumber(); $this->assertEqual($tree1->tree_array[1]['object'], $tree->tree_array[1]['object']); + $this->assertTrue(empty($tree->need_update)); } function test_grade_tree_remove_element() { @@ -218,15 +230,33 @@ class grade_tree_test extends gradelib_test { function test_grade_tree_build_tree_filled() { $tree = new grade_tree($this->courseid); - echo $tree->display_grades() . "
"; $element = $tree->tree_array[7]; $tree->remove_element(7); $tree->renumber(); - echo $tree->display_grades() . "
"; $tree->insert_element($element, 4); $tree->renumber(); - echo $tree->display_grades() . "
"; } + + function test_grade_tree_update_db() { + $tree = new grade_tree($this->courseid); + $tree->remove_element(7); + $tree->renumber(); + $tree->update_db(); + $item = grade_item::fetch('id', $this->grade_items[6]->id); + $this->assertTrue(empty($item->id)); + + $tree->move_element(4, 9); + $tree->renumber(); + $tree->update_db(); + $item = grade_item::fetch('id', $this->grade_items[1]->id); + $this->assertFalse(empty($item->id)); + $this->assertEqual(8, $item->sortorder); + + $grade_item = new grade_item($this->grade_items[2]); + $element = array('object' => $grade_item); + $tree->insert_element($element, 9); + + } } -- 2.11.4.GIT