Exemple #1
0
 /**
  * Initialise the iterator
  * @return boolean success
  */
 function init()
 {
     global $CFG;
     $this->close();
     grade_regrade_final_grades($this->course->id);
     $course_item = grade_item::fetch_course_item($this->course->id);
     if ($course_item->needsupdate) {
         // can not calculate all final grades - sorry
         return false;
     }
     if (strpos($CFG->gradebookroles, ',') !== false) {
         $gradebookroles = " = {$CFG->gradebookroles}";
     } else {
         $gradebookroles = " IN ({$CFG->gradebookroles})";
     }
     $relatedcontexts = get_related_contexts_string(get_context_instance(CONTEXT_COURSE, $this->course->id));
     if ($this->groupid) {
         $groupsql = "INNER JOIN {$CFG->prefix}groups_members gm ON gm.userid = u.id";
         $groupwheresql = "AND gm.groupid = {$this->groupid}";
     } else {
         $groupsql = "";
         $groupwheresql = "";
     }
     $users_sql = "SELECT u.*\n                        FROM {$CFG->prefix}user u\n                             INNER JOIN {$CFG->prefix}role_assignments ra ON u.id = ra.userid\n                             {$groupsql}\n                       WHERE ra.roleid {$gradebookroles}\n                             AND ra.contextid {$relatedcontexts}\n                             {$groupwheresql}\n                    ORDER BY u.id ASC";
     $this->users_rs = get_recordset_sql($users_sql);
     if (!empty($this->grade_items)) {
         $itemids = array_keys($this->grade_items);
         $itemids = implode(',', $itemids);
         $grades_sql = "SELECT g.*\n                             FROM {$CFG->prefix}grade_grades g\n                                  INNER JOIN {$CFG->prefix}user u ON g.userid = u.id\n                                  INNER JOIN {$CFG->prefix}role_assignments ra ON u.id = ra.userid\n                                  {$groupsql}\n                            WHERE ra.roleid {$gradebookroles}\n                                  AND ra.contextid {$relatedcontexts}\n                                  AND g.itemid IN ({$itemids})\n                                  {$groupwheresql}\n                         ORDER BY g.userid ASC, g.itemid ASC";
         $this->grades_rs = get_recordset_sql($grades_sql);
     }
     return true;
 }
Exemple #2
0
 /**
  * Initialise the iterator
  * @return boolean success
  */
 public function init()
 {
     global $CFG, $DB;
     $this->close();
     grade_regrade_final_grades($this->course->id);
     $course_item = grade_item::fetch_course_item($this->course->id);
     if ($course_item->needsupdate) {
         // can not calculate all final grades - sorry
         return false;
     }
     $coursecontext = get_context_instance(CONTEXT_COURSE, $this->course->id);
     $relatedcontexts = get_related_contexts_string($coursecontext);
     list($gradebookroles_sql, $params) = $DB->get_in_or_equal(explode(',', $CFG->gradebookroles), SQL_PARAMS_NAMED, 'grbr');
     //limit to users with an active enrolment
     list($enrolledsql, $enrolledparams) = get_enrolled_sql($coursecontext);
     $params = array_merge($params, $enrolledparams);
     if ($this->groupid) {
         $groupsql = "INNER JOIN {groups_members} gm ON gm.userid = u.id";
         $groupwheresql = "AND gm.groupid = :groupid";
         // $params contents: gradebookroles
         $params['groupid'] = $this->groupid;
     } else {
         $groupsql = "";
         $groupwheresql = "";
     }
     if (empty($this->sortfield1)) {
         // we must do some sorting even if not specified
         $ofields = ", u.id AS usrt";
         $order = "usrt ASC";
     } else {
         $ofields = ", u.{$this->sortfield1} AS usrt1";
         $order = "usrt1 {$this->sortorder1}";
         if (!empty($this->sortfield2)) {
             $ofields .= ", u.{$this->sortfield2} AS usrt2";
             $order .= ", usrt2 {$this->sortorder2}";
         }
         if ($this->sortfield1 != 'id' and $this->sortfield2 != 'id') {
             // user order MUST be the same in both queries,
             // must include the only unique user->id if not already present
             $ofields .= ", u.id AS usrt";
             $order .= ", usrt ASC";
         }
     }
     // $params contents: gradebookroles and groupid (for $groupwheresql)
     $users_sql = "SELECT u.* {$ofields}\n                        FROM {user} u\n                        JOIN ({$enrolledsql}) je ON je.id = u.id\n                             {$groupsql}\n                        JOIN (\n                                  SELECT DISTINCT ra.userid\n                                    FROM {role_assignments} ra\n                                   WHERE ra.roleid {$gradebookroles_sql}\n                                     AND ra.contextid {$relatedcontexts}\n                             ) rainner ON rainner.userid = u.id\n                         WHERE u.deleted = 0\n                             {$groupwheresql}\n                    ORDER BY {$order}";
     $this->users_rs = $DB->get_recordset_sql($users_sql, $params);
     if (!empty($this->grade_items)) {
         $itemids = array_keys($this->grade_items);
         list($itemidsql, $grades_params) = $DB->get_in_or_equal($itemids, SQL_PARAMS_NAMED, 'items');
         $params = array_merge($params, $grades_params);
         // $params contents: gradebookroles, enrolledparams, groupid (for $groupwheresql) and itemids
         $grades_sql = "SELECT g.* {$ofields}\n                             FROM {grade_grades} g\n                             JOIN {user} u ON g.userid = u.id\n                             JOIN ({$enrolledsql}) je ON je.id = u.id\n                                  {$groupsql}\n                             JOIN (\n                                      SELECT DISTINCT ra.userid\n                                        FROM {role_assignments} ra\n                                       WHERE ra.roleid {$gradebookroles_sql}\n                                         AND ra.contextid {$relatedcontexts}\n                                  ) rainner ON rainner.userid = u.id\n                              WHERE u.deleted = 0\n                              AND g.itemid {$itemidsql}\n                              {$groupwheresql}\n                         ORDER BY {$order}, g.itemid ASC";
         $this->grades_rs = $DB->get_recordset_sql($grades_sql, $params);
     } else {
         $this->grades_rs = false;
     }
     return true;
 }
Exemple #3
0
 /**
  * Initialise the iterator
  * @return boolean success
  */
 function init()
 {
     global $CFG;
     $this->close();
     grade_regrade_final_grades($this->course->id);
     $course_item = grade_item::fetch_course_item($this->course->id);
     if ($course_item->needsupdate) {
         // can not calculate all final grades - sorry
         return false;
     }
     if (strpos($CFG->gradebookroles, ',') === false) {
         $gradebookroles = " = {$CFG->gradebookroles}";
     } else {
         $gradebookroles = " IN ({$CFG->gradebookroles})";
     }
     $relatedcontexts = get_related_contexts_string(get_context_instance(CONTEXT_COURSE, $this->course->id));
     if ($this->groupid) {
         $groupsql = "INNER JOIN {$CFG->prefix}groups_members gm ON gm.userid = u.id";
         $groupwheresql = "AND gm.groupid = {$this->groupid}";
     } else {
         $groupsql = "";
         $groupwheresql = "";
     }
     if (empty($this->sortfield1)) {
         // we must do some sorting even if not specified
         $ofields = ", u.id AS usrt";
         $order = "usrt ASC";
     } else {
         $ofields = ", u.{$this->sortfield1} AS usrt1";
         $order = "usrt1 {$this->sortorder1}";
         if (!empty($this->sortfield2)) {
             $ofields .= ", u.{$this->sortfield2} AS usrt2";
             $order .= ", usrt2 {$this->sortorder2}";
         }
         if ($this->sortfield1 != 'id' and $this->sortfield2 != 'id') {
             // user order MUST be the same in both queries, must include the only unique user->id if not already present
             $ofields .= ", u.id AS usrt";
             $order .= ", usrt ASC";
         }
     }
     $users_sql = "SELECT u.* {$ofields}\n                        FROM {$CFG->prefix}user u\n                             INNER JOIN {$CFG->prefix}role_assignments ra ON u.id = ra.userid\n                             {$groupsql}\n                       WHERE ra.roleid {$gradebookroles}\n                             AND ra.contextid {$relatedcontexts}\n                             {$groupwheresql}\n                    ORDER BY {$order}";
     $this->users_rs = get_recordset_sql($users_sql);
     if (!empty($this->grade_items)) {
         $itemids = array_keys($this->grade_items);
         $itemids = implode(',', $itemids);
         $grades_sql = "SELECT g.* {$ofields}\n                             FROM {$CFG->prefix}grade_grades g\n                                  INNER JOIN {$CFG->prefix}user u ON g.userid = u.id\n                                  INNER JOIN {$CFG->prefix}role_assignments ra ON u.id = ra.userid\n                                  {$groupsql}\n                            WHERE ra.roleid {$gradebookroles}\n                                  AND ra.contextid {$relatedcontexts}\n                                  AND g.itemid IN ({$itemids})\n                                  {$groupwheresql}\n                         ORDER BY {$order}, g.itemid ASC";
         $this->grades_rs = get_recordset_sql($grades_sql);
     } else {
         $this->grades_rs = false;
     }
     return true;
 }
