private function fill_table_recursive(&$element) { global $DB, $CFG; $type = $element['type']; $depth = $element['depth']; $grade_object = $element['object']; $eid = $grade_object->id; $element['userid'] = $this->user->id; $fullname = $this->gtree->get_element_header($element, true, true, true); $data = array(); $hidden = ''; $excluded = ''; $class = ''; $classfeedback = ''; // If this is a hidden grade category, hide it completely from the user if ($type == 'category' && $grade_object->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_object->is_hiddenuntil())) { return false; } if ($type == 'category') { $this->evenodd[$depth] = ($this->evenodd[$depth] + 1) % 2; } $alter = $this->evenodd[$depth] == 0 ? 'even' : 'odd'; /// Process those items that have scores associated if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem') { $header_row = "row_{$eid}_{$this->user->id}"; $header_cat = "cat_{$grade_object->categoryid}_{$this->user->id}"; if (!($grade_grade = grade_grade::fetch(array('itemid' => $grade_object->id, 'userid' => $this->user->id)))) { $grade_grade = new grade_grade(); $grade_grade->userid = $this->user->id; $grade_grade->itemid = $grade_object->id; } $grade_grade->load_grade_item(); /// Hidden Items if ($grade_grade->grade_item->is_hidden()) { $hidden = ' dimmed_text'; } $hide = false; // If this is a hidden grade item, hide it completely from the user. if ($grade_grade->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_grade->is_hiddenuntil())) { $hide = true; } else { if (!empty($grade_object->itemmodule) && !empty($grade_object->iteminstance)) { // The grade object can be marked visible but still be hidden if // the student cannot see the activity due to conditional access // and it's set to be hidden entirely. $instances = $this->modinfo->get_instances_of($grade_object->itemmodule); if (!empty($instances[$grade_object->iteminstance])) { $cm = $instances[$grade_object->iteminstance]; if (!$cm->uservisible) { // If there is 'availableinfo' text then it is only greyed // out and not entirely hidden. if (!$cm->availableinfo) { $hide = true; } } } } } if (!$hide) { /// Excluded Item if ($grade_grade->is_excluded()) { $fullname .= ' [' . get_string('excluded', 'grades') . ']'; $excluded = ' excluded'; } /// Other class information $class = "{$hidden} {$excluded}"; if ($this->switch) { // alter style based on whether aggregation is first or last $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggt b2b" : " item b1b"; } else { $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggb" : " item b1b"; } if ($type == 'categoryitem' or $type == 'courseitem') { $header_cat = "cat_{$grade_object->iteminstance}_{$this->user->id}"; } /// Name $data['itemname']['content'] = $fullname; $data['itemname']['class'] = $class; $data['itemname']['colspan'] = $this->maxdepth - $depth; $data['itemname']['celltype'] = 'th'; $data['itemname']['id'] = $header_row; /// Actual Grade $gradeval = $grade_grade->finalgrade; if (!$this->canviewhidden) { /// Virtual Grade (may be calculated excluding hidden items etc). $adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($this->courseid, $grade_grade->grade_item, $gradeval); $gradeval = $adjustedgrade['grade']; // We temporarily adjust the view of this grade item - because the min and // max are affected by the hidden values in the aggregation. $grade_grade->grade_item->grademax = $adjustedgrade['grademax']; $grade_grade->grade_item->grademin = $adjustedgrade['grademin']; } if ($this->showfeedback) { // Copy $class before appending itemcenter as feedback should not be centered $classfeedback = $class; } $class .= " itemcenter "; if ($this->showweight) { $data['weight']['class'] = $class; $data['weight']['content'] = '-'; $data['weight']['headers'] = "{$header_cat} {$header_row} weight"; // has a weight assigned, might be extra credit if ($grade_object->aggregationcoef > 0 && $type != 'courseitem') { $data['weight']['content'] = number_format($grade_object->aggregationcoef, 2); } } if ($this->showgrade) { if ($grade_grade->grade_item->needsupdate) { $data['grade']['class'] = $class . ' gradingerror'; $data['grade']['content'] = get_string('error'); } else { if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden() and !$grade_grade->grade_item->is_category_item() and !$grade_grade->grade_item->is_course_item()) { // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records $class .= ' datesubmitted'; $data['grade']['class'] = $class; $data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort'))); } else { if ($grade_grade->is_hidden()) { $data['grade']['class'] = $class . ' dimmed_text'; $data['grade']['content'] = '-'; if ($this->canviewhidden) { $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true); } } else { $data['grade']['class'] = $class; $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true); } } } $data['grade']['headers'] = "{$header_cat} {$header_row} grade"; } // Range if ($this->showrange) { $data['range']['class'] = $class; $data['range']['content'] = $grade_grade->grade_item->get_formatted_range(GRADE_DISPLAY_TYPE_REAL, $this->rangedecimals); $data['range']['headers'] = "{$header_cat} {$header_row} range"; } // Percentage if ($this->showpercentage) { if ($grade_grade->grade_item->needsupdate) { $data['percentage']['class'] = $class . ' gradingerror'; $data['percentage']['content'] = get_string('error'); } else { if ($grade_grade->is_hidden()) { $data['percentage']['class'] = $class . ' dimmed_text'; $data['percentage']['content'] = '-'; if ($this->canviewhidden) { $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE); } } else { $data['percentage']['class'] = $class; $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE); } } $data['percentage']['headers'] = "{$header_cat} {$header_row} percentage"; } // Lettergrade if ($this->showlettergrade) { if ($grade_grade->grade_item->needsupdate) { $data['lettergrade']['class'] = $class . ' gradingerror'; $data['lettergrade']['content'] = get_string('error'); } else { if ($grade_grade->is_hidden()) { $data['lettergrade']['class'] = $class . ' dimmed_text'; if (!$this->canviewhidden) { $data['lettergrade']['content'] = '-'; } else { $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER); } } else { $data['lettergrade']['class'] = $class; $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER); } } $data['lettergrade']['headers'] = "{$header_cat} {$header_row} lettergrade"; } // Rank if ($this->showrank) { if ($grade_grade->grade_item->needsupdate) { $data['rank']['class'] = $class . ' gradingerror'; $data['rank']['content'] = get_string('error'); } elseif ($grade_grade->is_hidden()) { $data['rank']['class'] = $class . ' dimmed_text'; $data['rank']['content'] = '-'; } else { if (is_null($gradeval)) { // no grade, no rank $data['rank']['class'] = $class; $data['rank']['content'] = '-'; } else { /// find the number of users with a higher grade $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {grade_grades}\n WHERE finalgrade > ?\n AND itemid = ?\n AND hidden = 0"; $rank = $DB->count_records_sql($sql, array($grade_grade->finalgrade, $grade_grade->grade_item->id)) + 1; $data['rank']['class'] = $class; $data['rank']['content'] = "{$rank}/" . $this->get_numusers(false); // total course users } } $data['rank']['headers'] = "{$header_cat} {$header_row} rank"; } // Average if ($this->showaverage) { $data['average']['class'] = $class; if (!empty($this->gtree->items[$eid]->avg)) { $data['average']['content'] = $this->gtree->items[$eid]->avg; } else { $data['average']['content'] = '-'; } $data['average']['headers'] = "{$header_cat} {$header_row} average"; } // Feedback if ($this->showfeedback) { if ($grade_grade->overridden > 0 and ($type == 'categoryitem' or $type == 'courseitem')) { $data['feedback']['class'] = $classfeedback . ' feedbacktext'; $data['feedback']['content'] = get_string('overridden', 'grades') . ': ' . format_text($grade_grade->feedback, $grade_grade->feedbackformat); } else { if (empty($grade_grade->feedback) or !$this->canviewhidden and $grade_grade->is_hidden()) { $data['feedback']['class'] = $classfeedback . ' feedbacktext'; $data['feedback']['content'] = ' '; } else { $data['feedback']['class'] = $classfeedback . ' feedbacktext'; $data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat); } } $data['feedback']['headers'] = "{$header_cat} {$header_row} feedback"; } } } /// Category if ($type == 'category') { $data['leader']['class'] = $class . ' ' . $alter . "d{$depth} b1t b2b b1l"; $data['leader']['rowspan'] = $element['rowspan']; if ($this->switch) { // alter style based on whether aggregation is first or last $data['itemname']['class'] = $class . ' ' . $alter . "d{$depth} b1b b1t"; } else { $data['itemname']['class'] = $class . ' ' . $alter . "d{$depth} b2t"; } $data['itemname']['colspan'] = $this->maxdepth - $depth + count($this->tablecolumns) - 1; $data['itemname']['content'] = $fullname; $data['itemname']['celltype'] = 'th'; $data['itemname']['id'] = "cat_{$grade_object->id}_{$this->user->id}"; } /// Add this row to the overall system $this->tabledata[] = $data; /// Recursively iterate through all child elements if (isset($element['children'])) { foreach ($element['children'] as $key => $child) { $this->fill_table_recursive($element['children'][$key]); } } }
/** * Recursive function for building the table holding the grade categories and items, * with CSS indentation and styles. * * @param array $element The current tree element being rendered * @param boolean $totals Whether or not to print category grade items (category totals) * @param array $parents An array of parent categories for the current element (used for indentation and row classes) * * @return string HTML */ public function build_html_tree($element, $totals, $parents, $level, &$row_count) { global $CFG, $COURSE, $PAGE, $OUTPUT; $object = $element['object']; $eid = $element['eid']; $object->name = $this->gtree->get_element_header($element, true, true, true, true, true); $object->stripped_name = $this->gtree->get_element_header($element, false, false, false); $is_category_item = false; if ($element['type'] == 'categoryitem' || $element['type'] == 'courseitem') { $is_category_item = true; } $rowclasses = array(); foreach ($parents as $parent_eid) { $rowclasses[] = $parent_eid; } $moveaction = ''; $actionsmenu = new action_menu(); $actionsmenu->set_menu_trigger(get_string('edit')); $actionsmenu->set_owner_selector('grade-item-' . $eid); $actionsmenu->set_alignment(action_menu::TL, action_menu::BL); if (!$is_category_item && ($icon = $this->gtree->get_edit_icon($element, $this->gpr, true))) { $actionsmenu->add($icon); } // MDL-49281 if grade_item already has calculation, it should be editable even if global setting is off. $type = $element['type']; $iscalculated = ($type == 'item' or $type == 'courseitem' or $type == 'categoryitem') && $object->is_calculated(); $icon = $this->gtree->get_calculation_icon($element, $this->gpr, true); if ($iscalculated || $this->show_calculations && $icon) { $actionsmenu->add($icon); } if ($element['type'] == 'item' or $element['type'] == 'category' and $element['depth'] > 1) { if ($this->element_deletable($element)) { $aurl = new moodle_url('index.php', array('id' => $COURSE->id, 'action' => 'delete', 'eid' => $eid, 'sesskey' => sesskey())); $icon = new action_menu_link_secondary($aurl, new pix_icon('t/delete', get_string('delete')), get_string('delete')); $actionsmenu->add($icon); } $aurl = new moodle_url('index.php', array('id' => $COURSE->id, 'action' => 'moveselect', 'eid' => $eid, 'sesskey' => sesskey())); $moveaction .= $OUTPUT->action_icon($aurl, new pix_icon('t/move', get_string('move'))); } if ($icon = $this->gtree->get_hiding_icon($element, $this->gpr, true)) { $actionsmenu->add($icon); } if ($icon = $this->gtree->get_reset_icon($element, $this->gpr, true)) { $actionsmenu->add($icon); } $actions = $OUTPUT->render($actionsmenu); $returnrows = array(); $root = false; $id = required_param('id', PARAM_INT); /// prepare move target if needed $last = ''; /// print the list items now if ($this->moving == $eid) { // do not diplay children $cell = new html_table_cell(); $cell->colspan = 12; $cell->attributes['class'] = $element['type'] . ' moving column-name level' . ($level + 1) . ' level' . ($level % 2 ? 'even' : 'odd'); $cell->text = $object->name . ' (' . get_string('move') . ')'; return array(new html_table_row(array($cell))); } if ($element['type'] == 'category') { $level++; $this->categories[$object->id] = $object->stripped_name; $category = grade_category::fetch(array('id' => $object->id)); $item = $category->get_grade_item(); // Add aggregation coef input if not a course item and if parent category has correct aggregation type $dimmed = $item->is_hidden() ? 'dimmed_text' : ''; // Before we print the category's row, we must find out how many rows will appear below it (for the filler cell's rowspan) $aggregation_position = grade_get_setting($COURSE->id, 'aggregationposition', $CFG->grade_aggregationposition); $category_total_data = null; // Used if aggregationposition is set to "last", so we can print it last $html_children = array(); $row_count = 0; foreach ($element['children'] as $child_el) { $moveto = null; if (empty($child_el['object']->itemtype)) { $child_el['object']->itemtype = false; } if (($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') && !$totals) { continue; } $child_eid = $child_el['eid']; $first = ''; if ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') { $first = array('first' => 1); $child_eid = $eid; } if ($this->moving && $this->moving != $child_eid) { $strmove = get_string('move'); $strmovehere = get_string('movehere'); $actions = $moveaction = ''; // no action icons when moving $aurl = new moodle_url('index.php', array('id' => $COURSE->id, 'action' => 'move', 'eid' => $this->moving, 'moveafter' => $child_eid, 'sesskey' => sesskey())); if ($first) { $aurl->params($first); } $cell = new html_table_cell(); $cell->colspan = 12; $cell->attributes['class'] = 'movehere level' . ($level + 1) . ' level' . ($level % 2 ? 'even' : 'odd'); $icon = new pix_icon('movehere', $strmovehere, null, array('class' => 'movetarget')); $cell->text = $OUTPUT->action_icon($aurl, $icon); $moveto = new html_table_row(array($cell)); } $newparents = $parents; $newparents[] = $eid; $row_count++; $child_row_count = 0; // If moving, do not print course and category totals, but still print the moveto target box if ($this->moving && ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category')) { $html_children[] = $moveto; } elseif ($child_el['object']->itemtype == 'course' || $child_el['object']->itemtype == 'category') { // We don't build the item yet because we first need to know the deepest level of categories (for category/name colspans) $category_total_item = $this->build_html_tree($child_el, $totals, $newparents, $level, $child_row_count); if (!$aggregation_position) { $html_children = array_merge($html_children, $category_total_item); } } else { $html_children = array_merge($html_children, $this->build_html_tree($child_el, $totals, $newparents, $level, $child_row_count)); if (!empty($moveto)) { $html_children[] = $moveto; } if ($this->moving) { $row_count++; } } $row_count += $child_row_count; // If the child is a category, increment row_count by one more (for the extra coloured row) if ($child_el['type'] == 'category') { $row_count++; } } // Print category total at the end if aggregation position is "last" (1) if (!empty($category_total_item) && $aggregation_position) { $html_children = array_merge($html_children, $category_total_item); } // Determine if we are at the root if (isset($element['object']->grade_item) && $element['object']->grade_item->is_course_item()) { $root = true; } $levelclass = "level{$level} level" . ($level % 2 ? 'odd' : 'even'); $courseclass = ''; if ($level == 1) { $courseclass = 'coursecategory'; } $row = new html_table_row(); $row->id = 'grade-item-' . $eid; $row->attributes['class'] = $courseclass . ' category ' . $dimmed; $row->attributes['data-category'] = $eid; $row->attributes['data-itemid'] = $category->get_grade_item()->id; foreach ($rowclasses as $class) { $row->attributes['class'] .= ' ' . $class; } $headercell = new html_table_cell(); $headercell->header = true; $headercell->scope = 'row'; $headercell->attributes['title'] = $object->stripped_name; $headercell->attributes['class'] = 'cell column-rowspan rowspan ' . $levelclass; $headercell->rowspan = $row_count + 1; $row->cells[] = $headercell; foreach ($this->columns as $column) { if (!($this->moving && $column->hide_when_moving)) { $row->cells[] = $column->get_category_cell($category, $levelclass, ['id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, 'moveaction' => $moveaction, 'eid' => $eid]); } } $returnrows[] = $row; $returnrows = array_merge($returnrows, $html_children); // Print a coloured row to show the end of the category across the table $endcell = new html_table_cell(); $endcell->colspan = 19 - $level; $endcell->attributes['class'] = 'emptyrow colspan ' . $levelclass; $returnrows[] = new html_table_row(array($endcell)); } else { // Dealing with a grade item $item = grade_item::fetch(array('id' => $object->id)); $element['type'] = 'item'; $element['object'] = $item; $categoryitemclass = ''; if ($item->itemtype == 'category') { $categoryitemclass = 'categoryitem'; } if ($item->itemtype == 'course') { $categoryitemclass = 'courseitem'; } $dimmed = $item->is_hidden() ? "dimmed_text" : ""; $gradeitemrow = new html_table_row(); $gradeitemrow->id = 'grade-item-' . $eid; $gradeitemrow->attributes['class'] = $categoryitemclass . ' item ' . $dimmed; $gradeitemrow->attributes['data-itemid'] = $object->id; foreach ($rowclasses as $class) { $gradeitemrow->attributes['class'] .= ' ' . $class; } foreach ($this->columns as $column) { if (!($this->moving && $column->hide_when_moving)) { $gradeitemrow->cells[] = $column->get_item_cell($item, array('id' => $id, 'name' => $object->name, 'level' => $level, 'actions' => $actions, 'element' => $element, 'eid' => $eid, 'moveaction' => $moveaction, 'itemtype' => $object->itemtype)); } } $returnrows[] = $gradeitemrow; } return $returnrows; }
private function fill_table_recursive(&$element) { global $DB, $CFG; $type = $element['type']; $depth = $element['depth']; $grade_object = $element['object']; $eid = $grade_object->id; $element['userid'] = $this->user->id; $fullname = $this->gtree->get_element_header($element, true, true, true); $data = array(); $hidden = ''; $excluded = ''; $class = ''; // If this is a hidden grade category, hide it completely from the user if ($type == 'category' && $grade_object->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_object->is_hiddenuntil())) { return false; } if ($type == 'category') { $this->evenodd[$depth] = ($this->evenodd[$depth] + 1) % 2; } $alter = $this->evenodd[$depth] == 0 ? 'even' : 'odd'; /// Process those items that have scores associated if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem') { if (!($grade_grade = grade_grade::fetch(array('itemid' => $grade_object->id, 'userid' => $this->user->id)))) { $grade_grade = new grade_grade(); $grade_grade->userid = $this->user->id; $grade_grade->itemid = $grade_object->id; } $grade_grade->load_grade_item(); /// Hidden Items if ($grade_grade->grade_item->is_hidden()) { $hidden = ' hidden'; } // If this is a hidden grade item, hide it completely from the user. if ($grade_grade->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_grade->is_hiddenuntil())) { // return false; } else { /// Excluded Item if ($grade_grade->is_excluded()) { $fullname .= ' [' . get_string('excluded', 'grades') . ']'; $excluded = ' excluded'; } /// Other class information $class = "{$hidden} {$excluded}"; if ($this->switch) { // alter style based on whether aggregation is first or last $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggt b2b" : " item b1b"; } else { $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggb" : " item b1b"; } /// Name $data['itemname']['content'] = $fullname; $data['itemname']['class'] = $class; $data['itemname']['colspan'] = $this->maxdepth - $depth; /// Actual Grade $gradeval = $grade_grade->finalgrade; $class .= " itemcenter "; if ($this->showweight) { $data['weight']['class'] = $class; $data['weight']['content'] = '-'; // has a weight assigned, might be extra credit if ($grade_object->aggregationcoef > 0 && $type != 'courseitem') { $data['weight']['content'] = number_format($grade_object->aggregationcoef, 2) . '%'; } } if ($this->showgrade) { if ($grade_grade->grade_item->needsupdate) { $data['grade']['class'] = $class . ' gradingerror'; $data['grade']['content'] = get_string('error'); } else { if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden() and !$grade_grade->grade_item->is_category_item() and !$grade_grade->grade_item->is_course_item()) { // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records $class .= ' datesubmitted'; $data['grade']['class'] = $class; $data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort'))); } elseif ($grade_grade->is_hidden()) { $data['grade']['class'] = $class . ' hidden'; $data['grade']['content'] = '-'; } else { $data['grade']['class'] = $class; $gradeval = $this->blank_hidden_total($this->courseid, $grade_grade->grade_item, $gradeval); $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true); } } } // Range if ($this->showrange) { $data['range']['class'] = $class; $data['range']['content'] = $grade_grade->grade_item->get_formatted_range(GRADE_DISPLAY_TYPE_REAL, $this->rangedecimals); } // Percentage if ($this->showpercentage) { if ($grade_grade->grade_item->needsupdate) { $data['percentage']['class'] = $class . ' gradingerror'; $data['percentage']['content'] = get_string('error'); } else { if ($grade_grade->is_hidden()) { $data['percentage']['class'] = $class . ' hidden'; $data['percentage']['content'] = '-'; } else { $data['percentage']['class'] = $class; $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE); } } } // Lettergrade if ($this->showlettergrade) { if ($grade_grade->grade_item->needsupdate) { $data['lettergrade']['class'] = $class . ' gradingerror'; $data['lettergrade']['content'] = get_string('error'); } else { if ($grade_grade->is_hidden()) { $data['lettergrade']['class'] = $class . ' hidden'; if (!$this->canviewhidden) { $data['lettergrade']['content'] = '-'; } else { $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER); } } else { $data['lettergrade']['class'] = $class; $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER); } } } // Rank if ($this->showrank) { if ($grade_grade->grade_item->needsupdate) { $data['rank']['class'] = $class . ' gradingerror'; $data['rank']['content'] = get_string('error'); } elseif ($grade_grade->is_hidden()) { $data['rank']['class'] = $class . ' hidden'; $data['rank']['content'] = '-'; } else { if (is_null($gradeval)) { // no grade, no rank $data['rank']['class'] = $class; $data['rank']['content'] = '-'; } else { /// find the number of users with a higher grade $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {grade_grades}\n WHERE finalgrade > ?\n AND itemid = ?\n AND hidden = 0"; $rank = $DB->count_records_sql($sql, array($grade_grade->finalgrade, $grade_grade->grade_item->id)) + 1; $data['rank']['class'] = $class; $data['rank']['content'] = "{$rank}/" . $this->get_numusers(false); // total course users } } } // Average if ($this->showaverage) { $data['average']['class'] = $class; if (!empty($this->gtree->items[$eid]->avg)) { $data['average']['content'] = $this->gtree->items[$eid]->avg; } else { $data['average']['content'] = '-'; } } // Feedback if ($this->showfeedback) { if ($grade_grade->overridden > 0 and ($type == 'categoryitem' or $type == 'courseitem')) { $data['feedback']['class'] = $class . ' feedbacktext'; $data['feedback']['content'] = get_string('overridden', 'grades') . ': ' . format_text($grade_grade->feedback, $grade_grade->feedbackformat); } else { if (empty($grade_grade->feedback) or !$this->canviewhidden and $grade_grade->is_hidden()) { $data['feedback']['class'] = $class . ' feedbacktext'; $data['feedback']['content'] = ' '; } else { $data['feedback']['class'] = $class . ' feedbacktext'; $data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat); } } } } } /// Category if ($type == 'category') { $data['leader']['class'] = $class . ' ' . $alter . "d{$depth} b1t b2b b1l"; $data['leader']['rowspan'] = $element['rowspan']; if ($this->switch) { // alter style based on whether aggregation is first or last $data['itemname']['class'] = $class . ' ' . $alter . "d{$depth} b1b b1t"; } else { $data['itemname']['class'] = $class . ' ' . $alter . "d{$depth} b2t"; } $data['itemname']['colspan'] = $this->maxdepth - $depth + count($this->tablecolumns) - 1; $data['itemname']['content'] = $fullname; } /// Add this row to the overall system $this->tabledata[] = $data; /// Recursively iterate through all child elements if (isset($element['children'])) { foreach ($element['children'] as $key => $child) { $this->fill_table_recursive($element['children'][$key]); } } }
private function fill_table_recursive(&$element) { global $DB, $CFG; $type = $element['type']; $depth = $element['depth']; $grade_object = $element['object']; $eid = $grade_object->id; $element['userid'] = $this->user->id; $fullname = $this->gtree->get_element_header($element, true, false, true); $data = array(); $hidden = ''; $excluded = ''; $class = ''; $classfeedback = ''; $row_class = ''; $activity_start_date = ''; // If this is a hidden grade category, hide it completely from the user if ($type == 'category' && $grade_object->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_MARKSHEET_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_MARKSHEET_HIDE_UNTIL && !$grade_object->is_hiddenuntil())) { return false; } if ($type == 'category') { $this->evenodd[$depth] = ($this->evenodd[$depth] + 1) % 2; } $alter = $this->evenodd[$depth] == 0 ? 'even' : 'odd'; if ($type == 'item') { $cat_id = $grade_object->categoryid; } else { $cat_id = ' '; } /// Process those items that have scores associated if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem') { //&& ($depth == 2)) { $header_row = "row_{$eid}_{$this->user->id}"; $header_cat = "cat_{$grade_object->categoryid}_{$this->user->id}"; if (!($grade_grade = grade_grade::fetch(array('itemid' => $grade_object->id, 'userid' => $this->user->id)))) { $grade_grade = new grade_grade(); $grade_grade->userid = $this->user->id; $grade_grade->itemid = $grade_object->id; } $grade_grade->load_grade_item(); $hide = false; // If this is a hidden grade item, hide it completely from the user. if ($grade_grade->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_MARKSHEET_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_MARKSHEET_HIDE_UNTIL && !$grade_grade->is_hiddenuntil())) { $hide = true; } else { if (!empty($grade_object->itemmodule) && !empty($grade_object->iteminstance)) { // The grade object can be marked visible but still be hidden if... // 1) "enablegroupmembersonly" is on and the activity is assigned to a grouping the user is not in. // 2) the student cannot see the activity due to conditional access and its set to be hidden entirely. $instances = $this->gtree->modinfo->get_instances_of($grade_object->itemmodule); if (!empty($instances[$grade_object->iteminstance])) { $cm = $instances[$grade_object->iteminstance]; if (!$cm->uservisible) { // Further checks are required to determine whether the activity is entirely hidden or just greyed out. if ($cm->is_user_access_restricted_by_group() || $cm->is_user_access_restricted_by_conditional_access() || $cm->is_user_access_restricted_by_capability()) { $hide = true; } } } } } if ($grade_grade->grade_item->is_hidden() && !$this->showhiddenactivity) { $hide = true; } //set start dates by category $categoryid = $grade_grade->grade_item->categoryid; if ($type == 'item' && isset($cm)) { $this->grade_category_modids[$categoryid][] = $cm->id; } /// Hidden Items if ($grade_grade->grade_item->is_hidden()) { $hidden = ' hidden'; } if (!$hide) { /// Excluded Item if ($grade_grade->is_excluded()) { $fullname .= ' [' . get_string('excluded', 'grades') . ']'; $excluded = ' excluded'; } if (isset($grade_grade->grade_item->itemmodule)) { $modname = $grade_grade->grade_item->itemmodule; } if (isset($cm)) { $modid = $cm->id; } if ($type == "categoryitem") { // print_r($grade_grade); // $timemodified = $grade_grade->grade_item->timemodified; // $activity_start_date = new DateTime('@'.$timemodified); // print_r($activity_start_date); echo "<br>"; } /// Other class information if (isset($modname) && isset($modid)) { $modaction = "view"; $course = $this->course; $user = $this->user->id; $activity_start_date = get_activity_start_date($course, $user, $modname, $modaction, $modid); } if ($type == 'item') { $categoryid = $grade_grade->grade_item->categoryid; if (!isset($this->grade_category_start_dates[$categoryid])) { $this->grade_category_start_dates[$categoryid] = new DateTime("now"); } if ($activity_start_date < $this->grade_category_start_dates[$categoryid]) { $this->grade_category_start_dates[$categoryid] = $activity_start_date; } } if ($type == 'categoryitem') { $iteminstance = $grade_grade->grade_item->iteminstance; if (isset($iteminstance) && isset($this->grade_category_start_dates)) { $activity_start_date = $this->grade_category_start_dates[$iteminstance]; } } $class = "{$hidden} {$excluded}"; if ($this->switch) { // alter style based on whether aggregation is first or last $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggt b2b" : " item b1b"; } else { $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggb" : " item b1b"; $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " categoryitem " : ""; } if ($type == 'categoryitem' or $type == 'courseitem') { $header_cat = "cat_{$grade_object->iteminstance}_{$this->user->id}"; } /// Name $data['itemname']['content'] = $fullname; $data['itemname']['class'] = $class; $data['itemname']['colspan'] = $this->maxdepth - $depth + 2; $data['itemname']['celltype'] = 'th'; $data['itemname']['id'] = $header_row; /// Actual Grade $gradeval = $grade_grade->finalgrade; if ($this->showfeedback) { // Copy $class before appending itemcenter as feedback should not be centered $classfeedback = $class; } $class .= " itemcenter "; if ($this->showweight) { $data['weight']['class'] = $class; $data['weight']['content'] = '-'; $data['weight']['headers'] = "{$header_cat} {$header_row} weight"; // has a weight assigned, might be extra credit if ($grade_object->aggregationcoef > 0 && $type != 'courseitem') { $data['weight']['content'] = number_format($grade_object->aggregationcoef, 2); } } if ($this->showgrade) { if ($grade_grade->grade_item->needsupdate) { $data['grade']['class'] = $class . ' gradingerror'; $data['grade']['content'] = get_string('error'); } else { if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden() and !$grade_grade->grade_item->is_category_item() and !$grade_grade->grade_item->is_course_item()) { // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records $class .= ' datesubmitted'; $data['grade']['class'] = $class; $data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort'))); } elseif ($grade_grade->is_hidden()) { $data['grade']['class'] = $class . ' hidden'; $data['grade']['content'] = '-'; } else { $data['grade']['class'] = $class; $gradeval = $this->blank_hidden_total($this->courseid, $grade_grade->grade_item, $gradeval); $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true); } } $data['grade']['headers'] = "{$header_cat} {$header_row} grade"; } // Range if ($this->showrange) { $data['range']['class'] = $class; $data['range']['content'] = $grade_grade->grade_item->get_formatted_range(GRADE_DISPLAY_TYPE_REAL, $this->rangedecimals); $data['range']['headers'] = "{$header_cat} {$header_row} range"; } // Percentage if ($this->showpercentage) { if ($grade_grade->grade_item->needsupdate) { $data['percentage']['class'] = $class . ' gradingerror'; $data['percentage']['content'] = get_string('error'); } else { if ($grade_grade->is_hidden()) { $data['percentage']['class'] = $class . ' hidden'; $data['percentage']['content'] = '-'; } else { $data['percentage']['class'] = $class; $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE); } } $data['percentage']['headers'] = "{$header_cat} {$header_row} percentage"; } // Lettergrade if ($this->showlettergrade) { if ($grade_grade->grade_item->needsupdate) { $data['lettergrade']['class'] = $class . ' gradingerror'; $data['lettergrade']['content'] = get_string('error'); } else { if ($grade_grade->is_hidden()) { $data['lettergrade']['class'] = $class . ' hidden'; if (!$this->canviewhidden) { $data['lettergrade']['content'] = '-'; } else { $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER); } } else { $data['lettergrade']['class'] = $class; $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER); } } $data['lettergrade']['headers'] = "{$header_cat} {$header_row} lettergrade"; } // Rank if ($this->showrank) { if ($grade_grade->grade_item->needsupdate) { $data['rank']['class'] = $class . ' gradingerror'; $data['rank']['content'] = get_string('error'); } elseif ($grade_grade->is_hidden()) { $data['rank']['class'] = $class . ' hidden'; $data['rank']['content'] = '-'; } else { if (is_null($gradeval)) { // no grade, no rank $data['rank']['class'] = $class; $data['rank']['content'] = '-'; } else { /// find the number of users with a higher grade $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {grade_grades}\n WHERE finalgrade > ?\n AND itemid = ?\n AND hidden = 0"; $rank = $DB->count_records_sql($sql, array($grade_grade->finalgrade, $grade_grade->grade_item->id)) + 1; $data['rank']['class'] = $class; $data['rank']['content'] = "{$rank}/" . $this->get_numusers(false); // total course users } } $data['rank']['headers'] = "{$header_cat} {$header_row} rank"; } // Average if ($this->showaverage) { $data['average']['class'] = $class; if (!empty($this->gtree->items[$eid]->avg)) { $data['average']['content'] = $this->gtree->items[$eid]->avg; } else { $data['average']['content'] = '-'; } $data['average']['headers'] = "{$header_cat} {$header_row} average"; } // Start Date if ($this->showtimeupdate) { $data['startdate']['class'] = $class; if (!empty($activity_start_date)) { $data['startdate']['content'] = $activity_start_date->format('d-m-Y'); } else { $data['startdate']['content'] = '-'; } $data['startdate']['headers'] = "{$header_cat} {$header_row} startdate"; } // Time Update if ($this->showtimeupdate) { $data['timeupdate']['class'] = $class; if (!empty($grade_grade->timemodified)) { $data['timeupdate']['content'] = date("d/m/Y", $grade_grade->timemodified); } else { // if ((!empty($grade_grade->grade_item->timemodified)) && ($type == "categoryitem")){ // $data['timeupdate']['content'] = date("d/m/Y", $grade_grade->grade_item->timemodified); // }else { // } $data['timeupdate']['content'] = '-'; } $data['timeupdate']['headers'] = "{$header_cat} {$header_row} timeupdate"; } // Feedback if ($this->showfeedback) { if ($grade_grade->overridden > 0 and ($type == 'categoryitem' or $type == 'courseitem')) { $data['feedback']['class'] = $classfeedback . ' feedbacktext'; $data['feedback']['content'] = get_string('overridden', 'grades') . ': ' . format_text($grade_grade->feedback, $grade_grade->feedbackformat); } else { if (empty($grade_grade->feedback) or !$this->canviewhidden and $grade_grade->is_hidden()) { $data['feedback']['class'] = $classfeedback . ' feedbacktext'; $data['feedback']['content'] = ' '; } else { $data['feedback']['class'] = $classfeedback . ' feedbacktext'; $data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat); } } $data['feedback']['headers'] = "{$header_cat} {$header_row} feedback"; } } } /// Category if ($type == 'category') { //&& ($depth == 2)){ // $data['leader']['class'] = $class.' '.$alter."d$depth b1t b2b b1l"; // $data['leader']['rowspan'] = $element['rowspan']; // if ($this->switch) { // alter style based on whether aggregation is first or last // $data['itemname']['class'] = $class.' '.$alter."d$depth b1b b1t"; // } else { // $data['itemname']['class'] = $class.' '.$alter."d$depth b2t"; $data['itemname']['class'] = $class . ' category'; // } $data['itemname']['colspan'] = $this->maxdepth - $depth + count($this->tablecolumns) - 0; $data['itemname']['content'] = $fullname; $data['itemname']['celltype'] = 'th'; $data['itemname']['id'] = "cat_{$grade_object->id}_{$this->user->id}"; } /// Add this row to the overall system $this->tabledata[] = $data; /// Recursively iterate through all child elements if (isset($element['children'])) { foreach ($element['children'] as $key => $child) { $this->fill_table_recursive($element['children'][$key]); } } }
/** * Fill the table with data. * * @param $element - An array containing the table data for the current row. */ private function fill_table_recursive(&$element) { global $DB, $CFG; $type = $element['type']; $depth = $element['depth']; $grade_object = $element['object']; $eid = $grade_object->id; $element['userid'] = $this->user->id; $fullname = $this->gtree->get_element_header($element, true, true, true, true, true); $data = array(); $hidden = ''; $excluded = ''; $itemlevel = ($type == 'categoryitem' || $type == 'category' || $type == 'courseitem') ? $depth : ($depth + 1); $class = 'level' . $itemlevel . ' level' . ($itemlevel % 2 ? 'odd' : 'even'); $classfeedback = ''; // If this is a hidden grade category, hide it completely from the user if ($type == 'category' && $grade_object->is_hidden() && !$this->canviewhidden && ( $this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_object->is_hiddenuntil()))) { return false; } if ($type == 'category') { $this->evenodd[$depth] = (($this->evenodd[$depth] + 1) % 2); } $alter = ($this->evenodd[$depth] == 0) ? 'even' : 'odd'; /// Process those items that have scores associated if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem') { $header_row = "row_{$eid}_{$this->user->id}"; $header_cat = "cat_{$grade_object->categoryid}_{$this->user->id}"; if (! $grade_grade = grade_grade::fetch(array('itemid'=>$grade_object->id,'userid'=>$this->user->id))) { $grade_grade = new grade_grade(); $grade_grade->userid = $this->user->id; $grade_grade->itemid = $grade_object->id; } $grade_grade->load_grade_item(); /// Hidden Items if ($grade_grade->grade_item->is_hidden()) { $hidden = ' dimmed_text'; } $hide = false; // If this is a hidden grade item, hide it completely from the user. if ($grade_grade->is_hidden() && !$this->canviewhidden && ( $this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_grade->is_hiddenuntil()))) { $hide = true; } else if (!empty($grade_object->itemmodule) && !empty($grade_object->iteminstance)) { // The grade object can be marked visible but still be hidden if // the student cannot see the activity due to conditional access // and it's set to be hidden entirely. $instances = $this->modinfo->get_instances_of($grade_object->itemmodule); if (!empty($instances[$grade_object->iteminstance])) { $cm = $instances[$grade_object->iteminstance]; if (!$cm->uservisible) { // If there is 'availableinfo' text then it is only greyed // out and not entirely hidden. if (!$cm->availableinfo) { $hide = true; } } } } // Actual Grade - We need to calculate this whether the row is hidden or not. $gradeval = $grade_grade->finalgrade; $hint = $grade_grade->get_aggregation_hint(); if (!$this->canviewhidden) { /// Virtual Grade (may be calculated excluding hidden items etc). $adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($this->courseid, $grade_grade->grade_item, $gradeval); $gradeval = $adjustedgrade['grade']; // We temporarily adjust the view of this grade item - because the min and // max are affected by the hidden values in the aggregation. $grade_grade->grade_item->grademax = $adjustedgrade['grademax']; $grade_grade->grade_item->grademin = $adjustedgrade['grademin']; $hint['status'] = $adjustedgrade['aggregationstatus']; $hint['weight'] = $adjustedgrade['aggregationweight']; } else { // The max and min for an aggregation may be different to the grade_item. if (!is_null($gradeval)) { $grade_grade->grade_item->grademax = $grade_grade->rawgrademax; $grade_grade->grade_item->grademin = $grade_grade->rawgrademin; } } if (!$hide) { /// Excluded Item /** if ($grade_grade->is_excluded()) { $fullname .= ' ['.get_string('excluded', 'grades').']'; $excluded = ' excluded'; } **/ /// Other class information $class .= $hidden . $excluded; if ($this->switch) { // alter style based on whether aggregation is first or last $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " ".$alter."d$depth baggt b2b" : " item b1b"; } else { $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " ".$alter."d$depth baggb" : " item b1b"; } if ($type == 'categoryitem' or $type == 'courseitem') { $header_cat = "cat_{$grade_object->iteminstance}_{$this->user->id}"; } /// Name $data['itemname']['content'] = $fullname; $data['itemname']['class'] = $class; $data['itemname']['colspan'] = ($this->maxdepth - $depth); $data['itemname']['celltype'] = 'th'; $data['itemname']['id'] = $header_row; if ($this->showfeedback) { // Copy $class before appending itemcenter as feedback should not be centered $classfeedback = $class; } $class .= " itemcenter "; if ($this->showweight) { $data['weight']['class'] = $class; $data['weight']['content'] = '-'; $data['weight']['headers'] = "$header_cat $header_row weight"; // has a weight assigned, might be extra credit // This obliterates the weight because it provides a more informative description. if (is_numeric($hint['weight'])) { $data['weight']['content'] = format_float($hint['weight'] * 100.0, 2) . ' %'; } if ($hint['status'] != 'used' && $hint['status'] != 'unknown') { $data['weight']['content'] .= '<br>' . get_string('aggregationhint' . $hint['status'], 'grades'); } } if ($this->showgrade) { if ($grade_grade->grade_item->needsupdate) { $data['grade']['class'] = $class.' gradingerror'; $data['grade']['content'] = get_string('error'); } else if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden() and !$grade_grade->grade_item->is_category_item() and !$grade_grade->grade_item->is_course_item()) { // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records $class .= ' datesubmitted'; $data['grade']['class'] = $class; $data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort'))); } else if ($grade_grade->is_hidden()) { $data['grade']['class'] = $class.' dimmed_text'; $data['grade']['content'] = '-'; if ($this->canviewhidden) { $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true); } } else { $data['grade']['class'] = $class; $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true); } $data['grade']['headers'] = "$header_cat $header_row grade"; } // Range if ($this->showrange) { $data['range']['class'] = $class; $data['range']['content'] = $grade_grade->grade_item->get_formatted_range(GRADE_DISPLAY_TYPE_REAL, $this->rangedecimals); $data['range']['headers'] = "$header_cat $header_row range"; } // Percentage if ($this->showpercentage) { if ($grade_grade->grade_item->needsupdate) { $data['percentage']['class'] = $class.' gradingerror'; $data['percentage']['content'] = get_string('error'); } else if ($grade_grade->is_hidden()) { $data['percentage']['class'] = $class.' dimmed_text'; $data['percentage']['content'] = '-'; if ($this->canviewhidden) { $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE); } } else { $data['percentage']['class'] = $class; $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE); } $data['percentage']['headers'] = "$header_cat $header_row percentage"; } // Lettergrade if ($this->showlettergrade) { if ($grade_grade->grade_item->needsupdate) { $data['lettergrade']['class'] = $class.' gradingerror'; $data['lettergrade']['content'] = get_string('error'); } else if ($grade_grade->is_hidden()) { $data['lettergrade']['class'] = $class.' dimmed_text'; if (!$this->canviewhidden) { $data['lettergrade']['content'] = '-'; } else { $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER); } } else { $data['lettergrade']['class'] = $class; $data['lettergrade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_LETTER); } $data['lettergrade']['headers'] = "$header_cat $header_row lettergrade"; } // Rank if ($this->showrank) { if ($grade_grade->grade_item->needsupdate) { $data['rank']['class'] = $class.' gradingerror'; $data['rank']['content'] = get_string('error'); } elseif ($grade_grade->is_hidden()) { $data['rank']['class'] = $class.' dimmed_text'; $data['rank']['content'] = '-'; } else if (is_null($gradeval)) { // no grade, no rank $data['rank']['class'] = $class; $data['rank']['content'] = '-'; } else { /// find the number of users with a higher grade $sql = "SELECT COUNT(DISTINCT(userid)) FROM {grade_grades} WHERE finalgrade > ? AND itemid = ? AND hidden = 0"; $rank = $DB->count_records_sql($sql, array($grade_grade->finalgrade, $grade_grade->grade_item->id)) + 1; $data['rank']['class'] = $class; $data['rank']['content'] = "$rank/".$this->get_numusers(false); // total course users } $data['rank']['headers'] = "$header_cat $header_row rank"; } // Average if ($this->showaverage) { $data['average']['class'] = $class; if (!empty($this->gtree->items[$eid]->avg)) { $data['average']['content'] = $this->gtree->items[$eid]->avg; } else { $data['average']['content'] = '-'; } $data['average']['headers'] = "$header_cat $header_row average"; } // Feedback if ($this->showfeedback) { if ($grade_grade->overridden > 0 AND ($type == 'categoryitem' OR $type == 'courseitem')) { $data['feedback']['class'] = $classfeedback.' feedbacktext'; $data['feedback']['content'] = get_string('overridden', 'grades').': ' . format_text($grade_grade->feedback, $grade_grade->feedbackformat); } else if (empty($grade_grade->feedback) or (!$this->canviewhidden and $grade_grade->is_hidden())) { $data['feedback']['class'] = $classfeedback.' feedbacktext'; $data['feedback']['content'] = ' '; } else { $data['feedback']['class'] = $classfeedback.' feedbacktext'; $data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat); } $data['feedback']['headers'] = "$header_cat $header_row feedback"; } // Contribution to the course total column. if ($this->showcontributiontocoursetotal) { $data['contributiontocoursetotal']['class'] = $class; $data['contributiontocoursetotal']['content'] = '-'; $data['contributiontocoursetotal']['headers'] = "$header_cat $header_row contributiontocoursetotal"; } } // We collect the aggregation hints whether they are hidden or not. if ($this->showcontributiontocoursetotal) { $hint['grademax'] = $grade_grade->grade_item->grademax; $hint['grademin'] = $grade_grade->grade_item->grademin; $hint['grade'] = $gradeval; $parent = $grade_object->load_parent_category(); if ($grade_object->is_category_item()) { $parent = $parent->load_parent_category(); } $hint['parent'] = $parent->load_grade_item()->id; $this->aggregationhints[$grade_grade->itemid] = $hint; } } /// Category if ($type == 'category') { $data['leader']['class'] = $class.' '.$alter."d$depth b1t b2b b1l"; $data['leader']['rowspan'] = $element['rowspan']; if ($this->switch) { // alter style based on whether aggregation is first or last $data['itemname']['class'] = $class.' '.$alter."d$depth b1b b1t"; } else { $data['itemname']['class'] = $class.' '.$alter."d$depth b2t"; } $data['itemname']['colspan'] = ($this->maxdepth - $depth + count($this->tablecolumns) - 1); $data['itemname']['content'] = $fullname; $data['itemname']['celltype'] = 'th'; $data['itemname']['id'] = "cat_{$grade_object->id}_{$this->user->id}"; } /// Add this row to the overall system foreach ($data as $key => $celldata) { $data[$key]['class'] .= ' column-' . $key; } $this->tabledata[] = $data; /// Recursively iterate through all child elements if (isset($element['children'])) { foreach ($element['children'] as $key=>$child) { $this->fill_table_recursive($element['children'][$key]); } } // Check we are showing this column, and we are looking at the root of the table. // This should be the very last thing this fill_table_recursive function does. if ($this->showcontributiontocoursetotal && ($type == 'category' && $depth == 1)) { // We should have collected all the hints by now - walk the tree again and build the contributions column. $this->fill_contributions_column($element); } }