diff --git a/grade/lib.php b/grade/lib.php index ca85582f943..f968fd5974e 100644 --- a/grade/lib.php +++ b/grade/lib.php @@ -347,10 +347,9 @@ class grade_tree { * @param int $courseid * @param boolean $fillers include fillers and colspans, make the levels var "rectangular" * @param boolean $category_grade_last category grade item is the last child - * @param boolean $aggregation_view Either full view (0) or compact view (1) + * @param array $collapsed array of collapsed categories */ - function grade_tree($courseid, $fillers=true, $category_grade_last=false, - $aggregation_view=GRADE_REPORT_AGGREGATION_VIEW_FULL) { + function grade_tree($courseid, $fillers=true, $category_grade_last=false, $collapsed=null) { global $USER, $CFG; $this->courseid = $courseid; @@ -361,6 +360,12 @@ class grade_tree { // get course grade tree $this->top_element = grade_category::fetch_course_tree($courseid, true); + // collapse the categories if requested + if (!empty($collapsed)) { + grade_tree::category_collapse($this->top_element, $collapsed); + } + + // move category item to last position in category if ($category_grade_last) { grade_tree::category_grade_last($this->top_element); } @@ -375,6 +380,31 @@ class grade_tree { grade_tree::fill_levels($this->levels, $this->top_element, 0); } + /** + * Static recursive helper - removes items from collapsed categories + * @static + * @param array $element The seed of the recursion + * @param array $collapsed array of collapsed categories + * @return void + */ + function category_collapse(&$element, $collapsed) { + if ($element['type'] != 'category') { + return; + } + if (empty($element['children']) or count($element['children']) < 2) { + return; + } + + if (in_array($element['object']->id, $collapsed)) { + $category_item = reset($element['children']); //keep only category item + $element['children'] = array(key($element['children'])=>$category_item); + + } else { + foreach ($element['children'] as $sortorder=>$child) { + grade_tree::category_collapse($element['children'][$sortorder], $collapsed); + } + } + } /** * Static recursive helper - makes the grade_item for category the last children diff --git a/grade/report/grader/lib.php b/grade/report/grader/lib.php index 1e106835ee2..8f9ce4fe29f 100644 --- a/grade/report/grader/lib.php +++ b/grade/report/grader/lib.php @@ -51,6 +51,12 @@ class grade_report_grader extends grade_report { */ var $userselect; + /** + * List of collapsed captegories from user perference + * @var array $collapsed + */ + var $collapsed; + /** * Constructor. Sets local copies of user preferences and initialises grade_tree. * @param int $courseid @@ -63,6 +69,20 @@ class grade_report_grader extends grade_report { global $CFG; parent::grade_report($courseid, $gpr, $context, $page); + // load collapsed settings for this report + if ($collapsed = get_user_preferences('grade_report_grader_collapsed_categories')) { + $this->collapsed = unserialize($collapsed); + foreach ($this->collapsed as $key=>$id) { + if ($this->get_pref('aggregationview', $id) == GRADE_REPORT_AGGREGATION_VIEW_FULL) { + unset($this->collapsed[$key]); // full view categories can not be collapsed + } + } + } else { + $this->collapsed = array(); + } + // Grab the grade_tree for this course + $this->gtree = new grade_tree($this->courseid, true, $this->get_pref('aggregationposition'), $this->collapsed); + $this->sortitemid = $sortitemid; // base url for sorting by first/last name @@ -434,8 +454,9 @@ class grade_report_grader extends grade_report { $headerhtml .= ' '; } // Element is a category - else if ($type == 'category' && !in_array($eid, $columns_to_unset)) { + else if ($type == 'category') { $headerhtml .= ''.$element['object']->get_name(); + $headerhtml .= $this->get_collapsing_icon($element); // Print icons if ($USER->gradeediting[$this->courseid]) { @@ -445,7 +466,7 @@ class grade_report_grader extends grade_report { $headerhtml .= ''; } // Element is a grade_item - elseif (!in_array($eid, $columns_to_unset)) { + else { if ($element['object']->id == $this->sortitemid) { if ($this->sortorder == 'ASC') { $arrow = print_arrow('up', $strsortasc, true); @@ -879,7 +900,6 @@ class grade_report_grader extends grade_report { $edit_icon = $this->gtree->get_edit_icon($element, $this->gpr); $edit_calculation_icon = ''; $show_hide_icon = ''; - $contract_expand_icon = ''; $lock_unlock_icon = ''; if ($this->get_pref('showcalculations')) { @@ -894,6 +914,18 @@ class grade_report_grader extends grade_report { $lock_unlock_icon = $this->gtree->get_locking_icon($element, $this->gpr); } + return '
'.$edit_icon.$edit_calculation_icon.$show_hide_icon.$lock_unlock_icon.'
'; + } + + /** + * Given a category element returns collapsing +/- icon if available + * @param object $object + * @return string HTML + */ + function get_collapsing_icon($element) { + global $CFG; + + $contract_expand_icon = ''; // If object is a category, display expand/contract icon if ($element['type'] == 'category' && $this->get_pref('aggregationview', $element['object']->id) == GRADE_REPORT_AGGREGATION_VIEW_COMPACT) { // Load language strings @@ -901,18 +933,14 @@ class grade_report_grader extends grade_report { $strswitch_plus = $this->get_lang_string('expand', 'grades'); $expand_contract = 'switch_minus'; // Default: expanded - $state = get_user_preferences('grade_report_categorystate' . $element['object']->id, GRADE_CATEGORY_EXPANDED); - - if ($state == GRADE_CATEGORY_CONTRACTED) { + if (in_array($element['object']->id, $this->collapsed)) { $expand_contract = 'switch_plus'; } - $contract_expand_icon = 'gtree->commonvars . "\">\n" - . ''
-                              . ${'str' . $expand_contract}.''. "\n"; + $url = $this->gpr->get_return_url(null, array('target'=>$element['eid'], 'action'=>$expand_contract, 'sesskey'=>sesskey())); + $contract_expand_icon = ''
+                                    .${'str'.$expand_contract}.''; } - - return '
'.$edit_icon.$edit_calculation_icon.$show_hide_icon.$lock_unlock_icon.$contract_expand_icon.'
'; + return $contract_expand_icon; } /** @@ -922,15 +950,33 @@ class grade_report_grader extends grade_report { * @return */ function process_action($target, $action) { + // TODO: this code should be in some grade_tree static method $targettype = substr($target, 0, 1); $targetid = substr($target, 1); + // TODO: end + + if ($collapsed = get_user_preferences('grade_report_grader_collapsed_categories')) { + $collapsed = unserialize($collapsed); + } else { + $collapsed = array(); + } + switch ($action) { case 'switch_minus': - set_user_preference('grade_report_categorystate' . $targetid, GRADE_CATEGORY_CONTRACTED); + if (!in_array($targetid, $collapsed)) { + $collapsed[] = $targetid; + set_user_preference('grade_report_grader_collapsed_categories', serialize($collapsed)); + } break; + case 'switch_plus': - set_user_preference('grade_report_categorystate' . $targetid, GRADE_CATEGORY_EXPANDED); + $key = array_search($targetid, $collapsed); + if ($key !== false) { + unset($collapsed[$key]); + set_user_preference('grade_report_grader_collapsed_categories', serialize($collapsed)); + } break; + default: break; } diff --git a/grade/report/lib.php b/grade/report/lib.php index 171e7aef35d..5b95cdea7af 100755 --- a/grade/report/lib.php +++ b/grade/report/lib.php @@ -106,17 +106,15 @@ class grade_report { function grade_report($courseid, $gpr, $context, $page=null) { global $CFG; - $this->courseid = $courseid; - $this->gpr = $gpr; - $this->context = $context; - $this->page = $page; + $this->courseid = $courseid; + $this->gpr = $gpr; + $this->context = $context; + $this->page = $page; // roles to be displayed in the gradebook $this->gradebookroles = $CFG->gradebookroles; - // Grab the grade_tree for this course - $this->gtree = new grade_tree($this->courseid, true, $this->get_pref('aggregationposition')); - + // init gtree in child class } /** diff --git a/grade/report/user/lib.php b/grade/report/user/lib.php index 20051681ec6..88d7a2600ed 100644 --- a/grade/report/user/lib.php +++ b/grade/report/user/lib.php @@ -37,6 +37,9 @@ class grade_report_user extends grade_report { global $CFG; parent::grade_report($courseid, $gpr, $context); + // Grab the grade_tree for this course + $this->gtree = new grade_tree($this->courseid, true, $this->get_pref('aggregationposition')); + // get the user (for full name) $this->user = get_record('user', 'id', $userid); diff --git a/lib/grade/grade_category.php b/lib/grade/grade_category.php index 6eac93f4faa..6f4a5128515 100644 --- a/lib/grade/grade_category.php +++ b/lib/grade/grade_category.php @@ -628,41 +628,14 @@ class grade_category extends grade_object { */ function fetch_course_tree($courseid, $include_category_items=false) { $course_category = grade_category::fetch_course_category($courseid); - $categorystate = grade_category::get_categorystate($course_category); - if ($categorystate == GRADE_CATEGORY_EXPANDED) { - $include_category_items = false; - } - - $category_array = array('object'=>$course_category, - 'type'=>'category', - 'depth'=>1, - 'categorystate' => $categorystate, + $category_array = array('object'=>$course_category, 'type'=>'category', 'depth'=>1, 'children'=>$course_category->get_children($include_category_items)); - $sortorder = 1; $course_category->set_sortorder($sortorder); $course_category->sortorder = $sortorder; return grade_category::_fetch_course_tree_recursion($category_array, $sortorder); } - /** - * Checks the user preferences and returns the state of the category, for display purposes. This only - * applies when aggregationview is set to COMPACT. - * @param object $category_element - * @return int null, GRADE_CATEGORY_EXPANDED or GRADE_CATEGORY_CONTRACTED - */ - function get_categorystate($category_element) { - global $CFG; - require_once($CFG->dirroot . '/grade/report/lib.php'); - $aggregationview = grade_report::get_pref('aggregationview', $category_element->id); - - $categorystate = null; - if ($aggregationview == GRADE_REPORT_AGGREGATION_VIEW_COMPACT) { - $categorystate = get_user_preferences('grade_report_categorystate' . $category_element->id, GRADE_CATEGORY_EXPANDED); - } - return $categorystate; - } - function _fetch_course_tree_recursion($category_array, &$sortorder) { // update the sortorder in db if needed if ($category_array['object']->sortorder != $sortorder) { @@ -769,28 +742,17 @@ class grade_category extends grade_object { function _get_children_recursion($category) { $children_array = array(); - $categorystate = grade_category::get_categorystate($category); - foreach($category->children as $sortorder=>$child) { if (array_key_exists('itemtype', $child)) { $grade_item = new grade_item($child, false); - if (in_array($grade_item->itemtype, array('course', 'category'))) { // Child is a course or categoryitem - if ($categorystate == GRADE_CATEGORY_EXPANDED) { - continue; - } else { - $type = $grade_item->itemtype.'item'; - $depth = $category->depth; - } + if (in_array($grade_item->itemtype, array('course', 'category'))) { + $type = $grade_item->itemtype.'item'; + $depth = $category->depth; } else { - if ($categorystate == GRADE_CATEGORY_CONTRACTED) { - continue; - } $type = 'item'; $depth = $category->depth; // we use this to set the same colour } - $children_array[$sortorder] = array('object'=>$grade_item, - 'type'=>$type, - 'depth'=>$depth); + $children_array[$sortorder] = array('object'=>$grade_item, 'type'=>$type, 'depth'=>$depth); } else { $children = grade_category::_get_children_recursion($child); @@ -798,11 +760,7 @@ class grade_category extends grade_object { if (empty($children)) { $children = array(); } - $children_array[$sortorder] = array('object'=>$grade_category, - 'type'=>'category', - 'depth'=>$grade_category->depth, - 'categorystate' => $categorystate, - 'children'=>$children); + $children_array[$sortorder] = array('object'=>$grade_category, 'type'=>'category', 'depth'=>$grade_category->depth, 'children'=>$children); } } diff --git a/lib/gradelib.php b/lib/gradelib.php index 68599109f80..b5d9ae1dc08 100644 --- a/lib/gradelib.php +++ b/lib/gradelib.php @@ -66,10 +66,6 @@ define('GRADE_HISTORY_INSERT', 1); define('GRADE_HISTORY_UPDATE', 2); define('GRADE_HISTORY_DELETE', 3); -// Grader reports -define('GRADE_CATEGORY_CONTRACTED', 0); // The state of a category header in the grader report -define('GRADE_CATEGORY_EXPANDED', 1); // The state of a category header in the grader report - define('GRADE_REPORT_AGGREGATION_POSITION_LEFT', 0); define('GRADE_REPORT_AGGREGATION_POSITION_RIGHT', 1); define('GRADE_REPORT_AGGREGATION_VIEW_FULL', 0);