private function get_moodle_grades() { global $DB, $CFG; $grades = $DB->get_records('grade_grades', array('itemid' => $this->course_grade_item->id), 'userid', 'userid, finalgrade'); if (!is_array($grades)) { $grades = array(); } $this->moodle_grades = array(); if ($this->course_grade_item->gradetype == GRADE_TYPE_SCALE) { $pg_scale = new grade_scale(array('id' => $CFG->grade_report_newgradereport_scale)); $scale_items = $pg_scale->load_items(); foreach ($this->moodle_students as $st) { if (isset($grades[$st->id])) { $fg = (int) $grades[$st->id]->finalgrade; if (isset($scale_items[$fg - 1])) { $this->moodle_grades[$st->id] = $scale_items[$fg - 1]; } else { $this->moodle_grades[$st->id] = null; } } else { $this->moodle_grades[$st->id] = null; } } } else { foreach ($this->moodle_students as $st) { if (isset($grades[$st->id])) { $this->moodle_grades[$st->id] = grade_format_gradevalue($grades[$st->id]->finalgrade, $this->course_grade_item, true, $this->course_grade_item->get_displaytype(), null); } else { $this->moodle_grades[$st->id] = null; } } } }
/** * Prepare to print the course grade. * * @deprecated since iomadcertificate version 2012052501 * @param stdClass $course * @return mixed */ function iomadcertificate_print_course_grade($course) { debugging('iomadcertificate_print_course_grade is deprecated, please use iomadcertificate_get_grade instead. Ideally you should be using iomadcertificate_get_grade in your iomadcertificate type which will either get the course or module grade depending on your iomadcertificate settings.', DEBUG_DEVELOPER); global $USER, $DB; if ($course_item = grade_item::fetch_course_item($course->id)) { $grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $USER->id)); $course_item->gradetype = GRADE_TYPE_VALUE; $coursegrade = new stdClass(); $coursegrade->points = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_REAL, $decimals = 2); $coursegrade->percentage = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals = 2); $coursegrade->letter = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals = 0); return $coursegrade; } return false; }
public function edit_form(&$mform, $locks) { global $COURSE; foreach ($locks as $lock) { if ($lock['type'] == 'grade' and $item = $this->get_grade_item($lock['id'])) { $name = $this->get_grade_item_name($item); $mform->addElement('header', 'grade_' . $lock['id'] . '_header', get_string('activitygradelockx', 'format_page', $name)); $fieldname = 'grade[' . $lock['id'] . '][grade]'; $maxgrade = grade_format_gradevalue($item->grademax, $item); $gradegroup = array(); $gradegroup[] =& $mform->createElement('text', $fieldname, get_string('requiredgrade', 'format_page'), array('size' => '5')); $gradegroup[] =& $mform->createElement('static', "{$fieldname}_maxgrade", '', get_string('maxgradex', 'format_page', $maxgrade)); $mform->addGroup($gradegroup, "group{$fieldname}", get_string('requiredgrade', 'format_page'), ' ', false); $mform->setHelpButton("group{$fieldname}", array('reqgrade', get_string('requiredgrade', 'format_page'), 'format_page')); $mform->setDefault($fieldname, $lock['grade']); $mform->addElement('checkbox', 'grade[' . $lock['id'] . '][delete]', get_string('removelock', 'format_page')); } } }
/** * Get the given user courses final grades * * @param int $userid get grades for this user (optional, default current) * * @return array the grades tables * @since Moodle 3.2 */ public static function get_course_grades($userid = 0) { global $USER; $warnings = array(); // Validate the parameter. $params = self::validate_parameters(self::get_course_grades_parameters(), array('userid' => $userid)); $userid = $params['userid']; if (empty($userid)) { $userid = $USER->id; } $systemcontext = context_system::instance(); self::validate_context($systemcontext); if ($USER->id != $userid) { // We must check if the current user can view other users grades. $user = core_user::get_user($userid, '*', MUST_EXIST); core_user::require_active_user($user); require_capability('moodle/grade:viewall', $systemcontext); } // We need the site course, and course context. $course = get_course(SITEID); $context = context_course::instance($course->id); // Force a regrade if required. grade_regrade_final_grades_if_required($course); // Get the course final grades now. $gpr = new grade_plugin_return(array('type' => 'report', 'plugin' => 'overview', 'courseid' => $course->id, 'userid' => $userid)); $report = new grade_report_overview($userid, $gpr, $context); $coursesgrades = $report->setup_courses_data(true); $grades = array(); foreach ($coursesgrades as $coursegrade) { $gradeinfo = array('courseid' => $coursegrade['course']->id, 'grade' => grade_format_gradevalue($coursegrade['finalgrade'], $coursegrade['courseitem'], true), 'rawgrade' => $coursegrade['finalgrade']); if (isset($coursegrade['rank'])) { $gradeinfo['rank'] = $coursegrade['rank']; } $grades[] = $gradeinfo; } $result = array(); $result['grades'] = $grades; $result['warnings'] = $warnings; return $result; }
/** * Hook for export the next data record in-place * * @return array The next record to be exported */ public function next() { // Fetch the current record. $record = $this->recordset->current(); // Set up our grade item. $grade_item = new stdClass(); if ($record->mdlcrsid !== null) { $grade_item->courseid = $record->mdlcrsid; } else { $grade_item->courseid = SITEID; } $grade_item->gradetype = GRADE_TYPE_VALUE; $grade_item->grademin = 0; $grade_item->grademax = 100; // Write the line out of a file. $csvrecord = array($record->firstname, $record->lastname, $record->username, $record->idnumber, $record->crsidnumber, date('M/d/Y', $record->enrolmenttime), date('M/d/Y', $record->completetime), $this->completestatusstring, $record->grade, grade_format_gradevalue($record->grade, $grade_item, true, GRADE_DISPLAY_TYPE_LETTER, 5)); // Add additional data for extra fields. $additional_data = rlipexport_version1elis_extrafields::get_all_data($record); $csvrecord = array_merge($csvrecord, $additional_data); // Move on to the next data record. $this->recordset->next(); return $csvrecord; }
/** * Builds and return the row of averages for the right part of the grader report. * @param array $rows Whether to return only group averages or all averages. * @param bool $grouponly Whether to return only group averages or all averages. * @return array Array of rows for the right part of the report */ public function get_right_avg_row($rows = array(), $grouponly = false) { global $USER, $DB, $OUTPUT, $CFG; if (!$this->canviewhidden) { // Totals might be affected by hiding, if user can not see hidden grades the aggregations might be altered // better not show them at all if user can not see all hidden grades. return $rows; } $averagesdisplaytype = $this->get_pref('averagesdisplaytype'); $averagesdecimalpoints = $this->get_pref('averagesdecimalpoints'); $meanselection = $this->get_pref('meanselection'); $shownumberofgrades = $this->get_pref('shownumberofgrades'); if ($grouponly) { $showaverages = $this->currentgroup && $this->get_pref('showaverages'); $groupsql = $this->groupsql; $groupwheresql = $this->groupwheresql; $groupwheresqlparams = $this->groupwheresql_params; } else { $showaverages = $this->get_pref('showaverages'); $groupsql = ""; $groupwheresql = ""; $groupwheresqlparams = array(); } if ($showaverages) { $totalcount = $this->get_numusers($grouponly); // Limit to users with a gradeable role. list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0'); // Limit to users with an active enrollment. $coursecontext = $this->context->get_course_context(true); $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol); $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol); $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $coursecontext); list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context, '', 0, $showonlyactiveenrol); // We want to query both the current context and parent contexts. list($relatedctxsql, $relatedctxparams) = $DB->get_in_or_equal($this->context->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'relatedctx'); $params = array_merge(array('courseid' => $this->courseid), $gradebookrolesparams, $enrolledparams, $groupwheresqlparams, $relatedctxparams); // Find sums of all grade items in course. $sql = "SELECT g.itemid, SUM(g.finalgrade) AS sum\n FROM {grade_items} gi\n JOIN {grade_grades} g ON g.itemid = gi.id\n JOIN {user} u ON u.id = g.userid\n JOIN ({$enrolledsql}) je ON je.id = u.id\n JOIN (\n SELECT DISTINCT ra.userid\n FROM {role_assignments} ra\n WHERE ra.roleid {$gradebookrolessql}\n AND ra.contextid {$relatedctxsql}\n ) rainner ON rainner.userid = u.id\n {$groupsql}\n WHERE gi.courseid = :courseid\n AND u.deleted = 0\n AND g.finalgrade IS NOT NULL\n {$groupwheresql}\n GROUP BY g.itemid"; $sumarray = array(); if ($sums = $DB->get_records_sql($sql, $params)) { foreach ($sums as $itemid => $csum) { $sumarray[$itemid] = $csum->sum; } } // MDL-10875 Empty grades must be evaluated as grademin, NOT always 0 // This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table) $sql = "SELECT gi.id, COUNT(DISTINCT u.id) AS count\n FROM {grade_items} gi\n CROSS JOIN {user} u\n JOIN ({$enrolledsql}) je\n ON je.id = u.id\n JOIN {role_assignments} ra\n ON ra.userid = u.id\n LEFT OUTER JOIN {grade_grades} g\n ON (g.itemid = gi.id AND g.userid = u.id AND g.finalgrade IS NOT NULL)\n {$groupsql}\n WHERE gi.courseid = :courseid\n AND ra.roleid {$gradebookrolessql}\n AND ra.contextid {$relatedctxsql}\n AND u.deleted = 0\n AND g.id IS NULL\n {$groupwheresql}\n GROUP BY gi.id"; $ungradedcounts = $DB->get_records_sql($sql, $params); $avgrow = new html_table_row(); $avgrow->attributes['class'] = 'avg'; foreach ($this->gtree->items as $itemid => $unused) { $item =& $this->gtree->items[$itemid]; if ($item->needsupdate) { $avgcell = new html_table_cell(); $avgcell->attributes['class'] = 'i' . $itemid; $avgcell->text = $OUTPUT->container(get_string('error'), 'gradingerror'); $avgrow->cells[] = $avgcell; continue; } if (!isset($sumarray[$item->id])) { $sumarray[$item->id] = 0; } if (empty($ungradedcounts[$itemid])) { $ungradedcount = 0; } else { $ungradedcount = $ungradedcounts[$itemid]->count; } if ($meanselection == GRADE_REPORT_MEAN_GRADED) { $meancount = $totalcount - $ungradedcount; } else { // Bump up the sum by the number of ungraded items * grademin $sumarray[$item->id] += $ungradedcount * $item->grademin; $meancount = $totalcount; } // Determine which display type to use for this average if ($USER->gradeediting[$this->courseid]) { $displaytype = GRADE_DISPLAY_TYPE_REAL; } else { if ($averagesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) { // no ==0 here, please resave the report and user preferences $displaytype = $item->get_displaytype(); } else { $displaytype = $averagesdisplaytype; } } // Override grade_item setting if a display preference (not inherit) was set for the averages if ($averagesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) { $decimalpoints = $item->get_decimals(); } else { $decimalpoints = $averagesdecimalpoints; } if (!isset($sumarray[$item->id]) || $meancount == 0) { $avgcell = new html_table_cell(); $avgcell->attributes['class'] = 'i' . $itemid; $avgcell->text = '-'; $avgrow->cells[] = $avgcell; } else { $sum = $sumarray[$item->id]; $avgradeval = $sum / $meancount; $gradehtml = grade_format_gradevalue($avgradeval, $item, true, $displaytype, $decimalpoints); $numberofgrades = ''; if ($shownumberofgrades) { $numberofgrades = " ({$meancount})"; } $avgcell = new html_table_cell(); $avgcell->attributes['class'] = 'i' . $itemid; $avgcell->text = $gradehtml . $numberofgrades; $avgrow->cells[] = $avgcell; } } $rows[] = $avgrow; } return $rows; }
/** * Build the array of grades for the report. * * @param int $courseid The course record ID. * @param mixed $users An array of user IDs. * @param int $startdate The start date for the time period to fetch logs. * @param int $enddate The end date for the time period to fetch logs. * @return array An array of user course log information. * @uses $CFG, $DB */ function report_ncccscensus_build_grades_array($courseid, $users, $startdate, $enddate) { global $CFG, $DB; require_once $CFG->dirroot . '/lib/gradelib.php'; require_once $CFG->dirroot . '/lib/grade/constants.php'; require_once $CFG->dirroot . '/lib/grade/grade_item.php'; require_once $CFG->dirroot . '/mod/assign/locallib.php'; require_once $CFG->dirroot . '/mod/quiz/locallib.php'; $reportname = 'report_ncccscensus'; $context = context_course::instance($courseid); $results = array(); $gis = array(); if (empty($users)) { $users = 'null'; } else { $users = implode(',', $users); } // Pass #1 - Get any graded forum post records from the DB. $sql = 'SELECT DISTINCT u.id AS userid, fp.id AS postid, gi.id AS giid, u.firstname, u.lastname, u.idnumber, gg.overridden, fp.message, gi.itemname, gg.finalgrade, fp.created AS timesubmitted, fp.modified AS timecreated, u.firstnamephonetic, u.lastnamephonetic, u.middlename, u.alternatename FROM {forum_posts} fp INNER JOIN {forum_discussions} fd ON fd.id = fp.discussion INNER JOIN {forum} f ON f.id = fd.forum INNER JOIN {grade_items} gi ON gi.iteminstance = fd.forum LEFT JOIN {grade_grades} gg ON gg.itemid = gi.id AND gg.userid = fp.userid INNER JOIN {user} u ON u.id = fp.userid AND fp.userid in (' . $users . ') WHERE fd.course = :courseid AND f.assessed > 0 AND fp.userid != 0 AND gi.itemmodule = \'forum\' AND fp.created >= :timestart AND fp.created <= :timeend ORDER BY fp.created ASC, u.lastname ASC, u.firstname ASC'; $dbparams = array('courseid' => $courseid, 'timestart' => $startdate, 'timeend' => $enddate); $rs = $DB->get_recordset_sql($sql, $dbparams); foreach ($rs as $record) { if (empty($gis[$record->giid])) { $gis[$record->giid] = new grade_item(array('id' => $record->giid)); } // Only record the oldest record found. if (empty($results[$record->userid]) || $record->timecreated < $results[$record->userid]->timecreated) { if (empty($record->finalgrade)) { $grade = get_string('nograde', $reportname); $date = ''; } else { $grade = grade_format_gradevalue($record->finalgrade, $gis[$record->giid]); $date = userdate($record->timecreated, get_string('dateformat', $reportname)); } $result = new stdClass(); $result->userid = $record->userid; $result->lastname = $record->lastname; $result->firstname = $record->firstname; $result->student = fullname($record); $result->studentid = $record->idnumber; $result->activity = $record->itemname; $result->module = get_string('moduleforum', $reportname); $result->status = get_string('submissionstatusna', $reportname); // No status info required for 'forum'. $result->submitdate = userdate($record->timesubmitted, get_string('dateformat', $reportname)); $result->grade = $grade; $result->overridden = $record->overridden; $result->timecreated = $record->timecreated; $result->date = $date; $results[$record->userid] = $result; } } unset($rs); // Pass #2 - Get any graded glossary entries from the DB. $sql = 'SELECT u.id AS userid, ent.id AS entid, gi.id AS giid, u.firstname, u.lastname, u.idnumber, gi.itemname, gg.finalgrade, ent.timecreated AS timesubmitted, ent.timemodified AS timecreated, gg.overridden, u.firstnamephonetic, u.lastnamephonetic, u.middlename, u.alternatename FROM {glossary_entries} ent INNER JOIN {glossary} glos ON ent.glossaryid = glos.id INNER JOIN {grade_items} gi ON gi.iteminstance = glos.id LEFT JOIN {grade_grades} gg ON gg.itemid = gi.id AND gg.userid = ent.userid INNER JOIN {user} u ON u.id = ent.userid AND ent.userid in (' . $users . ') WHERE glos.course = :courseid AND glos.assessed > 0 AND ent.userid != 0 AND gi.itemmodule = \'glossary\' AND ent.timecreated >= :timestart AND ent.timecreated <= :timeend'; $dbparams = array('courseid' => $courseid, 'timestart' => $startdate, 'timeend' => $enddate); $rs = $DB->get_recordset_sql($sql, $dbparams); foreach ($rs as $record) { if (empty($gis[$record->giid])) { $gis[$record->giid] = new grade_item(array('id' => $record->giid)); } // Only record the oldest record found. if (empty($results[$record->userid]) || $record->timecreated < $results[$record->userid]->timecreated) { if (empty($record->finalgrade)) { $grade = get_string('nograde', $reportname); $date = ''; } else { $grade = grade_format_gradevalue($record->finalgrade, $gis[$record->giid]); $date = userdate($record->timecreated, get_string('dateformat', $reportname)); } $result = new stdClass(); $result->userid = $record->userid; $result->lastname = $record->lastname; $result->firstname = $record->firstname; $result->student = fullname($record); $result->studentid = $record->idnumber; $result->activity = $record->itemname; $result->module = get_string('moduleglossary', $reportname); $result->status = get_string('submissionstatusna', $reportname); // No status info required for 'glossary'. $result->submitdate = userdate($record->timesubmitted, get_string('dateformat', $reportname)); $result->grade = $grade; $result->overridden = $record->overridden; $result->timecreated = $record->timecreated; $result->date = $date; $results[$record->userid] = $result; } } unset($rs); // Pass #3 - Get any graded assignment entries from the DB. $sql = 'SELECT u.id AS userid, s.id AS entid, gi.id AS giid, u.firstname, u.lastname, u.idnumber, s.status, gi.itemname, gg.finalgrade, s.timemodified AS timesubmitted, ag.timemodified AS timegraded, u.alternatename, s.timemodified AS timecreated, gg.overridden, u.firstnamephonetic, u.lastnamephonetic, u.middlename FROM {assign_submission} s INNER JOIN {assign} a ON s.assignment = a.id INNER JOIN {grade_items} gi ON gi.iteminstance = a.id LEFT JOIN {grade_grades} gg ON gg.itemid = gi.id AND gg.userid = s.userid LEFT JOIN {assign_grades} ag ON ag.assignment = a.id AND ag.userid = s.userid INNER JOIN {user} u ON u.id = s.userid AND s.userid in (' . $users . ') WHERE a.course = :courseid AND s.status NOT IN (\'' . ASSIGN_SUBMISSION_STATUS_NEW . '\', \'' . ASSIGN_SUBMISSION_STATUS_DRAFT . '\') AND s.userid != 0 AND gi.itemmodule = \'assign\' AND s.timemodified >= :timestart AND s.timemodified <= :timeend'; $dbparams = array('courseid' => $courseid, 'timestart' => $startdate, 'timeend' => $enddate); $rs = $DB->get_recordset_sql($sql, $dbparams); foreach ($rs as $record) { if (empty($gis[$record->giid])) { $gis[$record->giid] = new grade_item(array('id' => $record->giid)); } // Only record the oldest record found. if (empty($results[$record->userid]) || $record->timecreated < $results[$record->userid]->timecreated) { if (empty($record->finalgrade)) { $grade = get_string('nograde', $reportname); $date = ''; } else { $grade = grade_format_gradevalue($record->finalgrade, $gis[$record->giid]); $date = userdate($record->timegraded, get_string('dateformat', $reportname)); } $result = new stdClass(); $result->userid = $record->userid; $result->lastname = $record->lastname; $result->firstname = $record->firstname; $result->student = fullname($record); $result->studentid = $record->idnumber; $result->activity = $record->itemname; $result->module = get_string('moduleassignment', $reportname); $result->status = get_string('submissionstatus' . $record->status, $reportname); $result->submitdate = userdate($record->timesubmitted, get_string('dateformat', $reportname)); $result->grade = $grade; $result->overridden = $record->overridden; $result->timecreated = $record->timecreated; $result->date = $date; $results[$record->userid] = $result; } } unset($rs); // Pass #4 - Get any graded quiz from the DB. $sql = 'SELECT u.id AS userid, q.id AS qid, gi.id AS giid, u.firstname, u.lastname, u.idnumber, q.state, gi.itemname, gg.finalgrade, q.timefinish AS timesubmitted, q.timefinish AS timecreated, gg.overridden, qg.timemodified AS timegraded, u.firstnamephonetic, u.lastnamephonetic, u.middlename, u.alternatename FROM {quiz_attempts} q INNER JOIN {quiz} qu ON q.quiz = qu.id INNER JOIN {grade_items} gi ON gi.iteminstance = qu.id LEFT JOIN {grade_grades} gg ON gg.itemid = gi.id AND gg.userid = q.userid LEFT JOIN {quiz_grades} qg ON qg.quiz = qu.id AND qg.userid = q.userid INNER JOIN {user} u ON u.id = q.userid AND q.userid in (' . $users . ') WHERE qu.course = :courseid AND q.state NOT IN (\'' . quiz_attempt::IN_PROGRESS . '\', \'' . quiz_attempt::ABANDONED . '\') AND q.userid != 0 AND gi.itemmodule = \'quiz\' AND q.timefinish >= :timestart AND q.timefinish <= :timeend'; $dbparams = array('courseid' => $courseid, 'timestart' => $startdate, 'timeend' => $enddate); $rs = $DB->get_recordset_sql($sql, $dbparams); foreach ($rs as $record) { if (empty($gis[$record->giid])) { $gis[$record->giid] = new grade_item(array('id' => $record->giid)); } // Only record the oldest record found. if (empty($results[$record->userid]) || $record->timecreated < $results[$record->userid]->timecreated) { if (empty($record->finalgrade)) { $grade = get_string('nograde', $reportname); $date = ''; } else { $grade = grade_format_gradevalue($record->finalgrade, $gis[$record->giid]); $date = userdate($record->timegraded, get_string('dateformat', $reportname)); } $result = new stdClass(); $result->userid = $record->userid; $result->lastname = $record->lastname; $result->firstname = $record->firstname; $result->student = fullname($record); $result->studentid = $record->idnumber; $result->activity = $record->itemname; $result->module = get_string('modulequiz', $reportname); $result->status = get_string('submissionstatus' . $record->state, $reportname); $result->submitdate = userdate($record->timesubmitted, get_string('dateformat', $reportname)); $result->grade = $grade; $result->overridden = $record->overridden; $result->timecreated = $record->timecreated; $result->date = $date; $results[$record->userid] = $result; } } unset($rs); // Add in users without activity if desired. if (report_ncccscensus_check_field_status('showallstudents')) { $sql = 'SELECT u.id as userid, u.lastname, u.firstname, u.idnumber, u.firstnamephonetic, u.lastnamephonetic, u.middlename, u.alternatename FROM {user} u WHERE u.id in (' . $users . ')'; $rs = $DB->get_recordset_sql($sql); foreach ($rs as $record) { if (empty($results[$record->userid])) { $result = new stdClass(); $result->userid = $record->userid; $result->lastname = $record->lastname; $result->firstname = $record->firstname; $result->student = fullname($record); $result->studentid = $record->idnumber; $result->activity = get_string('noactivitycompleted', $reportname); $result->module = ''; $result->status = get_string('submissionstatusna', $reportname); $result->submitdate = ''; $result->grade = get_string('nograde', $reportname); $result->overridden = false; $result->timecreated = 0; $result->date = ''; $results[$record->userid] = $result; } } unset($rs); } // Sort the resulting data by using a "lastname ASC, firstname ASC" sorting algorithm. usort($results, 'report_ncccscensus_results_sort'); return $results; }
/** * 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; } }
/** * Returns a string representing the range of grademin - grademax for this grade item. * @param int $rangesdisplaytype * @param int $rangesdecimalpoints * @return string */ function get_formatted_range($rangesdisplaytype = null, $rangesdecimalpoints = null) { global $USER; // Determine which display type to use for this average if (isset($USER->gradeediting) && $USER->gradeediting[$this->courseid]) { $displaytype = GRADE_DISPLAY_TYPE_REAL; } else { if ($rangesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) { // no ==0 here, please resave report and user prefs $displaytype = $this->get_displaytype(); } else { $displaytype = $rangesdisplaytype; } } // Override grade_item setting if a display preference (not default) was set for the averages if ($rangesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) { $decimalpoints = $this->get_decimals(); } else { $decimalpoints = $rangesdecimalpoints; } if ($displaytype == GRADE_DISPLAY_TYPE_PERCENTAGE) { $grademin = "0 %"; $grademax = "100 %"; } else { $grademin = grade_format_gradevalue($this->grademin, $this, true, $displaytype, $decimalpoints); $grademax = grade_format_gradevalue($this->grademax, $this, true, $displaytype, $decimalpoints); } return $grademin . '–' . $grademax; }
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; } }
/** * Return a grade in user-friendly form, whether it's a scale or not. * * @param mixed $grade int|null * @param boolean $editing Are we allowing changes to this grade? * @param int $userid The user id the grade belongs to * @param int $modified Timestamp from when the grade was last modified * @return string User-friendly representation of grade */ public function display_grade($grade, $editing, $userid = 0, $modified = 0) { global $DB; static $scalegrades = array(); $o = ''; if ($this->get_instance()->grade >= 0) { // Normal number. if ($editing && $this->get_instance()->grade > 0) { if ($grade < 0) { $displaygrade = ''; } else { $displaygrade = format_float($grade, 2); } $o .= '<label class="accesshide" for="quickgrade_' . $userid . '">' . get_string('usergrade', 'assign') . '</label>'; $o .= '<input type="text" id="quickgrade_' . $userid . '" name="quickgrade_' . $userid . '" value="' . $displaygrade . '" size="6" maxlength="10" class="quickgrade"/>'; $o .= ' / ' . format_float($this->get_instance()->grade, 2); $o .= '<input type="hidden" name="grademodified_' . $userid . '" value="' . $modified . '"/>'; return $o; } else { $o .= '<input type="hidden" name="grademodified_' . $userid . '" value="' . $modified . '"/>'; if ($grade == -1 || $grade === null) { $o .= '-'; } else { $item = $this->get_grade_item(); $o .= grade_format_gradevalue($grade, $item); if ($item->get_displaytype() == GRADE_DISPLAY_TYPE_REAL) { // If displaying the raw grade, also display the total value. $o .= ' / ' . format_float($this->get_instance()->grade, 2); } } return $o; } } else { // Scale. if (empty($this->cache['scale'])) { if ($scale = $DB->get_record('scale', array('id' => -$this->get_instance()->grade))) { $this->cache['scale'] = make_menu_from_list($scale->scale); } else { $o .= '-'; return $o; } } if ($editing) { $o .= '<label class="accesshide" for="quickgrade_' . $userid . '">' . get_string('usergrade', 'assign') . '</label>'; $o .= '<select name="quickgrade_' . $userid . '" class="quickgrade">'; $o .= '<option value="-1">' . get_string('nograde') . '</option>'; foreach ($this->cache['scale'] as $optionid => $option) { $selected = ''; if ($grade == $optionid) { $selected = 'selected="selected"'; } $o .= '<option value="' . $optionid . '" ' . $selected . '>' . $option . '</option>'; } $o .= '</select>'; $o .= '<input type="hidden" ' . 'name="grademodified_' . $userid . '" ' . 'value="' . $modified . '"/>'; return $o; } else { $scaleid = (int) $grade; if (isset($this->cache['scale'][$scaleid])) { $o .= $this->cache['scale'][$scaleid]; return $o; } $o .= '-'; return $o; } } }
/** * Returns string representation of final grade * @param object $grade instance of grade_grade class * @param integer $gradedisplayconst grade display type constant. * @return string */ public function format_grade($grade, $gradedisplayconst = null) { $displaytype = $this->displaytype; if (is_array($this->displaytype) && !is_null($gradedisplayconst)) { $displaytype = $gradedisplayconst; } $gradeitem = $this->grade_items[$grade->itemid]; // We are going to store the min and max so that we can "reset" the grade_item for later. $grademax = $gradeitem->grademax; $grademin = $gradeitem->grademin; // Updating grade_item with this grade_grades min and max. $gradeitem->grademax = $grade->get_grade_max(); $gradeitem->grademin = $grade->get_grade_min(); $formattedgrade = grade_format_gradevalue($grade->finalgrade, $gradeitem, false, $displaytype, $this->decimalpoints); // Resetting the grade item in case it is reused. $gradeitem->grademax = $grademax; $gradeitem->grademin = $grademin; return $formattedgrade; }
/** * Returns grading information for given activity - optionally with users grades * Manual, course or category items can not be queried. * @param int $courseid id of course * @param string $itemtype 'mod', 'block' * @param string $itemmodule 'forum, 'quiz', etc. * @param int $iteminstance id of the item module * @param int $userid optional id of the graded user; if userid not used, returns only information about grade_item * @return array of grade information objects (scaleid, name, grade and locked status, etc.) indexed with itemnumbers */ function grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids = 0) { global $CFG; $return = new object(); $return->items = array(); $return->outcomes = array(); $course_item = grade_item::fetch_course_item($courseid); $needsupdate = array(); if ($course_item->needsupdate) { $result = grade_regrade_final_grades($courseid); if ($result !== true) { $needsupdate = array_keys($result); } } if ($grade_items = grade_item::fetch_all(array('itemtype' => $itemtype, 'itemmodule' => $itemmodule, 'iteminstance' => $iteminstance, 'courseid' => $courseid))) { foreach ($grade_items as $grade_item) { $decimalpoints = null; if (empty($grade_item->outcomeid)) { // prepare information about grade item $item = new object(); $item->itemnumber = $grade_item->itemnumber; $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(); $item->grades = array(); 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; } if (empty($userid_or_ids)) { $userids = array(); } else { if (is_array($userid_or_ids)) { $userids = $userid_or_ids; } else { $userids = array($userid_or_ids); } } if ($userids) { $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true); foreach ($userids as $userid) { $grade_grades[$userid]->grade_item =& $grade_item; $grade = new object(); $grade->grade = $grade_grades[$userid]->finalgrade; $grade->locked = $grade_grades[$userid]->is_locked(); $grade->hidden = $grade_grades[$userid]->is_hidden(); $grade->overridden = $grade_grades[$userid]->overridden; $grade->feedback = $grade_grades[$userid]->feedback; $grade->feedbackformat = $grade_grades[$userid]->feedbackformat; $grade->usermodified = $grade_grades[$userid]->usermodified; // create text representation of grade if (in_array($grade_item->id, $needsupdate)) { $grade->grade = false; $grade->str_grade = get_string('error'); } else { if (is_null($grade->grade)) { $grade->str_grade = '-'; } else { $grade->str_grade = grade_format_gradevalue($grade->grade, $grade_item); } } // create html representation of feedback if (is_null($grade->feedback)) { $grade->str_feedback = ''; } else { $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat); } $item->grades[$userid] = $grade; } } $return->items[$grade_item->itemnumber] = $item; } else { if (!($grade_outcome = grade_outcome::fetch(array('id' => $grade_item->outcomeid)))) { debugging('Incorect outcomeid found'); continue; } // outcome info $outcome = new object(); $outcome->itemnumber = $grade_item->itemnumber; $outcome->scaleid = $grade_outcome->scaleid; $outcome->name = $grade_outcome->get_name(); $outcome->locked = $grade_item->is_locked(); $outcome->hidden = $grade_item->is_hidden(); if (empty($userid_or_ids)) { $userids = array(); } else { if (is_array($userid_or_ids)) { $userids = $userid_or_ids; } else { $userids = array($userid_or_ids); } } if ($userids) { $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true); foreach ($userids as $userid) { $grade_grades[$userid]->grade_item =& $grade_item; $grade = new object(); $grade->grade = $grade_grades[$userid]->finalgrade; $grade->locked = $grade_grades[$userid]->is_locked(); $grade->hidden = $grade_grades[$userid]->is_hidden(); $grade->feedback = $grade_grades[$userid]->feedback; $grade->feedbackformat = $grade_grades[$userid]->feedbackformat; $grade->usermodified = $grade_grades[$userid]->usermodified; // create text representation of grade if (in_array($grade_item->id, $needsupdate)) { $grade->grade = false; $grade->str_grade = get_string('error'); } else { if (is_null($grade->grade)) { $grade->grade = 0; $grade->str_grade = get_string('nooutcome', 'grades'); } else { $grade->grade = (int) $grade->grade; $scale = $grade_item->load_scale(); $grade->str_grade = format_string($scale->scale_items[(int) $grade->grade - 1]); } } // create html representation of feedback if (is_null($grade->feedback)) { $grade->str_feedback = ''; } else { $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat); } $outcome->grades[$userid] = $grade; } } $return->outcomes[$grade_item->itemnumber] = $outcome; } } } // sort results using itemnumbers ksort($return->items, SORT_NUMERIC); ksort($return->outcomes, SORT_NUMERIC); return $return; }
private function fill_table_recursive(&$element) { global $CFG, $DB; $type = $element['type']; $depth = $element['depth']; $grade_object = $element['object']; $eid = $grade_object->id; $fullname = $this->gtree->get_element_header($element, true, true, true); $data = array(); $hidden = ''; $excluded = ''; $class = ''; // If this is a hidden grade category, hide it completely from the user if ($type == 'category' && $grade_object->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_object->is_hiddenuntil())) { return false; } if ($type == 'category') { $this->evenodd[$depth] = ($this->evenodd[$depth] + 1) % 2; } $alter = $this->evenodd[$depth] == 0 ? 'even' : 'odd'; /// Process those items that have scores associated if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem') { if (!($grade_grade = grade_grade::fetch(array('itemid' => $grade_object->id, 'userid' => $this->user->id)))) { $grade_grade = new grade_grade(); $grade_grade->userid = $this->user->id; $grade_grade->itemid = $grade_object->id; } $grade_grade->load_grade_item(); /// Hidden Items if ($grade_grade->grade_item->is_hidden()) { $hidden = ' hidden'; } // If this is a hidden grade item, hide it completely from the user. if ($grade_grade->is_hidden() && !$this->canviewhidden && ($this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN || $this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_grade->is_hiddenuntil())) { // return false; } else { /// Excluded Item if ($grade_grade->is_excluded()) { $fullname .= ' [' . get_string('excluded', 'grades') . ']'; $excluded = ' excluded'; } /// Other class information $class = "{$hidden} {$excluded}"; if ($this->switch) { // alter style based on whether aggregation is first or last $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggt b2b" : " item b1b"; } else { $class .= ($type == 'categoryitem' or $type == 'courseitem') ? " " . $alter . "d{$depth} baggb" : " item b1b"; } /// Name $data['itemname']['content'] = $fullname; $data['itemname']['class'] = $class; $data['itemname']['colspan'] = $this->maxdepth - $depth; /// Actual Grade $gradeval = $grade_grade->finalgrade; if ($grade_grade->grade_item->needsupdate) { $data['grade']['class'] = $class . ' gradingerror'; $data['grade']['content'] = get_string('error'); } else { if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden() and !$grade_grade->grade_item->is_category_item() and !$grade_grade->grade_item->is_course_item()) { // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records $class .= ' datesubmitted'; $data['grade']['class'] = $class; $data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort'))); } elseif ($grade_grade->is_hidden()) { $data['grade']['class'] = $class . ' hidden'; $data['grade']['content'] = '-'; } else { $data['grade']['class'] = $class; $gradeval = $this->blank_hidden_total($this->courseid, $grade_grade->grade_item, $gradeval); $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true); } } /// Percentage if ($this->showpercentage) { if ($grade_grade->grade_item->needsupdate) { $data['percentage']['class'] = $class . ' gradingerror'; $data['percentage']['content'] = get_string('error'); } elseif ($grade_grade->is_hidden()) { $data['percentage']['class'] = $class . ' hidden'; $data['percentage']['content'] = '-'; } else { $data['percentage']['class'] = $class; $data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE); } } /// Rank if ($this->showrank) { // TODO: this is broken if hidden grades present!! if ($grade_grade->grade_item->needsupdate) { $data['rank']['class'] = $class . ' gradingerror'; $data['rank']['content'] = get_string('error'); } elseif ($grade_grade->is_hidden()) { $data['rank']['class'] = $class . ' hidden'; $data['rank']['content'] = '-'; } else { if (is_null($gradeval)) { // no grade, no rank $data['rank']['class'] = $class; $data['rank']['content'] = '-'; } else { /// find the number of users with a higher grade $sql = "SELECT COUNT(DISTINCT(userid))\n FROM {grade_grades}\n WHERE finalgrade > ?\n AND itemid = ?"; $rank = $DB->count_records_sql($sql, array($grade_grade->finalgrade, $grade_grade->grade_item->id)) + 1; $data['rank']['class'] = $class; $data['rank']['content'] = "{$rank}/" . $this->get_numusers(false); // total course users } } } /// Feedback if (empty($grade_grade->feedback) or !$this->canviewhidden and $grade_grade->is_hidden()) { $data['feedback']['class'] = $class . ' feedbacktext'; $data['feedback']['content'] = ' '; } else { $data['feedback']['class'] = $class . ' feedbacktext'; $data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat, array('overflowdiv' => true)); } /// Range if ($this->showrange) { $data['range']['class'] = $class; $data['range']['content'] = $grade_grade->grade_item->get_formatted_range(); } } } /// Category if ($type == 'category') { $data['leader']['class'] = $class . ' ' . $alter . "d{$depth} b1t b2b b1l"; $data['leader']['rowspan'] = $element['rowspan']; if ($this->switch) { // alter style based on whether aggregation is first or last $data['itemname']['class'] = $class . ' ' . $alter . "d{$depth} b1b b1t"; } else { $data['itemname']['class'] = $class . ' ' . $alter . "d{$depth} b2t"; } $data['itemname']['colspan'] = $this->maxdepth - $depth + count($this->tablecolumns) - 1; $data['itemname']['content'] = $fullname; } /// Add this row to the overall system $this->tabledata[] = $data; /// Recursively iterate through all child elements if (isset($element['children'])) { foreach ($element['children'] as $key => $child) { $this->fill_table_recursive($element['children'][$key]); } } }
/** * Builds and return the HTML row of column totals. * @param bool $grouponly Whether to return only group averages or all averages. * @return string HTML */ function get_avghtml($grouponly = false) { global $CFG, $USER; if (!$this->canviewhidden) { // totals might be affected by hiding, if user can not see hidden grades the aggregations might be altered // better not show them at all if user can not see all hideen grades return; } $averagesdisplaytype = $this->get_pref('averagesdisplaytype'); $averagesdecimalpoints = $this->get_pref('averagesdecimalpoints'); $meanselection = $this->get_pref('meanselection'); $shownumberofgrades = $this->get_pref('shownumberofgrades'); $avghtml = ''; $avgcssclass = 'avg'; if ($grouponly) { $straverage = get_string('groupavg', 'grades'); $showaverages = $this->currentgroup && $this->get_pref('showaverages'); $groupsql = $this->groupsql; $groupwheresql = $this->groupwheresql; $avgcssclass = 'groupavg'; } else { $straverage = get_string('overallaverage', 'grades'); $showaverages = $this->get_pref('showaverages'); $groupsql = ""; $groupwheresql = ""; } if ($shownumberofgrades) { $straverage .= ' (' . get_string('submissions', 'grades') . ') '; } $totalcount = $this->get_numusers($grouponly); if ($showaverages) { // find sums of all grade items in course $SQL = "SELECT g.itemid, SUM(g.finalgrade) AS sum\n FROM {$CFG->prefix}grade_items gi\n JOIN {$CFG->prefix}grade_grades g ON g.itemid = gi.id\n JOIN {$CFG->prefix}user u ON u.id = g.userid\n JOIN {$CFG->prefix}role_assignments ra ON ra.userid = u.id\n {$groupsql}\n WHERE gi.courseid = {$this->courseid}\n AND ra.roleid in ({$this->gradebookroles})\n AND ra.contextid " . get_related_contexts_string($this->context) . "\n AND g.finalgrade IS NOT NULL\n {$groupwheresql}\n GROUP BY g.itemid"; $sum_array = array(); if ($sums = get_records_sql($SQL)) { foreach ($sums as $itemid => $csum) { $sum_array[$itemid] = $csum->sum; } } $columncount = 0; $avghtml = '<tr class="' . $avgcssclass . ' r' . $this->rowcount++ . '">'; // MDL-10875 Empty grades must be evaluated as grademin, NOT always 0 // This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table) $SQL = "SELECT gi.id, COUNT(u.id) AS count\n FROM {$CFG->prefix}grade_items gi\n CROSS JOIN {$CFG->prefix}user u\n JOIN {$CFG->prefix}role_assignments ra ON ra.userid = u.id\n LEFT OUTER JOIN {$CFG->prefix}grade_grades g ON (g.itemid = gi.id AND g.userid = u.id AND g.finalgrade IS NOT NULL)\n {$groupsql}\n WHERE gi.courseid = {$this->courseid}\n AND ra.roleid in ({$this->gradebookroles})\n AND ra.contextid " . get_related_contexts_string($this->context) . "\n AND g.id IS NULL\n {$groupwheresql}\n GROUP BY gi.id"; $ungraded_counts = get_records_sql($SQL); $fixedstudents = $this->is_fixed_students(); if (!$fixedstudents) { $colspan = ''; if ($this->get_pref('showuseridnumber')) { $colspan = 'colspan="2" '; } $avghtml .= '<th class="header c0 range" ' . $colspan . ' scope="row">' . $straverage . '</th>'; } foreach ($this->gtree->items as $itemid => $unused) { $item =& $this->gtree->items[$itemid]; if ($item->needsupdate) { $avghtml .= '<td class="cell c' . $columncount++ . '"><span class="gradingerror">' . get_string('error') . '</span></td>'; continue; } if (!isset($sum_array[$item->id])) { $sum_array[$item->id] = 0; } if (empty($ungraded_counts[$itemid])) { $ungraded_count = 0; } else { $ungraded_count = $ungraded_counts[$itemid]->count; } if ($meanselection == GRADE_REPORT_MEAN_GRADED) { $mean_count = $totalcount - $ungraded_count; } else { // Bump up the sum by the number of ungraded items * grademin $sum_array[$item->id] += $ungraded_count * $item->grademin; $mean_count = $totalcount; } $decimalpoints = $item->get_decimals(); // Determine which display type to use for this average if ($USER->gradeediting[$this->courseid]) { $displaytype = GRADE_DISPLAY_TYPE_REAL; } else { if ($averagesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) { // no ==0 here, please resave the report and user preferences $displaytype = $item->get_displaytype(); } else { $displaytype = $averagesdisplaytype; } } // Override grade_item setting if a display preference (not inherit) was set for the averages if ($averagesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) { $decimalpoints = $item->get_decimals(); } else { $decimalpoints = $averagesdecimalpoints; } if (!isset($sum_array[$item->id]) || $mean_count == 0) { $avghtml .= '<td class="cell c' . $columncount++ . '">-</td>'; } else { $sum = $sum_array[$item->id]; $avgradeval = $sum / $mean_count; $gradehtml = grade_format_gradevalue($avgradeval, $item, true, $displaytype, $decimalpoints); $numberofgrades = ''; if ($shownumberofgrades) { $numberofgrades = " ({$mean_count})"; } $avghtml .= '<td class="cell c' . $columncount++ . '">' . $gradehtml . $numberofgrades . '</td>'; } } $avghtml .= '</tr>'; } return $avghtml; }
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; } }
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; } }
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; } }
/** * Returns grading information for one or more activities, optionally with user grades * Manual, course or category items can not be queried. * * @category grade * @param int $courseid ID of course * @param string $itemtype Type of grade item. For example, 'mod' or 'block' * @param string $itemmodule More specific then $itemtype. For example, 'forum' or 'quiz'. May be NULL for some item types * @param int $iteminstance ID of the item module * @param mixed $userid_or_ids Either a single user ID, an array of user IDs or null. If user ID or IDs are not supplied returns information about grade_item * @return array Array of grade information objects (scaleid, name, grade and locked status, etc.) indexed with itemnumbers */ function grade_get_grades($courseid, $itemtype = null, $itemmodule = null, $iteminstance = null, $userid_or_ids = null) { global $CFG; if (empty($itemtype) or empty($itemmodule) or empty($iteminstance)) { debugging('itemtype, itemmodule or iteminstance parameters should not be empty. For Moodle 2.8 and onwards are required', DEBUG_DEVELOPER); } $return = new stdClass(); $return->items = array(); $return->outcomes = array(); $course_item = grade_item::fetch_course_item($courseid); $needsupdate = array(); if ($course_item->needsupdate) { $result = grade_regrade_final_grades($courseid); if ($result !== true) { $needsupdate = array_keys($result); } } $params = array('courseid' => $courseid); if (!empty($itemtype)) { $params['itemtype'] = $itemtype; } if (!empty($itemmodule)) { $params['itemmodule'] = $itemmodule; } if (!empty($iteminstance)) { $params['iteminstance'] = $iteminstance; } if ($grade_items = grade_item::fetch_all($params)) { foreach ($grade_items as $grade_item) { $decimalpoints = null; if (empty($grade_item->outcomeid)) { // prepare information about grade item $item = new stdClass(); $item->id = $grade_item->id; $item->itemnumber = $grade_item->itemnumber; $item->itemtype = $grade_item->itemtype; $item->itemmodule = $grade_item->itemmodule; $item->iteminstance = $grade_item->iteminstance; $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(); $item->grades = array(); 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; } if (empty($userid_or_ids)) { $userids = array(); } else { if (is_array($userid_or_ids)) { $userids = $userid_or_ids; } else { $userids = array($userid_or_ids); } } if ($userids) { $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true); foreach ($userids as $userid) { $grade_grades[$userid]->grade_item =& $grade_item; $grade = new stdClass(); $grade->grade = $grade_grades[$userid]->finalgrade; $grade->locked = $grade_grades[$userid]->is_locked(); $grade->hidden = $grade_grades[$userid]->is_hidden(); $grade->overridden = $grade_grades[$userid]->overridden; $grade->feedback = $grade_grades[$userid]->feedback; $grade->feedbackformat = $grade_grades[$userid]->feedbackformat; $grade->usermodified = $grade_grades[$userid]->usermodified; $grade->datesubmitted = $grade_grades[$userid]->get_datesubmitted(); $grade->dategraded = $grade_grades[$userid]->get_dategraded(); // create text representation of grade if ($grade_item->gradetype == GRADE_TYPE_TEXT or $grade_item->gradetype == GRADE_TYPE_NONE) { $grade->grade = null; $grade->str_grade = '-'; $grade->str_long_grade = $grade->str_grade; } else { if (in_array($grade_item->id, $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); } $item->grades[$userid] = $grade; } } $return->items[$grade_item->itemnumber] = $item; } else { if (!($grade_outcome = grade_outcome::fetch(array('id' => $grade_item->outcomeid)))) { debugging('Incorect outcomeid found'); continue; } // outcome info $outcome = new stdClass(); $outcome->id = $grade_item->id; $outcome->itemnumber = $grade_item->itemnumber; $outcome->itemtype = $grade_item->itemtype; $outcome->itemmodule = $grade_item->itemmodule; $outcome->iteminstance = $grade_item->iteminstance; $outcome->scaleid = $grade_outcome->scaleid; $outcome->name = $grade_outcome->get_name(); $outcome->locked = $grade_item->is_locked(); $outcome->hidden = $grade_item->is_hidden(); if (empty($userid_or_ids)) { $userids = array(); } else { if (is_array($userid_or_ids)) { $userids = $userid_or_ids; } else { $userids = array($userid_or_ids); } } if ($userids) { $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true); foreach ($userids as $userid) { $grade_grades[$userid]->grade_item =& $grade_item; $grade = new stdClass(); $grade->grade = $grade_grades[$userid]->finalgrade; $grade->locked = $grade_grades[$userid]->is_locked(); $grade->hidden = $grade_grades[$userid]->is_hidden(); $grade->feedback = $grade_grades[$userid]->feedback; $grade->feedbackformat = $grade_grades[$userid]->feedbackformat; $grade->usermodified = $grade_grades[$userid]->usermodified; // create text representation of grade if (in_array($grade_item->id, $needsupdate)) { $grade->grade = false; $grade->str_grade = get_string('error'); } else { if (is_null($grade->grade)) { $grade->grade = 0; $grade->str_grade = get_string('nooutcome', 'grades'); } else { $grade->grade = (int) $grade->grade; $scale = $grade_item->load_scale(); $grade->str_grade = format_string($scale->scale_items[(int) $grade->grade - 1]); } } // create html representation of feedback if (is_null($grade->feedback)) { $grade->str_feedback = ''; } else { $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat); } $outcome->grades[$userid] = $grade; } } if (isset($return->outcomes[$grade_item->itemnumber])) { // itemnumber duplicates - lets fix them! $newnumber = $grade_item->itemnumber + 1; while (grade_item::fetch(array('itemtype' => $itemtype, 'itemmodule' => $itemmodule, 'iteminstance' => $iteminstance, 'courseid' => $courseid, 'itemnumber' => $newnumber))) { $newnumber++; } $outcome->itemnumber = $newnumber; $grade_item->itemnumber = $newnumber; $grade_item->update('system'); } $return->outcomes[$grade_item->itemnumber] = $outcome; } } } // sort results using itemnumbers ksort($return->items, SORT_NUMERIC); ksort($return->outcomes, SORT_NUMERIC); return $return; }
/** * Retuns the HTML table cell for a user's grade for a grade_item * * @param object $user * @param int $itemid * @param int $columncount * @param int $nexttabindex * @param array $altered * @param array $unknown * * @return string */ function get_gradecellhtml($user, $itemid, $columncount, $nexttabindex, $altered = array(), $unknown = array()) { global $CFG, $USER; $strfeedback = $this->get_lang_string("feedback"); $strgrade = $this->get_lang_string('grade'); // Preload scale objects for items with a scaleid $scales_array = $this->get_scales_array(); $userid = $user->id; $item =& $this->gtree->items[$itemid]; $grade = $this->grades[$userid][$item->id]; // Get the decimal points preference for this item $decimalpoints = $item->get_decimals(); if (in_array($itemid, $unknown)) { $gradeval = null; } else { if (array_key_exists($itemid, $altered)) { $gradeval = $altered[$itemid]; } else { $gradeval = $grade->finalgrade; } } $gradecellhtml = ''; // MDL-11274 // Hide grades in the grader report if the current grader doesn't have 'moodle/grade:viewhidden' if (!$this->canviewhidden and $grade->is_hidden()) { if (!empty($CFG->grade_hiddenasdate) and $grade->get_datesubmitted() and !$item->is_category_item() and !$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 $gradecellhtml .= '<td class="cell c' . $columncount++ . '"><span class="datesubmitted">' . userdate($grade->get_datesubmitted(), get_string('strftimedatetimeshort')) . '</span></td>'; } else { $gradecellhtml .= '<td class="cell c' . $columncount++ . '">-</td>'; } continue; } // emulate grade element $eid = $this->gtree->get_grade_eid($grade); $element = array('eid' => $eid, 'object' => $grade, 'type' => 'grade'); $cellclasses = 'grade ajax cell c' . $columncount++; if ($item->is_category_item()) { $cellclasses .= ' cat'; } if ($item->is_course_item()) { $cellclasses .= ' course'; } if ($grade->is_overridden()) { $cellclasses .= ' overridden'; } if ($grade->is_excluded()) { $cellclasses .= ' excluded'; } $grade_title = '<div class="fullname">' . fullname($user) . '</div>'; $grade_title .= '<div class="itemname">' . $item->get_name(true) . '</div>'; if (!empty($grade->feedback) && !$USER->gradeediting[$this->courseid]) { $grade_title .= '<div class="feedback">' . wordwrap(trim(format_string($grade->feedback, $grade->feedbackformat)), 34, '<br/ >') . '</div>'; } $gradecellhtml .= "<td id=\"gradecell_u{$userid}-i{$itemid}\" class=\"{$cellclasses}\" title=\"{$grade_title}\">"; if ($grade->is_excluded()) { $gradecellhtml .= get_string('excluded', 'grades') . ' '; } // Do not show any icons if no grade (no record in DB to match) if (!$item->needsupdate and $USER->gradeediting[$this->courseid]) { $gradecellhtml .= $this->get_icons($element); // Add a class to the icon so that it floats left $gradecellhtml = str_replace('class="iconsmall"', 'class="iconsmall ajax"', $gradecellhtml); } $hidden = ''; if ($grade->is_hidden()) { $hidden = ' hidden '; } $gradepass = '******'; if ($grade->is_passed($item)) { $gradepass = '******'; } elseif (is_null($grade->is_passed($item))) { $gradepass = ''; } // 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) { $gradecellhtml .= '<span class="gradingerror' . $hidden . '">' . get_string('error') . '</span>'; } else { if ($USER->gradeediting[$this->courseid]) { $anchor_id = "gradevalue_{$userid}-i{$itemid}"; if ($item->scaleid && !empty($scales_array[$item->scaleid])) { $scale = $scales_array[$item->scaleid]; $gradeval = (int) $gradeval; // scales use only integers $scales = explode(",", $scale->scale); // reindex because scale is off 1 // MDL-12104 some previous scales might have taken up part of the array // so this needs to be reset $scaleopt = array(); $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'); } $gradecellhtml .= '<select name="grade_' . $userid . '_' . $item->id . '" class="gradescale editable" ' . 'id="gradescale_' . $userid . '-i' . $item->id . '" tabindex="' . $nexttabindex . '">' . "\n"; $gradecellhtml .= '<option value="-1">' . $nogradestr . "</option>\n"; foreach ($scaleopt as $val => $label) { $selected = ''; if ($val == $oldval) { $selected = 'selected="selected"'; } $gradecellhtml .= "<option value=\"{$val}\" {$selected}>{$label}</option>\n"; } $gradecellhtml .= "</select>\n"; } elseif (!empty($scale)) { $scales = explode(",", $scale->scale); // invalid grade if gradeval < 1 if ($gradeval < 1) { $gradecellhtml .= '<a tabindex="' . $nexttabindex . '" id="' . $anchor_id . '" class="gradevalue' . $hidden . $gradepass . '">-</a>'; } else { //just in case somebody changes scale $gradeval = (int) bounded_number($grade->grade_item->grademin, $gradeval, $grade->grade_item->grademax); $gradecellhtml .= '<a tabindex="' . $nexttabindex . '" id="' . $anchor_id . '" class="gradevalue' . $hidden . $gradepass . '">' . $scales[$gradeval - 1] . '</a>'; } } else { // no such scale, throw error? } } else { if ($item->gradetype != GRADE_TYPE_TEXT) { // Value type $value = $gradeval; if ($this->get_pref('quickgrading') and $grade->is_editable()) { $gradecellhtml .= '<a tabindex="' . $nexttabindex . '" id="' . $anchor_id . '" class="gradevalue' . $hidden . $gradepass . ' editable">' . $value . '</a>'; } else { $gradecellhtml .= '<a tabindex="' . $nexttabindex . '" id="' . $anchor_id . '" class="gradevalue' . $hidden . $gradepass . '">' . $value . '</a>'; } } } // If quickfeedback is on, print an input element if ($this->get_pref('showquickfeedback') and $grade->is_editable()) { if ($this->get_pref('quickgrading')) { $gradecellhtml .= '<br />'; } $feedback = s($grade->feedback); $anchor_id = "gradefeedback_{$userid}-i{$itemid}"; $gradecellhtml .= '<a '; if (empty($feedback)) { $feedback = get_string('addfeedback', 'grades'); } $feedback_tabindex = $nexttabindex + $this->numusers; $short_feedback = shorten_text($feedback, $this->feedback_trunc_length); $gradecellhtml .= ' tabindex="' . $feedback_tabindex . '" id="' . $anchor_id . '" class="gradefeedback editable">' . $short_feedback . '</a>'; $this->feedbacks[$userid][$item->id] = $feedback; } } else { // Not editing $gradedisplaytype = $item->get_displaytype(); if ($item->needsupdate) { $gradecellhtml .= '<span class="gradingerror' . $hidden . $gradepass . '">' . get_string('error') . '</span>'; } else { $gradecellhtml .= '<span class="gradevalue' . $hidden . $gradepass . '">' . grade_format_gradevalue($gradeval, $item, true, $gradedisplaytype, null) . '</span>'; } // Close feedback span if (!empty($grade->feedback)) { $gradecellhtml .= '</span>'; } } } if (!empty($this->gradeserror[$item->id][$userid])) { $gradecellhtml .= $this->gradeserror[$item->id][$userid]; } $gradecellhtml .= '</td>' . "\n"; return $gradecellhtml; }
/** * Returns the outcome to display on the certificate * * @param stdClass $certificate * @param stdClass $course * @return string the outcome */ function certificate_get_outcome($certificate, $course) { global $USER; if ($certificate->printoutcome > 0) { if ($grade_item = new grade_item(array('id' => $certificate->printoutcome))) { $outcomeinfo = new stdClass(); $outcomeinfo->name = $grade_item->get_name(); $outcome = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $USER->id)); $outcomeinfo->grade = grade_format_gradevalue($outcome->finalgrade, $grade_item, true, GRADE_DISPLAY_TYPE_REAL); return $outcomeinfo->name . ': ' . $outcomeinfo->grade; } } return ''; }
/** * Builds and return the row of averages for the right part of the grader report. * @param array $rows Whether to return only group averages or all averages. * @param bool $grouponly Whether to return only group averages or all averages. * @return array Array of rows for the right part of the report */ public function get_right_avg_row($rows=array(), $grouponly=false) { global $CFG, $USER, $DB, $OUTPUT; if (!$this->canviewhidden) { // totals might be affected by hiding, if user can not see hidden grades the aggregations might be altered // better not show them at all if user can not see all hidden grades return $rows; } $showaverages = $this->get_pref('showaverages'); $showaveragesgroup = $this->currentgroup && $showaverages; $averagesdisplaytype = $this->get_pref('averagesdisplaytype'); $averagesdecimalpoints = $this->get_pref('averagesdecimalpoints'); $meanselection = $this->get_pref('meanselection'); $shownumberofgrades = $this->get_pref('shownumberofgrades'); $avghtml = ''; $avgcssclass = 'avg'; if ($grouponly) { $straverage = get_string('groupavg', 'grades'); $showaverages = $this->currentgroup && $this->get_pref('showaverages'); $groupsql = $this->groupsql; $groupwheresql = $this->groupwheresql; $groupwheresqlparams = $this->groupwheresql_params; $avgcssclass = 'groupavg'; } else { $straverage = get_string('overallaverage', 'grades'); $showaverages = $this->get_pref('showaverages'); $groupsql = ""; $groupwheresql = ""; $groupwheresqlparams = array(); } if ($shownumberofgrades) { $straverage .= ' (' . get_string('submissions', 'grades') . ') '; } $totalcount = $this->get_numusers($grouponly); //limit to users with a gradeable role list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0'); //limit to users with an active enrollment list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context); if ($showaverages) { $params = array_merge(array('courseid'=>$this->courseid), $gradebookrolesparams, $enrolledparams, $groupwheresqlparams); // find sums of all grade items in course $SQL = "SELECT g.itemid, SUM(g.finalgrade) AS sum FROM {grade_items} gi JOIN {grade_grades} g ON g.itemid = gi.id JOIN {user} u ON u.id = g.userid JOIN ($enrolledsql) je ON je.id = u.id JOIN {role_assignments} ra ON ra.userid = u.id $groupsql WHERE gi.courseid = :courseid AND ra.roleid $gradebookrolessql AND ra.contextid ".get_related_contexts_string($this->context)." AND g.finalgrade IS NOT NULL $groupwheresql GROUP BY g.itemid"; $sumarray = array(); if ($sums = $DB->get_records_sql($SQL, $params)) { foreach ($sums as $itemid => $csum) { $sumarray[$itemid] = $csum->sum; } } // MDL-10875 Empty grades must be evaluated as grademin, NOT always 0 // This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table) $SQL = "SELECT gi.id, COUNT(u.id) AS count FROM {grade_items} gi CROSS JOIN {user} u JOIN ($enrolledsql) je ON je.id = u.id JOIN {role_assignments} ra ON ra.userid = u.id LEFT OUTER JOIN {grade_grades} g ON (g.itemid = gi.id AND g.userid = u.id AND g.finalgrade IS NOT NULL) $groupsql WHERE gi.courseid = :courseid AND ra.roleid $gradebookrolessql AND ra.contextid ".get_related_contexts_string($this->context)." AND g.id IS NULL $groupwheresql GROUP BY gi.id"; $ungradedcounts = $DB->get_records_sql($SQL, $params); $avgrow = new html_table_row(); $avgrow->attributes['class'] = 'avg'; foreach ($this->gtree->items as $itemid=>$unused) { $item =& $this->gtree->items[$itemid]; if ($item->needsupdate) { $avgcell = new html_table_cell(); $avgcell->text = $OUTPUT->container(get_string('error'), 'gradingerror'); $avgrow->cells[] = $avgcell; continue; } if (!isset($sumarray[$item->id])) { $sumarray[$item->id] = 0; } if (empty($ungradedcounts[$itemid])) { $ungradedcount = 0; } else { $ungradedcount = $ungradedcounts[$itemid]->count; } if ($meanselection == GRADE_REPORT_MEAN_GRADED) { $meancount = $totalcount - $ungradedcount; } else { // Bump up the sum by the number of ungraded items * grademin $sumarray[$item->id] += $ungradedcount * $item->grademin; $meancount = $totalcount; } $decimalpoints = $item->get_decimals(); // Determine which display type to use for this average if ($USER->gradeediting[$this->courseid]) { $displaytype = GRADE_DISPLAY_TYPE_REAL; } else if ($averagesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) { // no ==0 here, please resave the report and user preferences $displaytype = $item->get_displaytype(); } else { $displaytype = $averagesdisplaytype; } // Override grade_item setting if a display preference (not inherit) was set for the averages if ($averagesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) { $decimalpoints = $item->get_decimals(); } else { $decimalpoints = $averagesdecimalpoints; } if (!isset($sumarray[$item->id]) || $meancount == 0) { $avgcell = new html_table_cell(); $avgcell->text = '-'; $avgrow->cells[] = $avgcell; } else { $sum = $sumarray[$item->id]; $avgradeval = $sum/$meancount; $gradehtml = grade_format_gradevalue($avgradeval, $item, true, $displaytype, $decimalpoints); $numberofgrades = ''; if ($shownumberofgrades) { $numberofgrades = " ($meancount)"; } $avgcell = new html_table_cell(); $avgcell->text = $gradehtml.$numberofgrades; $avgrow->cells[] = $avgcell; } } $rows[] = $avgrow; } return $rows; }
/** * 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; }
/** * Returns string representation of final grade * @param $object $grade instance of grade_grade class * @return string */ function format_grade($grade) { $displaytype = null; if ($this->export_letters) { $displaytype = GRADE_DISPLAY_TYPE_LETTER; } else { $displaytype = GRADE_DISPLAY_TYPE_REAL; } return grade_format_gradevalue($grade->finalgrade, $this->grade_items[$grade->itemid], false, $displaytype, null); }
/** * Returns string representation of final grade * @param $object $grade instance of grade_grade class * @return string */ function format_grade($grade) { return grade_format_gradevalue($grade->finalgrade, $this->grade_items[$grade->itemid], false, $this->displaytype, $this->decimalpoints); }
/** * Returns string representation of final grade * @param object $grade instance of grade_grade class * @param integer $gradedisplayconst grade display type constant. * @return string */ public function format_grade($grade, $gradedisplayconst = null) { $displaytype = $this->displaytype; if (is_array($this->displaytype) && !is_null($gradedisplayconst)) { $displaytype = $gradedisplayconst; } return grade_format_gradevalue($grade->finalgrade, $this->grade_items[$grade->itemid], false, $displaytype, $this->decimalpoints); }
/** * Prepare to print the course grade. * * @param stdClass $course * @return mixed */ function certificate_print_course_grade($course) { global $USER, $DB; if ($course_item = grade_item::fetch_course_item($course->id)) { $grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $USER->id)); $course_item->gradetype = GRADE_TYPE_VALUE; $coursegrade = new stdClass(); $coursegrade->points = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_REAL, $decimals = 2); $coursegrade->percentage = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals = 2); $coursegrade->letter = grade_format_gradevalue($grade->finalgrade, $course_item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals = 0); return $coursegrade; } return false; }
/** * Returns latest grades * * @param string $user Username * @param int $cid Course identifier */ function get_last_user_grades($username, $limit) { global $CFG, $DB; $username = utf8_decode($username); $username = strtolower($username); $user = get_complete_user_data('username', $username); $uid = $user->id; if (!$limit) { $limit = 1000; } $SQL = "SELECT distinct(g.itemid), g.finalgrade,gi.courseid,gi.itemname,gi.id, g.timemodified as tm\n FROM {$CFG->prefix}grade_items gi\n JOIN {$CFG->prefix}grade_grades g ON g.itemid = gi.id\n JOIN {$CFG->prefix}user u ON u.id = g.userid\n JOIN {$CFG->prefix}role_assignments ra ON ra.userid = u.id\n WHERE g.finalgrade IS NOT NULL \n\t\t \tand gi.itemname IS NOT NULL\n\t\t\t AND u.id = ?\n \tORDER BY tm\n\t\t\tLIMIT {$limit}"; $sum_array = array(); $params = array($uid); if ($sums = $DB->get_records_sql($SQL, $params)) { $i = 0; foreach ($sums as $sum) { if (!($grade_grade = grade_grade::fetch(array('itemid' => $sum->id, 'userid' => $uid)))) { $grade_grade = new grade_grade(); $grade_grade->userid = $this->user->id; $grade_grade->itemid = $grade_object->id; } $grade_item = $grade_grade->load_grade_item(); $scale = $grade_item->load_scale(); $formatted_grade = grade_format_gradevalue($sum->finalgrade, $grade_item, true, GRADE_DISPLAY_TYPE_REAL); $t['itemname'] = $sum->itemname; $t['finalgrade'] = $formatted_grade; $t['average'] = $this->get_average_grade($grade_grade->itemid); $tareas[] = $t; $i++; } return $tareas; } return array(); }
/** * Builds the grade item averages. */ function calculate_averages() { global $USER, $DB; if ($this->showaverage) { // This settings are actually grader report settings (not user report) // however we're using them as having two separate but identical settings the // user would have to keep in sync would be annoying. $averagesdisplaytype = $this->get_pref('averagesdisplaytype'); $averagesdecimalpoints = $this->get_pref('averagesdecimalpoints'); $meanselection = $this->get_pref('meanselection'); $shownumberofgrades = $this->get_pref('shownumberofgrades'); $avghtml = ''; $groupsql = $this->groupsql; $groupwheresql = $this->groupwheresql; $totalcount = $this->get_numusers(false); // We want to query both the current context and parent contexts. list($relatedctxsql, $relatedctxparams) = $DB->get_in_or_equal($this->context->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'relatedctx'); // Limit to users with a gradeable role ie students. list($gradebookrolessql, $gradebookrolesparams) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0'); // Limit to users with an active enrolment. list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->context); $params = array_merge($this->groupwheresql_params, $gradebookrolesparams, $enrolledparams, $relatedctxparams); $params['courseid'] = $this->courseid; // find sums of all grade items in course $sql = "SELECT gg.itemid, SUM(gg.finalgrade) AS sum\n FROM {grade_items} gi\n JOIN {grade_grades} gg ON gg.itemid = gi.id\n JOIN {user} u ON u.id = gg.userid\n JOIN ({$enrolledsql}) je ON je.id = gg.userid\n JOIN (\n SELECT DISTINCT ra.userid\n FROM {role_assignments} ra\n WHERE ra.roleid {$gradebookrolessql}\n AND ra.contextid {$relatedctxsql}\n ) rainner ON rainner.userid = u.id\n {$groupsql}\n WHERE gi.courseid = :courseid\n AND u.deleted = 0\n AND gg.finalgrade IS NOT NULL\n AND gg.hidden = 0\n {$groupwheresql}\n GROUP BY gg.itemid"; $sum_array = array(); $sums = $DB->get_recordset_sql($sql, $params); foreach ($sums as $itemid => $csum) { $sum_array[$itemid] = $csum->sum; } $sums->close(); $columncount = 0; // Empty grades must be evaluated as grademin, NOT always 0 // This query returns a count of ungraded grades (NULL finalgrade OR no matching record in grade_grades table) // No join condition when joining grade_items and user to get a grade item row for every user // Then left join with grade_grades and look for rows with null final grade (which includes grade items with no grade_grade) $sql = "SELECT gi.id, COUNT(u.id) AS count\n FROM {grade_items} gi\n JOIN {user} u ON u.deleted = 0\n JOIN ({$enrolledsql}) je ON je.id = u.id\n JOIN (\n SELECT DISTINCT ra.userid\n FROM {role_assignments} ra\n WHERE ra.roleid {$gradebookrolessql}\n AND ra.contextid {$relatedctxsql}\n ) rainner ON rainner.userid = u.id\n LEFT JOIN {grade_grades} gg\n ON (gg.itemid = gi.id AND gg.userid = u.id AND gg.finalgrade IS NOT NULL AND gg.hidden = 0)\n {$groupsql}\n WHERE gi.courseid = :courseid\n AND gg.finalgrade IS NULL\n {$groupwheresql}\n GROUP BY gi.id"; $ungraded_counts = $DB->get_records_sql($sql, $params); foreach ($this->gtree->items as $itemid => $unused) { if (!empty($this->gtree->items[$itemid]->avg)) { continue; } $item = $this->gtree->items[$itemid]; if ($item->needsupdate) { $avghtml .= '<td class="cell c' . $columncount++ . '"><span class="gradingerror">' . get_string('error') . '</span></td>'; continue; } if (empty($sum_array[$item->id])) { $sum_array[$item->id] = 0; } if (empty($ungraded_counts[$itemid])) { $ungraded_count = 0; } else { $ungraded_count = $ungraded_counts[$itemid]->count; } //do they want the averages to include all grade items if ($meanselection == GRADE_REPORT_MEAN_GRADED) { $mean_count = $totalcount - $ungraded_count; } else { // Bump up the sum by the number of ungraded items * grademin $sum_array[$item->id] += $ungraded_count * $item->grademin; $mean_count = $totalcount; } // Determine which display type to use for this average if (!empty($USER->gradeediting) && $USER->gradeediting[$this->courseid]) { $displaytype = GRADE_DISPLAY_TYPE_REAL; } else { if ($averagesdisplaytype == GRADE_REPORT_PREFERENCE_INHERIT) { // no ==0 here, please resave the report and user preferences $displaytype = $item->get_displaytype(); } else { $displaytype = $averagesdisplaytype; } } // Override grade_item setting if a display preference (not inherit) was set for the averages if ($averagesdecimalpoints == GRADE_REPORT_PREFERENCE_INHERIT) { $decimalpoints = $item->get_decimals(); } else { $decimalpoints = $averagesdecimalpoints; } if (empty($sum_array[$item->id]) || $mean_count == 0) { $this->gtree->items[$itemid]->avg = '-'; } else { $sum = $sum_array[$item->id]; $avgradeval = $sum / $mean_count; $gradehtml = grade_format_gradevalue($avgradeval, $item, true, $displaytype, $decimalpoints); $numberofgrades = ''; if ($shownumberofgrades) { $numberofgrades = " ({$mean_count})"; } $this->gtree->items[$itemid]->avg = $gradehtml . $numberofgrades; } } } }
/** * Returns the outcome to display on the certificate * * @return string the outcome */ protected function get_outcome($userid) { global $USER, $DB; if (empty($userid)) { $userid = $USER->id; } if ($this->get_instance()->outcome > 0) { if ($grade_item = new grade_item(array('id' => $this->get_instance()->outcome))) { $outcomeinfo = new stdClass(); $outcomeinfo->name = $grade_item->get_name(); $outcome = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $userid)); $outcomeinfo->grade = grade_format_gradevalue($outcome->finalgrade, $grade_item, true, GRADE_DISPLAY_TYPE_REAL); return $outcomeinfo->name . ': ' . $outcomeinfo->grade; } } return ''; }