From: nicolasconnault Date: Wed, 16 May 2007 15:04:35 +0000 (+0000) Subject: MDL-9506 Created new grade_tree object for working with a tree of grade_categories... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=e835361626c5cd27cabdc046fc0e23a2c6ff98db;p=moodle.git MDL-9506 Created new grade_tree object for working with a tree of grade_categories and items. --- diff --git a/lib/grade/grade_tree.php b/lib/grade/grade_tree.php new file mode 100644 index 0000000000..95105fec4a --- /dev/null +++ b/lib/grade/grade_tree.php @@ -0,0 +1,236 @@ +tree_array as $topcatkey => $topcat) { + $topcatcount++; + $subcatcount = 0; + $retval = new stdClass(); + $retval->topcatindex = $topcatkey; + + if ($topcatkey == $sortorder) { + $retval->depth = 1; + $retval->element = $topcat; + $retval->position = $topcatcount; + return $retval; + } + + if (is_array($topcat)) { + foreach ($topcat as $subcatkey => $subcat) { + $subcatcount++; + $itemcount = 0; + + $retval->subcatindex = $subcatkey; + if ($subcatkey == $sortorder) { + $retval->depth = 2; + $retval->element = $subcat; + $retval->position = $subcatcount; + return $retval; + } + + if (is_array($subcat)) { + foreach ($subcat as $itemkey => $item) { + $itemcount++; + $retval->itemindex = $itemkey; + if ($itemkey == $sortorder) { + $retval->depth = 3; + $retval->element = $item; + $retval->position = $itemcount; + return $retval; + } + } + } + } + } + } + return $retval; + } + + /** + * Removes the given element (a stdClass object or a sortorder), remove_elements + * it from the tree. This does not renumber the tree. + * @var object $element An stdClass object typically returned by $this->locate(), or a sortorder + * @return boolean + */ + function remove_element($element) { + if (isset($element->depth)) { + switch ($element->depth) { + case 1: + unset($this->tree_array[$element->topcatindex]); + break; + case 2: + unset($this->tree_array[$element->topcatindex][$element->subcatindex]); + break; + case 3: + unset($this->tree_array[$element->topcatindex][$element->subcatindex][$element->itemindex]); + break; + } + return true; + } else { + $element = $this->locate_element($element); + if (!empty($element)) { + return $this->remove_element($element); + } else { + return false; + } + } + } + + /** + * Inserts an element in the tree. This can be either an array as returned by the grade_category methods, or + * an element object returned by grade_tree. + * @param mixed $element array or object. If object, the sub-tree is contained in $object->element + * @param int $destination_sortorder Where to insert the element + * @param string $position Either 'before' the destination_sortorder or 'after' + * @param boolean + */ + function insert_element($element, $destination_sortorder, $position='before') { + if ($position == 'before') { + $offset = -1; + } elseif ($position == 'after') { + $offset = 0; + } else { + die ('move_element(..... $position) can only be "before" or "after", you gave ' . $position); + } + + // TODO Problem when moving topcategories: sortorder gets reindexed when splicing the array + $destination_array = array($destination_sortorder => $source->element); + switch($element->depth) { + case 1: + array_splice($this->tree_array, + $element->position + $offset, 0, + $destination_array); + break; + case 2: + array_splice($this->tree_array[$element->topcatindex], + $element->position + $offset, 0, + $destination_array); + break; + case 3: + array_splice($this->tree_array[$element->topcatindex][$element->subcatindex], + $element->position + $offset, 0, + $destination_array); + break; + } + + return true; + } + + /** + * Moves an existing element in the tree to another position OF EQUAL LEVEL. This + * constraint is essential and very important. + * @param int $source_sortorder The sortorder of the element to move + * @param int $destination_sortorder The sortorder where the element will go + * @param string $position Either 'before' the destination_sortorder or 'after' it + * @return boolean + */ + function move_element($source_sortorder, $destination_sortorder, $position='before') { + // Locate the position of the source element in the tree + $source = $this->locate_element($source_sortorder); + + // Remove this element from the tree + $this->remove_element($source); + + $destination = $this->locate_element($destination_sortorder); + + if ($destination->depth != $source->depth) { + echo "Source and Destination were at different levels."; + return false; + } + + // Insert the element before the destination sortorder + $this->insert_element($destination, $destination_sortorder, $position); + + return true; + } + + + /** + * One at a time, re-assigns new sort orders for every element in the tree, starting + * with a base number. + * @return boolean; + */ + function renumber($starting_sortorder=NULL) { + $sortorder = $starting_sortorder; + + if (empty($starting_sortorder)) { + $sortorder = $this->first_sortorder; + } + + $newtree = array(); + + foreach ($this->tree_array as $topcat) { + $sortorder++; + if (is_array($topcat)) { + $topcatsortorder = $sortorder; + foreach ($topcat as $subcat) { + $sortorder++; + if(is_array($subcat)) { + $subcatsortorder = $sortorder; + foreach ($subcat as $item) { + $sortorder++; + $newtree[$topcatsortorder][$subcatsortorder][$sortorder] = $item; + } + } else { + $newtree[$topcatsortorder][$sortorder] = $subcat; + } + } + } else { + $newtree[$sortorder] = $topcat; + } + } + + $this->tree_array = $newtree; + return true; + } +} diff --git a/lib/simpletest/grade/simpletest/testgradeitem.php b/lib/simpletest/grade/simpletest/testgradeitem.php index b832134414..88718661a4 100755 --- a/lib/simpletest/grade/simpletest/testgradeitem.php +++ b/lib/simpletest/grade/simpletest/testgradeitem.php @@ -481,5 +481,8 @@ class grade_item_test extends gradelib_test { $grade_item->load_final(); $this->assertEqual(3, count($grade_item->grade_grades_final)); } + + function test_float_keys() { + } } ?> diff --git a/lib/simpletest/grade/simpletest/testgradetree.php b/lib/simpletest/grade/simpletest/testgradetree.php new file mode 100644 index 0000000000..ced5f6a54d --- /dev/null +++ b/lib/simpletest/grade/simpletest/testgradetree.php @@ -0,0 +1,39 @@ +libdir . '/simpletest/testgradelib.php'); + +class grade_tree_test extends gradelib_test { + +}