From 607a0bbbc9cd3e75b0c5c414a907ae61ece260d1 Mon Sep 17 00:00:00 2001 From: nicolasconnault Date: Thu, 17 May 2007 04:13:42 +0000 Subject: [PATCH] MDL-9506 Successfully implemented the grade_tree methods for moving an element somewhere else in the tree. Tests pass successfully. However the test data doesn't yet include more than 1 top-category, so I can't test moving it. Direct insertion and deletion have not yet been tested, although insertion is used by the move_element method. --- lib/grade/grade_tree.php | 59 +++++++++++----- .../grade/simpletest/testgradetree.php | 67 ++++++++++++++++++- 2 files changed, 105 insertions(+), 21 deletions(-) diff --git a/lib/grade/grade_tree.php b/lib/grade/grade_tree.php index 12746441ce..774aef06bd 100644 --- a/lib/grade/grade_tree.php +++ b/lib/grade/grade_tree.php @@ -42,6 +42,13 @@ class grade_tree { */ var $tree_array = array(); + /** + * Another array with fillers for categories and items that do not have a parent, but have + * are not at level 2. This is used by the display_grades method. + * @var array $tree_filled + */ + var $tree_filled = array(); + /** * An array of objects that need updating (normally just grade_item.sortorder). * @var array $need_update @@ -75,12 +82,15 @@ class grade_tree { */ function locate_element($sortorder) { $topcatcount = 0; + $retval = false; foreach ($this->tree_array as $topcatkey => $topcat) { $topcatcount++; $subcatcount = 0; $retval = new stdClass(); $retval->topcatindex = $topcatkey; + unset($retval->subcatindex); + unset($retval->itemindex); if ($topcatkey == $sortorder) { $retval->depth = 1; @@ -92,6 +102,7 @@ class grade_tree { if (!empty($topcat['children'])) { foreach ($topcat['children'] as $subcatkey => $subcat) { $subcatcount++; + unset($retval->itemindex); $itemcount = 0; $retval->subcatindex = $subcatkey; @@ -166,7 +177,7 @@ class grade_tree { if (empty($this->first_sortorder)) { $this->first_sortorder = key($this->tree_array); } - + if ($position == 'before') { $offset = -1; } elseif ($position == 'after') { @@ -176,21 +187,26 @@ class grade_tree { } // TODO Problem when moving topcategories: sortorder gets reindexed when splicing the array - $destination_array = array($destination_sortorder => $source->element); + $destination_array = array($destination_sortorder => $element->element); + + // Get the position of the destination element + $destination_element = $this->locate_element($destination_sortorder); + $position = $destination_element->position; + switch($element->depth) { case 1: array_splice($this->tree_array, - $element->position + $offset, 0, + $position + $offset, 0, $destination_array); break; case 2: - array_splice($this->tree_array[$element->topcatindex]['children'], - $element->position + $offset, 0, + array_splice($this->tree_array[$destination_element->topcatindex]['children'], + $position + $offset, 0, $destination_array); break; case 3: - array_splice($this->tree_array[$element->topcatindex]['children'][$element->subcatindex]['children'], - $element->position + $offset, 0, + array_splice($this->tree_array[$destination_element->topcatindex]['children'][$destination_element->subcatindex]['children'], + $position + $offset, 0, $destination_array); break; } @@ -225,7 +241,7 @@ class grade_tree { } // Insert the element before the destination sortorder - $this->insert_element($destination, $destination_sortorder, $position); + $this->insert_element($source, $destination_sortorder, $position); return true; } @@ -240,7 +256,7 @@ class grade_tree { $sortorder = $starting_sortorder; if (empty($starting_sortorder)) { - $sortorder = $this->first_sortorder; + $sortorder = $this->first_sortorder - 1; } $newtree = array(); @@ -257,15 +273,16 @@ class grade_tree { $sortorder++; $newtree[$topcatsortorder]['children'][$subcatsortorder]['children'][$sortorder] = $item; } + $newtree[$topcatsortorder]['children'][$subcatsortorder]['object'] = $subcat['object']; } else { $newtree[$topcatsortorder]['children'][$sortorder] = $subcat; } } + $newtree[$topcatsortorder]['object'] = $topcat['object']; } else { $newtree[$sortorder] = $topcat; } } - $this->tree_array = $newtree; unset($this->first_sortorder); return true; @@ -336,10 +353,10 @@ class grade_tree { $object = current($fillers); unset($fillers[$sortorder]); - $tree[$sortorder] = $this->get_filler($object, $fullobjects); + $this->tree_filled[$sortorder] = $this->get_filler($object, $fullobjects); } - $query = "SELECT $category_table.* FROM $category_table, $items_table + $query = "SELECT $category_table.*, sortorder FROM $category_table, $items_table WHERE iteminstance = $category_table.id AND parent = $topcatid ORDER BY sortorder"; $subcats = get_records_sql($query); $subcattree = array(); @@ -368,30 +385,36 @@ class grade_tree { } if ($fullobjects) { + $sortorder = $item->sortorder; $item = new grade_item($item); + $item->sortorder = $sortorder; } - $itemtree[] = array('object' => $item, 'finalgrades' => $finals); + $itemtree[$item->sortorder] = array('object' => $item, 'finalgrades' => $finals); } if ($fullobjects) { + $sortorder = $subcat->sortorder; $subcat = new grade_category($subcat, false); + $subcat->sortorder = $sortorder; } - - $subcattree[] = array('object' => $subcat, 'children' => $itemtree); + $subcattree[$subcat->sortorder] = array('object' => $subcat, 'children' => $itemtree); } if ($fullobjects) { + $sortorder = $topcat->sortorder; $topcat = new grade_category($topcat, false); + $topcat->sortorder = $sortorder; } - $tree[] = array('object' => $topcat, 'children' => $subcattree); + $tree[$topcat->sortorder] = array('object' => $topcat, 'children' => $subcattree); + $this->tree_filled[$topcat->sortorder] = array('object' => $topcat, 'children' => $subcattree); } // If there are still grade_items or grade_categories without a top category, add another filler if (!empty($fillers)) { foreach ($fillers as $sortorder => $object) { - $tree[] = $this->get_filler($object, $fullobjects); + $this->tree_filled[$sortorder] = $this->get_filler($object, $fullobjects); } } @@ -455,7 +478,7 @@ class grade_tree { */ function display_grades() { // 1. Fetch all top-level categories for this course, with all children preloaded, sorted by sortorder - $tree = $this->tree_array; + $tree = $this->tree_filled; $topcathtml = ''; $cathtml = ''; $itemhtml = ''; diff --git a/lib/simpletest/grade/simpletest/testgradetree.php b/lib/simpletest/grade/simpletest/testgradetree.php index 2840e92d28..78cc5208d5 100644 --- a/lib/simpletest/grade/simpletest/testgradetree.php +++ b/lib/simpletest/grade/simpletest/testgradetree.php @@ -36,6 +36,11 @@ require_once($CFG->libdir . '/simpletest/testgradelib.php'); class grade_tree_test extends gradelib_test { + function test_grade_tree_constructor() { + $tree = new grade_tree($this->courseid); + + } + function test_grade_tree_display_grades() { $tree = new grade_tree($this->courseid); $result_html = $tree->display_grades(); @@ -46,12 +51,68 @@ class grade_tree_test extends gradelib_test { function test_grade_tree_get_tree() { $tree = new grade_tree($this->courseid); - $result_count = count($tree->tree_array, COUNT_RECURSIVE); - $this->assertEqual(58, $result_count); - print_object($tree); + $this->assertEqual(58, count($tree->tree_filled, COUNT_RECURSIVE)); + $this->assertEqual(27, count($tree->tree_array, COUNT_RECURSIVE)); + } + + function test_grade_tree_locate_element() { + $tree = new grade_tree($this->courseid); + $element = $tree->locate_element(5); + $this->assertEqual(1, $element->topcatindex); + $this->assertEqual(5, $element->subcatindex); + $this->assertTrue(empty($element->itemindex)); + $this->assertEqual(2, $element->depth); + $this->assertNotNull($element->element); + $this->assertEqual('unittestcategory3', $element->element['object']->fullname); + $this->assertEqual('unittestgradeitem3', $element->element['children'][6]['object']->itemname); + } + + function test_grade_tree_renumber() { + $tree = new grade_tree($this->courseid); + $tree->renumber(); + + } + + function test_grade_tree_move_element() { + $tree = new grade_tree($this->courseid); + $tree->move_element(4, 6); + $this->assertFalse(empty($tree->tree_array[1]['children'][5]['children'][0])); + $this->assertEqual('unittestgradeitem2', $tree->tree_array[1]['children'][5]['children'][0]['object']->itemname); + $tree->renumber(); + $this->assertFalse(empty($tree->tree_array[1]['children'][4]['children'][5])); + $this->assertEqual('unittestgradeitem2', $tree->tree_array[1]['children'][4]['children'][5]['object']->itemname); + + $tree->move_element(6, 3, 'after'); + $this->assertFalse(empty($tree->tree_array[1]['children'][2]['children'][1])); + $this->assertEqual('unittestgradeitem3', $tree->tree_array[1]['children'][2]['children'][1]['object']->itemname); + $tree->renumber(); + $this->assertFalse(empty($tree->tree_array[1]['children'][2]['children'][4])); + $this->assertEqual('unittestgradeitem3', $tree->tree_array[1]['children'][2]['children'][4]['object']->itemname); + + // Try moving a subcategory + $tree->move_element(2, 5, 'after'); + $this->assertFalse(empty($tree->tree_array[1]['children'][1])); + $this->assertEqual('unittestcategory2', $tree->tree_array[1]['children'][1]['object']->fullname); + $tree->renumber(); + $this->assertFalse(empty($tree->tree_array[1]['children'][4])); + $this->assertEqual('unittestcategory2', $tree->tree_array[1]['children'][4]['object']->fullname); + + // Try moving elements from different levels + $this->assertFalse($tree->move_element(1, 2)); + } + + function test_grade_tree_insert_element() { + $tree = new grade_tree($this->courseid); + + } + + function test_grade_tree_remove_element() { + $tree = new grade_tree($this->courseid); + } function test_grade_tree_get_filler() { + $tree = new grade_tree($this->courseid); } -- 2.39.5