Skip to content

Commit

Permalink
MDL-9506 Refactored some of the category methods into grade_tree, sam…
Browse files Browse the repository at this point in the history
…e for unit tests.
  • Loading branch information
nicolasconnault committed May 17, 2007
1 parent 6c146b7 commit 8ff4550
Show file tree
Hide file tree
Showing 5 changed files with 303 additions and 267 deletions.
236 changes: 1 addition & 235 deletions lib/grade/grade_category.php
Original file line number Diff line number Diff line change
Expand Up @@ -647,240 +647,6 @@ function load_parent_category() {
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.
* @static
* @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';

$catconstraint = '';
$itemconstraint = '';

if (!empty($courseid)) {
$catconstraint = " 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
$query = "SELECT $category_table.*, sortorder FROM $category_table, $items_table
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);
$object = current($fillers);
unset($fillers[$sortorder]);

$tree[] = $this->get_filler($object, $fullobjects);
}

$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 or grade_categories without a top category, add another filler
if (!empty($fillers)) {
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.
* @static
* @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)) {
if (get_class($object) == 'grade_item') {
$finals = $object->load_final();
} else {
$item_object = new grade_item($object, false);
$finals = $object->load_final();
}

$filler_array = array('object' => 'filler', 'children' =>
array(0 => array('object' => 'filler', 'children' =>
array(0 => array('object' => $object, 'finalgrades' => $finals)))));
} else {
$subcat_children = $object->get_children(0, 'flat');
$children_for_tree = array();
foreach ($subcat_children as $itemid => $item) {
if (get_class($item) == 'grade_item') {
$finals = $item->load_final();
} else {
$item_object = new grade_item($item, false);
$finals = $item->load_final();
}

$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
* @static
* @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 = '<tr>';
$cathtml = '<tr>';
$itemhtml = '<tr>';

foreach ($tree as $topcat) {
$itemcount = 0;

foreach ($topcat['children'] as $catkey => $cat) {
$catitemcount = 0;

foreach ($cat['children'] as $item) {
$itemcount++;
$catitemcount++;
$itemhtml .= '<td>' . $item['object']->itemname . '</td>';
}

if ($cat['object'] == 'filler') {
$cathtml .= '<td class="subfiller">&nbsp;</td>';
} else {
$cat['object']->load_grade_item();
$cathtml .= '<td colspan="' . $catitemcount . '">' . $cat['object']->fullname . '</td>';
}
}

if ($topcat['object'] == 'filler') {
$colspan = null;
if (!empty($topcat['colspan'])) {
$colspan = 'colspan="' . $topcat['colspan'] . '" ';
}
$topcathtml .= '<td ' . $colspan . 'class="topfiller">&nbsp;</td>';
} else {
$topcathtml .= '<th colspan="' . $itemcount . '">' . $topcat['object']->fullname . '</th>';
}

}

$itemhtml .= '</tr>';
$cathtml .= '</tr>';
$topcathtml .= '</tr>';

return "<table style=\"text-align: center\" border=\"1\">$topcathtml$cathtml$itemhtml</table>";

}

}

}
?>
Loading

0 comments on commit 8ff4550

Please sign in to comment.