From 5e16f809f8dd9f71c071651d6cbd442175131915 Mon Sep 17 00:00:00 2001 From: nicolasconnault Date: Tue, 15 May 2007 09:59:53 +0000 Subject: [PATCH] MDL-9506 Experimental development of numbering and displaying of category and items tree/table. Messy work :-) --- lib/grade/grade_category.php | 123 ++++++++++ lib/simpletest/testgradelib.php | 388 +++++++++++++++++++++++++++++++- 2 files changed, 510 insertions(+), 1 deletion(-) diff --git a/lib/grade/grade_category.php b/lib/grade/grade_category.php index 431386caa6..317d71c69f 100644 --- a/lib/grade/grade_category.php +++ b/lib/grade/grade_category.php @@ -646,6 +646,129 @@ class grade_category extends grade_object { } return $this->parent_category; } + + /** + * Static method that returns a sorted, nested array of all grade_categories and grade_items for + * a given course, or for the entire site if no courseid is given. + * @param int $courseid + * @param boolean $fullobjects Whether to instantiate full objects based on the data or not + * @return array + */ + function get_tree($courseid=NULL, $fullobjects=true) { + global $CFG; + global $db; + $db->debug = false; + $tree = array(); + $fillers = array(); + + $category_table = $CFG->prefix . 'grade_categories'; + $items_table = $CFG->prefix . 'grade_items'; + + $constraint = ''; + $itemconstraint = ''; + + if (!empty($courseid)) { + $constraint = " AND $category_table.courseid = $courseid "; + $itemconstraint = " AND $items_table.courseid = $courseid "; + } + + // Get ordered list of grade_items (not category type) + $query = "SELECT * FROM $items_table WHERE itemtype <> 'category' $itemconstraint ORDER BY sortorder"; + $grade_items = get_records_sql($query); + + // For every grade_item that doesn't have a parent category, create category fillers + foreach ($grade_items as $itemid => $item) { + if (empty($item->categoryid)) { + if ($fullobjects) { + $item = new grade_item($item); + } + $fillers[$item->sortorder] = $item; + } + } + + // Get all top categories first + $query = "SELECT $category_table.*, sortorder FROM $category_table, $items_table + WHERE iteminstance = $category_table.id AND depth = 1 $constraint ORDER BY sortorder"; + + $topcats = get_records_sql($query); + + if (empty($topcats)) { + return null; + } + + foreach ($topcats as $topcatid => $topcat) { + // Check the fillers array, see if one must be inserted before this topcat + if (key($fillers) < $topcat->sortorder) { + $sortorder = key($fillers); + $itemtoinsert = current($fillers); + unset($fillers[$sortorder]); + $tree[] = array('object' => 'filler', 'children' => + array(0 => array('object' => 'filler', 'children' => + array(0 => array('object' => $itemtoinsert, 'finalgrades' => null))))); + } + + $query = "SELECT $category_table.* FROM $category_table, $items_table + WHERE iteminstance = $category_table.id AND parent = $topcatid ORDER BY sortorder"; + $subcats = get_records_sql($query); + $subcattree = array(); + + if (empty($subcats)) { + continue; + } + + foreach ($subcats as $subcatid => $subcat) { + $itemtree = array(); + $items = get_records('grade_items', 'categoryid', $subcatid, 'sortorder'); + + if (empty($items)) { + continue; + } + + foreach ($items as $itemid => $item) { + $finaltree = array(); + + if ($fullobjects) { + $final = new grade_grades_final(); + $final->itemid = $itemid; + $finals = $final->fetch_all_using_this(); + } else { + $finals = get_records('grade_grades_final', 'itemid', $itemid); + } + + if ($fullobjects) { + $item = new grade_item($item); + } + + $itemtree[] = array('object' => $item, 'finalgrades' => $finals); + } + + if ($fullobjects) { + $subcat = new grade_category($subcat, false); + } + + $subcattree[] = array('object' => $subcat, 'children' => $itemtree); + } + + if ($fullobjects) { + $topcat = new grade_category($topcat, false); + } + + $tree[] = array('object' => $topcat, 'children' => $subcattree); + } + + // If there are still grade_items, outside of categories, add another filler + if (!empty($fillers)) { + foreach ($fillers as $sortorder => $item) { + $tree[] = array('object' => 'filler', 'children' => + array(0 => array('object' => 'filler', 'children' => + array(0 => array('object' => $item, 'finalgrades' => null))))); + + } + } + + $db->debug = false; + return $tree; + } } ?> diff --git a/lib/simpletest/testgradelib.php b/lib/simpletest/testgradelib.php index 423f2e90a7..7943cef99a 100644 --- a/lib/simpletest/testgradelib.php +++ b/lib/simpletest/testgradelib.php @@ -389,6 +389,7 @@ class gradelib_test extends UnitTestCase { $grade_category->hidden = 0; $grade_category->timecreated = mktime(); $grade_category->timemodified = mktime(); + $grade_category->depth = 1; if ($grade_category->id = insert_record('grade_categories', $grade_category)) { $this->grade_categories[] = $grade_category; @@ -405,6 +406,7 @@ class gradelib_test extends UnitTestCase { $grade_category->parent = $this->grade_categories[0]->id; $grade_category->timecreated = mktime(); $grade_category->timemodified = mktime(); + $grade_category->depth = 2; if ($grade_category->id = insert_record('grade_categories', $grade_category)) { $this->grade_categories[] = $grade_category; @@ -421,6 +423,25 @@ class gradelib_test extends UnitTestCase { $grade_category->parent = $this->grade_categories[0]->id; $grade_category->timecreated = mktime(); $grade_category->timemodified = mktime(); + $grade_category->depth = 2; + + if ($grade_category->id = insert_record('grade_categories', $grade_category)) { + $this->grade_categories[] = $grade_category; + } + + // A category with no parent, but grade_items as children + + $grade_category = new stdClass(); + + $grade_category->fullname = 'level1category'; + $grade_category->courseid = $this->courseid; + $grade_category->aggregation = GRADE_AGGREGATE_MEAN; + $grade_category->keephigh = 100; + $grade_category->droplow = 10; + $grade_category->hidden = 0; + $grade_category->timecreated = mktime(); + $grade_category->timemodified = mktime(); + $grade_category->depth = 1; if ($grade_category->id = insert_record('grade_categories', $grade_category)) { $this->grade_categories[] = $grade_category; @@ -431,6 +452,7 @@ class gradelib_test extends UnitTestCase { * Load grade_item data into the database, and adds the corresponding objects to this class' variable. */ function load_grade_items() { + // id = 0 $grade_item = new stdClass(); $grade_item->courseid = $this->courseid; @@ -446,11 +468,13 @@ class gradelib_test extends UnitTestCase { $grade_item->iteminfo = 'Grade item used for unit testing'; $grade_item->timecreated = mktime(); $grade_item->timemodified = mktime(); + $grade_item->sortorder = 3; if ($grade_item->id = insert_record('grade_items', $grade_item)) { $this->grade_items[] = $grade_item; } + // id = 1 $grade_item = new stdClass(); $grade_item->courseid = $this->courseid; @@ -467,11 +491,13 @@ class gradelib_test extends UnitTestCase { $grade_item->locked = mktime() + 240000; $grade_item->timecreated = mktime(); $grade_item->timemodified = mktime(); + $grade_item->sortorder = 4; if ($grade_item->id = insert_record('grade_items', $grade_item)) { $this->grade_items[] = $grade_item; } + // id = 2 $grade_item = new stdClass(); $grade_item->courseid = $this->courseid; @@ -487,12 +513,14 @@ class gradelib_test extends UnitTestCase { $grade_item->iteminfo = 'Grade item used for unit testing'; $grade_item->timecreated = mktime(); $grade_item->timemodified = mktime(); + $grade_item->sortorder = 6; if ($grade_item->id = insert_record('grade_items', $grade_item)) { $this->grade_items[] = $grade_item; } // Load grade_items associated with the 3 categories + // id = 3 $grade_item = new stdClass(); $grade_item->courseid = $this->courseid; @@ -505,11 +533,13 @@ class gradelib_test extends UnitTestCase { $grade_item->iteminfo = 'Grade item used for unit testing'; $grade_item->timecreated = mktime(); $grade_item->timemodified = mktime(); + $grade_item->sortorder = 1; if ($grade_item->id = insert_record('grade_items', $grade_item)) { $this->grade_items[] = $grade_item; } + // id = 4 $grade_item = new stdClass(); $grade_item->courseid = $this->courseid; @@ -522,11 +552,13 @@ class gradelib_test extends UnitTestCase { $grade_item->iteminfo = 'Grade item used for unit testing'; $grade_item->timecreated = mktime(); $grade_item->timemodified = mktime(); + $grade_item->sortorder = 2; if ($grade_item->id = insert_record('grade_items', $grade_item)) { $this->grade_items[] = $grade_item; } + // id = 5 $grade_item = new stdClass(); $grade_item->courseid = $this->courseid; @@ -539,6 +571,94 @@ class gradelib_test extends UnitTestCase { $grade_item->iteminfo = 'Grade item used for unit testing'; $grade_item->timecreated = mktime(); $grade_item->timemodified = mktime(); + $grade_item->sortorder = 5; + + if ($grade_item->id = insert_record('grade_items', $grade_item)) { + $this->grade_items[] = $grade_item; + } + + // Orphan grade_item + // id = 6 + $grade_item = new stdClass(); + + $grade_item->courseid = $this->courseid; + $grade_item->itemname = 'unittestorphangradeitem1'; + $grade_item->itemtype = 'mod'; + $grade_item->itemmodule = 'quiz'; + $grade_item->iteminstance = 1; + $grade_item->gradetype = GRADE_TYPE_VALUE; + $grade_item->grademin = 10; + $grade_item->grademax = 120; + $grade_item->iteminfo = 'Orphan Grade item used for unit testing'; + $grade_item->timecreated = mktime(); + $grade_item->timemodified = mktime(); + $grade_item->sortorder = 7; + + if ($grade_item->id = insert_record('grade_items', $grade_item)) { + $this->grade_items[] = $grade_item; + } + + // 2 grade items under level1category + // id = 7 + $grade_item = new stdClass(); + + $grade_item->courseid = $this->courseid; + $grade_item->categoryid = $this->grade_categories[3]->id; + $grade_item->itemname = 'grade_item with only one parent level'; + $grade_item->itemtype = 'mod'; + $grade_item->itemmodule = 'forum'; + $grade_item->iteminstance = 3; + $grade_item->gradetype = GRADE_TYPE_SCALE; + $grade_item->scaleid = 1; + $grade_item->grademin = 0; + $grade_item->grademax = 7; + $grade_item->iteminfo = 'Grade item used for unit testing'; + $grade_item->timecreated = mktime(); + $grade_item->timemodified = mktime(); + $grade_item->sortorder = 9; + + if ($grade_item->id = insert_record('grade_items', $grade_item)) { + $this->grade_items[] = $grade_item; + } + + // id = 8 + $grade_item = new stdClass(); + + $grade_item->courseid = $this->courseid; + $grade_item->categoryid = $this->grade_categories[3]->id; + $grade_item->itemname = 'grade_item with only one parent level'; + $grade_item->itemtype = 'mod'; + $grade_item->itemmodule = 'forum'; + $grade_item->iteminstance = 3; + $grade_item->gradetype = GRADE_TYPE_VALUE; + $grade_item->grademin = 0; + $grade_item->grademax = 100; + $grade_item->iteminfo = 'Grade item used for unit testing'; + $grade_item->timecreated = mktime(); + $grade_item->timemodified = mktime(); + $grade_item->sortorder = 10; + + if ($grade_item->id = insert_record('grade_items', $grade_item)) { + $this->grade_items[] = $grade_item; + } + + // Grade_item for level1category + // id = 9 + $grade_item = new stdClass(); + + $grade_item->courseid = $this->courseid; + $grade_item->itemname = 'grade_item for level1 category'; + $grade_item->itemtype = 'category'; + $grade_item->itemmodule = 'quiz'; + $grade_item->iteminstance = 1; + $grade_item->needsupdate = true; + $grade_item->gradetype = GRADE_TYPE_VALUE; + $grade_item->grademin = 10; + $grade_item->grademax = 120; + $grade_item->iteminfo = 'Orphan Grade item used for unit testing'; + $grade_item->timecreated = mktime(); + $grade_item->timemodified = mktime(); + $grade_item->sortorder = 8; if ($grade_item->id = insert_record('grade_items', $grade_item)) { $this->grade_items[] = $grade_item; @@ -763,6 +883,111 @@ class gradelib_test extends UnitTestCase { if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { $this->grade_grades_raw[] = $grade_raw; } + + // Grades for grade_item 7 + + $grade_raw = new stdClass(); + $grade_raw->itemid = $this->grade_items[6]->id; + $grade_raw->userid = 1; + $grade_raw->gradevalue = 97; + $grade_raw->timecreated = mktime(); + $grade_raw->timemodified = mktime(); + + if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { + $this->grade_grades_raw[] = $grade_raw; + } + + $grade_raw = new stdClass(); + $grade_raw->itemid = $this->grade_items[6]->id; + $grade_raw->userid = 2; + $grade_raw->gradevalue = 49; + $grade_raw->timecreated = mktime(); + $grade_raw->timemodified = mktime(); + + if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { + $this->grade_grades_raw[] = $grade_raw; + } + + $grade_raw = new stdClass(); + $grade_raw->itemid = $this->grade_items[6]->id; + $grade_raw->userid = 3; + $grade_raw->gradevalue = 67; + $grade_raw->timecreated = mktime(); + $grade_raw->timemodified = mktime(); + + if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { + $this->grade_grades_raw[] = $grade_raw; + } + + // Grades for grade_item 8 + + $grade_raw = new stdClass(); + $grade_raw->itemid = $this->grade_items[7]->id; + $grade_raw->userid = 1; + $grade_raw->gradevalue = 97; + $grade_raw->timecreated = mktime(); + $grade_raw->timemodified = mktime(); + + if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { + $this->grade_grades_raw[] = $grade_raw; + } + + $grade_raw = new stdClass(); + $grade_raw->itemid = $this->grade_items[7]->id; + $grade_raw->userid = 2; + $grade_raw->gradevalue = 49; + $grade_raw->timecreated = mktime(); + $grade_raw->timemodified = mktime(); + + if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { + $this->grade_grades_raw[] = $grade_raw; + } + + $grade_raw = new stdClass(); + $grade_raw->itemid = $this->grade_items[7]->id; + $grade_raw->userid = 3; + $grade_raw->gradevalue = 67; + $grade_raw->timecreated = mktime(); + $grade_raw->timemodified = mktime(); + + if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { + $this->grade_grades_raw[] = $grade_raw; + } + + // Grades for grade_item 9 + + $grade_raw = new stdClass(); + $grade_raw->itemid = $this->grade_items[8]->id; + $grade_raw->userid = 1; + $grade_raw->gradevalue = 49; + $grade_raw->timecreated = mktime(); + $grade_raw->timemodified = mktime(); + + if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { + $this->grade_grades_raw[] = $grade_raw; + } + + $grade_raw = new stdClass(); + $grade_raw->itemid = $this->grade_items[8]->id; + $grade_raw->userid = 2; + $grade_raw->gradevalue = 93; + $grade_raw->timecreated = mktime(); + $grade_raw->timemodified = mktime(); + + if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { + $this->grade_grades_raw[] = $grade_raw; + } + + $grade_raw = new stdClass(); + $grade_raw->itemid = $this->grade_items[7]->id; + $grade_raw->userid = 3; + $grade_raw->gradevalue = 76; + $grade_raw->timecreated = mktime(); + $grade_raw->timemodified = mktime(); + + if ($grade_raw->id = insert_record('grade_grades_raw', $grade_raw)) { + $this->grade_grades_raw[] = $grade_raw; + } } /** @@ -881,6 +1106,120 @@ class gradelib_test extends UnitTestCase { if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { $this->grade_grades_final[] = $grade_final; } + + // Grades for grade_item 7 (orphan item) + + $grade_final = new stdClass(); + $grade_final->itemid = $this->grade_items[6]->id; + $grade_final->userid = 1; + $grade_final->gradevalue = 69; + $grade_final->timecreated = mktime(); + $grade_final->timemodified = mktime(); + $grade_final->locked = true; + + if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { + $this->grade_grades_final[] = $grade_final; + } + + $grade_final = new stdClass(); + $grade_final->itemid = $this->grade_items[6]->id; + $grade_final->userid = 2; + $grade_final->gradevalue = 87; + $grade_final->timecreated = mktime(); + $grade_final->timemodified = mktime(); + $grade_final->locked = true; + + if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { + $this->grade_grades_final[] = $grade_final; + } + + $grade_final = new stdClass(); + $grade_final->itemid = $this->grade_items[6]->id; + $grade_final->userid = 3; + $grade_final->gradevalue = 94; + $grade_final->timecreated = mktime(); + $grade_final->timemodified = mktime(); + $grade_final->locked = false; + + if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { + $this->grade_grades_final[] = $grade_final; + } + + // Grades for grade_item 8 + + $grade_final = new stdClass(); + $grade_final->itemid = $this->grade_items[7]->id; + $grade_final->userid = 1; + $grade_final->gradevalue = 69; + $grade_final->timecreated = mktime(); + $grade_final->timemodified = mktime(); + $grade_final->locked = true; + + if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { + $this->grade_grades_final[] = $grade_final; + } + + $grade_final = new stdClass(); + $grade_final->itemid = $this->grade_items[7]->id; + $grade_final->userid = 2; + $grade_final->gradevalue = 87; + $grade_final->timecreated = mktime(); + $grade_final->timemodified = mktime(); + $grade_final->locked = true; + + if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { + $this->grade_grades_final[] = $grade_final; + } + + $grade_final = new stdClass(); + $grade_final->itemid = $this->grade_items[7]->id; + $grade_final->userid = 3; + $grade_final->gradevalue = 94; + $grade_final->timecreated = mktime(); + $grade_final->timemodified = mktime(); + $grade_final->locked = false; + + if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { + $this->grade_grades_final[] = $grade_final; + } + + // Grades for grade_item 9 + + $grade_final = new stdClass(); + $grade_final->itemid = $this->grade_items[8]->id; + $grade_final->userid = 1; + $grade_final->gradevalue = 69; + $grade_final->timecreated = mktime(); + $grade_final->timemodified = mktime(); + $grade_final->locked = true; + + if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { + $this->grade_grades_final[] = $grade_final; + } + + $grade_final = new stdClass(); + $grade_final->itemid = $this->grade_items[8]->id; + $grade_final->userid = 2; + $grade_final->gradevalue = 87; + $grade_final->timecreated = mktime(); + $grade_final->timemodified = mktime(); + $grade_final->locked = true; + + if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { + $this->grade_grades_final[] = $grade_final; + } + + $grade_final = new stdClass(); + $grade_final->itemid = $this->grade_items[8]->id; + $grade_final->userid = 3; + $grade_final->gradevalue = 94; + $grade_final->timecreated = mktime(); + $grade_final->timemodified = mktime(); + $grade_final->locked = false; + + if ($grade_final->id = insert_record('grade_grades_final', $grade_final)) { + $this->grade_grades_final[] = $grade_final; + } } /** @@ -970,7 +1309,7 @@ class gradelib_test extends UnitTestCase { $grade_items = grade_get_items($this->courseid); $this->assertTrue(is_array($grade_items)); - $this->assertEqual(count($grade_items), 6); + $this->assertEqual(count($grade_items), 10); } } @@ -1032,6 +1371,53 @@ class gradelib_test extends UnitTestCase { $this->assertEqual(4, round(standardise_score(6, 0, 7, 0, 5))); $this->assertEqual(40, standardise_score(50, 30, 80, 0, 100)); } + + /** + * This is not a real unit test, but an experimental attempt at building a HTML table + * based on the sortorders set for each test grade_item. + */ + function test_grade_build_table() { + // 1. Fetch all top-level categories for this course, with all children preloaded, sorted by sortorder + $tree = grade_category::get_tree($this->courseid); + $topcathtml = ''; + $cathtml = ''; + $itemhtml = ''; + + foreach ($tree as $topcat) { + $itemcount = 0; + + foreach ($topcat['children'] as $catkey => $cat) { + $catitemcount = 0; + + foreach ($cat['children'] as $item) { + $itemcount++; + $catitemcount++; + $itemhtml .= '' . $item['object']->itemname . ''; + } + + if ($cat['object'] == 'filler') { + $cathtml .= ' '; + } else { + $cat['object']->load_grade_item(); + $cathtml .= '' . $cat['object']->fullname . ''; + } + } + + if ($topcat['object'] == 'filler') { + $topcathtml .= ' '; + } else { + $topcathtml .= '' . $topcat['object']->fullname . ''; + } + + } + + $itemhtml .= ''; + $cathtml .= ''; + $topcathtml .= ''; + + echo "$topcathtml$cathtml$itemhtml
"; + + } } ?> -- 2.39.5