public function execute() { global $DB; $TIMELIMITHOURS = 8; $timebound = time() - $TIMELIMITHOURS * 60 * 60; $sql = 'SELECT id, itemid, userid FROM {grade_grades} WHERE locked = 0 AND overridden > 0 AND overridden < ?'; $records = $DB->get_records_sql($sql, array($timebound)); foreach ($records as $record) { $gradeitem = \grade_item::fetch(array('id' => $record->itemid)); $grades = \grade_grade::fetch_users_grades($gradeitem, array($record->userid)); $grades[$record->userid]->set_locked(1); } }
/** * Calculates the completion state for an activity and user. * * Internal function. Not private, so we can unit-test it. * * @param stdClass|cm_info $cm Activity * @param int $userid ID of user * @param stdClass $current Previous completion information from database * @return mixed */ public function internal_get_state($cm, $userid, $current) { global $USER, $DB, $CFG; // Get user ID if (!$userid) { $userid = $USER->id; } // Check viewed if ($cm->completionview == COMPLETION_VIEW_REQUIRED && $current->viewed == COMPLETION_NOT_VIEWED) { return COMPLETION_INCOMPLETE; } // Modname hopefully is provided in $cm but just in case it isn't, let's grab it if (!isset($cm->modname)) { $cm->modname = $DB->get_field('modules', 'name', array('id' => $cm->module)); } $newstate = COMPLETION_COMPLETE; // Check grade if (!is_null($cm->completiongradeitemnumber)) { require_once $CFG->libdir . '/gradelib.php'; $item = grade_item::fetch(array('courseid' => $cm->course, 'itemtype' => 'mod', 'itemmodule' => $cm->modname, 'iteminstance' => $cm->instance, 'itemnumber' => $cm->completiongradeitemnumber)); if ($item) { // Fetch 'grades' (will be one or none) $grades = grade_grade::fetch_users_grades($item, array($userid), false); if (empty($grades)) { // No grade for user return COMPLETION_INCOMPLETE; } if (count($grades) > 1) { $this->internal_systemerror("Unexpected result: multiple grades for\n item '{$item->id}', user '{$userid}'"); } $newstate = self::internal_get_grade_state($item, reset($grades)); if ($newstate == COMPLETION_INCOMPLETE) { return COMPLETION_INCOMPLETE; } } else { $this->internal_systemerror("Cannot find grade item for '{$cm->modname}'\n cm '{$cm->id}' matching number '{$cm->completiongradeitemnumber}'"); } } if (plugin_supports('mod', $cm->modname, FEATURE_COMPLETION_HAS_RULES)) { $function = $cm->modname . '_get_completion_state'; if (!function_exists($function)) { $this->internal_systemerror("Module {$cm->modname} claims to support\n FEATURE_COMPLETION_HAS_RULES but does not have required\n {$cm->modname}_get_completion_state function"); } if (!$function($this->course, $cm, $userid, COMPLETION_AND)) { return COMPLETION_INCOMPLETE; } } return $newstate; }
/** * Returns grading information for given activity - optionally with users grades * Manual, course or category items can not be queried. * @param int $courseid id of course * @param string $itemtype 'mod', 'block' * @param string $itemmodule 'forum, 'quiz', etc. * @param int $iteminstance id of the item module * @param int $userid optional id of the graded user; if userid not used, returns only information about grade_item * @return array of grade information objects (scaleid, name, grade and locked status, etc.) indexed with itemnumbers */ function grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids = 0) { global $CFG; $return = new object(); $return->items = array(); $return->outcomes = array(); $course_item = grade_item::fetch_course_item($courseid); $needsupdate = array(); if ($course_item->needsupdate) { $result = grade_regrade_final_grades($courseid); if ($result !== true) { $needsupdate = array_keys($result); } } if ($grade_items = grade_item::fetch_all(array('itemtype' => $itemtype, 'itemmodule' => $itemmodule, 'iteminstance' => $iteminstance, 'courseid' => $courseid))) { foreach ($grade_items as $grade_item) { $decimalpoints = null; if (empty($grade_item->outcomeid)) { // prepare information about grade item $item = new object(); $item->itemnumber = $grade_item->itemnumber; $item->scaleid = $grade_item->scaleid; $item->name = $grade_item->get_name(); $item->grademin = $grade_item->grademin; $item->grademax = $grade_item->grademax; $item->gradepass = $grade_item->gradepass; $item->locked = $grade_item->is_locked(); $item->hidden = $grade_item->is_hidden(); $item->grades = array(); switch ($grade_item->gradetype) { case GRADE_TYPE_NONE: continue; case GRADE_TYPE_VALUE: $item->scaleid = 0; break; case GRADE_TYPE_TEXT: $item->scaleid = 0; $item->grademin = 0; $item->grademax = 0; $item->gradepass = 0; break; } if (empty($userid_or_ids)) { $userids = array(); } else { if (is_array($userid_or_ids)) { $userids = $userid_or_ids; } else { $userids = array($userid_or_ids); } } if ($userids) { $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true); foreach ($userids as $userid) { $grade_grades[$userid]->grade_item =& $grade_item; $grade = new object(); $grade->grade = $grade_grades[$userid]->finalgrade; $grade->locked = $grade_grades[$userid]->is_locked(); $grade->hidden = $grade_grades[$userid]->is_hidden(); $grade->overridden = $grade_grades[$userid]->overridden; $grade->feedback = $grade_grades[$userid]->feedback; $grade->feedbackformat = $grade_grades[$userid]->feedbackformat; $grade->usermodified = $grade_grades[$userid]->usermodified; // create text representation of grade if (in_array($grade_item->id, $needsupdate)) { $grade->grade = false; $grade->str_grade = get_string('error'); } else { if (is_null($grade->grade)) { $grade->str_grade = '-'; } else { $grade->str_grade = grade_format_gradevalue($grade->grade, $grade_item); } } // create html representation of feedback if (is_null($grade->feedback)) { $grade->str_feedback = ''; } else { $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat); } $item->grades[$userid] = $grade; } } $return->items[$grade_item->itemnumber] = $item; } else { if (!($grade_outcome = grade_outcome::fetch(array('id' => $grade_item->outcomeid)))) { debugging('Incorect outcomeid found'); continue; } // outcome info $outcome = new object(); $outcome->itemnumber = $grade_item->itemnumber; $outcome->scaleid = $grade_outcome->scaleid; $outcome->name = $grade_outcome->get_name(); $outcome->locked = $grade_item->is_locked(); $outcome->hidden = $grade_item->is_hidden(); if (empty($userid_or_ids)) { $userids = array(); } else { if (is_array($userid_or_ids)) { $userids = $userid_or_ids; } else { $userids = array($userid_or_ids); } } if ($userids) { $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true); foreach ($userids as $userid) { $grade_grades[$userid]->grade_item =& $grade_item; $grade = new object(); $grade->grade = $grade_grades[$userid]->finalgrade; $grade->locked = $grade_grades[$userid]->is_locked(); $grade->hidden = $grade_grades[$userid]->is_hidden(); $grade->feedback = $grade_grades[$userid]->feedback; $grade->feedbackformat = $grade_grades[$userid]->feedbackformat; $grade->usermodified = $grade_grades[$userid]->usermodified; // create text representation of grade if (in_array($grade_item->id, $needsupdate)) { $grade->grade = false; $grade->str_grade = get_string('error'); } else { if (is_null($grade->grade)) { $grade->grade = 0; $grade->str_grade = get_string('nooutcome', 'grades'); } else { $grade->grade = (int) $grade->grade; $scale = $grade_item->load_scale(); $grade->str_grade = format_string($scale->scale_items[(int) $grade->grade - 1]); } } // create html representation of feedback if (is_null($grade->feedback)) { $grade->str_feedback = ''; } else { $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat); } $outcome->grades[$userid] = $grade; } } $return->outcomes[$grade_item->itemnumber] = $outcome; } } } // sort results using itemnumbers ksort($return->items, SORT_NUMERIC); ksort($return->outcomes, SORT_NUMERIC); return $return; }
/** * Returns the aggregated or calculated course grade(s) in given course. * @public * @param int $courseid id of course * @param int $userid_or_ids optional id of the graded user or array of ids; if userid not used, returns only information about grade_item * @return information about course grade item scaleid, name, grade and locked status, etc. + user grades */ function grade_get_course_grades($courseid, $userid_or_ids = null) { $grade_item = grade_item::fetch_course_item($courseid); 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(); $item->grades = array(); switch ($grade_item->gradetype) { case GRADE_TYPE_NONE: continue; case GRADE_TYPE_VALUE: $item->scaleid = 0; break; case GRADE_TYPE_TEXT: $item->scaleid = 0; $item->grademin = 0; $item->grademax = 0; $item->gradepass = 0; break; } if (empty($userid_or_ids)) { $userids = array(); } else { if (is_array($userid_or_ids)) { $userids = $userid_or_ids; } else { $userids = array($userid_or_ids); } } if ($userids) { $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true); foreach ($userids as $userid) { $grade_grades[$userid]->grade_item =& $grade_item; $grade = new stdClass(); $grade->grade = $grade_grades[$userid]->finalgrade; $grade->locked = $grade_grades[$userid]->is_locked(); $grade->hidden = $grade_grades[$userid]->is_hidden(); $grade->overridden = $grade_grades[$userid]->overridden; $grade->feedback = $grade_grades[$userid]->feedback; $grade->feedbackformat = $grade_grades[$userid]->feedbackformat; $grade->usermodified = $grade_grades[$userid]->usermodified; $grade->dategraded = $grade_grades[$userid]->get_dategraded(); // 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); } $item->grades[$userid] = $grade; } } return $item; }
/** * Returns array of grades for given grade_item+users * * @param grade_item $grade_item * @param array $userids * @param bool $include_missing include grades that do not exist yet * @return array userid=>grade_grade array */ public static function fetch_users_grades($grade_item, $userids, $include_missing = true) { global $DB; // hmm, there might be a problem with length of sql query // if there are too many users requested - we might run out of memory anyway $limit = 2000; $count = count($userids); if ($count > $limit) { $half = (int) ($count / 2); $first = array_slice($userids, 0, $half); $second = array_slice($userids, $half); return grade_grade::fetch_users_grades($grade_item, $first, $include_missing) + grade_grade::fetch_users_grades($grade_item, $second, $include_missing); } list($user_ids_cvs, $params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED, 'uid0'); $params['giid'] = $grade_item->id; $result = array(); if ($grade_records = $DB->get_records_select('grade_grades', "itemid=:giid AND userid {$user_ids_cvs}", $params)) { foreach ($grade_records as $record) { $result[$record->userid] = new grade_grade($record, false); } } if ($include_missing) { foreach ($userids as $userid) { if (!array_key_exists($userid, $result)) { $grade_grade = new grade_grade(); $grade_grade->userid = $userid; $grade_grade->itemid = $grade_item->id; $result[$userid] = $grade_grade; } } } return $result; }
/** * Obtains the automatic completion state for this quiz on any conditions * in quiz settings, such as if all attempts are used or a certain grade is achieved. * * @param object $course Course * @param object $cm Course-module * @param int $userid User ID * @param bool $type Type of comparison (or/and; can be used as return value if no conditions) * @return bool True if completed, false if not. (If no conditions, then return * value depends on comparison type) */ function quiz_get_completion_state($course, $cm, $userid, $type) { global $DB; global $CFG; $quiz = $DB->get_record('quiz', array('id' => $cm->instance), '*', MUST_EXIST); if (!$quiz->completionattemptsexhausted && !$quiz->completionpass) { return $type; } // Check if the user has used up all attempts. if ($quiz->completionattemptsexhausted) { $attempts = quiz_get_user_attempts($quiz->id, $userid, 'finished', true); if ($attempts) { $lastfinishedattempt = end($attempts); $context = context_module::instance($cm->id); $quizobj = quiz::create($quiz->id, $userid); $accessmanager = new quiz_access_manager($quizobj, time(), has_capability('mod/quiz:ignoretimelimits', $context, $userid, false)); if ($accessmanager->is_finished(count($attempts), $lastfinishedattempt)) { return true; } } } // Check for passing grade. if ($quiz->completionpass) { require_once $CFG->libdir . '/gradelib.php'; $item = grade_item::fetch(array('courseid' => $course->id, 'itemtype' => 'mod', 'itemmodule' => 'quiz', 'iteminstance' => $cm->instance, 'outcomeid' => null)); if ($item) { $grades = grade_grade::fetch_users_grades($item, array($userid), false); if (!empty($grades[$userid])) { return $grades[$userid]->is_passed($item); } } } return false; }
/** * Returns array of grades for given grade_item+users. * @param object $grade_item * @param array $userids * @param bool $include_missing include grades that do not exist yet * @return array userid=>grade_grade array */ function fetch_users_grades($grade_item, $userids, $include_missing = true) { // hmm, there might be a problem with length of sql query // if there are too many users requested - we might run out of memory anyway $limit = 2000; $count = count($userids); if ($count > $limit) { $half = (int) ($count / 2); $first = array_slice($userids, 0, $half); $second = array_slice($userids, $half); return grade_grade::fetch_users_grades($grade_item, $first, $include_missing) + grade_grade::fetch_users_grades($grade_item, $second, $include_missing); } $user_ids_cvs = implode(',', $userids); $result = array(); if ($grade_records = get_records_select('grade_grades', "itemid={$grade_item->id} AND userid IN ({$user_ids_cvs})")) { foreach ($grade_records as $record) { $result[$record->userid] = new grade_grade($record, false); } } if ($include_missing) { foreach ($userids as $userid) { if (!array_key_exists($userid, $result)) { $grade_grade = new grade_grade(); $grade_grade->userid = $userid; $grade_grade->itemid = $grade_item->id; $result[$userid] = $grade_grade; } } } return $result; }
/** * Returns grading information for one or more activities, optionally with user grades * Manual, course or category items can not be queried. * * @category grade * @param int $courseid ID of course * @param string $itemtype Type of grade item. For example, 'mod' or 'block' * @param string $itemmodule More specific then $itemtype. For example, 'forum' or 'quiz'. May be NULL for some item types * @param int $iteminstance ID of the item module * @param mixed $userid_or_ids Either a single user ID, an array of user IDs or null. If user ID or IDs are not supplied returns information about grade_item * @return array Array of grade information objects (scaleid, name, grade and locked status, etc.) indexed with itemnumbers */ function grade_get_grades($courseid, $itemtype = null, $itemmodule = null, $iteminstance = null, $userid_or_ids = null) { global $CFG; if (empty($itemtype) or empty($itemmodule) or empty($iteminstance)) { debugging('itemtype, itemmodule or iteminstance parameters should not be empty. For Moodle 2.8 and onwards are required', DEBUG_DEVELOPER); } $return = new stdClass(); $return->items = array(); $return->outcomes = array(); $course_item = grade_item::fetch_course_item($courseid); $needsupdate = array(); if ($course_item->needsupdate) { $result = grade_regrade_final_grades($courseid); if ($result !== true) { $needsupdate = array_keys($result); } } $params = array('courseid' => $courseid); if (!empty($itemtype)) { $params['itemtype'] = $itemtype; } if (!empty($itemmodule)) { $params['itemmodule'] = $itemmodule; } if (!empty($iteminstance)) { $params['iteminstance'] = $iteminstance; } if ($grade_items = grade_item::fetch_all($params)) { foreach ($grade_items as $grade_item) { $decimalpoints = null; if (empty($grade_item->outcomeid)) { // prepare information about grade item $item = new stdClass(); $item->id = $grade_item->id; $item->itemnumber = $grade_item->itemnumber; $item->itemtype = $grade_item->itemtype; $item->itemmodule = $grade_item->itemmodule; $item->iteminstance = $grade_item->iteminstance; $item->scaleid = $grade_item->scaleid; $item->name = $grade_item->get_name(); $item->grademin = $grade_item->grademin; $item->grademax = $grade_item->grademax; $item->gradepass = $grade_item->gradepass; $item->locked = $grade_item->is_locked(); $item->hidden = $grade_item->is_hidden(); $item->grades = array(); switch ($grade_item->gradetype) { case GRADE_TYPE_NONE: continue; case GRADE_TYPE_VALUE: $item->scaleid = 0; break; case GRADE_TYPE_TEXT: $item->scaleid = 0; $item->grademin = 0; $item->grademax = 0; $item->gradepass = 0; break; } if (empty($userid_or_ids)) { $userids = array(); } else { if (is_array($userid_or_ids)) { $userids = $userid_or_ids; } else { $userids = array($userid_or_ids); } } if ($userids) { $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true); foreach ($userids as $userid) { $grade_grades[$userid]->grade_item =& $grade_item; $grade = new stdClass(); $grade->grade = $grade_grades[$userid]->finalgrade; $grade->locked = $grade_grades[$userid]->is_locked(); $grade->hidden = $grade_grades[$userid]->is_hidden(); $grade->overridden = $grade_grades[$userid]->overridden; $grade->feedback = $grade_grades[$userid]->feedback; $grade->feedbackformat = $grade_grades[$userid]->feedbackformat; $grade->usermodified = $grade_grades[$userid]->usermodified; $grade->datesubmitted = $grade_grades[$userid]->get_datesubmitted(); $grade->dategraded = $grade_grades[$userid]->get_dategraded(); // create text representation of grade if ($grade_item->gradetype == GRADE_TYPE_TEXT or $grade_item->gradetype == GRADE_TYPE_NONE) { $grade->grade = null; $grade->str_grade = '-'; $grade->str_long_grade = $grade->str_grade; } else { if (in_array($grade_item->id, $needsupdate)) { $grade->grade = false; $grade->str_grade = get_string('error'); $grade->str_long_grade = $grade->str_grade; } else { if (is_null($grade->grade)) { $grade->str_grade = '-'; $grade->str_long_grade = $grade->str_grade; } else { $grade->str_grade = grade_format_gradevalue($grade->grade, $grade_item); if ($grade_item->gradetype == GRADE_TYPE_SCALE or $grade_item->get_displaytype() != GRADE_DISPLAY_TYPE_REAL) { $grade->str_long_grade = $grade->str_grade; } else { $a = new stdClass(); $a->grade = $grade->str_grade; $a->max = grade_format_gradevalue($grade_item->grademax, $grade_item); $grade->str_long_grade = get_string('gradelong', 'grades', $a); } } } } // create html representation of feedback if (is_null($grade->feedback)) { $grade->str_feedback = ''; } else { $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat); } $item->grades[$userid] = $grade; } } $return->items[$grade_item->itemnumber] = $item; } else { if (!($grade_outcome = grade_outcome::fetch(array('id' => $grade_item->outcomeid)))) { debugging('Incorect outcomeid found'); continue; } // outcome info $outcome = new stdClass(); $outcome->id = $grade_item->id; $outcome->itemnumber = $grade_item->itemnumber; $outcome->itemtype = $grade_item->itemtype; $outcome->itemmodule = $grade_item->itemmodule; $outcome->iteminstance = $grade_item->iteminstance; $outcome->scaleid = $grade_outcome->scaleid; $outcome->name = $grade_outcome->get_name(); $outcome->locked = $grade_item->is_locked(); $outcome->hidden = $grade_item->is_hidden(); if (empty($userid_or_ids)) { $userids = array(); } else { if (is_array($userid_or_ids)) { $userids = $userid_or_ids; } else { $userids = array($userid_or_ids); } } if ($userids) { $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true); foreach ($userids as $userid) { $grade_grades[$userid]->grade_item =& $grade_item; $grade = new stdClass(); $grade->grade = $grade_grades[$userid]->finalgrade; $grade->locked = $grade_grades[$userid]->is_locked(); $grade->hidden = $grade_grades[$userid]->is_hidden(); $grade->feedback = $grade_grades[$userid]->feedback; $grade->feedbackformat = $grade_grades[$userid]->feedbackformat; $grade->usermodified = $grade_grades[$userid]->usermodified; // create text representation of grade if (in_array($grade_item->id, $needsupdate)) { $grade->grade = false; $grade->str_grade = get_string('error'); } else { if (is_null($grade->grade)) { $grade->grade = 0; $grade->str_grade = get_string('nooutcome', 'grades'); } else { $grade->grade = (int) $grade->grade; $scale = $grade_item->load_scale(); $grade->str_grade = format_string($scale->scale_items[(int) $grade->grade - 1]); } } // create html representation of feedback if (is_null($grade->feedback)) { $grade->str_feedback = ''; } else { $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat); } $outcome->grades[$userid] = $grade; } } if (isset($return->outcomes[$grade_item->itemnumber])) { // itemnumber duplicates - lets fix them! $newnumber = $grade_item->itemnumber + 1; while (grade_item::fetch(array('itemtype' => $itemtype, 'itemmodule' => $itemmodule, 'iteminstance' => $iteminstance, 'courseid' => $courseid, 'itemnumber' => $newnumber))) { $newnumber++; } $outcome->itemnumber = $newnumber; $grade_item->itemnumber = $newnumber; $grade_item->update('system'); } $return->outcomes[$grade_item->itemnumber] = $outcome; } } } // sort results using itemnumbers ksort($return->items, SORT_NUMERIC); ksort($return->outcomes, SORT_NUMERIC); return $return; }
/** * copies the grades from the source(s) to the target(s) for the selected activity * * @param int $activity ID of activity to get/set grades from/for * @param bool $mygroupsonly limit source-grades to those given by current user * @param int[] $selected array with ids of groups/users to copy grades to as keys (depends on filter) * @param int[] $source optional array with ids of entries for whom no source has been selected * (just to display a clue to select a source) * @param bool $overwrite optional overwrite existing grades (std: false) * @param bool $previewonly optional just return preview data * @return array ($error, $message) */ private function copy_grades($activity, $mygroupsonly, $selected, $source, $overwrite = false, $previewonly = false) { global $DB, $USER, $PAGE; $error = false; // If he want's to grade all he needs the corresponding capability! if (!$mygroupsonly) { require_capability('mod/grouptool:grade', $this->context); } else { if (!has_capability('mod/grouptool:grade', $this->context)) { /* * if he wants to grade his own (=submissions where he graded at least 1 group member) * he needs either capability to grade all or to grade his own at least */ require_capability('mod/grouptool:grade_own_submission', $this->context); } } $cmtouse = get_coursemodule_from_id('', $activity, $this->course->id); if (!$cmtouse) { return array(true, get_string('couremodule_misconfigured')); } if ($previewonly) { $previewtable = new html_table(); $previewtable->attributes['class'] = 'coloredrows grading_previewtable'; } else { $info = ""; } $gradeitem = grade_item::fetch(array('itemtype' => 'mod', 'itemmodule' => $cmtouse->modname, 'iteminstance' => $cmtouse->instance)); if (is_array($source)) { // Then we are in multigroup mode (filter = 0 || -1)! $sourceusers = $DB->get_records_list('user', 'id', $source); $groups = groups_get_all_groups($this->course->id); if (!isset($previewtable)) { $previewtable = new stdClass(); } $previewtable->head = array(get_string('groups') . " (" . count($selected) . ")", get_string('fullname'), get_string('grade'), get_string('feedback')); foreach ($selected as $group) { if ($previewonly) { $grouprows = array(); } else { $groupinfo = ""; } $sourcegrade = grade_grade::fetch_users_grades($gradeitem, $source[$group], false); $sourcegrade = reset($sourcegrade); $sourcegrade->load_optional_fields(); $origteacher = $DB->get_record('user', array('id' => $sourcegrade->usermodified)); $formattedgrade = round($sourcegrade->finalgrade, 2) . ' / ' . round($gradeitem->grademax, 2); $groupmembers = groups_get_members($group); $targetgrades = grade_grade::fetch_users_grades($gradeitem, array_keys($groupmembers), true); $propertiestocopy = array('rawgrade', 'finalgrade', 'feedback', 'feedbackformat'); foreach ($targetgrades as $currentgrade) { if ($currentgrade->id == $sourcegrade->id) { continue; } if (!$overwrite && $currentgrade->finalgrade != null) { if ($previewonly) { $rowcells = array(); if (empty($grouprows)) { $rowcells[] = new html_table_cell($groups[$group]->name . "\n" . html_writer::empty_tag('br') . "(" . (count($groupmembers) - 1) . ")"); } $fullname = fullname($groupmembers[$currentgrade->userid]); $rowcells[] = new html_table_cell($fullname); $cell = new html_table_cell(get_string('skipped', 'grouptool')); $cell->colspan = 2; $rowcells[] = $cell; $row = new html_table_row(); $row->cells = $rowcells; if (empty($grouprows)) { $row->attributes['class'] .= ' firstgrouprow'; } $grouprows[] = $row; } continue; } $currentgrade->load_optional_fields(); foreach ($propertiestocopy as $property) { $currentgrade->{$property} = $sourcegrade->{$property}; } $details = array('student' => fullname($sourceusers[$source[$group]]), 'teacher' => fullname($origteacher), 'date' => userdate($sourcegrade->get_dategraded(), get_string('strftimedatetimeshort')), 'feedback' => $sourcegrade->feedback); $currentgrade->feedback = format_text(get_string('copied_grade_feedback', 'grouptool', $details), $currentgrade->feedbackformat); $currentgrade->usermodified = $USER->id; if ($previewonly) { $rowcells = array(); if (empty($grouprows)) { $rowcells[] = new html_table_cell($groups[$group]->name . "\n" . html_writer::empty_tag('br') . "(" . count($groupmembers) . ")"); } $fullname = fullname($groupmembers[$currentgrade->userid]); $rowcells[] = new html_table_cell($fullname); $rowcells[] = new html_table_cell($formattedgrade); $rowcells[] = new html_table_cell($currentgrade->feedback); $row = new html_table_row(); $row->cells = $rowcells; if (empty($grouprows)) { $row->attributes['class'] .= ' firstgrouprow'; } $grouprows[] = $row; } else { if (function_exists('grouptool_copy_' . $cmtouse->modname . '_grades')) { $copyfunction = 'grouptool_copy_' . $cmtouse->modname . '_grades'; $copyfunction($cmtouse->instance, $sourcegrade->userid, $currentgrade->userid); } if ($currentgrade->id) { $noerror = $currentgrade->update(); } else { $noerror = $currentgrade->insert(); } $currentgrade->set_overridden(true, false); $fullname = fullname($groupmembers[$currentgrade->userid]); if ($noerror) { $groupinfo .= html_writer::tag('span', '✓ ' . $fullname . " (" . $formattedgrade . ")", array('class' => 'notifysuccess')); } else { $error = true; $groupinfo .= html_writer::tag('span', '✗ ' . $fullname . " (" . $formattedgrade . ")", array('class' => 'notifyproblem')); } } } if ($previewonly) { $grouprows[0]->cells[0]->rowspan = count($grouprows); if (!is_array($previewtable->data)) { $previewtable->data = array(); } $previewtable->data = array_merge($previewtable->data, $grouprows); } else { $grpinfo = ""; $grpinfo .= html_writer::tag('div', $groups[$group]->name . " (" . count($groupmembers) . "): " . $groupinfo); $data = array('student' => fullname($sourceusers[$source[$group]]), 'teacher' => fullname($origteacher), 'date' => userdate($sourcegrade->get_dategraded(), get_string('strftimedatetimeshort')), 'feedback' => $sourcegrade->feedback); $temp = get_string('copied_grade_feedback', 'grouptool', $data); $grpinfo .= html_writer::tag('div', $formattedgrade . html_writer::empty_tag('br') . format_text($temp, $sourcegrade->feedbackformat)); $info .= html_writer::tag('div', $grpinfo, array('class' => 'box1embottom')); // Trigger the event! $logdata = new stdClass(); $logdata->groupid = $group; $logdata->cmtouse = $cmtouse->id; \mod_grouptool\event\group_graded::create_direct($this->cm, $logdata)->trigger(); } } } else { $sourceuser = $DB->get_record('user', array('id' => $source)); $targetusers = $DB->get_records_list('user', 'id', $selected); $sourcegrade = grade_grade::fetch_users_grades($gradeitem, $source, false); $sourcegrade = reset($sourcegrade); $origteacher = $DB->get_record('user', array('id' => $sourcegrade->usermodified)); $formattedgrade = round($sourcegrade->finalgrade, 2) . ' / ' . round($gradeitem->grademax, 2); $targetgrades = grade_grade::fetch_users_grades($gradeitem, $selected, true); $propertiestocopy = array('rawgrade', 'finalgrade', 'feedback', 'feedbackformat'); if ($previewonly) { $grouprows = array(); $count = in_array($source, $selected) ? count($selected) - 1 : count($selected); $previewtable->head = array('', get_string('fullname') . " (" . $count . ")", get_string('grade'), get_string('feedback')); $previewtable->attributes['class'] = 'coloredrows grading_previewtable'; } else { $info .= html_writer::start_tag('div'); $nameinfo = ""; } foreach ($targetgrades as $currentgrade) { if ($currentgrade->id == $sourcegrade->id) { continue; } if (!$overwrite && $currentgrade->rawgrade != null) { if ($previewonly) { $rowcells = array(); if (empty($grouprows)) { $rowcells[] = new html_table_cell(get_string('users')); } $fullname = fullname($targetusers[$currentgrade->userid]); $rowcells[] = new html_table_cell($fullname); $cell = new html_table_cell(get_string('skipped', 'grouptool')); $cell->colspan = 2; $rowcells[] = $cell; $row = new html_table_row(); $row->cells = $rowcells; if (empty($grouprows)) { $row->attributes['class'] .= ' firstgrouprow'; } $grouprows[] = $row; } continue; } $currentgrade->load_optional_fields(); foreach ($propertiestocopy as $property) { $currentgrade->{$property} = $sourcegrade->{$property}; } $details = array('student' => fullname($sourceuser), 'teacher' => fullname($origteacher), 'date' => userdate($sourcegrade->get_dategraded(), get_string('strftimedatetimeshort')), 'feedback' => $sourcegrade->feedback); $currentgrade->feedback = format_text(get_string('copied_grade_feedback', 'grouptool', $details), $currentgrade->feedbackformat); $currentgrade->usermodified = $USER->id; if ($previewonly) { $rowcells = array(); if (empty($grouprows)) { $rowcells[] = new html_table_cell(get_string('users')); } $fullname = fullname($targetusers[$currentgrade->userid]); $rowcells[] = new html_table_cell($fullname); $rowcells[] = new html_table_cell($formattedgrade); $rowcells[] = new html_table_cell(format_text($currentgrade->feedback, $currentgrade->feedbackformat)); $row = new html_table_row(); $row->cells = $rowcells; if (empty($grouprows)) { $row->attributes['class'] .= ' firstgrouprow'; } $grouprows[] = $row; } else { if ($nameinfo != "") { $nameinfo .= ", "; } if ($currentgrade->id) { $noerror = $currentgrade->update(); } else { $noerror = $currentgrade->insert(); } $currentgrade->set_overridden(true, false); $fullname = fullname($targetusers[$currentgrade->userid]); if (function_exists('grouptool_copy_' . $cmtouse->modname . '_grades')) { $copyfunction = 'grouptool_copy_' . $cmtouse->modname . '_grades'; $copyfunction($cmtouse->instance, $sourcegrade->userid, $currentgrade->userid); } if ($noerror) { $nameinfo .= html_writer::tag('span', '✓ ' . $fullname, array('class' => 'notifysuccess')); } else { $error = true; $nameinfo .= html_writer::tag('span', '✗ ' . $fullname, array('class' => 'notifyproblem')); } } } if ($previewonly) { $grouprows[0]->cells[0]->rowspan = count($grouprows); $previewtable->data = $grouprows; } else { $info .= $nameinfo . html_writer::end_tag('div'); $details = array('student' => fullname($sourceuser), 'teacher' => fullname($origteacher), 'date' => userdate($sourcegrade->get_dategraded(), get_string('strftimedatetimeshort')), 'feedback' => $sourcegrade->feedback); $info .= html_writer::tag('div', get_string('grade') . ": " . $formattedgrade . html_writer::empty_tag('br') . format_text(get_string('copied_grade_feedback', 'grouptool', $details), $sourcegrade->feedbackformat), array('class' => 'gradeinfo')); } if (!$previewonly) { // Trigger the event! $logdata = new stdClass(); $logdata->source = $source; $logdata->selected = $selected; $logdata->cmtouse = $cmtouse->id; \mod_grouptool\event\group_graded::create_without_groupid($this->cm, $logdata)->trigger(); } } if ($previewonly) { return array($error, html_writer::tag('div', html_writer::table($previewtable), array('class' => 'centeredblock'))); } else { return array($error, html_writer::tag('div', $info, array('class' => 'centeredblock'))); } }
function blended_get_users_grades(grade_item $item, array $users) { global $DB; $ids = array_map(function ($user) { if ($user instanceof stdClass) { return $user->id; } else { return $user; } }, $users); $user_grades = array(); foreach ($ids as $userid) { $user_grade = new stdClass(); $user_grade->blended = ''; $user_grade->grade = ''; $user_grades[$userid] = $user_grade; } $blended_grades = $DB->get_records('blended_grade', array('id_item' => $item->id)); foreach ($blended_grades as $blended_grade) { $team = $blended_grade->id_team; $blended_members = groups_get_members($team); foreach ($blended_members as $blended_member) { if (array_key_exists($blended_member->id, $user_grades)) { $user_grades[$blended_member->id]->blended = isset($blended_grade->grade) ? $blended_grade->grade : null; } } } // $grades_bd=$DB->get_records('grade_grades', array('itemid'=>$item->id)); if (count($ids) > 0) { $grades_db = grade_grade::fetch_users_grades($item, $ids, true); } else { $grades_db = array(); } foreach ($grades_db as $grade) { $rawgrade = $grade->rawgrade; $user_grades[$grade->userid]->grade = isset($rawgrade) ? $rawgrade : ''; //$user_grades[$grade->userid]->rawscaleid = isset($grade->rawscaleid)?($grade->rawscaleid):null; } return $user_grades; }
/** * Returns grade item info and grades. * * @param string $source * @param string $courseid * @param string $itemtype * @param string $itemmodule * @param string $iteminstance * @param string $itemnumber * @param string $grades * @param string $itemdetails * @return mixed * @throws invalid_parameter_exception * @throws moodle_exception */ public static function get_grade($source = 'mhaairs', $courseid = '', $itemtype = self::ITEM_DEFAULT_TYPE, $itemmodule = self::ITEM_DEFAULT_MODULE, $iteminstance = '0', $itemnumber = '0', $grades = null, $itemdetails = null) { global $USER; $result = array(); // Gradebook sync must be enabled by admin in the block's site configuration. if (!($syncgrades = get_config('core', 'block_mhaairs_sync_gradebook'))) { return $result; } // Parameters validation. $params = self::validate_parameters(self::update_grade_parameters(), array('source' => $source, 'courseid' => $courseid, 'itemtype' => $itemtype, 'itemmodule' => $itemmodule, 'iteminstance' => $iteminstance, 'itemnumber' => $itemnumber, 'grades' => $grades, 'itemdetails' => $itemdetails)); // Extract the validated parameters to their respective variables. foreach ($params as $var => $value) { ${$var} = $value; } // Context validation. // OPTIONAL but in most web service it should be present. $context = context_user::instance($USER->id); self::validate_context($context); // Capability checking. // OPTIONAL but in most web service it should be present. require_capability('moodle/user:viewdetails', $context, null, true, 'cannotviewprofile'); // Validate item details. $itemdetails = json_decode(urldecode($itemdetails), true); $itemdetails = self::validate_item_details($itemdetails); // Get the item details identity type variable. $identitytype = self::get_details_itentity_type($itemdetails); // Validate grades. $grades = json_decode(urldecode($grades), true); $grades = self::validate_grades($grades); // HACK Make sure grades has identity type; take from item details if must. if ($grades and !isset($grades['identity_type'])) { $grades['identity_type'] = null; if ($identitytype) { $grades['identity_type'] = $identitytype; } } // Get the course. $course = self::get_course($courseid, $identitytype); if ($course === false) { // No valid course specified. return GRADE_UPDATE_FAILED; } $courseid = $course->id; // Get the grade item. $gitem = self::get_grade_item($source, $courseid, self::ITEM_DEFAULT_TYPE, self::ITEM_DEFAULT_MODULE, $iteminstance, $itemnumber); if (!$gitem) { return $result; } // Prepare result. $result = array('item' => array('courseid' => $courseid, 'categoryid' => $gitem->categoryid, 'itemname' => $gitem->itemname, 'itemtype' => $gitem->itemtype, 'idnumber' => $gitem->idnumber, 'gradetype' => $gitem->gradetype, 'grademax' => $gitem->grademax), 'grades' => array()); if ($grades) { if (!empty($grades['userid'])) { $gradegrades = grade_grade::fetch_users_grades($gitem, array($grades['userid']), false); } else { $gradegrades = grade_grade::fetch_all(array('itemid' => $gitem->id)); } if ($gradegrades) { foreach ($gradegrades as $grade) { $result['grades'][] = array('userid' => $grade->userid, 'grade' => $grade->finalgrade); } } } return $result; }
/** * Obtains the automatic completion state for this hotpot * based on the conditions in hotpot settings. * * @param object $course record from "course" table * @param object $cm record from "course_modules" table * @param integer $userid id from "user" table * @param bool $type of comparison (or/and; used as return value if there are no conditions) * @return mixed TRUE if completed, FALSE if not, or $type if no conditions are set */ function hotpot_get_completion_state($course, $cm, $userid, $type) { global $CFG, $DB; require_once $CFG->dirroot . '/mod/hotpot/locallib.php'; // set default return $state $state = $type; // get the hotpot record if ($hotpot = $DB->get_record('hotpot', array('id' => $cm->instance))) { // get grade, if necessary $grade = false; if ($hotpot->completionmingrade || $hotpot->completionpass) { require_once $CFG->dirroot . '/lib/gradelib.php'; $params = array('courseid' => $course->id, 'itemtype' => 'mod', 'itemmodule' => 'hotpot', 'iteminstance' => $cm->instance); if ($grade_item = grade_item::fetch($params)) { $grades = grade_grade::fetch_users_grades($grade_item, array($userid), false); if (isset($grades[$userid])) { $grade = $grades[$userid]; } unset($grades); } unset($grade_item); } // the HotPot completion conditions $conditions = array('completionmingrade', 'completionpass', 'completioncompleted'); foreach ($conditions as $condition) { if (empty($hotpot->{$condition})) { continue; } switch ($condition) { case 'completionmingrade': $state = $grade && $grade->finalgrade >= $hotpot->completionmingrade; break; case 'completionpass': $state = $grade && $grade->is_passed(); break; case 'completioncompleted': $params = array('hotpotid' => $cm->instance, 'userid' => $userid, 'status' => hotpot::STATUS_COMPLETED); $state = $DB->record_exists('hotpot_attempts', $params); break; } // finish early if possible if ($type == COMPLETION_AND && $state == false) { return false; } if ($type == COMPLETION_OR && $state) { return true; } } } return $state; }