From: nicolasconnault Date: Wed, 16 May 2007 02:47:56 +0000 (+0000) Subject: MDL-9506 grade_category::display_grades() and grade_category::get_tree() correctly... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=0dfe77317ad5d03907de2dac6517a90b17b1b8e9;p=moodle.git MDL-9506 grade_category::display_grades() and grade_category::get_tree() correctly built the headers for a HTML table of grades, with two layers of categories and one layer of grade_items. Empty filler cells are used when a 1st or 2nd level category doesn't exist for a grade_item. --- diff --git a/lib/grade/grade_category.php b/lib/grade/grade_category.php index 317d71c69f..b85aae526f 100644 --- a/lib/grade/grade_category.php +++ b/lib/grade/grade_category.php @@ -664,11 +664,11 @@ class grade_category extends grade_object { $category_table = $CFG->prefix . 'grade_categories'; $items_table = $CFG->prefix . 'grade_items'; - $constraint = ''; + $catconstraint = ''; $itemconstraint = ''; if (!empty($courseid)) { - $constraint = " AND $category_table.courseid = $courseid "; + $catconstraint = " AND $category_table.courseid = $courseid "; $itemconstraint = " AND $items_table.courseid = $courseid "; } @@ -686,25 +686,34 @@ class grade_category extends grade_object { } } - // Get all top categories first + // Get all top categories $query = "SELECT $category_table.*, sortorder FROM $category_table, $items_table - WHERE iteminstance = $category_table.id AND depth = 1 $constraint ORDER BY sortorder"; + WHERE iteminstance = $category_table.id $catconstraint ORDER BY sortorder"; $topcats = get_records_sql($query); if (empty($topcats)) { return null; } - + + // If any of these categories has grade_items as children, create a topcategory filler with colspan=count(children) + foreach ($topcats as $topcatid => $topcat) { + $topcatobject = new grade_category($topcat, false); + if ($topcatobject->get_childrentype() == 'grade_item' && empty($topcatobject->parent)) { + $topcatobject->childrencount = $topcatobject->has_children(); + $fillers[$topcat->sortorder] = $topcatobject; + unset($topcats[$topcatid]); + } + } + 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); + $object = current($fillers); unset($fillers[$sortorder]); - $tree[] = array('object' => 'filler', 'children' => - array(0 => array('object' => 'filler', 'children' => - array(0 => array('object' => $itemtoinsert, 'finalgrades' => null))))); + + $tree[] = $this->get_filler($object, $fullobjects); } $query = "SELECT $category_table.* FROM $category_table, $items_table @@ -756,19 +765,112 @@ class grade_category extends grade_object { $tree[] = array('object' => $topcat, 'children' => $subcattree); } - // If there are still grade_items, outside of categories, add another filler + // If there are still grade_items or grade_categories without a top category, 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))))); - + foreach ($fillers as $sortorder => $object) { + $tree[] = grade_category::get_filler($object, $fullobjects); } } - + $db->debug = false; return $tree; } + + /** + * Returns a hierarchical array, prefilled with the values needed to populate + * the tree of grade_items in the cases where a grade_item or grade_category doesn't have a + * 2nd level topcategory. + * @param object $object A grade_item or a grade_category object + * @param boolean $fullobjects Whether to instantiate full objects or just return stdClass objects + * @return array + */ + function get_filler($object, $fullobjects=true) { + $filler_array = array(); + + // Depending on whether the filler is for a grade_item or a category... + if (isset($object->itemname)) { + $filler_array = array('object' => 'filler', 'children' => + array(0 => array('object' => 'filler', 'children' => + array(0 => array('object' => $object, 'finalgrades' => null))))); + } else { + $subcat_children = $object->get_children(0, 'flat'); + $children_for_tree = array(); + foreach ($subcat_children as $itemid => $item) { + 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); + } + $children_for_tree[$itemid] = array('object' => $item, 'finalgrades' => $finals); + } + + $filler_array = array('object' => 'filler', 'colspan' => $object->childrencount, 'children' => + array(0 => array('object' => $object, 'children' => $children_for_tree))); + } + + return $filler_array; + } + + /** + * Returns a HTML table with all the grades in the course requested, or all the grades in the site. + * IMPORTANT: This method (and its associated methods) assumes that we are using only 2 levels of categories (topcat and subcat) + * @todo Return extra column for students + * @todo Return a row of final grades for each student + * @todo Return icons + * @todo Return totals + * @todo Return row below headers for grading range + * @param int $courseid + * @return string HTML table + */ + function display_grades($courseid=null) { + // 1. Fetch all top-level categories for this course, with all children preloaded, sorted by sortorder + $tree = grade_category::get_tree($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') { + $colspan = null; + if (!empty($topcat['colspan'])) { + $colspan = 'colspan="' . $topcat['colspan'] . '" '; + } + $topcathtml .= ' '; + } else { + $topcathtml .= '' . $topcat['object']->fullname . ''; + } + + } + + $itemhtml .= ''; + $cathtml .= ''; + $topcathtml .= ''; + + return "$topcathtml$cathtml$itemhtml
"; + + } + } ?> diff --git a/lib/simpletest/grade/simpletest/testgradecategory.php b/lib/simpletest/grade/simpletest/testgradecategory.php index 1e050dcfad..a4ecd93e87 100755 --- a/lib/simpletest/grade/simpletest/testgradecategory.php +++ b/lib/simpletest/grade/simpletest/testgradecategory.php @@ -217,5 +217,15 @@ class grade_category_test extends gradelib_test { $raw_grade->insert(); return $raw_grade->gradevalue; } + + function test_grade_category_display_grades() { + $result_html = grade_category::display_grades(); + $expected_html = '
unittestcategory1  
unittestcategory2unittestcategory3 level1category
unittestgradeitem1unittestgradeitem2unittestgradeitem3unittestorphangradeitem1singleparentitem1singleparentitem2
'; + $this->assertEqual($expected_html, $result_html); + } + + function test_grade_category_build_tree() { + + } } ?> diff --git a/lib/simpletest/testgradelib.php b/lib/simpletest/testgradelib.php index 7943cef99a..a348105f96 100644 --- a/lib/simpletest/testgradelib.php +++ b/lib/simpletest/testgradelib.php @@ -604,7 +604,7 @@ class gradelib_test extends UnitTestCase { $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->itemname = 'singleparentitem1'; $grade_item->itemtype = 'mod'; $grade_item->itemmodule = 'forum'; $grade_item->iteminstance = 3; @@ -626,7 +626,7 @@ class gradelib_test extends UnitTestCase { $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->itemname = 'singleparentitem2'; $grade_item->itemtype = 'mod'; $grade_item->itemmodule = 'forum'; $grade_item->iteminstance = 3; @@ -650,7 +650,7 @@ class gradelib_test extends UnitTestCase { $grade_item->itemname = 'grade_item for level1 category'; $grade_item->itemtype = 'category'; $grade_item->itemmodule = 'quiz'; - $grade_item->iteminstance = 1; + $grade_item->iteminstance = $this->grade_categories[3]->id; $grade_item->needsupdate = true; $grade_item->gradetype = GRADE_TYPE_VALUE; $grade_item->grademin = 10; @@ -1372,52 +1372,6 @@ class gradelib_test extends UnitTestCase { $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
"; - - } } ?>