/**
 * 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;
}
Exemple #5
0
 /**
  * Does this course have any visible feedback for current user?.
  *
  * @param $course
  * @return stdClass | null
  */
 public static function course_feedback($course)
 {
     global $USER;
     // Get course context.
     $coursecontext = \context_course::instance($course->id);
     // Security check - should they be allowed to see course grade?
     $onlyactive = true;
     if (!is_enrolled($coursecontext, $USER, 'moodle/grade:view', $onlyactive)) {
         return self::skipgradewarning('User not enrolled on course with capability moodle/grade:view');
     }
     // Security check - are they allowed to see the grade report for the course?
     if (!has_capability('gradereport/user:view', $coursecontext)) {
         return self::skipgradewarning('User does not have required course capability gradereport/user:view');
     }
     // See if user can view hidden grades for this course.
     $canviewhidden = has_capability('moodle/grade:viewhidden', $coursecontext);
     // Do not show grade if grade book disabled for students.
     // Note - moodle/grade:viewall is a capability held by teachers and thus used to exclude them from not getting
     // the grade.
     if (empty($course->showgrades) && !has_capability('moodle/grade:viewall', $coursecontext)) {
         return self::skipgradewarning('Course set up to not show gradebook to students');
     }
     // 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' => $USER->id));
     $coursegrade->grade_item =& $courseitem;
     // Return null if can't view.
     if ($coursegrade->is_hidden() && !$canviewhidden) {
         return self::skipgradewarning('Course grade is hidden from students');
     }
     // Use user grade report to get course total - this is to take hidden grade settings into account.
     $gpr = new \grade_plugin_return(array('type' => 'report', 'plugin' => 'user', 'courseid' => $course->id, 'userid' => $USER->id));
     $report = new \grade_report_user($course->id, $gpr, $coursecontext, $USER->id);
     $report->fill_table();
     $visiblegradefound = false;
     foreach ($report->tabledata as $item) {
         if (self::item_has_grade_or_feedback($item)) {
             $visiblegradefound = true;
             break;
         }
     }
     $feedbackhtml = '';
     if ($visiblegradefound) {
         // Just output - feedback available.
         $url = new \moodle_url('/grade/report/user/index.php', array('id' => $course->id));
         $feedbackhtml = \html_writer::link($url, get_string('feedbackavailable', 'theme_snap'), array('class' => 'coursegrade'));
     }
     return (object) array('feedbackhtml' => $feedbackhtml);
 }
/**
 * 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;
}
 /**
  * Validate that the method respects the locked status when run for a
  * specific user
  */
 public function test_methodonlyupdatesunlockedenrolmentsforspecificuserid()
 {
     global $DB;
     $this->load_csv_data();
     // Set up enrolments.
     $this->make_course_enrollable();
     enrol_try_internal_enrol(2, 100, 1);
     enrol_try_internal_enrol(2, 101, 1);
     // Set required PM course grade.
     $pmcourse = new \course(array('id' => 100, 'completion_grade' => 50));
     $pmcourse->save();
     // Set up course grade item.
     $coursegradeitem = \grade_item::fetch_course_item(2);
     $coursegradeitem->grademax = 100;
     $coursegradeitem->needsupdate = false;
     $coursegradeitem->locked = true;
     $coursegradeitem->update();
     // Assign student grades.
     $coursegradegrade = new \grade_grade(array('itemid' => 1, 'userid' => 100, 'finalgrade' => 100));
     $coursegradegrade->insert();
     $coursegradegrade = new \grade_grade(array('itemid' => 1, 'userid' => 101, 'finalgrade' => 100));
     $coursegradegrade->insert();
     // Enrol the student.
     $student = new \student();
     $student->userid = 103;
     $student->classid = 100;
     $student->grade = 0;
     $student->completestatusid = STUSTATUS_NOTCOMPLETE;
     $student->locked = 1;
     $student->save();
     // Call and validate that locked record is not changed.
     $sync = new \local_elisprogram\moodle\synchronize();
     $sync->synchronize_moodle_class_grades(100);
     $this->assert_student_exists(100, 103, 0, STUSTATUS_NOTCOMPLETE, null, null, 1);
     $DB->execute("UPDATE {" . \student::TABLE . "} SET locked = 0");
     // Call and validate that unlocked record is changed.
     $sync = new \local_elisprogram\moodle\synchronize();
     $sync->synchronize_moodle_class_grades(100);
     // Validate count.
     $count = $DB->count_records(\student::TABLE, array('completestatusid' => STUSTATUS_PASSED));
     $this->assertEquals(1, $count);
     // NOTE: this method does not lock enrolments.
     $this->assert_student_exists(100, 103, 100, STUSTATUS_PASSED, null, null, 0);
 }
Exemple #8
0
 protected function sub_test_grade_item_fetch_course_item()
 {
     $grade_item = grade_item::fetch_course_item($this->courseid);
     $this->assertTrue(method_exists($grade_item, 'fetch_course_item'));
     $this->assertEquals($grade_item->itemtype, 'course');
 }
Exemple #9
0
 /**
  * Tests grade_report::blank_hidden_total_and_adjust_bounds()
  */
 public function test_blank_hidden_total_and_adjust_bounds()
 {
     global $DB;
     $this->resetAfterTest(true);
     $student = $this->getDataGenerator()->create_user();
     $this->setUser($student);
     // Create a course and two activities.
     // One activity will be hidden.
     $course = $this->getDataGenerator()->create_course();
     $coursegradeitem = grade_item::fetch_course_item($course->id);
     $coursecontext = context_course::instance($course->id);
     $data = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $datacm = get_coursemodule_from_id('data', $data->cmid);
     $forum = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $forumcm = get_coursemodule_from_id('forum', $forum->cmid);
     // Insert student grades for the two activities.
     $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'data', 'iteminstance' => $data->id, 'courseid' => $course->id));
     $datagrade = 50;
     $grade_grade = new grade_grade();
     $grade_grade->itemid = $gi->id;
     $grade_grade->userid = $student->id;
     $grade_grade->rawgrade = $datagrade;
     $grade_grade->finalgrade = $datagrade;
     $grade_grade->rawgrademax = 100;
     $grade_grade->rawgrademin = 0;
     $grade_grade->timecreated = time();
     $grade_grade->timemodified = time();
     $grade_grade->insert();
     $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum->id, 'courseid' => $course->id));
     $forumgrade = 70;
     $grade_grade = new grade_grade();
     $grade_grade->itemid = $gi->id;
     $grade_grade->userid = $student->id;
     $grade_grade->rawgrade = $forumgrade;
     $grade_grade->finalgrade = $forumgrade;
     $grade_grade->rawgrademax = 100;
     $grade_grade->rawgrademin = 0;
     $grade_grade->timecreated = time();
     $grade_grade->timemodified = time();
     $grade_grade->insert();
     // Hide the database activity.
     set_coursemodule_visible($datacm->id, 0);
     $gpr = new grade_plugin_return(array('type' => 'report', 'courseid' => $course->id));
     $report = new grade_report_test($course->id, $gpr, $coursecontext, $student);
     // Should return the supplied student total grade regardless of hiding.
     $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN);
     $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
     $this->assertEquals(array('grade' => $datagrade + $forumgrade, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result);
     // Should blank the student total as course grade depends on a hidden item.
     $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN);
     $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
     $this->assertEquals(array('grade' => null, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result);
     // Should return the course total minus the hidden database activity grade.
     $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN);
     $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
     $this->assertEquals(array('grade' => floatval($forumgrade), 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result);
     // Note: we cannot simply hide modules and call $report->blank_hidden_total() again.
     // It stores grades in a static variable so $report->blank_hidden_total() will return incorrect totals
     // In practice this isn't a problem. Grade visibility isn't altered mid-request outside of the unit tests.
     // Add a second course to test:
     // 1) How a course with no visible activities behaves.
     // 2) That $report->blank_hidden_total() correctly moves on to the new course.
     $course = $this->getDataGenerator()->create_course();
     $coursegradeitem = grade_item::fetch_course_item($course->id);
     $coursecontext = context_course::instance($course->id);
     $data = $this->getDataGenerator()->create_module('data', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $datacm = get_coursemodule_from_id('data', $data->cmid);
     $forum = $this->getDataGenerator()->create_module('forum', array('assessed' => 1, 'scale' => 100, 'course' => $course->id));
     $forumcm = get_coursemodule_from_id('forum', $forum->cmid);
     $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'data', 'iteminstance' => $data->id, 'courseid' => $course->id));
     $datagrade = 50;
     $grade_grade = new grade_grade();
     $grade_grade->itemid = $gi->id;
     $grade_grade->userid = $student->id;
     $grade_grade->rawgrade = $datagrade;
     $grade_grade->finalgrade = $datagrade;
     $grade_grade->rawgrademax = 100;
     $grade_grade->rawgrademin = 0;
     $grade_grade->timecreated = time();
     $grade_grade->timemodified = time();
     $grade_grade->insert();
     $gi = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => 'forum', 'iteminstance' => $forum->id, 'courseid' => $course->id));
     $forumgrade = 70;
     $grade_grade = new grade_grade();
     $grade_grade->itemid = $gi->id;
     $grade_grade->userid = $student->id;
     $grade_grade->rawgrade = $forumgrade;
     $grade_grade->finalgrade = $forumgrade;
     $grade_grade->rawgrademax = 100;
     $grade_grade->rawgrademin = 0;
     $grade_grade->timecreated = time();
     $grade_grade->timemodified = time();
     $grade_grade->insert();
     // Hide both activities.
     set_coursemodule_visible($datacm->id, 0);
     set_coursemodule_visible($forumcm->id, 0);
     $gpr = new grade_plugin_return(array('type' => 'report', 'courseid' => $course->id));
     $report = new grade_report_test($course->id, $gpr, $coursecontext, $student);
     // Should return the supplied student total grade regardless of hiding.
     $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN);
     $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
     $this->assertEquals(array('grade' => $datagrade + $forumgrade, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result);
     // Should blank the student total as course grade depends on a hidden item.
     $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN);
     $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
     $this->assertEquals(array('grade' => null, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result);
     // Should return the course total minus the hidden activity grades.
     // They are both hidden so should return null.
     $report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN);
     $result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
     $this->assertEquals(array('grade' => null, 'grademax' => $coursegradeitem->grademax, 'grademin' => $coursegradeitem->grademin, 'aggregationstatus' => 'unknown', 'aggregationweight' => null), $result);
 }
