Exemple #1
0
/**
 * 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;
}
Exemple #2
0
 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;
 }
Exemple #4
0
 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;
     }
 }
Exemple #5
0
 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'] = '&nbsp;';
             } 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]);
         }
     }
 }
Exemple #6
0
    /**
     * 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'] = '&nbsp;';
                    } 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);
        }
    }
Exemple #7
0
 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;
     }
 }
Exemple #8
0
 /**
  * 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;
     }
 }
Exemple #9
0
 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'] = '&nbsp;';
                     } 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]);
         }
     }
 }
Exemple #10
0
 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">&nbsp;</div>';
         } else {
             $data[] = '<div class="' . $hidden . 'feedbacktext">' . format_text($grade_grade->feedback, $grade_grade->feedbackformat) . '</div>';
         }
         $this->table->add_data($data);
     }
     return true;
 }
Exemple #11
0
 /**
  * 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;
 }
Exemple #12
0
 /**
  * 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;
                     }
                 }
             }
         }
     }
 }
Exemple #14
0
 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;
     }
 }
Exemple #15
0
 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;
     }
 }
Exemple #16
0
 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;
     }
 }
Exemple #17
0
 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'] = '&nbsp;';
                     } 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]);
         }
     }
 }
Exemple #18
0
 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[] = '&nbsp;';
             }
             $this->table->add_data($data);
         }
         return true;
     } else {
         notify(get_string('nogradeitem', 'grades'));
         return false;
     }
 }