diff --git a/lib/grade/grade_calculation.php b/lib/grade/grade_calculation.php index beb786962fb..1508dc89a21 100644 --- a/lib/grade/grade_calculation.php +++ b/lib/grade/grade_calculation.php @@ -91,14 +91,15 @@ class grade_calculation extends grade_object { */ function fetch($field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields="*") { if ($grade_calculation = get_record('grade_calculations', $field1, $value1, $field2, $value2, $field3, $value3, $fields)) { - if (!isset($this)) { - $grade_calculation = new grade_calculation($grade_calculation); - return $grade_calculation; - } else { + if (isset($this) && get_class($this) == 'grade_calculation') { + print_object($this); foreach ($grade_calculation as $param => $value) { $this->$param = $value; } return $this; + } else { + $grade_calculation = new grade_calculation($grade_calculation); + return $grade_calculation; } } else { return false; diff --git a/lib/grade/grade_category.php b/lib/grade/grade_category.php index f5af8674376..9b34efd2047 100644 --- a/lib/grade/grade_category.php +++ b/lib/grade/grade_category.php @@ -27,7 +27,7 @@ require_once('grade_object.php'); class grade_category extends grade_object { /** - * DB Table (used by grade_object). + * The DB table. * @var string $table */ var $table = 'grade_categories'; @@ -36,7 +36,7 @@ class grade_category extends grade_object { * Array of class variables that are not part of the DB table fields * @var array $nonfields */ - var $nonfields = array('table', 'nonfields'); + var $nonfields = array('table', 'nonfields', 'children', 'all_children'); /** * The course this category belongs to. @@ -99,6 +99,13 @@ class grade_category extends grade_object { */ var $children; + /** + * A hierarchical array of all children below this category. This is stored separately from + * $children because it is more memory-intensive and may not be used as often. + * @var array $all_children + */ + var $all_children; + /** * Constructor. Extends the basic functionality defined in grade_object. * @param array $params Can also be a standard object. @@ -144,14 +151,14 @@ class grade_category extends grade_object { function fetch($field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields="*") { if ($grade_category = get_record('grade_categories', $field1, $value1, $field2, $value2, $field3, $value3, $fields)) { - if (!isset($this)) { - $grade_category = new grade_category($grade_category); - return $grade_category; - } else { + if (isset($this) && get_class($this) == 'grade_category') { foreach ($grade_category as $param => $value) { $this->$param = $value; } return $this; + } else { + $grade_category = new grade_category($grade_category); + return $grade_category; } } else { return false; @@ -195,6 +202,44 @@ class grade_category extends grade_object { return $depth; } + + /** + * Fetches and returns all the children categories and/or grade_items belonging to this category. + * By default only returns the immediate children (depth=1), but deeper levels can be requested, + * as well as all levels (0). + * @param int $depth 1 for immediate children, 0 for all children, and 2+ for specific levels deeper than 1. + * @param string $arraytype Either 'nested' or 'flat'. A nested array represents the true hierarchy, but is more difficult to work with. + * @return array Array of child objects (grade_category and grade_item). + */ + function get_children($depth=1, $arraytype='nested') { + $children = array(); + + if ($depth == 1) { + if (!empty($this->children)) { + return $this->children; + } else { + $cat = new grade_category(); + $cat->parent = $this->id; + $children = $cat->fetch_all_using_this(); + $item = new grade_item(); + $item->categoryid = $this->id; + $item_children = $item->fetch_all_using_this(); + + if (!empty($children)) { + $children = array_merge($children, $item_children); + } else { + $children = $item_children; + } + + $this->children = $children; + } + } elseif ($depth > 1) { + // TODO implement + } elseif ($depth == 0) { + // TODO implement + } + return $children; + } } ?> diff --git a/lib/grade/grade_grades_final.php b/lib/grade/grade_grades_final.php index 6ffd62b0e96..82c7958bd2a 100644 --- a/lib/grade/grade_grades_final.php +++ b/lib/grade/grade_grades_final.php @@ -27,7 +27,7 @@ require_once('grade_object.php'); class grade_grades_final extends grade_object { /** - * DB Table (used by grade_object). + * The DB table. * @var string $table */ var $table = 'grade_grades_final'; @@ -36,7 +36,7 @@ class grade_grades_final extends grade_object { * Array of class variables that are not part of the DB table fields * @var array $nonfields */ - var $nonfields = array('table', 'nonfields'); + var $nonfields = array('nonfields', 'table'); /** * The id of the grade_item this final grade belongs to. @@ -110,14 +110,14 @@ class grade_grades_final extends grade_object { */ function fetch($field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields="*") { if ($object = get_record('grade_grades_final', $field1, $value1, $field2, $value2, $field3, $value3, $fields)) { - if (!isset($this)) { - $object = new grade_grades_final($object); - return $object; - } else { + if (isset($this) && get_class($this) == 'grade_grades_final') { foreach ($object as $param => $value) { $this->$param = $value; } return $this; + } else { + $object = new grade_grades_final($object); + return $object; } } else { return false; diff --git a/lib/grade/grade_grades_raw.php b/lib/grade/grade_grades_raw.php index 79216c3d98f..1d9d8b37e85 100644 --- a/lib/grade/grade_grades_raw.php +++ b/lib/grade/grade_grades_raw.php @@ -26,8 +26,9 @@ require_once('grade_object.php'); class grade_grades_raw extends grade_object { + /** - * DB Table (used by grade_object). + * The DB table. * @var string $table */ var $table = 'grade_grades_raw'; @@ -121,14 +122,14 @@ class grade_grades_raw extends grade_object { function fetch($field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields="*") { if ($object = get_record('grade_grades_raw', $field1, $value1, $field2, $value2, $field3, $value3, $fields)) { - if (!isset($this)) { - $object = new grade_grades_raw($object); - return $object; - } else { + if (isset($this) && get_class($this) == 'grade_grades_raw') { foreach ($object as $param => $value) { $this->$param = $value; } return $this; + } else { + $object = new grade_grades_raw($object); + return $object; } } else { return false; diff --git a/lib/grade/grade_item.php b/lib/grade/grade_item.php index 00d865cf838..91561490e61 100644 --- a/lib/grade/grade_item.php +++ b/lib/grade/grade_item.php @@ -213,14 +213,14 @@ class grade_item extends grade_object { */ function fetch($field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields="*") { if ($grade_item = get_record('grade_items', $field1, $value1, $field2, $value2, $field3, $value3, $fields)) { - if (!isset($this)) { - $grade_item = new grade_item($grade_item); - return $grade_item; - } else { + if (isset($this) && get_class($this) == 'grade_item') { foreach ($grade_item as $param => $value) { $this->$param = $value; } return $this; + } else { + $grade_item = new grade_item($grade_item); + return $grade_item; } } else { return false; @@ -298,12 +298,11 @@ class grade_item extends grade_object { * @return mixed $calculation A string if found, false otherwise. */ function get_calculation($fetch = false) { - if (!$fetch) { + if (!$fetch && get_class($this->calculation) == 'grade_calculation') { return $this->calculation; } - - $grade_calculation = grade_calculation::fetch(true, 'itemid', $this->id); - + $grade_calculation = grade_calculation::fetch('itemid', $this->id); + if (empty($grade_calculation)) { // There is no calculation in DB return false; } elseif ($grade_calculation->calculation != $this->calculation->calculation) { // The object's calculation is not in sync with the DB (new value??) diff --git a/lib/grade/grade_object.php b/lib/grade/grade_object.php index ea203807bd0..02ed32cd8cf 100644 --- a/lib/grade/grade_object.php +++ b/lib/grade/grade_object.php @@ -132,7 +132,20 @@ class grade_object { // Trim trailing AND $wheresql = substr($wheresql, 0, strrpos($wheresql, 'AND')); - return get_records_select($this->table, $wheresql, 'id'); + $objects = get_records_select($this->table, $wheresql, 'id'); + + if (!empty($objects)) { + $full_objects = array(); + + // Convert the stdClass objects returned by the get_records_select method into proper objects + $classname = get_class($this); + foreach ($objects as $id => $stdobject) { + $full_objects[$id] = new $classname($stdobject, false); + } + return $full_objects; + } else { + return $objects; + } } /** diff --git a/lib/simpletest/testgradelib.php b/lib/simpletest/testgradelib.php index 6434306d32a..58ba8281534 100644 --- a/lib/simpletest/testgradelib.php +++ b/lib/simpletest/testgradelib.php @@ -51,6 +51,12 @@ delete_records_select('grade_items', 'itemname LIKE "%unittest%"'); delete_records_select('grade_calculation', 'calculation LIKE "%unittest%"'); delete_records_select('scale', 'name LIKE "%unittest%"'); */ + +/** + * Here is a brief explanation of the test data set up in these unit tests. + * category1 => array(grade_item1, grade_item3, category2 => array(grade_item2)) + * 3 users for 3 grade_items + */ class gradelib_test extends UnitTestCase { /** @@ -129,6 +135,22 @@ class gradelib_test extends UnitTestCase { if ($grade_category->id = insert_record('grade_categories', $grade_category)) { $this->grade_categories[] = $grade_category; } + + $grade_category = new stdClass(); + + $grade_category->fullname = 'unittestcategory2'; + $grade_category->courseid = $this->courseid; + $grade_category->aggregation = GRADE_AGGREGATE_MODE; + $grade_category->keephigh = 100; + $grade_category->droplow = 10; + $grade_category->hidden = 0; + $grade_category->parent = $this->grade_categories[0]->id; + $grade_category->timecreated = mktime(); + $grade_category->timemodified = mktime(); + + if ($grade_category->id = insert_record('grade_categories', $grade_category)) { + $this->grade_categories[] = $grade_category; + } } /** @@ -156,6 +178,7 @@ class gradelib_test extends UnitTestCase { $grade_item = new stdClass(); $grade_item->courseid = $this->courseid; + $grade_item->categoryid = $this->grade_categories[1]->id; $grade_item->itemname = 'unittestgradeitem2'; $grade_item->itemtype = 'import'; $grade_item->itemmodule = 'assignment'; @@ -881,21 +904,66 @@ class gradelib_test extends UnitTestCase { } function test_grade_category_insert() { + $grade_category = new grade_category(); + $this->assertTrue(method_exists($grade_category, 'insert')); + + $grade_category->fullname = 'unittestcategory3'; + $grade_category->courseid = $this->courseid; + $grade_category->aggregation = GRADE_AGGREGATE_MODE; + $grade_category->keephigh = 100; + $grade_category->droplow = 10; + $grade_category->hidden = 0; + $grade_category->parent = $this->grade_categories[0]->id; + + $grade_category->insert(); + + $last_grade_category = end($this->grade_categories); + + $this->assertEqual($grade_category->id, $last_grade_category->id + 1); + $this->assertTrue(!empty($grade_category->timecreated)); + $this->assertTrue(!empty($grade_category->timemodified)); + $this->grade_categories[] = $grade_category; } function test_grade_category_update() { - + $grade_category = new grade_category($this->grade_categories[0]); + $this->assertTrue(method_exists($grade_category, 'update')); + + $grade_category->fullname = 'Updated info for this unittest grade_category'; + $this->assertTrue($grade_category->update()); + $fullname = get_field('grade_categories', 'fullname', 'id', $this->grade_categories[0]->id); + $this->assertEqual($grade_category->fullname, $fullname); } function test_grade_category_delete() { - + $grade_category = new grade_category($this->grade_categories[0]); + $this->assertTrue(method_exists($grade_category, 'delete')); + + $this->assertTrue($grade_category->delete()); + $this->assertFalse(get_record('grade_categories', 'id', $grade_category->id)); } function test_grade_category_fetch() { + $grade_category = new grade_category(); + $this->assertTrue(method_exists($grade_category, 'fetch')); + $grade_category = grade_category::fetch('id', $this->grade_categories[0]->id); + $this->assertEqual($this->grade_categories[0]->id, $grade_category->id); + $this->assertEqual($this->grade_categories[0]->fullname, $grade_category->fullname); } + function test_grade_category_get_children() { + $category = new grade_category($this->grade_categories[0]); + $this->assertTrue(method_exists($category, 'get_children')); + + $this->assertEqual(3, count($category->get_children())); + $this->assertEqual(5, count($category->get_children(0))); + + $category = new grade_category($this->grade_categories[1]); + $this->assertEqual(1, count($category->get_children())); + } + // GRADE_CALCULATION OBJECT // SCALE OBJECT