Exemple #10
0
 /**
  * Updates raw grade value for given user, this is a only way to update raw
  * grades from external source (modules, etc.),
  * because it logs the change in history table and deals with final grade recalculation.
  *
  * @param int $userid the graded user
  * @param mixed $rawgrade float value of raw grade - false means do not change
  * @param string $howmodified modification source
  * @param string $note optional note
  * @param mixed $feedback teachers feedback as string - false means do not change
  * @param int $feedbackformat
  * @param int $usermodified - user which did the grading
  * @param int $dategraded
  * @param int $datesubmitted
  * @param object $grade object - usefull for bulk upgrades
  * @return boolean success
  */
 function update_raw_grade($userid, $rawgrade = false, $source = NULL, $feedback = false, $feedbackformat = FORMAT_MOODLE, $usermodified = null, $dategraded = null, $datesubmitted = null, $grade = null)
 {
     global $USER;
     $result = true;
     // calculated grades can not be updated; course and category can not be updated  because they are aggregated
     if (!$this->is_raw_used() or $this->gradetype == GRADE_TYPE_NONE or $this->is_locked()) {
         return false;
     }
     if (is_null($grade)) {
         //fetch from db
         $grade = new grade_grade(array('itemid' => $this->id, 'userid' => $userid));
     }
     $grade->grade_item =& $this;
     // prevent db fetching of this grade_item
     if (empty($usermodified)) {
         $grade->usermodified = $USER->id;
     } else {
         $grade->usermodified = $usermodified;
     }
     if ($grade->is_locked()) {
         // do not update locked grades at all
         return false;
     }
     $locktime = $grade->get_locktime();
     if ($locktime and $locktime < time()) {
         // do not update grades that should be already locked and force regrade
         $this->force_regrading();
         return false;
     }
     $oldgrade = new object();
     $oldgrade->finalgrade = $grade->finalgrade;
     $oldgrade->rawgrade = $grade->rawgrade;
     $oldgrade->rawgrademin = $grade->rawgrademin;
     $oldgrade->rawgrademax = $grade->rawgrademax;
     $oldgrade->rawscaleid = $grade->rawscaleid;
     $oldgrade->feedback = $grade->feedback;
     $oldgrade->feedbackformat = $grade->feedbackformat;
     // use new min and max
     $grade->rawgrade = $grade->rawgrade;
     $grade->rawgrademin = $this->grademin;
     $grade->rawgrademax = $this->grademax;
     $grade->rawscaleid = $this->scaleid;
     // change raw grade?
     if ($rawgrade !== false) {
         $grade->rawgrade = $rawgrade;
     }
     // empty feedback means no feedback at all
     if ($feedback === '') {
         $feedback = null;
     }
     // do we have comment from teacher?
     if ($feedback !== false and !$grade->is_overridden()) {
         $grade->feedback = $feedback;
         $grade->feedbackformat = $feedbackformat;
     }
     // update final grade if possible
     if (!$grade->is_locked() and !$grade->is_overridden()) {
         $grade->finalgrade = $this->adjust_raw_grade($grade->rawgrade, $grade->rawgrademin, $grade->rawgrademax);
     }
     // TODO: hack alert - create new fields for these in 2.0
     $oldgrade->timecreated = $grade->timecreated;
     $oldgrade->timemodified = $grade->timemodified;
     $grade->timecreated = $datesubmitted;
     if ($grade->is_overridden()) {
         // keep original graded date - update_final_grade() sets this for overridden grades
     } else {
         if (is_null($grade->rawgrade) and is_null($grade->feedback)) {
             // no grade and feedback means no grading yet
             $grade->timemodified = null;
         } else {
             if (!empty($dategraded)) {
                 // fine - module sends info when graded (yay!)
                 $grade->timemodified = $dategraded;
             } else {
                 if (grade_floats_different($grade->finalgrade, $oldgrade->finalgrade) or $grade->feedback !== $oldgrade->feedback) {
                     // guess - if either grade or feedback changed set new graded date
                     $grade->timemodified = time();
                 } else {
                     //keep original graded date
                 }
             }
         }
     }
     // end of hack alert
     if (empty($grade->id)) {
         $result = (bool) $grade->insert($source);
     } else {
         if (grade_floats_different($grade->finalgrade, $oldgrade->finalgrade) or grade_floats_different($grade->rawgrade, $oldgrade->rawgrade) or grade_floats_different($grade->rawgrademin, $oldgrade->rawgrademin) or grade_floats_different($grade->rawgrademax, $oldgrade->rawgrademax) or $grade->rawscaleid != $oldgrade->rawscaleid or $grade->feedback !== $oldgrade->feedback or $grade->feedbackformat != $oldgrade->feedbackformat or $grade->timecreated != $oldgrade->timecreated or $grade->timemodified != $oldgrade->timemodified) {
             $result = $grade->update($source);
         } else {
             return $result;
         }
     }
     if (!$result) {
         // something went wrong - better force final grade recalculation
         $this->force_regrading();
     } else {
         if (!$this->needsupdate) {
             $course_item = grade_item::fetch_course_item($this->courseid);
             if (!$course_item->needsupdate) {
                 if (grade_regrade_final_grades($this->courseid, $userid, $this) !== true) {
                     $this->force_regrading();
                 }
             }
         }
     }
     return $result;
 }
