/** * Returns the aggregated or calculated course grade for the given user(s). * @public * @param int $userid * @param int $courseid optional id of course or array of ids, empty means all uses courses (returns array if not present) * @return mixed grade info or grades array including item info, false if error */ function grade_get_course_grade($userid, $courseid_or_ids = null) { if (!is_array($courseid_or_ids)) { if (empty($courseid_or_ids)) { if (!($courses = enrol_get_users_courses($userid))) { return false; } $courseids = array_keys($courses); return grade_get_course_grade($userid, $courseids); } if (!is_numeric($courseid_or_ids)) { return false; } if (!($grades = grade_get_course_grade($userid, array($courseid_or_ids)))) { return false; } else { // only one grade - not array $grade = reset($grades); return $grade; } } foreach ($courseid_or_ids as $courseid) { $grade_item = grade_item::fetch_course_item($courseid); $course_items[$grade_item->courseid] = $grade_item; } $grades = array(); foreach ($course_items as $grade_item) { if ($grade_item->needsupdate) { grade_regrade_final_grades($courseid); } $item = new stdClass(); $item->scaleid = $grade_item->scaleid; $item->name = $grade_item->get_name(); $item->grademin = $grade_item->grademin; $item->grademax = $grade_item->grademax; $item->gradepass = $grade_item->gradepass; $item->locked = $grade_item->is_locked(); $item->hidden = $grade_item->is_hidden(); switch ($grade_item->gradetype) { case GRADE_TYPE_NONE: continue; case GRADE_TYPE_VALUE: $item->scaleid = 0; break; case GRADE_TYPE_TEXT: $item->scaleid = 0; $item->grademin = 0; $item->grademax = 0; $item->gradepass = 0; break; } $grade_grade = new grade_grade(array('userid' => $userid, 'itemid' => $grade_item->id)); $grade_grade->grade_item =& $grade_item; $grade = new stdClass(); $grade->grade = $grade_grade->finalgrade; $grade->locked = $grade_grade->is_locked(); $grade->hidden = $grade_grade->is_hidden(); $grade->overridden = $grade_grade->overridden; $grade->feedback = $grade_grade->feedback; $grade->feedbackformat = $grade_grade->feedbackformat; $grade->usermodified = $grade_grade->usermodified; $grade->dategraded = $grade_grade->get_dategraded(); $grade->item = $item; // create text representation of grade if ($grade_item->needsupdate) { $grade->grade = false; $grade->str_grade = get_string('error'); $grade->str_long_grade = $grade->str_grade; } else { if (is_null($grade->grade)) { $grade->str_grade = '-'; $grade->str_long_grade = $grade->str_grade; } else { $grade->str_grade = grade_format_gradevalue($grade->grade, $grade_item); if ($grade_item->gradetype == GRADE_TYPE_SCALE or $grade_item->get_displaytype() != GRADE_DISPLAY_TYPE_REAL) { $grade->str_long_grade = $grade->str_grade; } else { $a = new stdClass(); $a->grade = $grade->str_grade; $a->max = grade_format_gradevalue($grade_item->grademax, $grade_item); $grade->str_long_grade = get_string('gradelong', 'grades', $a); } } } // create html representation of feedback if (is_null($grade->feedback)) { $grade->str_feedback = ''; } else { $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat); } $grades[$grade_item->courseid] = $grade; } return $grades; }
public static function graded() { global $USER, $PAGE; $output = $PAGE->get_renderer('theme_snap', 'core', RENDERER_TARGET_GENERAL); $grades = activity::events_graded(); $o = ''; foreach ($grades as $grade) { $modinfo = get_fast_modinfo($grade->courseid); $course = $modinfo->get_course(); $modtype = $grade->itemmodule; $cm = $modinfo->instances[$modtype][$grade->iteminstance]; $coursecontext = \context_course::instance($grade->courseid); $canviewhiddengrade = has_capability('moodle/grade:viewhidden', $coursecontext); $url = new \moodle_url('/grade/report/user/index.php', ['id' => $grade->courseid]); if (in_array($modtype, ['quiz', 'assign']) && (!empty($grade->rawgrade) || !empty($grade->feedback))) { // Only use the course module url if the activity was graded in the module, not in the gradebook, etc. $url = $cm->url; } $modimageurl = $output->pix_url('icon', $cm->modname); $modname = get_string('modulename', 'mod_' . $cm->modname); $modimage = \html_writer::img($modimageurl, $modname); $gradetitle = "<small>{$course->fullname} / </small> {$cm->name}"; $releasedon = isset($grade->timemodified) ? $grade->timemodified : $grade->timecreated; $meta = get_string('released', 'theme_snap', $output->friendly_datetime($releasedon)); $grade = new \grade_grade(array('itemid' => $grade->itemid, 'userid' => $USER->id)); if (!$grade->is_hidden() || $canviewhiddengrade) { $o .= $output->snap_media_object($url, $modimage, $gradetitle, $meta, ''); } } if (empty($o)) { return '<p>' . get_string('nograded', 'theme_snap') . '</p>'; } return $o; }
/** * Return standard meta data for module * * @param cm_info $mod * @param string $timeopenfld * @param string $timeclosefld * @param string $keyfield * @param string $submissiontable * @param string $submittedonfld * @param string $submitstrkey * @param bool $isgradeable * @param string $submitselect - sql to further filter submission row select statement - e.g. st.status='finished' * @return bool | \theme_snap\activity_meta */ protected static function std_meta(\cm_info $mod, $timeopenfld, $timeclosefld, $keyfield, $submissiontable, $submittedonfld, $submitstrkey, $isgradeable = false, $submitselect = '') { global $USER; $courseid = $mod->course; // Create meta data object. $meta = new \theme_snap\activity_meta(); $meta->submitstrkey = $submitstrkey; $meta->submittedstr = get_string($submitstrkey, 'theme_snap'); $meta->notsubmittedstr = get_string('not' . $submitstrkey, 'theme_snap'); if (get_string_manager()->string_exists($mod->modname . 'draft', 'theme_snap')) { $meta->draftstr = get_string($mod->modname . 'draft', 'theme_snap'); } else { $meta->drafstr = get_string('draft', 'theme_snap'); } if (get_string_manager()->string_exists($mod->modname . 'reopened', 'theme_snap')) { $meta->reopenedstr = get_string($mod->modname . 'reopened', 'theme_snap'); } else { $meta->reopenedstr = get_string('reopened', 'theme_snap'); } // If module is not visible to the user then don't bother getting meta data. if (!$mod->uservisible) { return $meta; } $activitydates = self::instance_activity_dates($courseid, $mod, $timeopenfld, $timeclosefld); $meta->timeopen = $activitydates->timeopen; $meta->timeclose = $activitydates->timeclose; // TODO: use activity specific "teacher" capabilities. if (has_capability('mod/assign:grade', \context_course::instance($courseid))) { $meta->isteacher = true; // Teacher - useful teacher meta data. $methodnsubmissions = $mod->modname . '_num_submissions'; $methodnungraded = $mod->modname . '_num_submissions_ungraded'; if (method_exists('theme_snap\\activity', $methodnsubmissions)) { $meta->numsubmissions = call_user_func('theme_snap\\activity::' . $methodnsubmissions, $courseid, $mod->instance); } if (method_exists('theme_snap\\activity', $methodnungraded)) { $meta->numrequiregrading = call_user_func('theme_snap\\activity::' . $methodnungraded, $courseid, $mod->instance); } } else { // Student - useful student meta data - only display if activity is available. if (empty($activitydates->timeopen) || usertime($activitydates->timeopen) <= time()) { $submissionrow = self::get_submission_row($courseid, $mod, $submissiontable, $keyfield, $submitselect); if (!empty($submissionrow)) { if ($submissionrow->status) { switch ($submissionrow->status) { case 'draft': $meta->draft = true; break; case 'reopened': $meta->reopened = true; break; case 'submitted': $meta->submitted = true; break; } } else { $meta->submitted = true; $meta->timesubmitted = !empty($submissionrow->{$submittedonfld}) ? $submissionrow->{$submittedonfld} : null; } // If submitted on field uses modified field then fall back to timecreated if modified is 0. if (empty($meta->timesubmitted) && ($submittedonfld = 'timemodified')) { if (isset($submissionrow->timemodified)) { $meta->timesubmitted = $submissionrow->timemodified; } else { $meta->timesubmitted = $submissionrow->timecreated; } } } } $graderow = false; if ($isgradeable) { $graderow = self::grade_row($courseid, $mod); } if ($graderow) { $gradeitem = \grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => $mod->modname, 'iteminstance' => $mod->instance)); $grade = new \grade_grade(array('itemid' => $gradeitem->id, 'userid' => $USER->id)); $coursecontext = \context_course::instance($courseid); $canviewhiddengrade = has_capability('moodle/grade:viewhidden', $coursecontext); if (!$grade->is_hidden() || $canviewhiddengrade) { $meta->grade = true; } } } return $meta; }
public function fill_table() { global $CFG, $DB, $OUTPUT; // Only show user's courses instead of all courses. if ($this->courses) { $numusers = $this->get_numusers(false); foreach ($this->courses as $course) { if (!$course->showgrades) { continue; } $coursecontext = context_course::instance($course->id); if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { // The course is hidden and the user isn't allowed to see it continue; } $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext)); $courselink = html_writer::link(new moodle_url('/grade/report/user/index.php', array('id' => $course->id, 'userid' => $this->user->id)), $courseshortname); $canviewhidden = has_capability('moodle/grade:viewhidden', $coursecontext); // Get course grade_item $course_item = grade_item::fetch_course_item($course->id); // Get the stored grade $course_grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $this->user->id)); $course_grade->grade_item =& $course_item; $finalgrade = $course_grade->finalgrade; if (!$canviewhidden and !is_null($finalgrade)) { if ($course_grade->is_hidden()) { $finalgrade = null; } else { $adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($course->id, $course_item, $finalgrade); // We temporarily adjust the view of this grade item - because the min and // max are affected by the hidden values in the aggregation. $finalgrade = $adjustedgrade['grade']; $course_item->grademax = $adjustedgrade['grademax']; $course_item->grademin = $adjustedgrade['grademin']; } } $data = array($courselink, grade_format_gradevalue($finalgrade, $course_item, true)); if (!$this->showrank['any']) { //nothing to do } else { if ($this->showrank[$course->id] && !is_null($finalgrade)) { /// find the number of users with a higher grade /// please note this can not work if hidden grades involved :-( to be fixed in 2.0 $params = array($finalgrade, $course_item->id); $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {grade_grades}\n WHERE finalgrade IS NOT NULL AND finalgrade > ?\n AND itemid = ?"; $rank = $DB->count_records_sql($sql, $params) + 1; $data[] = "{$rank}/{$numusers}"; } else { // No grade, no rank. // Or this course wants rank hidden. $data[] = '-'; } } $this->table->add_data($data); } return true; } else { echo $OUTPUT->notification(get_string('nocourses', 'grades')); return false; } }
private function fill_table_recursive(&$element) { global $CFG, $DB; $type = $element['type']; $depth = $element['depth']; $grade_object = $element['object']; $eid = $grade_object->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; 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); } } /// Percentage if ($this->showpercentage) { if ($grade_grade->grade_item->needsupdate) { $data['percentage']['class'] = $class . ' gradingerror'; $data['percentage']['content'] = get_string('error'); } elseif ($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); } } /// Rank if ($this->showrank) { // TODO: this is broken if hidden grades present!! 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 = ?"; $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 } } } /// Feedback 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, array('overflowdiv' => true)); } /// Range if ($this->showrange) { $data['range']['class'] = $class; $data['range']['content'] = $grade_grade->grade_item->get_formatted_range(); } } } /// 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]); } } }
/** * 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); } }
function fill_table() { global $CFG; // MDL-11679, only show 'mycourses' instead of all courses if ($courses = get_my_courses($this->user->id, 'c.sortorder ASC', 'id, shortname')) { $numusers = $this->get_numusers(false); foreach ($courses as $course) { $courselink = '<a href="' . $CFG->wwwroot . '/grade/report/user/index.php?id=' . $course->id . '">' . $course->shortname . '</a>'; // Get course grade_item $grade_item = grade_item::fetch_course_item($course->id); // Get the grade $grade = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $this->user->id)); $grade->grade_item =& $grade_item; $finalgrade = $grade->finalgrade; // TODO: this DOES NOT work properly if there are any hidden grades, // rank might be wrong & totals might be different from user report!!! if ($grade->is_hidden() and !has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $course->id))) { $finalgrade = null; } $data = array($courselink, grade_format_gradevalue($finalgrade, $grade_item, true)); if (!$this->showrank) { //nothing to do } else { if (!is_null($finalgrade)) { /// find the number of users with a higher grade $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {$CFG->prefix}grade_grades\n WHERE finalgrade IS NOT NULL AND finalgrade > {$finalgrade}\n AND itemid = {$grade_item->id}"; $rank = count_records_sql($sql) + 1; $data[] = "{$rank}/{$numusers}"; } else { // no grade, no rank $data[] = '-'; } } $this->table->add_data($data); } return true; } else { notify(get_string('nocourses', 'grades')); return false; } }
/** * Fill the table for displaying. * * @param bool $activitylink If this report link to the activity report or the user report. * @param bool $studentcoursesonly Only show courses that the user is a student of. */ public function fill_table($activitylink = false, $studentcoursesonly = false) { global $CFG, $DB, $OUTPUT, $USER; if ($studentcoursesonly && count($this->studentcourseids) == 0) { return false; } // Only show user's courses instead of all courses. if ($this->courses) { $numusers = $this->get_numusers(false); foreach ($this->courses as $course) { if (!$course->showgrades) { continue; } // If we are only showing student courses and this course isn't part of the group, then move on. if ($studentcoursesonly && !isset($this->studentcourseids[$course->id])) { continue; } $coursecontext = context_course::instance($course->id); if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { // The course is hidden and the user isn't allowed to see it continue; } if (!has_capability('moodle/user:viewuseractivitiesreport', context_user::instance($this->user->id)) && ((!has_capability('moodle/grade:view', $coursecontext) || $this->user->id != $USER->id) && !has_capability('moodle/grade:viewall', $coursecontext))) { continue; } $coursename = format_string(get_course_display_name_for_list($course), true, array('context' => $coursecontext)); // Link to the activity report version of the user grade report. if ($activitylink) { $courselink = html_writer::link(new moodle_url('/course/user.php', array('mode' => 'grade', 'id' => $course->id, 'user' => $this->user->id)), $coursename); } else { $courselink = html_writer::link(new moodle_url('/grade/report/user/index.php', array('id' => $course->id, 'userid' => $this->user->id)), $coursename); } $canviewhidden = has_capability('moodle/grade:viewhidden', $coursecontext); // Get course grade_item $course_item = grade_item::fetch_course_item($course->id); // Get the stored grade $course_grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $this->user->id)); $course_grade->grade_item =& $course_item; $finalgrade = $course_grade->finalgrade; if (!$canviewhidden and !is_null($finalgrade)) { if ($course_grade->is_hidden()) { $finalgrade = null; } else { $adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($course->id, $course_item, $finalgrade); // We temporarily adjust the view of this grade item - because the min and // max are affected by the hidden values in the aggregation. $finalgrade = $adjustedgrade['grade']; $course_item->grademax = $adjustedgrade['grademax']; $course_item->grademin = $adjustedgrade['grademin']; } } else { // We must use the rawgrademin / rawgrademax because it can be different for // each grade_grade when items are excluded from sum of grades. if (!is_null($finalgrade)) { $course_item->grademin = $course_grade->rawgrademin; $course_item->grademax = $course_grade->rawgrademax; } } $data = array($courselink, grade_format_gradevalue($finalgrade, $course_item, true)); if (!$this->showrank['any']) { //nothing to do } else { if ($this->showrank[$course->id] && !is_null($finalgrade)) { /// find the number of users with a higher grade /// please note this can not work if hidden grades involved :-( to be fixed in 2.0 $params = array($finalgrade, $course_item->id); $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {grade_grades}\n WHERE finalgrade IS NOT NULL AND finalgrade > ?\n AND itemid = ?"; $rank = $DB->count_records_sql($sql, $params) + 1; $data[] = "{$rank}/{$numusers}"; } else { // No grade, no rank. // Or this course wants rank hidden. $data[] = '-'; } } $this->table->add_data($data); } return true; } else { echo $OUTPUT->notification(get_string('notenrolled', 'grades'), 'notifymessage'); return false; } }
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]); } } }
function fill_table() { global $CFG; $numusers = $this->get_numusers(false); // total course users $items =& $this->gseq->items; $grades = array(); $canviewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $this->courseid)); // fetch or create all grades foreach ($items as $key => $unused) { if (!($grade_grade = grade_grade::fetch(array('itemid' => $items[$key]->id, 'userid' => $this->user->id)))) { $grade_grade = new grade_grade(); $grade_grade->userid = $this->user->id; $grade_grade->itemid = $items[$key]->id; } $grades[$key] = $grade_grade; $grades[$key]->grade_item =& $items[$key]; } if ($canviewhidden) { $altered = array(); $unknown = array(); } else { $hiding_affected = grade_grade::get_hiding_affected($grades, $items); $altered = $hiding_affected['altered']; $unknown = $hiding_affected['unknown']; unset($hiding_affected); } foreach ($items as $itemid => $unused) { $grade_item =& $items[$itemid]; $grade_grade =& $grades[$itemid]; if (!$canviewhidden and $grade_item->is_hidden()) { if ($this->showhiddenitems == 0) { // no hidden items at all continue; } else { if ($this->showhiddenitems == 1 and !$grade_item->is_hiddenuntil()) { // hidden until that are still hidden are visible continue; } } } $class = 'gradeitem'; if ($grade_item->is_course_item()) { $class = 'courseitem'; } else { if ($grade_item->is_category_item()) { $class = 'categoryitem'; } } if (in_array($itemid, $unknown)) { $gradeval = null; } else { if (array_key_exists($itemid, $altered)) { $gradeval = $altered[$itemid]; } else { $gradeval = $grade_grade->finalgrade; } } $data = array(); // all users should know which items are still hidden $hidden = ''; if ($grade_item->is_hidden()) { $hidden = ' hidden '; } $element = $this->gseq->locate_element($this->gseq->get_item_eid($grade_item)); $header = $this->gseq->get_element_header($element, true, true, true); /// prints grade item name $data[] = '<span class="' . $hidden . $class . '">' . $header . '</span>'; /// prints category $cat = $grade_item->get_parent_category(); $data[] = '<span class="' . $hidden . $class . '">' . $cat->get_name() . '</span>'; $hidden = ''; if ($grade_item->is_hidden()) { // can not see grades in hidden items $hidden = ' hidden '; } else { if ($canviewhidden and $grade_grade->is_hidden()) { // if user can see hidden grades, indicate which ones are hidden $hidden = ' hidden '; } } /// prints the grade if ($grade_grade->is_excluded()) { $excluded = get_string('excluded', 'grades') . ' '; } else { $excluded = ''; } if ($grade_item->needsupdate) { $data[] = '<span class="' . $hidden . $class . ' gradingerror">' . get_string('error') . '</span>'; } else { if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$canviewhidden and $grade_grade->is_hidden() and !$grade_item->is_category_item() and !$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 $data[] = '<span class="' . $hidden . $class . ' datesubmitted">' . $excluded . get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort'))) . '</span>'; } else { $data[] = '<span class="' . $hidden . $class . '">' . $excluded . grade_format_gradevalue($gradeval, $grade_item, true) . '</span>'; } } /// prints percentage if ($grade_item->needsupdate) { $data[] = '<span class="' . $hidden . $class . 'gradingerror">' . get_string('error') . '</span>'; } else { $data[] = '<span class="' . $hidden . $class . '">' . grade_format_gradevalue($gradeval, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE) . '</span>'; } /// prints rank if ($this->showrank) { // TODO: this is broken if hidden grades present!! if ($grade_item->needsupdate) { $data[] = '<span class="' . $hidden . $class . 'gradingerror">' . get_string('error') . '</span>'; } else { if (is_null($gradeval)) { // no grade, no rank $data[] = '<span class="' . $hidden . $class . '">-</span>'; } else { /// find the number of users with a higher grade $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {$CFG->prefix}grade_grades\n WHERE finalgrade > {$grade_grade->finalgrade}\n AND itemid = {$grade_item->id}"; $rank = count_records_sql($sql) + 1; $data[] = '<span class="' . $hidden . $class . '">' . "{$rank}/{$numusers}" . '</span>'; } } } /// prints feedback if (empty($grade_grade->feedback) or !$canviewhidden and $grade_grade->is_hidden()) { $data[] = '<div class="' . $hidden . 'feedbacktext"> </div>'; } else { $data[] = '<div class="' . $hidden . 'feedbacktext">' . format_text($grade_grade->feedback, $grade_grade->feedbackformat) . '</div>'; } $this->table->add_data($data); } return true; }
/** * Set up the courses grades data for the report. * * @param bool $studentcoursesonly Only show courses that the user is a student of. * @return array of course grades information */ public function setup_courses_data($studentcoursesonly) { global $USER, $DB; $coursesdata = array(); $numusers = $this->get_numusers(false); foreach ($this->courses as $course) { if (!$course->showgrades) { continue; } // If we are only showing student courses and this course isn't part of the group, then move on. if ($studentcoursesonly && !isset($this->studentcourseids[$course->id])) { continue; } $coursecontext = context_course::instance($course->id); if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { // The course is hidden and the user isn't allowed to see it. continue; } if (!has_capability('moodle/user:viewuseractivitiesreport', context_user::instance($this->user->id)) && ((!has_capability('moodle/grade:view', $coursecontext) || $this->user->id != $USER->id) && !has_capability('moodle/grade:viewall', $coursecontext))) { continue; } $coursesdata[$course->id]['course'] = $course; $coursesdata[$course->id]['context'] = $coursecontext; $canviewhidden = has_capability('moodle/grade:viewhidden', $coursecontext); // Get course grade_item. $courseitem = grade_item::fetch_course_item($course->id); // Get the stored grade. $coursegrade = new grade_grade(array('itemid' => $courseitem->id, 'userid' => $this->user->id)); $coursegrade->grade_item =& $courseitem; $finalgrade = $coursegrade->finalgrade; if (!$canviewhidden and !is_null($finalgrade)) { if ($coursegrade->is_hidden()) { $finalgrade = null; } else { $adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($course->id, $courseitem, $finalgrade); // We temporarily adjust the view of this grade item - because the min and // max are affected by the hidden values in the aggregation. $finalgrade = $adjustedgrade['grade']; $courseitem->grademax = $adjustedgrade['grademax']; $courseitem->grademin = $adjustedgrade['grademin']; } } else { // We must use the specific max/min because it can be different for // each grade_grade when items are excluded from sum of grades. if (!is_null($finalgrade)) { $courseitem->grademin = $coursegrade->get_grade_min(); $courseitem->grademax = $coursegrade->get_grade_max(); } } $coursesdata[$course->id]['finalgrade'] = $finalgrade; $coursesdata[$course->id]['courseitem'] = $courseitem; if ($this->showrank['any'] && $this->showrank[$course->id] && !is_null($finalgrade)) { // Find the number of users with a higher grade. // Please note this can not work if hidden grades involved :-( to be fixed in 2.0. $params = array($finalgrade, $courseitem->id); $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {grade_grades}\n WHERE finalgrade IS NOT NULL AND finalgrade > ?\n AND itemid = ?"; $rank = $DB->count_records_sql($sql, $params) + 1; $coursesdata[$course->id]['rank'] = $rank; $coursesdata[$course->id]['numusers'] = $numusers; } } return $coursesdata; }
/** * Builds and return the HTML rows of the table (grades headed by student). * @return string HTML */ function get_studentshtml() { global $CFG, $USER; $studentshtml = ''; $strfeedback = $this->get_lang_string("feedback"); $strgrade = $this->get_lang_string('grade'); $gradetabindex = 1; $showuserimage = $this->get_pref('showuserimage'); $numusers = count($this->users); // Preload scale objects for items with a scaleid $scales_list = ''; $tabindices = array(); foreach ($this->items as $item) { if (!empty($item->scaleid)) { $scales_list .= "{$item->scaleid},"; } $tabindices[$item->id]['grade'] = $gradetabindex; $tabindices[$item->id]['feedback'] = $gradetabindex + $numusers; $gradetabindex += $numusers * 2; } $scales_array = array(); if (!empty($scales_list)) { $scales_list = substr($scales_list, 0, -1); $scales_array = get_records_list('scale', 'id', $scales_list); } $canviewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $this->course->id)); foreach ($this->users as $userid => $user) { $columncount = 0; // Student name and link $user_pic = null; if ($showuserimage) { $user_pic = '<div class="userpic">' . print_user_picture($user->id, $this->courseid, true, 0, true) . '</div>'; } $studentshtml .= '<tr class="r' . $this->rowcount++ . '"><th class="header c' . $columncount++ . ' user" scope="row">' . $user_pic . '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $user->id . '">' . fullname($user) . '</a></th>'; foreach ($this->items as $itemid => $item) { // Get the decimal points preference for this item $decimalpoints = $item->get_decimals(); if (isset($this->finalgrades[$userid][$item->id])) { $gradeval = $this->finalgrades[$userid][$item->id]->finalgrade; $grade = new grade_grade($this->finalgrades[$userid][$item->id], false); $grade->feedback = stripslashes_safe($this->finalgrades[$userid][$item->id]->feedback); $grade->feedbackformat = $this->finalgrades[$userid][$item->id]->feedbackformat; } else { $gradeval = null; $grade = new grade_grade(array('userid' => $userid, 'itemid' => $item->id), false); $grade->feedback = ''; } // MDL-11274 // Hide grades in the grader report if the current grader doesn't have 'moodle/grade:viewhidden' if ($grade->is_hidden() && !$canviewhidden) { if (isset($grade->finalgrade)) { $studentshtml .= '<td class="cell c' . $columncount++ . '">' . userdate($grade->timecreated, get_string('strftimedatetimeshort')) . '</td>'; } else { $studentshtml .= '<td class="cell c' . $columncount++ . '">-</td>'; } continue; } $grade->courseid = $this->courseid; $grade->grade_item =& $this->items[$itemid]; // this speedsup is_hidden() and other grade_grade methods // emulate grade element $eid = $this->gtree->get_grade_eid($grade); $element = array('eid' => $eid, 'object' => $grade, 'type' => 'grade'); if ($grade->is_overridden()) { $studentshtml .= '<td class="overridden cell c' . $columncount++ . '">'; } else { $studentshtml .= '<td class="cell c' . $columncount++ . '">'; } if ($grade->is_excluded()) { $studentshtml .= get_string('excluded', 'grades'); // TODO: improve visual representation of excluded grades } // Do not show any icons if no grade (no record in DB to match) if (!$item->needsupdate and $USER->gradeediting[$this->courseid]) { $studentshtml .= $this->get_icons($element); } // if in editting mode, we need to print either a text box // or a drop down (for scales) // grades in item of type grade category or course are not directly editable if ($item->needsupdate) { $studentshtml .= '<span class="gradingerror">' . get_string('error') . '</span>'; } else { if ($USER->gradeediting[$this->courseid]) { // We need to retrieve each grade_grade object from DB in order to // know if they are hidden/locked if ($item->scaleid && !empty($scales_array[$item->scaleid])) { $scale = $scales_array[$item->scaleid]; $scales = explode(",", $scale->scale); // reindex because scale is off 1 $i = 0; foreach ($scales as $scaleoption) { $i++; $scaleopt[$i] = $scaleoption; } if ($this->get_pref('quickgrading') and $grade->is_editable()) { $oldval = empty($gradeval) ? -1 : $gradeval; if (empty($item->outcomeid)) { $nogradestr = $this->get_lang_string('nograde'); } else { $nogradestr = $this->get_lang_string('nooutcome', 'grades'); } $studentshtml .= '<input type="hidden" name="oldgrade_' . $userid . '_' . $item->id . '" value="' . $oldval . '"/>'; $studentshtml .= choose_from_menu($scaleopt, 'grade_' . $userid . '_' . $item->id, $gradeval, $nogradestr, '', '-1', true, false, $tabindices[$item->id]['grade']); } elseif (!empty($scale)) { $scales = explode(",", $scale->scale); // invalid grade if gradeval < 1 if ((int) $gradeval < 1) { $studentshtml .= '-'; } else { $gradeval = (int) bounded_number($grade->grade_item->grademin, $gradeval, $grade->grade_item->grademax); //just in case somebody changes scale $studentshtml .= $scales[$gradeval - 1]; } } else { // no such scale, throw error? } } else { if ($item->gradetype != GRADE_TYPE_TEXT) { // Value type if ($this->get_pref('quickgrading') and $grade->is_editable()) { $value = format_float($gradeval, $decimalpoints); $studentshtml .= '<input type="hidden" name="oldgrade_' . $userid . '_' . $item->id . '" value="' . $value . '" />'; $studentshtml .= '<input size="6" tabindex="' . $tabindices[$item->id]['grade'] . '" type="text" title="' . $strgrade . '" name="grade_' . $userid . '_' . $item->id . '" value="' . $value . '" />'; } else { $studentshtml .= format_float($gradeval, $decimalpoints); } } } // If quickfeedback is on, print an input element if ($this->get_pref('quickfeedback') and $grade->is_editable()) { if ($this->get_pref('quickgrading')) { $studentshtml .= '<br />'; } $studentshtml .= '<input type="hidden" name="oldfeedback_' . $userid . '_' . $item->id . '" value="' . s($grade->feedback) . '" />'; $studentshtml .= '<input class="quickfeedback" tabindex="' . $tabindices[$item->id]['feedback'] . '" size="6" title="' . $strfeedback . '" type="text" name="feedback_' . $userid . '_' . $item->id . '" value="' . s($grade->feedback) . '" />'; } } else { // Not editing $gradedisplaytype = $item->get_displaytype(); $percentsign = ''; $grademin = $item->grademin; $grademax = $item->grademax; // If feedback present, surround grade with feedback tooltip: Open span here if (!empty($grade->feedback)) { $overlib = ''; if ($grade->feedbackformat == 1) { $overlib = "return overlib('" . s(ltrim($grade->feedback)) . "', FULLHTML);"; } else { $overlib = "return overlib('" . s($grade->feedback) . "', BORDER, 0, FGCLASS, 'feedback', " . "CAPTIONFONTCLASS, 'caption', CAPTION, '{$strfeedback}');"; } $studentshtml .= '<span onmouseover="' . $overlib . '" onmouseout="return nd();">'; } if ($item->needsupdate) { $studentshtml .= '<span class="gradingerror">' . get_string('error') . '</span>'; } elseif ($item->scaleid && !empty($scales_array[$item->scaleid])) { $scale = $scales_array[$item->scaleid]; $scales = explode(",", $scale->scale); // invalid grade if gradeval < 1 if ((int) $gradeval < 1) { $studentshtml .= '-'; } else { $studentshtml .= $scales[$gradeval - 1]; } } else { if (is_null($gradeval)) { $studentshtml .= '-'; } else { $studentshtml .= grade_format_gradevalue($gradeval, $item, true, $gradedisplaytype, null); } } // Close feedback span if (!empty($grade->feedback)) { $studentshtml .= '</span>'; } } } if (!empty($this->gradeserror[$item->id][$userid])) { $studentshtml .= $this->gradeserror[$item->id][$userid]; } $studentshtml .= '</td>' . "\n"; } $studentshtml .= '</tr>'; } return $studentshtml; }
/** * Harvest the grades from the data base and build the finalgrades array. * Filters out hidden, locked and null grades based on users settings. * Partly based on grader reports load_final_grades function. */ public function harvest_data() { global $CFG, $DB; $params = array(); if (isset($DB) && !is_null($DB)) { $params = array_merge(array($this->courseid), $this->userselect_params); /// please note that we must fetch all grade_grades fields if we want to contruct grade_grade object from it! $sql = "SELECT g.*\n FROM {grade_items} gi,\n {grade_grades} g\n WHERE g.itemid = gi.id AND gi.courseid = ? {$this->userselect}"; $grades = $DB->get_records_sql($sql, $params); } else { /// please note that we must fetch all grade_grades fields if we want to contruct grade_grade object from it! $sql = "SELECT g.*\n FROM {$CFG->prefix}grade_items gi,\n {$CFG->prefix}grade_grades g\n WHERE g.itemid = gi.id AND gi.courseid = {$this->courseid} {$this->userselect}"; $grades = get_records_sql($sql); } $userids = array_keys($this->users); if ($grades) { foreach ($grades as $graderec) { if (in_array($graderec->userid, $userids) && array_key_exists($graderec->itemid, $this->gtree->items)) { // some items may not be present!! $grade = new grade_grade($graderec, false); $grade->grade_item =& $this->gtree->items[$graderec->itemid]; if (($grade->is_hidden() && $this->canviewhidden && ($this->get_pref('visual', 'usehidden') || is_null($this->get_pref('visual', 'usehidden'))) || !$grade->is_hidden()) && ($grade->is_locked() && ($this->get_pref('visual', 'uselocked') || is_null($this->get_pref('visual', 'uselocked'))) || !$grade->is_locked())) { $this->grades[$graderec->itemid][$graderec->userid] = $grade; } } } } if ($this->get_pref('visual', 'incompleasmin')) { /// prefil grades that do not exist yet foreach ($userids as $userid) { foreach ($this->gtree->items as $itemid => $unused) { if (!isset($this->grades[$itemid][$userid])) { $grade = new grade_grade(); $grade->itemid = $itemid; $grade->userid = $userid; $grade->grade_item =& $this->gtree->items[$itemid]; // db caching $grade->finalgrade = $this->gtree->items[$itemid]->grademin; if (($grade->is_hidden() && $this->canviewhidden && ($this->get_pref('visual', 'usehidden') || is_null($this->get_pref('visual', 'usehidden'))) || !$grade->is_hidden()) && ($grade->is_locked() && ($this->get_pref('visual', 'uselocked') || is_null($this->get_pref('visual', 'uselocked'))) || !$grade->is_locked())) { $this->grades[$itemid][$userid] = $grade; } } } } } }
function fill_table() { global $CFG; // MDL-11679, only show 'mycourses' instead of all courses if ($courses = get_my_courses($this->user->id, 'c.sortorder ASC', 'id, shortname, showgrades')) { $numusers = $this->get_numusers(false); foreach ($courses as $course) { if (!$course->showgrades) { continue; } $courselink = '<a href="' . $CFG->wwwroot . '/grade/report/user/index.php?id=' . $course->id . '&userid=' . $this->user->id . '">' . $course->shortname . '</a>'; $canviewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $course->id)); // Get course grade_item $course_item = grade_item::fetch_course_item($course->id); // Get the stored grade $course_grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $this->user->id)); $course_grade->grade_item =& $course_item; $finalgrade = $course_grade->finalgrade; if (!$canviewhidden and !is_null($finalgrade)) { if ($course_grade->is_hidden()) { $finalgrade = null; } else { $finalgrade = $this->blank_hidden_total($course->id, $course_item, $finalgrade); } } $data = array($courselink, grade_format_gradevalue($finalgrade, $course_item, true)); if (!$this->showrank) { //nothing to do } else { if (!is_null($finalgrade)) { /// find the number of users with a higher grade /// please note this can not work if hidden grades involved :-( to be fixed in 2.0 $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {$CFG->prefix}grade_grades\n WHERE finalgrade IS NOT NULL AND finalgrade > {$finalgrade}\n AND itemid = {$course_item->id}"; $rank = count_records_sql($sql) + 1; $data[] = "{$rank}/{$numusers}"; } else { // no grade, no rank $data[] = '-'; } } $this->table->add_data($data); } return true; } else { notify(get_string('nocourses', 'grades')); return false; } }
public function fill_table() { global $CFG, $DB; // MDL-11679, only show 'mycourses' instead of all courses if ($courses = get_my_courses($this->user->id, 'c.sortorder ASC', 'id, shortname, showgrades')) { $numusers = $this->get_numusers(false); foreach ($courses as $course) { if (!$course->showgrades) { continue; } $courselink = '<a href="' . $CFG->wwwroot . '/grade/report/user/index.php?id=' . $course->id . '">' . $course->shortname . '</a>'; $canviewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $course->id)); // Get course grade_item $course_item = grade_item::fetch_course_item($course->id); // Get the stored grade $course_grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $this->user->id)); $course_grade->grade_item =& $course_item; $finalgrade = $course_grade->finalgrade; if (!$canviewhidden and !is_null($finalgrade)) { if ($course_grade->is_hidden()) { $finalgrade = null; } else { // This is a really ugly hack, it will be fixed in 2.0 $items = grade_item::fetch_all(array('courseid' => $course->id)); $grades = array(); $sql = "SELECT g.*\n FROM {grade_grades} g\n JOIN {grade_items} gi ON gi.id = g.itemid\n WHERE g.userid = ? AND gi.courseid = ?"; if ($gradesrecords = $DB->get_records_sql($sql, array($this->user->id, $course->id))) { foreach ($gradesrecords as $grade) { $grades[$grade->itemid] = new grade_grade($grade, false); } unset($gradesrecords); } foreach ($items as $itemid => $unused) { if (!isset($grades[$itemid])) { $grade_grade = new grade_grade(); $grade_grade->userid = $this->user->id; $grade_grade->itemid = $items[$itemid]->id; $grades[$itemid] = $grade_grade; } $grades[$itemid]->grade_item =& $items[$itemid]; } $hiding_affected = grade_grade::get_hiding_affected($grades, $items); if (array_key_exists($course_item->id, $hiding_affected['altered'])) { $finalgrade = $hiding_affected['altered'][$course_item->id]; } else { if (!empty($hiding_affected['unknown'][$course_item->id])) { $finalgrade = null; } } unset($hiding_affected); unset($grades); unset($items); } } $data = array($courselink, grade_format_gradevalue($finalgrade, $course_item, true)); if (!$this->showrank) { //nothing to do } else { if (!is_null($finalgrade)) { /// find the number of users with a higher grade /// please note this can not work if hidden grades involved :-( to be fixed in 2.0 $params = array($finalgrade, $course_item->id); $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {grade_grades}\n WHERE finalgrade IS NOT NULL AND finalgrade > ?\n AND itemid = ?"; $rank = $DB->count_records_sql($sql, $params) + 1; $data[] = "{$rank}/{$numusers}"; } else { // no grade, no rank $data[] = '-'; } } $this->table->add_data($data); } return true; } else { notify(get_string('nocourses', 'grades')); return false; } }
public function fill_table() { global $CFG, $DB, $OUTPUT; // MDL-11679, only show user's courses instead of all courses if ($courses = enrol_get_users_courses($this->user->id, false, 'id, shortname, showgrades')) { $numusers = $this->get_numusers(false); foreach ($courses as $course) { if (!$course->showgrades) { continue; } $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id); if (!$course->visible && !has_capability('moodle/course:viewhiddencourses', $coursecontext)) { // The course is hidden and the user isn't allowed to see it continue; } $courseshortname = format_string($course->shortname, true, array('context' => $coursecontext)); $courselink = html_writer::link(new moodle_url('/grade/report/user/index.php', array('id' => $course->id, 'userid' => $this->user->id)), $courseshortname); $canviewhidden = has_capability('moodle/grade:viewhidden', $coursecontext); // Get course grade_item $course_item = grade_item::fetch_course_item($course->id); // Get the stored grade $course_grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $this->user->id)); $course_grade->grade_item =& $course_item; $finalgrade = $course_grade->finalgrade; if (!$canviewhidden and !is_null($finalgrade)) { if ($course_grade->is_hidden()) { $finalgrade = null; } else { $finalgrade = $this->blank_hidden_total($course->id, $course_item, $finalgrade); } } $data = array($courselink, grade_format_gradevalue($finalgrade, $course_item, true)); if (!$this->showrank) { //nothing to do } else { if (!is_null($finalgrade)) { /// find the number of users with a higher grade /// please note this can not work if hidden grades involved :-( to be fixed in 2.0 $params = array($finalgrade, $course_item->id); $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {grade_grades}\n WHERE finalgrade IS NOT NULL AND finalgrade > ?\n AND itemid = ?"; $rank = $DB->count_records_sql($sql, $params) + 1; $data[] = "{$rank}/{$numusers}"; } else { // no grade, no rank $data[] = '-'; } } $this->table->add_data($data); } return true; } else { echo $OUTPUT->notification(get_string('nocourses', 'grades')); return false; } }
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]); } } }
function fill_table() { global $CFG; $numusers = $this->get_numusers(false); // total course users if ($all_grade_items = grade_item::fetch_all(array('courseid' => $this->courseid))) { $grade_items = array(); foreach ($all_grade_items as $item) { $grade_items[$item->sortorder] = $item; } unset($all_grade_items); ksort($grade_items); $total = $grade_items[1]; unset($grade_items[1]); $grade_items[] = $total; foreach ($grade_items as $grade_item) { $decimalpoints = $grade_item->get_decimals(); $data = array(); $grade_grade = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $this->user->id)); // TODO: indicate items that "needsupdate" - missing final calculation /// prints grade item name if ($grade_item->is_course_item() or $grade_item->is_category_item()) { $data[] = '<b>' . $grade_item->get_name() . '</b>'; } else { $data[] = $this->get_module_link($grade_item->get_name(), $grade_item->itemmodule, $grade_item->iteminstance); } /// prints category $cat = $grade_item->get_parent_category(); $data[] = $cat->fullname; /// prints the grade $displaytype = $grade_item->get_displaytype(); if ($grade_grade->is_excluded()) { $excluded = get_string('excluded', 'grades') . ' '; } else { $excluded = ''; } if ((int) $grade_grade->finalgrade < 1) { $data[] = '-'; } elseif ($grade_grade->is_hidden() && !has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $grade_item->courseid))) { $data[] = get_string('gradedon', 'grades', userdate($grade_grade->timemodified)); } elseif ($grade_item->scaleid) { if ($scale = get_record('scale', 'id', $grade_item->scaleid)) { $scales = explode(",", $scale->scale); // reindex because scale is off 1 $data[] = $excluded . $scales[$grade_grade->finalgrade - 1]; } } else { $data[] = $excluded . grade_format_gradevalue($grade_grade->finalgrade, $grade_item, true, $displaytype, $decimalpoints); } /// prints percentage if ($grade_grade->is_hidden() && !has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $grade_item->courseid))) { if ((int) $grade_grade->finalgrade < 1) { $data[] = '-'; } else { $data[] = get_string('gradedon', 'grades', userdate($grade_grade->timemodified)); } } else { if ($grade_item->gradetype == GRADE_TYPE_VALUE) { // processing numeric grade if ($grade_grade->finalgrade) { $percentage = format_float($grade_grade->finalgrade / $grade_item->grademax * 100, $decimalpoints) . '%'; } else { $percentage = '-'; } } else { if ($grade_item->gradetype == GRADE_TYPE_SCALE) { // processing scale grade $scale = get_record('scale', 'id', $grade_item->scaleid); $scalevals = explode(",", $scale->scale); $percentage = format_float($grade_grade->finalgrade / count($scalevals) * 100, $decimalpoints) . '%'; } else { // text grade $percentage = '-'; } } $data[] = $percentage; } /// prints rank if ($grade_grade->finalgrade) { /// find the number of users with a higher grade $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {$CFG->prefix}grade_grades\n WHERE finalgrade > {$grade_grade->finalgrade}\n AND itemid = {$grade_item->id}"; $rank = count_records_sql($sql) + 1; $data[] = "{$rank}/{$numusers}"; } else { // no grade, no rank $data[] = "-"; } /// prints notes if (!empty($grade_grade->feedback)) { $data[] = format_text($grade_grade->feedback, $grade_grade->feedbackformat); } else { $data[] = ' '; } $this->table->add_data($data); } return true; } else { notify(get_string('nogradeitem', 'grades')); return false; } }