From ce385eb4e34ee621af900a108190fcf5969aedef Mon Sep 17 00:00:00 2001 From: nicolasconnault Date: Tue, 1 May 2007 08:56:37 +0000 Subject: [PATCH] MDL-9506 Implemented category path and depth, and wrote unit tests for them. --- lib/grade/grade_category.php | 57 +++++++++++++++++++++++++++++++++++++---- lib/simpletest/testgradelib.php | 35 ++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/lib/grade/grade_category.php b/lib/grade/grade_category.php index a899cdea7..f5af86743 100644 --- a/lib/grade/grade_category.php +++ b/lib/grade/grade_category.php @@ -112,11 +112,20 @@ class grade_category extends grade_object { /** * Builds this category's path string based on its parents (if any) and its own id number. * This is typically done just before inserting this object in the DB for the first time, - * or when a new parent is added or changed. - * @todo implement + * or when a new parent is added or changed. It is a recursive function: once the calling + * object no longer has a parent, the path is complete. + * + * @static + * @param object $grade_category + * @return int The depth of this category (2 means there is one parent) */ - function build_path() { - + function build_path($grade_category) { + if (empty($grade_category->parent)) { + return "/$grade_category->id"; + } else { + $parent = get_record('grade_categories', 'id', $grade_category->parent); + return grade_category::build_path($parent) . "/$grade_category->id"; + } } @@ -147,7 +156,45 @@ class grade_category extends grade_object { } else { return false; } - } + } + + /** + * In addition to the normal insert() defined in grade_object, this method sets the depth + * and path for this object, and update the record accordingly. The reason why this must + * be done here instead of in the constructor, is that they both need to know the record's + * id number, which only gets created at insertion time. + */ + function insert() { + $result = parent::insert(); + + // Build path and depth variables + if (!empty($this->parent)) { + $this->path = grade_category::build_path($this); + $this->depth = $this->get_depth_from_path(); + } else { + $this->depth = 1; + $this->path = "/$this->id"; + } + + $this->update(); + return $result; + } + + /** + * Looks at a path string (e.g. /2/45/56) and returns the depth level represented by this path (in this example, 3). + * If no string is given, it looks at the obect's path and assigns the resulting depth to its $depth variable. + * @param string $path + * @return int Depth level + */ + function get_depth_from_path($path=NULL) { + if (empty($path)) { + $path = $this->path; + } + preg_match_all('/\/([0-9]+)+?/', $path, $matches); + $depth = count($matches[0]); + + return $depth; + } } ?> diff --git a/lib/simpletest/testgradelib.php b/lib/simpletest/testgradelib.php index 954b34ad0..6434306d3 100644 --- a/lib/simpletest/testgradelib.php +++ b/lib/simpletest/testgradelib.php @@ -45,11 +45,12 @@ require_once($CFG->libdir . '/dmllib.php'); * this search (%unittest%) will be deleted! Maybe a good idea to switch this off in * production environment. */ +/* delete_records_select('grade_categories', 'fullname LIKE "%unittest%"'); delete_records_select('grade_items', 'itemname LIKE "%unittest%"'); delete_records_select('grade_calculation', 'calculation LIKE "%unittest%"'); delete_records_select('scale', 'name LIKE "%unittest%"'); - +*/ class gradelib_test extends UnitTestCase { /** @@ -844,7 +845,39 @@ class gradelib_test extends UnitTestCase { // GRADE_CATEGORY OBJECT function test_grade_category_construct() { + $params = new stdClass(); + + $params->courseid = $this->courseid; + $params->fullname = 'unittestcategory4'; + $grade_category = new grade_category($params, false); + $grade_category->insert(); + $this->grade_categories[] = $grade_category; + + $this->assertEqual($params->courseid, $grade_category->courseid); + $this->assertEqual($params->fullname, $grade_category->fullname); + $this->assertEqual(1, $grade_category->depth); + $this->assertEqual("/$grade_category->id", $grade_category->path); + $parentpath = $grade_category->path; + + // Test a child category + $params->parent = $grade_category->id; + $params->fullname = 'unittestcategory5'; + $grade_category = new grade_category($params, false); + $grade_category->insert(); + $this->grade_categories[] = $grade_category; + $this->assertEqual(2, $grade_category->depth); + $this->assertEqual("$parentpath/$grade_category->id", $grade_category->path); + $parentpath = $grade_category->path; + + // Test a third depth category + $params->parent = $grade_category->id; + $params->fullname = 'unittestcategory6'; + $grade_category = new grade_category($params, false); + $grade_category->insert(); + $this->grade_categories[] = $grade_category; + $this->assertEqual(3, $grade_category->depth); + $this->assertEqual("$parentpath/$grade_category->id", $grade_category->path); } function test_grade_category_insert() { -- 2.11.4.GIT