Exemple #11
0
 /**
  * Test a specific type of module.
  *
  * @param string $modulename - the module name to test
  */
 private function update_specific_module_test($modulename)
 {
     global $DB, $CFG;
     $this->resetAfterTest(true);
     $this->setAdminUser();
     // Warnings: you'll need to change this line if ever you come to test a module not following Moodle standard.
     require_once $CFG->dirroot . '/mod/' . $modulename . '/lib.php';
     // Enable avaibility.
     // If not enabled all conditional fields will be ignored.
     set_config('enableavailability', 1);
     // Enable course completion.
     // If not enabled all completion settings will be ignored.
     set_config('enablecompletion', COMPLETION_ENABLED);
     // Enable forum RSS feeds.
     set_config('enablerssfeeds', 1);
     set_config('forum_enablerssfeeds', 1);
     $course = $this->getDataGenerator()->create_course(array('numsections' => 1, 'enablecompletion' => COMPLETION_ENABLED), array('createsections' => true));
     $grouping = $this->getDataGenerator()->create_grouping(array('courseid' => $course->id));
     // Create assign module instance for testing gradeitem.
     $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
     $params['course'] = $course->id;
     $instance = $generator->create_instance($params);
     $assigncm = get_coursemodule_from_instance('assign', $instance->id);
     // Create the test forum to update.
     $initvalues = new stdClass();
     $initvalues->introformat = FORMAT_HTML;
     $initvalues->course = $course->id;
     $forum = self::getDataGenerator()->create_module('forum', $initvalues);
     // Retrieve course module.
     $cm = get_coursemodule_from_instance('forum', $forum->id);
     // Module test values.
     $moduleinfo = new stdClass();
     // Always mandatory generic values to any module.
     $moduleinfo->coursemodule = $cm->id;
     $moduleinfo->modulename = $modulename;
     $moduleinfo->course = $course->id;
     $moduleinfo->groupingid = $grouping->id;
     $moduleinfo->visible = true;
     // Sometimes optional generic values for some modules.
     $moduleinfo->name = 'My test module';
     $moduleinfo->showdescription = 1;
     // standard boolean
     require_once $CFG->libdir . '/gradelib.php';
     $gradecats = grade_get_categories_menu($moduleinfo->course, false);
     $gradecatid = current(array_keys($gradecats));
     // Retrieve the first key of $gradecats
     $moduleinfo->gradecat = $gradecatid;
     $moduleinfo->groupmode = VISIBLEGROUPS;
     $moduleinfo->cmidnumber = 'idnumber_XXX';
     // Completion common to all module.
     $moduleinfo->completion = COMPLETION_TRACKING_AUTOMATIC;
     $moduleinfo->completionview = COMPLETION_VIEW_REQUIRED;
     $moduleinfo->completiongradeitemnumber = 1;
     $moduleinfo->completionexpected = time() + 7 * 24 * 3600;
     $moduleinfo->completionunlocked = 1;
     // Conditional activity.
     $coursegradeitem = grade_item::fetch_course_item($moduleinfo->course);
     //the activity will become available only when the user reach some grade into the course itself.
     $moduleinfo->availability = json_encode(\core_availability\tree::get_root_json(array(\availability_date\condition::get_json('>=', time()), \availability_date\condition::get_json('<', time() + 7 * 24 * 3600), \availability_grade\condition::get_json($coursegradeitem->id, 10, 80), \availability_profile\condition::get_json(false, 'email', 'contains', '@'), \availability_completion\condition::get_json($assigncm->id, COMPLETION_COMPLETE)), '&'));
     // Grading and Advanced grading.
     require_once $CFG->dirroot . '/rating/lib.php';
     $moduleinfo->assessed = RATING_AGGREGATE_AVERAGE;
     $moduleinfo->scale = 10;
     // Note: it could be minus (for specific course scale). It is a signed number.
     $moduleinfo->assesstimestart = time();
     $moduleinfo->assesstimefinish = time() + 7 * 24 * 3600;
     // RSS.
     $moduleinfo->rsstype = 2;
     $moduleinfo->rssarticles = 10;
     // Optional intro editor (depends of module).
     $draftid_editor = 0;
     file_prepare_draft_area($draftid_editor, null, null, null, null);
     $moduleinfo->introeditor = array('text' => 'This is a module', 'format' => FORMAT_HTML, 'itemid' => $draftid_editor);
     // Following is the advanced grading method area called 'submissions' for the 'assign' module.
     if (plugin_supports('mod', $modulename, FEATURE_GRADE_HAS_GRADE, false) && !plugin_supports('mod', $modulename, FEATURE_RATE, false)) {
         $moduleinfo->grade = 100;
     }
     // Plagiarism form values.
     // No plagiarism plugin installed by default. Use this space to make your own test.
     // Values specific to the module.
     $modulesetvalues = $modulename . '_update_set_values';
     $this->{$modulesetvalues}($moduleinfo);
     // Create the module.
     $result = update_module($moduleinfo);
     // Retrieve the module info.
     $dbmodinstance = $DB->get_record($moduleinfo->modulename, array('id' => $result->instance));
     $dbcm = get_coursemodule_from_instance($moduleinfo->modulename, $result->instance);
     // Retrieve the grade item.
     $gradeitem = $DB->get_record('grade_items', array('courseid' => $moduleinfo->course, 'iteminstance' => $dbmodinstance->id, 'itemmodule' => $moduleinfo->modulename));
     // Compare the values common to all module instances.
     $this->assertEquals($moduleinfo->modulename, $dbcm->modname);
     $this->assertEquals($moduleinfo->course, $dbcm->course);
     $this->assertEquals($moduleinfo->groupingid, $dbcm->groupingid);
     $this->assertEquals($moduleinfo->visible, $dbcm->visible);
     $this->assertEquals($moduleinfo->completion, $dbcm->completion);
     $this->assertEquals($moduleinfo->completionview, $dbcm->completionview);
     $this->assertEquals($moduleinfo->completiongradeitemnumber, $dbcm->completiongradeitemnumber);
     $this->assertEquals($moduleinfo->completionexpected, $dbcm->completionexpected);
     $this->assertEquals($moduleinfo->availability, $dbcm->availability);
     $this->assertEquals($moduleinfo->showdescription, $dbcm->showdescription);
     $this->assertEquals($moduleinfo->groupmode, $dbcm->groupmode);
     $this->assertEquals($moduleinfo->cmidnumber, $dbcm->idnumber);
     $this->assertEquals($moduleinfo->gradecat, $gradeitem->categoryid);
     // Optional grade testing.
     if (plugin_supports('mod', $modulename, FEATURE_GRADE_HAS_GRADE, false) && !plugin_supports('mod', $modulename, FEATURE_RATE, false)) {
         $this->assertEquals($moduleinfo->grade, $dbmodinstance->grade);
     }
     // Some optional (but quite common) to some module.
     $this->assertEquals($moduleinfo->name, $dbmodinstance->name);
     $this->assertEquals($moduleinfo->intro, $dbmodinstance->intro);
     $this->assertEquals($moduleinfo->introformat, $dbmodinstance->introformat);
     // Test specific to the module.
     $modulerunasserts = $modulename . '_update_run_asserts';
     $this->{$modulerunasserts}($moduleinfo, $dbmodinstance);
     return $moduleinfo;
 }
Exemple #12
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;
     }
 }
/**
 * Returns the grade to display for the certificate.
 *
 * @param stdClass $certificate
 * @param stdClass $course
 * @param int $userid
 * @param bool $valueonly if true return only the points, %age, or letter with no prefix
 * @return string the grade result
 */
function certificate_get_grade($certificate, $course, $userid = null, $valueonly = false)
{
    global $USER;
    if (empty($userid)) {
        $userid = $USER->id;
    }
    if ($certificate->printgrade > 0) {
        if ($certificate->printgrade == 1) {
            if ($course_item = grade_item::fetch_course_item($course->id)) {
                // Check we want to add a prefix to the grade.
                $strprefix = '';
                if (!$valueonly) {
                    $strprefix = get_string('coursegrade', 'certificate') . ': ';
                }
                $grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $userid));
                $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);
                if ($certificate->gradefmt == 1) {
                    $grade = $strprefix . $coursegrade->percentage;
                } else {
                    if ($certificate->gradefmt == 2) {
                        $grade = $strprefix . $coursegrade->points;
                    } else {
                        if ($certificate->gradefmt == 3) {
                            $grade = $strprefix . $coursegrade->letter;
                        }
                    }
                }
                return $grade;
            }
        } else {
            // Print the mod grade
            if ($modinfo = certificate_get_mod_grade($course, $certificate->printgrade, $userid)) {
                // Check we want to add a prefix to the grade.
                $strprefix = '';
                if (!$valueonly) {
                    $strprefix = $modinfo->name . ' ' . get_string('grade', 'certificate') . ': ';
                }
                if ($certificate->gradefmt == 1) {
                    $grade = $strprefix . $modinfo->percentage;
                } else {
                    if ($certificate->gradefmt == 2) {
                        $grade = $strprefix . $modinfo->points;
                    } else {
                        if ($certificate->gradefmt == 3) {
                            $grade = $strprefix . $modinfo->letter;
                        }
                    }
                }
                return $grade;
            }
        }
    } else {
        if ($certificate->printgrade < 0) {
            // Must be a category id.
            if ($category_item = grade_item::fetch(array('itemtype' => 'category', 'iteminstance' => -$certificate->printgrade))) {
                $category_item->gradetype = GRADE_TYPE_VALUE;
                $grade = new grade_grade(array('itemid' => $category_item->id, 'userid' => $userid));
                $category_grade = new stdClass();
                $category_grade->points = grade_format_gradevalue($grade->finalgrade, $category_item, true, GRADE_DISPLAY_TYPE_REAL, $decimals = 2);
                $category_grade->percentage = grade_format_gradevalue($grade->finalgrade, $category_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE, $decimals = 2);
                $category_grade->letter = grade_format_gradevalue($grade->finalgrade, $category_item, true, GRADE_DISPLAY_TYPE_LETTER, $decimals = 0);
                if ($certificate->gradefmt == 1) {
                    $formattedgrade = $category_grade->percentage;
                } else {
                    if ($certificate->gradefmt == 2) {
                        $formattedgrade = $category_grade->points;
                    } else {
                        if ($certificate->gradefmt == 3) {
                            $formattedgrade = $category_grade->letter;
                        }
                    }
                }
                return $formattedgrade;
            }
        }
    }
    return '';
}
//            }
            $row[] = date('d M, Y', $course->timemodified);
            //$modules = $mycourse->progress_modules_in_use($course->id);
            //$events = $mycourse->progress_event_information($modules, $course->id);
            //$attempts = $mycourse->progress_attempts($modules, $course->id, $events, $userid);
            //$percent = $mycourse->progress_percentage($events, $attempts);
            //$completedcount = $mycourse->progress_percentage($events, $attempts, true);
            //$bar = '<div class="dynamic_bar" style="width:' . $percent . '%"></div>';
            //$title = $completedcount . ' out of ' . sizeof($events) . ' graded activities are completed.';
            //$html = '<div class="main_list_bar" title="' . $title . '">
            //        <div class="task_bar">' . $bar . '</div>
            //        <div class="percent">' . $percent . '%' . '</div>
            //        </div>';
            //$row[] = $html;

            $course_item = grade_item::fetch_course_item($course->id);
            $course_grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $userid));
            $final_grade = round($course_grade->finalgrade, 2);
            $row[] = html_writer::tag('a', $final_grade, array('href' => $CFG->wwwroot . '/grade/report/user/index.php?id=' . $course->id));
        } else if ($is_teacher) {
            $row[] = html_writer::tag('a', 'Submit', array('href' => $CFG->wwwroot . '/grade/report/grader/index.php?id=' . $course->id));
        }
        $row[] = html_writer::tag('a', 'Launch', array('href' => $CFG->wwwroot . '/course/view.php?id=' . $course->id));
        $data[] = $row;
    }
    $table = new html_table();
    //$table->head  = array('Course', 'Enrolled on', 'Progress', 'Launch Course');
    $table->align = array('left', 'center', 'center', 'center');
    if ($is_student)
        $table->size = array('25%', '23%', '13%', '12%');
    if ($is_teacher)
Exemple #15
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 #16
0
 public function test_grade_grade_min_max_with_category_item()
 {
     global $CFG, $DB;
     $initialminmaxtouse = $CFG->grade_minmaxtouse;
     $this->setAdminUser();
     $course = $this->getDataGenerator()->create_course();
     $user = $this->getDataGenerator()->create_user();
     $coursegi = grade_item::fetch_course_item($course->id);
     // Create a category item.
     $gc = new grade_category(array('courseid' => $course->id, 'fullname' => 'test'), false);
     $gc->insert();
     $gi = $gc->get_grade_item();
     $gi->grademax = 100;
     $gi->grademin = 0;
     $gi->update();
     // Fetch the category item.
     $giparams = array('itemtype' => 'category', 'iteminstance' => $gc->id);
     $gi = grade_item::fetch($giparams);
     $this->assertEquals(0, $gi->grademin);
     $this->assertEquals(100, $gi->grademax);
     // Give a grade to the student.
     $gi->update_final_grade($user->id, 10);
     // Check the grade min/max stored in gradebook.
     $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id));
     $this->assertEquals(0, $gg->get_grade_min());
     $this->assertEquals(100, $gg->get_grade_max());
     // Change the min/max grade of the item.
     $gi->grademin = 2;
     $gi->grademax = 50;
     $gi->update();
     // Fetch the updated item.
     $gi = grade_item::fetch($giparams);
     // Now check the grade grade min/max with system setting.
     $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_ITEM;
     grade_set_setting($course->id, 'minmaxtouse', null);
     // Ensure no course setting.
     $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id));
     $this->assertEquals(0, $gg->get_grade_min());
     $this->assertEquals(100, $gg->get_grade_max());
     // Now with other system setting.
     $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_GRADE;
     grade_set_setting($course->id, 'minmaxtouse', null);
     // Ensure no course setting, and reset static cache.
     $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id));
     $this->assertEquals(0, $gg->get_grade_min());
     $this->assertEquals(100, $gg->get_grade_max());
     // Now with overriden setting in course.
     $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_ITEM;
     grade_set_setting($course->id, 'minmaxtouse', GRADE_MIN_MAX_FROM_GRADE_GRADE);
     $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id));
     $this->assertEquals(0, $gg->get_grade_min());
     $this->assertEquals(100, $gg->get_grade_max());
     $CFG->grade_minmaxtouse = GRADE_MIN_MAX_FROM_GRADE_GRADE;
     grade_set_setting($course->id, 'minmaxtouse', GRADE_MIN_MAX_FROM_GRADE_ITEM);
     $gg = grade_grade::fetch(array('userid' => $user->id, 'itemid' => $gi->id));
     $this->assertEquals(0, $gg->get_grade_min());
     $this->assertEquals(100, $gg->get_grade_max());
     $CFG->grade_minmaxtouse = $initialminmaxtouse;
 }
Exemple #17
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;
     }
 }
 function get_content()
 {
     if ($this->content !== NULL) {
         return $this->content;
     }
     global $CFG, $COURSE, $USER;
     $this->content = new stdClass();
     $this->content->text = '';
     $this->content->footer = '';
     // Does the user have the right capability?
     // Line 4354 of lib/weblib.php suggests that a teacher
     // is defined by one being able to view details of other users
     $context = get_context_instance(CONTEXT_COURSE, $COURSE->id);
     if (!has_capability('moodle/user:viewdetails', $context)) {
         return $this->content;
     }
     $user = CoursePrefsUser::findByUnique($USER->username);
     // No Atheletes in the course means this block is hidden
     if (get_athelete_count($COURSE) == 0) {
         // If in Edit mode: display the no athletes text
         $edit = optional_param('edit', 0, PARAM_INT);
         if ($edit) {
             $this->content->text = '<span>' . get_string('no_atheletes', 'block_athelete_reporting') . '</span>';
         }
         return $this->content;
     }
     // Check course's grade to pass
     $this->courseitem = grade_item::fetch_course_item($COURSE->id);
     if (is_siteadmin($USER->id)) {
         $sections = cps_sections($COURSE);
     } else {
         if ($user) {
             $sections = $user->getSectionsForMoodleCourse($COURSE);
         } else {
             return $this->content;
         }
     }
     $out = '<div class="block_athelete_reporting_body">
              <form method="POST" action="' . $CFG->wwwroot . '/blocks/athelete_reporting/report.php">';
     foreach ($sections as $section) {
         $atheletes = get_atheletes($section);
         if (!$atheletes) {
             continue;
         }
         $id = 'block_athelete_reporting_section_' . $section->id;
         $out .= '<div class="block_athelete_reporting_header">
                     <input type="image" src="' . $CFG->pixpath . '/t/switch_plus.gif"
                      onclick="elementToggleHide(this, true, function(el) { 
           return document.getElementById(\'' . $id . '\');}, \'Show Section\', \'Hide Section\'); return false;">
                 ' . get_string('format_section', 'block_courseprefs', $section) . '
                  </div>
                  <div id="' . $id . '"
                       class="block_athelete_reporting_section_body hidden">
                     ' . array_reduce($atheletes, array($this, 'reduce_athelete')) . '
                  </div>';
     }
     if (!empty($sections)) {
         $out .= '       <input type="hidden" name="id" value="' . $COURSE->id . '">
           <input type="submit" value="' . get_string('report', 'block_athelete_reporting') . '">
                     </form>';
     }
     $out .= '<a href="' . $CFG->wwwroot . '/blocks/student_gradeviewer/analysis.php?id=' . $COURSE->id . '">' . get_string('analysis', 'block_student_gradeviewer') . '</a>';
     $user = CoursePrefsUser::findByUnique($USER->username);
     if (!empty($CFG->cas_email) and $user and $user->getSectionsInfoAsTeacher(false, null, true)) {
         $out .= '<br/><span class="athlete_small_text">
                     <a href="' . $CFG->wwwroot . '/blocks/student_gradeviewer/options.php?id=' . $COURSE->id . '">' . get_string('options', 'block_student_gradeviewer') . '</a>
                  </span>';
     }
     $out .= '</div>';
     $this->content->text = $out;
     return $this->content;
 }
 /**
  * The availability data format was changed in Moodle 2.7. This test
  * ensures that a Moodle 2.6 backup with this data can still be correctly
  * restored.
  */
 public function test_restore_legacy_availability()
 {
     global $DB, $USER, $CFG;
     require_once $CFG->dirroot . '/grade/querylib.php';
     require_once $CFG->libdir . '/completionlib.php';
     $this->resetAfterTest(true);
     $this->setAdminUser();
     $CFG->enableavailability = true;
     $CFG->enablecompletion = true;
     // Extract backup file.
     $backupid = 'abc';
     $backuppath = $CFG->tempdir . '/backup/' . $backupid;
     check_dir_exists($backuppath);
     get_file_packer('application/vnd.moodle.backup')->extract_to_pathname(__DIR__ . '/fixtures/availability_26_format.mbz', $backuppath);
     // Do restore to new course with default settings.
     $generator = $this->getDataGenerator();
     $categoryid = $DB->get_field_sql("SELECT MIN(id) FROM {course_categories}");
     $newcourseid = restore_dbops::create_new_course('Test fullname', 'Test shortname', $categoryid);
     $rc = new restore_controller($backupid, $newcourseid, backup::INTERACTIVE_NO, backup::MODE_GENERAL, $USER->id, backup::TARGET_NEW_COURSE);
     $thrown = null;
     try {
         $this->assertTrue($rc->execute_precheck());
         $rc->execute_plan();
         $rc->destroy();
     } catch (Exception $e) {
         $thrown = $e;
         // Because of the PHPUnit exception behaviour in this situation, we
         // will not see this message unless it is explicitly echoed (just
         // using it in a fail() call or similar will not work).
         echo "\n\nEXCEPTION: " . $thrown->getMessage() . '[' . $thrown->getFile() . ':' . $thrown->getLine() . "]\n\n";
     }
     // Must set restore_controller variable to null so that php
     // garbage-collects it; otherwise the file will be left open and
     // attempts to delete it will cause a permission error on Windows
     // systems, breaking unit tests.
     $rc = null;
     $this->assertNull($thrown);
     // Get information about the resulting course and check that it is set
     // up correctly.
     $modinfo = get_fast_modinfo($newcourseid);
     $pages = array_values($modinfo->get_instances_of('page'));
     $forums = array_values($modinfo->get_instances_of('forum'));
     $quizzes = array_values($modinfo->get_instances_of('quiz'));
     $grouping = $DB->get_record('groupings', array('courseid' => $newcourseid));
     // FROM date.
     $this->assertEquals('{"op":"&","showc":[true],"c":[{"type":"date","d":">=","t":1893456000}]}', $pages[1]->availability);
     // UNTIL date.
     $this->assertEquals('{"op":"&","showc":[false],"c":[{"type":"date","d":"<","t":1393977600}]}', $pages[2]->availability);
     // FROM and UNTIL.
     $this->assertEquals('{"op":"&","showc":[true,false],"c":[' . '{"type":"date","d":">=","t":1449705600},' . '{"type":"date","d":"<","t":1893456000}' . ']}', $pages[3]->availability);
     // Grade >= 75%.
     $grades = array_values(grade_get_grade_items_for_activity($quizzes[0], true));
     $gradeid = $grades[0]->id;
     $coursegrade = grade_item::fetch_course_item($newcourseid);
     $this->assertEquals('{"op":"&","showc":[true],"c":[{"type":"grade","id":' . $gradeid . ',"min":75}]}', $pages[4]->availability);
     // Grade < 25%.
     $this->assertEquals('{"op":"&","showc":[true],"c":[{"type":"grade","id":' . $gradeid . ',"max":25}]}', $pages[5]->availability);
     // Grade 90-100%.
     $this->assertEquals('{"op":"&","showc":[true],"c":[{"type":"grade","id":' . $gradeid . ',"min":90,"max":100}]}', $pages[6]->availability);
     // Email contains frog.
     $this->assertEquals('{"op":"&","showc":[true],"c":[{"type":"profile","op":"contains","sf":"email","v":"frog"}]}', $pages[7]->availability);
     // Page marked complete..
     $this->assertEquals('{"op":"&","showc":[true],"c":[{"type":"completion","cm":' . $pages[0]->id . ',"e":' . COMPLETION_COMPLETE . '}]}', $pages[8]->availability);
     // Quiz complete but failed.
     $this->assertEquals('{"op":"&","showc":[true],"c":[{"type":"completion","cm":' . $quizzes[0]->id . ',"e":' . COMPLETION_COMPLETE_FAIL . '}]}', $pages[9]->availability);
     // Quiz complete and succeeded.
     $this->assertEquals('{"op":"&","showc":[true],"c":[{"type":"completion","cm":' . $quizzes[0]->id . ',"e":' . COMPLETION_COMPLETE_PASS . '}]}', $pages[10]->availability);
     // Quiz not complete.
     $this->assertEquals('{"op":"&","showc":[true],"c":[{"type":"completion","cm":' . $quizzes[0]->id . ',"e":' . COMPLETION_INCOMPLETE . '}]}', $pages[11]->availability);
     // Grouping.
     $this->assertEquals('{"op":"&","showc":[false],"c":[{"type":"grouping","id":' . $grouping->id . '}]}', $pages[12]->availability);
     // All the options.
     $this->assertEquals('{"op":"&",' . '"showc":[false,true,false,true,true,true,true,true,true],' . '"c":[' . '{"type":"grouping","id":' . $grouping->id . '},' . '{"type":"date","d":">=","t":1488585600},' . '{"type":"date","d":"<","t":1709510400},' . '{"type":"profile","op":"contains","sf":"email","v":"@"},' . '{"type":"profile","op":"contains","sf":"city","v":"Frogtown"},' . '{"type":"grade","id":' . $gradeid . ',"min":30,"max":35},' . '{"type":"grade","id":' . $coursegrade->id . ',"min":5,"max":10},' . '{"type":"completion","cm":' . $pages[0]->id . ',"e":' . COMPLETION_COMPLETE . '},' . '{"type":"completion","cm":' . $quizzes[0]->id . ',"e":' . COMPLETION_INCOMPLETE . '}' . ']}', $pages[13]->availability);
     // Group members only forum.
     $this->assertEquals('{"op":"&","showc":[false],"c":[{"type":"group"}]}', $forums[0]->availability);
     // Section with lots of conditions.
     $this->assertEquals('{"op":"&","showc":[false,false,false,false],"c":[' . '{"type":"date","d":">=","t":1417737600},' . '{"type":"profile","op":"contains","sf":"email","v":"@"},' . '{"type":"grade","id":' . $gradeid . ',"min":20},' . '{"type":"completion","cm":' . $pages[0]->id . ',"e":' . COMPLETION_COMPLETE . '}]}', $modinfo->get_section_info(3)->availability);
     // Section with grouping.
     $this->assertEquals('{"op":"&","showc":[false],"c":[{"type":"grouping","id":' . $grouping->id . '}]}', $modinfo->get_section_info(4)->availability);
 }
Exemple #20
0
/**
 * Updates all final grades in course.
 *
 * @param int $courseid The course ID
 * @param int $userid If specified try to do a quick regrading of the grades of this user only
 * @param object $updated_item Optional grade item to be marked for regrading
 * @param \core\progress\base $progress If provided, will be used to update progress on this long operation.
 * @return bool true if ok, array of errors if problems found. Grade item id => error message
 */
function grade_regrade_final_grades($courseid, $userid = null, $updated_item = null, $progress = null)
{
    // This may take a very long time.
    \core_php_time_limit::raise();
    $course_item = grade_item::fetch_course_item($courseid);
    if ($progress == null) {
        $progress = new \core\progress\none();
    }
    if ($userid) {
        // one raw grade updated for one user
        if (empty($updated_item)) {
            print_error("cannotbenull", 'debug', '', "updated_item");
        }
        if ($course_item->needsupdate) {
            $updated_item->force_regrading();
            return array($course_item->id => 'Can not do fast regrading after updating of raw grades');
        }
    } else {
        if (!$course_item->needsupdate) {
            // nothing to do :-)
            return true;
        }
    }
    // Categories might have to run some processing before we fetch the grade items.
    // This gives them a final opportunity to update and mark their children to be updated.
    // We need to work on the children categories up to the parent ones, so that, for instance,
    // if a category total is updated it will be reflected in the parent category.
    $cats = grade_category::fetch_all(array('courseid' => $courseid));
    $flatcattree = array();
    foreach ($cats as $cat) {
        if (!isset($flatcattree[$cat->depth])) {
            $flatcattree[$cat->depth] = array();
        }
        $flatcattree[$cat->depth][] = $cat;
    }
    krsort($flatcattree);
    foreach ($flatcattree as $depth => $cats) {
        foreach ($cats as $cat) {
            $cat->pre_regrade_final_grades();
        }
    }
    $progresstotal = 0;
    $progresscurrent = 0;
    $grade_items = grade_item::fetch_all(array('courseid' => $courseid));
    $depends_on = array();
    foreach ($grade_items as $gid => $gitem) {
        if ((!empty($updated_item) and $updated_item->id == $gid) || $gitem->is_course_item() || $gitem->is_category_item() || $gitem->is_calculated()) {
            $grade_items[$gid]->needsupdate = 1;
        }
        // We load all dependencies of these items later we can discard some grade_items based on this.
        if ($grade_items[$gid]->needsupdate) {
            $depends_on[$gid] = $grade_items[$gid]->depends_on();
            $progresstotal++;
        }
    }
    $progress->start_progress('regrade_course', $progresstotal);
    $errors = array();
    $finalids = array();
    $updatedids = array();
    $gids = array_keys($grade_items);
    $failed = 0;
    while (count($finalids) < count($gids)) {
        // work until all grades are final or error found
        $count = 0;
        foreach ($gids as $gid) {
            if (in_array($gid, $finalids)) {
                continue;
                // already final
            }
            if (!$grade_items[$gid]->needsupdate) {
                $finalids[] = $gid;
                // we can make it final - does not need update
                continue;
            }
            $thisprogress = $progresstotal;
            foreach ($grade_items as $item) {
                if ($item->needsupdate) {
                    $thisprogress--;
                }
            }
            // Clip between $progresscurrent and $progresstotal.
            $thisprogress = max(min($thisprogress, $progresstotal), $progresscurrent);
            $progress->progress($thisprogress);
            $progresscurrent = $thisprogress;
            foreach ($depends_on[$gid] as $did) {
                if (!in_array($did, $finalids)) {
                    // This item depends on something that is not yet in finals array.
                    continue 2;
                }
            }
            // If this grade item has no dependancy with any updated item at all, then remove it from being recalculated.
            // When we get here, all of this grade item's decendents are marked as final so they would be marked as updated too
            // if they would have been regraded. We don't need to regrade items which dependants (not only the direct ones
            // but any dependant in the cascade) have not been updated.
            // If $updated_item was specified we discard the grade items that do not depend on it or on any grade item that
            // depend on $updated_item.
            // Here we check to see if the direct decendants are marked as updated.
            if (!empty($updated_item) && $gid != $updated_item->id && !in_array($updated_item->id, $depends_on[$gid])) {
                // We need to ensure that none of this item's dependencies have been updated.
                // If we find that one of the direct decendants of this grade item is marked as updated then this
                // grade item needs to be recalculated and marked as updated.
                // Being marked as updated is done further down in the code.
                $updateddependencies = false;
                foreach ($depends_on[$gid] as $dependency) {
                    if (in_array($dependency, $updatedids)) {
                        $updateddependencies = true;
                        break;
                    }
                }
                if ($updateddependencies === false) {
                    // If no direct descendants are marked as updated, then we don't need to update this grade item. We then mark it
                    // as final.
                    $finalids[] = $gid;
                    continue;
                }
            }
            // Let's update, calculate or aggregate.
            $result = $grade_items[$gid]->regrade_final_grades($userid);
            if ($result === true) {
                // We should only update the database if we regraded all users.
                if (empty($userid)) {
                    $grade_items[$gid]->regrading_finished();
                    // Do the locktime item locking.
                    $grade_items[$gid]->check_locktime();
                } else {
                    $grade_items[$gid]->needsupdate = 0;
                }
                $count++;
                $finalids[] = $gid;
                $updatedids[] = $gid;
            } else {
                $grade_items[$gid]->force_regrading();
                $errors[$gid] = $result;
            }
        }
        if ($count == 0) {
            $failed++;
        } else {
            $failed = 0;
        }
        if ($failed > 1) {
            foreach ($gids as $gid) {
                if (in_array($gid, $finalids)) {
                    continue;
                    // this one is ok
                }
                $grade_items[$gid]->force_regrading();
                $errors[$grade_items[$gid]->id] = get_string('errorcalculationbroken', 'grades');
            }
            break;
            // Found error.
        }
    }
    $progress->end_progress();
    if (count($errors) == 0) {
        if (empty($userid)) {
            // do the locktime locking of grades, but only when doing full regrading
            grade_grade::check_locktime_all($gids);
        }
        return true;
    } else {
        return $errors;
    }
}
Exemple #21
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 #22
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;
     }
 }
function backup_gradebook_category_info($bf, $preferences)
{
    global $CFG;
    $status = true;
    // get grade categories in proper order - specified in category grade items
    $course_item = grade_item::fetch_course_item($preferences->backup_course);
    $grade_categories = get_records_sql("SELECT gc.*, gi.sortorder\n                                               FROM {$CFG->prefix}grade_categories gc\n                                                    JOIN {$CFG->prefix}grade_items gi\n                                                      ON (gi.iteminstance = gc.id)\n                                              WHERE gc.courseid = {$preferences->backup_course}\n                                                    AND (gi.itemtype='course' OR gi.itemtype='category')\n                                           ORDER BY gi.sortorder ASC");
    if ($grade_categories) {
        //Begin grade_categories tag
        fwrite($bf, start_tag("GRADE_CATEGORIES", 3, true));
        //Iterate for each category
        foreach ($grade_categories as $grade_category) {
            //Begin grade_category
            fwrite($bf, start_tag("GRADE_CATEGORY", 4, true));
            //Output individual fields
            fwrite($bf, full_tag("ID", 5, false, $grade_category->id));
            // not keeping path and depth because they can be derived
            fwrite($bf, full_tag("PARENT", 5, false, $grade_category->parent));
            fwrite($bf, full_tag("FULLNAME", 5, false, $grade_category->fullname));
            fwrite($bf, full_tag("AGGREGATION", 5, false, $grade_category->aggregation));
            fwrite($bf, full_tag("KEEPHIGH", 5, false, $grade_category->keephigh));
            fwrite($bf, full_tag("DROPLOW", 5, false, $grade_category->droplow));
            fwrite($bf, full_tag("AGGREGATEONLYGRADED", 5, false, $grade_category->aggregateonlygraded));
            fwrite($bf, full_tag("AGGREGATEOUTCOMES", 5, false, $grade_category->aggregateoutcomes));
            fwrite($bf, full_tag("AGGREGATESUBCATS", 5, false, $grade_category->aggregatesubcats));
            fwrite($bf, full_tag("TIMECREATED", 5, false, $grade_category->timecreated));
            fwrite($bf, full_tag("TIMEMODIFIED", 5, false, $grade_category->timemodified));
            //End grade_category
            fwrite($bf, end_tag("GRADE_CATEGORY", 4, true));
        }
        //End grade_categories tag
        $status = fwrite($bf, end_tag("GRADE_CATEGORIES", 3, true));
    }
    return $status;
}
 /**
  * Updates raw grade value for given user, this is a only way to update raw
  * grades from external source (modules, etc.),
  * because it logs the change in history table and deals with final grade recalculation.
  *
  * @param int $userid the graded user
  * @param mixed $rawgrade float value of raw grade - false means do not change
  * @param string $howmodified modification source
  * @param string $note optional note
  * @param mixed $feedback teachers feedback as string - false means do not change
  * @param int $feedbackformat
  * @return boolean success
  */
 function update_raw_grade($userid, $rawgrade = false, $source = NULL, $note = NULL, $feedback = false, $feedbackformat = FORMAT_MOODLE, $usermodified = null)
 {
     global $USER;
     if (empty($usermodified)) {
         $usermodified = $USER->id;
     }
     $result = true;
     // calculated grades can not be updated; course and category can not be updated  because they are aggregated
     if ($this->is_calculated() or $this->is_outcome_item() or !$this->is_normal_item() or $this->gradetype == GRADE_TYPE_NONE or $this->is_locked()) {
         return false;
     }
     $grade = new grade_grade(array('itemid' => $this->id, 'userid' => $userid));
     $grade->grade_item =& $this;
     // prevent db fetching of this grade_item
     $grade->usermodified = $usermodified;
     if ($grade->is_locked()) {
         // do not update locked grades at all
         return false;
     }
     $locktime = $grade->get_locktime();
     if ($locktime and $locktime < time()) {
         // do not update grades that should be already locked and force regrade
         $this->force_regrading();
         return false;
     }
     $oldgrade = new object();
     $oldgrade->finalgrade = $grade->finalgrade;
     $oldgrade->rawgrade = $grade->rawgrade;
     $oldgrade->rawgrademin = $grade->rawgrademin;
     $oldgrade->rawgrademax = $grade->rawgrademax;
     $oldgrade->rawscaleid = $grade->rawscaleid;
     $oldgrade->feedback = $grade->feedback;
     $oldgrade->feedbackformat = $grade->feedbackformat;
     // fist copy current grademin/max and scale
     $grade->rawgrademin = $this->grademin;
     $grade->rawgrademax = $this->grademax;
     $grade->rawscaleid = $this->scaleid;
     // change raw grade?
     if ($rawgrade !== false) {
         $grade->rawgrade = $rawgrade;
     }
     // do we have comment from teacher?
     if ($feedback !== false) {
         $grade->feedback = $feedback;
         $grade->feedbackformat = $feedbackformat;
     }
     if (empty($grade->id)) {
         $result = (bool) $grade->insert($source);
     } else {
         if ($grade->finalgrade !== $oldgrade->finalgrade or $grade->rawgrade !== $oldgrade->rawgrade or $grade->rawgrademin !== $oldgrade->rawgrademin or $grade->rawgrademax !== $oldgrade->rawgrademax or $grade->rawscaleid !== $oldgrade->rawscaleid or $grade->feedback !== $oldgrade->feedback or $grade->feedbackformat !== $oldgrade->feedbackformat) {
             $result = $grade->update($source);
         }
     }
     if (!$result) {
         // something went wrong - better force final grade recalculation
         $this->force_regrading();
     } else {
         if (!$this->needsupdate) {
             $course_item = grade_item::fetch_course_item($this->courseid);
             if (!$course_item->needsupdate) {
                 if (!grade_regrade_final_grades($this->courseid, $userid, $this)) {
                     $this->force_regrading();
                 }
             } else {
                 $this->force_regrading();
             }
         }
     }
     return $result;
 }
/**
 * Updates all final grades in course.
 *
 * @param int $courseid
 * @param int $userid if specified, try to do a quick regrading of grades of this user only
 * @param object $updated_item the item in which
 * @return boolean true if ok, array of errors if problems found (item id is used as key)
 */
function grade_regrade_final_grades($courseid, $userid = null, $updated_item = null)
{
    $course_item = grade_item::fetch_course_item($courseid);
    if ($userid) {
        // one raw grade updated for one user
        if (empty($updated_item)) {
            error("updated_item_id can not be null!");
        }
        if ($course_item->needsupdate) {
            $updated_item->force_regrading();
            return 'Can not do fast regrading after updating of raw grades';
        }
    } else {
        if (!$course_item->needsupdate) {
            // nothing to do :-)
            return true;
        }
    }
    $grade_items = grade_item::fetch_all(array('courseid' => $courseid));
    $depends_on = array();
    // first mark all category and calculated items as needing regrading
    // this is slower, but 100% accurate
    foreach ($grade_items as $gid => $gitem) {
        if (!empty($updated_item) and $updated_item->id == $gid) {
            $grade_items[$gid]->needsupdate = 1;
        } else {
            if ($gitem->is_course_item() or $gitem->is_category_item() or $gitem->is_calculated()) {
                $grade_items[$gid]->needsupdate = 1;
            }
        }
        // construct depends_on lookup array
        $depends_on[$gid] = $grade_items[$gid]->depends_on();
    }
    $errors = array();
    $finalids = array();
    $gids = array_keys($grade_items);
    $failed = 0;
    while (count($finalids) < count($gids)) {
        // work until all grades are final or error found
        $count = 0;
        foreach ($gids as $gid) {
            if (in_array($gid, $finalids)) {
                continue;
                // already final
            }
            if (!$grade_items[$gid]->needsupdate) {
                $finalids[] = $gid;
                // we can make it final - does not need update
                continue;
            }
            $doupdate = true;
            foreach ($depends_on[$gid] as $did) {
                if (!in_array($did, $finalids)) {
                    $doupdate = false;
                    continue;
                    // this item depends on something that is not yet in finals array
                }
            }
            //oki - let's update, calculate or aggregate :-)
            if ($doupdate) {
                $result = $grade_items[$gid]->regrade_final_grades($userid);
                if ($result === true) {
                    $grade_items[$gid]->regrading_finished();
                    $grade_items[$gid]->check_locktime();
                    // do the locktime item locking
                    $count++;
                    $finalids[] = $gid;
                } else {
                    $grade_items[$gid]->force_regrading();
                    $errors[$gid] = $result;
                }
            }
        }
        if ($count == 0) {
            $failed++;
        } else {
            $failed = 0;
        }
        if ($failed > 1) {
            foreach ($gids as $gid) {
                if (in_array($gid, $finalids)) {
                    continue;
                    // this one is ok
                }
                $grade_items[$gid]->force_regrading();
                $errors[$grade_items[$gid]->id] = 'Probably circular reference or broken calculation formula';
                // TODO: localize
            }
            break;
            // oki, found error
        }
    }
    if (count($errors) == 0) {
        if (empty($userid)) {
            // do the locktime locking of grades, but only when doing full regrading
            grade_grade::check_locktime_all($gids);
        }
        return true;
    } else {
        return $errors;
    }
}
 /**
  * Returns the grade to display for the certificate.
  * 
  * @param int $userid
  * @return string the grade result
  */
 protected function get_grade($userid = null)
 {
     global $USER, $DB;
     if (empty($userid)) {
         $userid = $USER->id;
     }
     //If certgrade = 0 return nothing
     if (empty($this->get_instance()->certgrade)) {
         //No grade
         return '';
     }
     switch ($this->get_instance()->certgrade) {
         case self::COURSE_GRADE:
             //Course grade
             if ($course_item = grade_item::fetch_course_item($this->get_course()->id)) {
                 $grade = new grade_grade(array('itemid' => $course_item->id, 'userid' => $userid));
                 $course_item->gradetype = GRADE_TYPE_VALUE;
                 $coursegrade = new stdClass();
                 // String used
                 $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);
             }
             break;
         default:
             // Module grade
             //Get grade from a specific module, stored at certgrade
             if ($modinfo = $this->get_mod_grade($this->get_instance()->certgrade, $userid)) {
                 // String used
                 $coursegrade = new stdClass();
                 $coursegrade->points = $modinfo->points;
                 $coursegrade->percentage = $modinfo->percentage;
                 $coursegrade->letter = $modinfo->letter;
                 break;
             }
     }
     return $this->get_formated_grade($coursegrade);
 }
Exemple #27
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 #28
0
/**
 * Fetches grade_item info and grades from the referenced course
 *
 * Returned structure is
 *  object(
 *      ->grades = array[userid] of object(->userid ->rawgrade ->feedback ->feedbackformat)
 *      ->grademax
 *      ->grademin
 *      ->itemname
 *      ...
 *  )
 *
 * @access public
 * @param int $subcourseid ID of subcourse instance
 * @param int $refcourseid ID of referenced course
 * @param bool|\boolan $gradeitemonly If true, fetch only grade item info without grades
 * @return object Object containing grades array and gradeitem info
 */
function subcourse_fetch_refgrades($subcourseid, $refcourseid, $gradeitemonly = false)
{
    global $CFG;
    $fetchedfields = subcourse_get_fetched_item_fields();
    if (!function_exists('grade_update')) {
        //workaround for buggy PHP versions
        require_once $CFG->libdir . '/gradelib.php';
    }
    $return = new stdClass();
    $return->grades = array();
    if (empty($refcourseid)) {
        return false;
    }
    $refgradeitem = grade_item::fetch_course_item($refcourseid);
    // get grade_item info
    foreach ($fetchedfields as $property) {
        if (!empty($refgradeitem->{$property})) {
            $return->{$property} = $refgradeitem->{$property};
        } else {
            $return->{$property} = null;
        }
    }
    // if the remote grade_item is non-global scale, do not fetch grades - they can't be used
    if ($refgradeitem->gradetype == GRADE_TYPE_SCALE && !subcourse_is_global_scale($refgradeitem->scaleid)) {
        $gradeitemonly = true;
        $return->localremotescale = true;
    }
    if (!$gradeitemonly) {
        // get grades
        $cm = get_coursemodule_from_instance("subcourse", $subcourseid);
        $context = get_context_instance(CONTEXT_MODULE, $cm->id);
        $users = get_users_by_capability($context, 'mod/subcourse:begraded', 'u.id,u.lastname', 'u.lastname', '', '', '', '', false, true);
        foreach ($users as $user) {
            $grade = new grade_grade(array('itemid' => $refgradeitem->id, 'userid' => $user->id));
            $grade->grade_item =& $refgradeitem;
            $return->grades[$user->id]->userid = $user->id;
            $return->grades[$user->id]->rawgrade = $grade->finalgrade;
            $return->grades[$user->id]->feedback = $grade->feedback;
            $return->grades[$user->id]->feedbackformat = $grade->feedbackformat;
        }
    }
    return $return;
}
Exemple #29
0
 /**
  * Initialise the iterator
  *
  * @return boolean success
  */
 public function init()
 {
     global $CFG, $DB;
     $this->close();
     export_verify_grades($this->course->id);
     $course_item = grade_item::fetch_course_item($this->course->id);
     if ($course_item->needsupdate) {
         // Can not calculate all final grades - sorry.
         return false;
     }
     $coursecontext = context_course::instance($this->course->id);
     list($relatedctxsql, $relatedctxparams) = $DB->get_in_or_equal($coursecontext->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'relatedctx');
     list($gradebookroles_sql, $params) = $DB->get_in_or_equal(explode(',', $CFG->gradebookroles), SQL_PARAMS_NAMED, 'grbr');
     list($enrolledsql, $enrolledparams) = get_enrolled_sql($coursecontext, '', 0, $this->onlyactive);
     $params = array_merge($params, $enrolledparams, $relatedctxparams);
     if ($this->groupid) {
         $groupsql = "INNER JOIN {groups_members} gm ON gm.userid = u.id";
         $groupwheresql = "AND gm.groupid = :groupid";
         // $params contents: gradebookroles
         $params['groupid'] = $this->groupid;
     } else {
         $groupsql = "";
         $groupwheresql = "";
     }
     if (empty($this->sortfield1)) {
         // We must do some sorting even if not specified.
         $ofields = ", u.id AS usrt";
         $order = "usrt ASC";
     } else {
         $ofields = ", u.{$this->sortfield1} AS usrt1";
         $order = "usrt1 {$this->sortorder1}";
         if (!empty($this->sortfield2)) {
             $ofields .= ", u.{$this->sortfield2} AS usrt2";
             $order .= ", usrt2 {$this->sortorder2}";
         }
         if ($this->sortfield1 != 'id' and $this->sortfield2 != 'id') {
             // User order MUST be the same in both queries,
             // must include the only unique user->id if not already present.
             $ofields .= ", u.id AS usrt";
             $order .= ", usrt ASC";
         }
     }
     $userfields = 'u.*';
     $customfieldssql = '';
     if ($this->allowusercustomfields && !empty($CFG->grade_export_customprofilefields)) {
         $customfieldscount = 0;
         $customfieldsarray = grade_helper::get_user_profile_fields($this->course->id, $this->allowusercustomfields);
         foreach ($customfieldsarray as $field) {
             if (!empty($field->customid)) {
                 $customfieldssql .= "\n                            LEFT JOIN (SELECT * FROM {user_info_data}\n                                WHERE fieldid = :cf{$customfieldscount}) cf{$customfieldscount}\n                            ON u.id = cf{$customfieldscount}.userid";
                 $userfields .= ", cf{$customfieldscount}.data AS customfield_{$field->shortname}";
                 $params['cf' . $customfieldscount] = $field->customid;
                 $customfieldscount++;
             }
         }
     }
     $users_sql = "SELECT {$userfields} {$ofields}\n                        FROM {user} u\n                        JOIN ({$enrolledsql}) je ON je.id = u.id\n                             {$groupsql} {$customfieldssql}\n                        JOIN (\n                                  SELECT DISTINCT ra.userid\n                                    FROM {role_assignments} ra\n                                   WHERE ra.roleid {$gradebookroles_sql}\n                                     AND ra.contextid {$relatedctxsql}\n                             ) rainner ON rainner.userid = u.id\n                         WHERE u.deleted = 0\n                             {$groupwheresql}\n                    ORDER BY {$order}";
     $this->users_rs = $DB->get_recordset_sql($users_sql, $params);
     if (!$this->onlyactive) {
         $context = context_course::instance($this->course->id);
         $this->suspendedusers = get_suspended_userids($context);
     } else {
         $this->suspendedusers = array();
     }
     if (!empty($this->grade_items)) {
         $itemids = array_keys($this->grade_items);
         list($itemidsql, $grades_params) = $DB->get_in_or_equal($itemids, SQL_PARAMS_NAMED, 'items');
         $params = array_merge($params, $grades_params);
         $grades_sql = "SELECT g.* {$ofields}\n                             FROM {grade_grades} g\n                             JOIN {user} u ON g.userid = u.id\n                             JOIN ({$enrolledsql}) je ON je.id = u.id\n                                  {$groupsql}\n                             JOIN (\n                                      SELECT DISTINCT ra.userid\n                                        FROM {role_assignments} ra\n                                       WHERE ra.roleid {$gradebookroles_sql}\n                                         AND ra.contextid {$relatedctxsql}\n                                  ) rainner ON rainner.userid = u.id\n                              WHERE u.deleted = 0\n                              AND g.itemid {$itemidsql}\n                              {$groupwheresql}\n                         ORDER BY {$order}, g.itemid ASC";
         $this->grades_rs = $DB->get_recordset_sql($grades_sql, $params);
     } else {
         $this->grades_rs = false;
     }
     return true;
 }
Exemple #30
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;
 }