// first make sure we have all final grades
// TODO: check that no grade_item has needsupdate set
- grade_update_final_grades($id);
+ grade_regrade_final_grades($id);
/// Check to see if groups are being used in this course
if ($groupmode = groupmode($course)) { // Groups are being used
$mform =& $this->_form;
$feedbackformat = get_user_preferences('grade_report_feedbackformat', $CFG->grade_report_feedbackformat);
-
+
// visible elements
// User preference determines the format
if ($CFG->htmleditor && $USER->htmleditor && $feedbackformat == GRADER_REPORT_FEEDBACK_FORMAT_HTML) {
redirect($returnurl);
} else if ($data = $mform->get_data()) {
- if (empty($data->checkbox)) {
- $data->checkbox = 0; // work around the missing value if checkbox not selected
- }
-
if (array_key_exists('calculation', $data)) {
$data->calculation = grade_item::normalize_formula($data->calculation, $course->id);
}
}
}
$mform->addElement('select', 'scaleid', get_string('scale'), $options);
- $mform->disabledIf('scaleid', 'gradetype', 'noteq', GRADE_TYPE_SCALE);
+ $mform->disabledIf('scaleid', 'gradetype', 'eq', GRADE_TYPE_TEXT);
+ $mform->disabledIf('scaleid', 'gradetype', 'eq', GRADE_TYPE_NONE);
+ $mform->disabledIf('scaleid', 'gradetype', 'eq', GRADE_TYPE_VALUE);
$mform->addElement('text', 'grademax', get_string('grademax', 'grades'));
- $mform->disabledIf('grademax', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
- $mform->setDefault('grademin', 100);
+ $mform->disabledIf('grademax', 'gradetype', 'eq', GRADE_TYPE_TEXT);
+ $mform->disabledIf('grademax', 'gradetype', 'eq', GRADE_TYPE_NONE);
+ $mform->disabledIf('grademax', 'gradetype', 'eq', GRADE_TYPE_SCALE);
+ $mform->setDefault('grademax', 100);
$mform->addElement('text', 'grademin', get_string('grademin', 'grades'));
- $mform->disabledIf('grademin', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
+ $mform->disabledIf('grademin', 'gradetype', 'eq', GRADE_TYPE_TEXT);
+ $mform->disabledIf('grademin', 'gradetype', 'eq', GRADE_TYPE_NONE);
+ $mform->disabledIf('grademin', 'gradetype', 'eq', GRADE_TYPE_SCALE);
$mform->setDefault('grademin', 0);
$mform->addElement('text', 'gradepass', get_string('gradepass', 'grades'));
$mform->disabledIf('plusfactor', 'gradetype', 'eq', GRADE_TYPE_NONE);
$mform->setDefault('plusfactor', 0);
- $mform->addElement('checkbox', 'locked', get_string('locked', 'grades'));
+ $mform->addElement('advcheckbox', 'locked', get_string('locked', 'grades'));
$mform->addElement('date_time_selector', 'locktime', get_string('locktime', 'grades'), array('optional'=>true));
$mform->disabledIf('locktime', 'gradetype', 'eq', GRADE_TYPE_NONE);
if ($id = $mform->getElementValue('id')) {
$grade_item = grade_item::fetch(array('id'=>$id));
- if (!in_array($grade_item->itemtype, array('manual', 'course', 'category'))) {
+ if ($grade_item->is_normal_item()) {
// following items are set up from modules and should not be overrided by user
$mform->hardFreeze('itemname,idnumber,calculation,gradetype,grademax,grademin,scaleid');
}
+ if ($grade_item->is_manual_item()) {
+ // manual grade item does not use these - uses only final grades
+ $mform->hardFreeze('plusfactor,multfactor');
+ }
}
}
}
}
+ if (array_key_exists('grademin', $data) and array_key_exists('grademax', $data)) {
+ if ($data['grademax'] == $data['grademin'] or $data['grademax'] < $data['grademin']) {
+ $errors['grademin'] = get_String('incorrectminmax', 'grades');
+ $errors['grademax'] = get_String('incorrectminmax', 'grades');
+ }
+ }
+
if (0 == count($errors)){
return true;
} else {
/// This creates and handles the whole grader report interface, sans header and footer
require_once($CFG->libdir.'/tablelib.php');
-include_once($CFG->libdir.'/gradelib.php');
+require_once($CFG->libdir.'/gradelib.php');
+$gradeserror = array();
/**
- * format number using lang specific decimal point and thousand separator
+ * format grade using lang specific decimal point and thousand separator
+ * the result is suitable for printing on html page
* @param float $gradeval raw grade value pulled from db
* @return string $gradeval formatted grade value
*/
function get_grade_clean($gradeval) {
global $CFG;
-
+
+ if (is_null($gradeval)) {
+ $gradeval = '';
+ } else {
+ // decimal points as specified by user
+ $decimals = get_user_preferences('grade_report_decimalpoints', $CFG->grade_report_decimalpoints);
+ $gradeval = number_format($gradeval, $decimals, get_string('decpoint', 'langconfig'), get_string('thousandsep', 'langconfig'));
+ }
+
+ return $gradeval;
+
/*
// commenting this out, if this is added, we also need to find the number of decimal place preserved
// so it can go into number_format
$gradeval = 0;
}
*/
- // decimal points as specified by user
- $decimals = get_user_preferences('grade_report_decimalpoints', $CFG->grade_report_decimalpoints);
- $gradeval = number_format($gradeval, $decimals, get_string('decpoint', 'langconfig'), get_string('thousandsep', 'langconfig'));
- return $gradeval;
}
/**
}
}
+
/// processing posted grades here
-if ($data = data_submitted()) {
- foreach ($data as $varname => $postedgrade) {
+if ($data = data_submitted() and confirm_sesskey()) {
- // clean posted values
- $postedgrade = clean_param($postedgrade, PARAM_RAW);
- // can not use param number here, because we can have "," in grade
- $varname = clean_param($varname, PARAM_RAW);
+ // always initialize all arrays
+ $queue = array();
+
+ foreach ($data as $varname => $postedgrade) {
+ // this is a bit tricky - we have to first load all grades into memory,
+ // check if changed and only then start updating the final grades because
+ // columns might depend one on another - the result would be overriden calculated and category grades
// skip, not a grade
if (!strstr($varname, 'grade')) {
$gradeinfo = explode("_", $varname);
- $grade = new object();
- $grade->userid = clean_param($gradeinfo[1], PARAM_INT);
- $gradeitemid = clean_param($gradeinfo[2], PARAM_INT);
- // grade needs to formatted to proper format for storage
- $grade->rawgrade = format_grade($postedgrade);
+ $userid = clean_param($gradeinfo[1], PARAM_INT);
+ $itemid = clean_param($gradeinfo[2], PARAM_INT);
- // put into grades array
- $grades[$gradeitemid][] = $grade;
- }
-}
-
-// array to hold all error found during grade processing, e.g. outofrange
-$gradeserror = array();
+ if (!$grade_item = grade_item::fetch(array('id'=>$itemid, 'courseid'=>$course->id))) { // we must verify course id here!
+ error('Incorrect grade item id');
+ }
-// now we update the raw grade for each posted grades
-if (!empty($grades)) {
- foreach ($grades as $gradeitemid => $itemgrades) {
- foreach ($itemgrades as $gradedata) {
- $gradeitem = new grade_item(array('id'=>$gradeitemid), true);
-
- // cbeck if grade is in range, if not, add to error array
- // MDL-10369
-
- // -1 is accepted for scale grades (no grade)
- if ($gradedata->rawgrade == -1 && $gradeitem->gradetype == 2) {
- $gradeitem->update_raw_grade($gradedata->userid, $gradedata->rawgrade);
+ if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
+ if ($postedgrade == -1) { // -1 means no grade
+ $finalgrade = null;
} else {
- if ($gradeitem->grademax < $gradedata->rawgrade || $gradeitem->grademin > $gradedata->rawgrade) {
- $gradeserror[$gradeitem->id][$gradedata->userid] = 'outofrange';
- } else {
- $gradeitem->update_raw_grade($gradedata->userid, $gradedata->rawgrade);
- }
+ $finalgrade = (float)$postedgrade;
+ }
+ } else {
+ if ($postedgrade == '') { // empty string means no grade
+ $finalgrade = null;
+ } else {
+ $finalgrade = format_grade($postedgrade);
+ }
+ }
+
+ if (!is_null($finalgrade) and ($finalgrade < $grade_item->grademin or $finalgrade > $grade_item->grademax)) {
+ $gradeserror[$grade_item->id][$userid] = 'outofrange'; //TODO: localize
+ // another possiblity is to use bounded number instead
+ continue;
+ }
+
+ if ($grade = grade_grades::fetch(array('userid'=>$userid, 'itemid'=>$grade_item->id))) {
+ if (!is_null($grade->finalgrade)) {
+ $grade->finalgrade = (float)$grade->finalgrade;
+ }
+ if ($grade->finalgrade === $finalgrade) {
+ // we must not update all grades, only changed ones - we do not want to mark everything as overriden
+ continue;
}
}
+
+ $gradedata = new object();
+ $gradedata->grade_item = $grade_item;
+ $gradedata->finalgrade = $finalgrade;
+ $gradedata->userid = $userid;
+
+ $queue[] = $gradedata;
+ }
+
+ // now we update the new final grade for each changed grade
+ foreach ($queue as $gradedata) {
+ $gradedata->grade_item->update_final_grade($gradedata->userid, $gradedata->finalgrade, 'gradebook');
}
}
// first make sure we have all final grades
// TODO: check that no grade_item has needsupdate set
-grade_update_final_grades($courseid);
+grade_regrade_final_grades($courseid);
// roles to be displaye in the gradebook
$gradebookroles = $CFG->gradebookroles;
// phase 2 sql, we supply the userids in this query, and get all the grades
// pulls out all the grades, this does not need to worry about paging
-$sql = "SELECT g.id, g.itemid, g.userid, g.finalgrade, g.hidden, g.locked, g.locktime, gt.feedback
+$sql = "SELECT g.id, g.itemid, g.userid, g.finalgrade, g.hidden, g.locked, g.locktime, g.overridden, gt.feedback
FROM {$CFG->prefix}grade_items gi,
{$CFG->prefix}grade_grades g
LEFT JOIN {$CFG->prefix}grade_grades_text gt ON g.id = gt.gradeid
$headerhtml .= '<tr class="heading">';
if ($key == $numrows - 1) {
- $headerhtml .= '<th class="user"><a href="'.$baseurl.'&sortitemid=firstname">Firstname</a> '
+ $headerhtml .= '<th class="user"><a href="'.$baseurl.'&sortitemid=firstname">Firstname</a> ' //TODO: localize
. $firstarrow. '/ <a href="'.$baseurl.'&sortitemid=lastname">Lastname </a>'. $lastarrow .'</th>';
} else {
$headerhtml .= '<td class="topleft"> </td>';
} else if ($object->itemtype == 'manual') {
//TODO: add manual grading icon
$icon = '<img src="'.$CFG->pixpath.'/t/edit.gif" class="icon" alt="'.get_string('manualgrade', 'grades')
- .'"/>'; // TODO: localize
+ .'"/>';
}
. $user->id . '">' . fullname($user) . '</a></th>';
foreach ($items as $item) {
- $studentshtml .= '<td>';
-
if (isset($finalgrades[$userid][$item->id])) {
-
- $gradeval = get_grade_clean($finalgrades[$userid][$item->id]->finalgrade);
-
+ $gradeval = $finalgrades[$userid][$item->id]->finalgrade;
$grade = new grade_grades($finalgrades[$userid][$item->id], false);
$grade->feedback = $finalgrades[$userid][$item->id]->feedback;
+
} else {
- // if itemtype is course or category, the grades in this item is not directly editable
- if ($USER->gradeediting && $item->itemtype != 'course' && $item->itemtype != 'category') {
- $gradeval ='';
- } else {
- $gradeval = '-';
- }
+ $gradeval = null;
$grade = new grade_grades(array('userid' => $userid, 'itemid' => $item->id), false);
+ $grade->feedback = '';
+ }
+
+ if ($grade->is_overridden()) {
+ $studentshtml .= '<td class="overridden">';
+ } else {
+ $studentshtml .= '<td>';
}
+
// if in editting mode, we need to print either a text box
// or a drop down (for scales)
// grades in item of type grade category or course are not directly editable
- if ($USER->gradeediting && $item->itemtype != 'course' && $item->itemtype != 'category') {
+ if ($USER->gradeediting) {
// We need to retrieve each grade_grade object from DB in order to
// know if they are hidden/locked
}
} else {
if ($quickgrading) {
- $studentshtml .= '<input size="6" type="text" name="grade_'.$userid.'_'.$item->id.'" value="'.$gradeval.'"/>';
+ $studentshtml .= '<input size="6" type="text" name="grade_'.$userid.'_'.$item->id.'" value="'.get_grade_clean($gradeval).'"/>';
} else {
- $studentshtml .= $gradeval;
+ $studentshtml .= get_grade_clean($gradeval);
}
}
}
if ($showfeedback && $quickfeedback) {
- $studentshtml .= '<input size="6" type="text" name="feedback_'.$userid.'_'.$item->id.'" value="'. @$grade->feedback . '"/>';
- } elseif ($showfeedback) { // If quickfeedback is off but showfeedback is on, print an edit feedback icon
+ $studentshtml .= '<input size="6" type="text" name="feedback_'.$userid.'_'.$item->id.'" value="'. s($grade->feedback) . '"/>';
+
+ } else if ($showfeedback) { // If quickfeedback is off but showfeedback is on, print an edit feedback icon
if (empty($grade->feedback)) {
$icons_html .= grade_get_icons($element, $gtree, array('add_feedback'));
} else {
$icons_html .= '</div>';
$studentshtml .= $icons_html;
+
} else {
// finalgrades[$userid][$itemid] could be null because of the outer join
// in this case it's different than a 0
// no such scale, throw error?
}
} else {
- $studentshtml .= get_grade_clean($gradeval);
+ if (is_null($gradeval)) {
+ $studentshtml .= '-';
+ } else {
+ $studentshtml .= get_grade_clean($gradeval);
+ }
}
}
*
* Please note that category grade is either calculated or aggregated - not both at the same time.
*
- * This method must be used ONLY from grade_item::update_final_grades(),
+ * This method must be used ONLY from grade_item::regrade_final_grades(),
* because the calculation must be done in correct order!
*
* Steps to follow:
$oldgrade->rawscaleid = $grade->rawscaleid;
}
- // locked grades are not regraded
- if ($grade->is_locked()) {
+ // no need to recalculate locked or overridden grades
+ if ($grade->is_locked() or $grade->is_overridden()) {
return;
}
*/
var $exported = 0;
+ /**
+ * Overridden flag
+ * @var boolean $overridden
+ */
+ var $overridden = 0;
+
/**
* Loads the grade_grades_text object linked to this grade (through the intersection of itemid and userid), and
* saves it as a class variable for this final object.
return !empty($this->locked) or $this->grade_item->is_locked();
}
+ function is_overridden() {
+ return !empty($this->overridden);
+ }
+
/**
* Lock/unlopck this grade.
*
* Performs the necessary calculations on the grades_final referenced by this grade_item.
* Also resets the needsupdate flag once successfully performed.
*
- * This function must be used ONLY from lib/gradeslib.php/grade_update_final_grades(),
+ * This function must be used ONLY from lib/gradeslib.php/grade_regrade_final_grades(),
* because the regrading must be done in correct order!!
*
* @return boolean true if ok, error string otherwise
*/
- function update_final_grades($userid=null) {
+ function regrade_final_grades($userid=null) {
global $CFG;
// locked grade items already have correct final grades
} else {
return "Could not aggregate final grades for category:".$this->id; // TODO: improve and localize
}
+ } else if ($this->is_manual_item()) {
+ // manual items track only final grades, no raw grades
+ return true;
}
// normal grade item - just new final grades
if ($rs) {
if ($rs->RecordCount() > 0) {
while ($grade_record = rs_fetch_next_record($rs)) {
- if (!empty($grade_record->locked)) {
+ if (!empty($grade_record->locked) or !empty($grade_record->overridden)) {
// this grade is locked - final grade must be ok
continue;
}
dubugging("Unkown grade type");
return null;;
}
-
-
}
/**
return ($this->itemtype == 'course');
}
+ /**
+ * Is this a manualy graded item?
+ * @return boolean
+ */
+ function is_manual_item() {
+ return ($this->itemtype == 'manual');
+ }
+
/**
* Is the grade item normal - associated with module, plugin or something else?
* @return boolean
*/
function is_normal_item() {
- return ($this->itemtype != 'course' and $this->itemtype != 'category');
+ return ($this->itemtype != 'course' and $this->itemtype != 'category' and $this->itemtype != 'manual');
}
/**
}
/**
- * Updates raw grade value for given user, this is a only way to update raw
- * grades from external source (module, gradebook, import, etc.),
- * because it logs the change in history table and deals with final grade recalculation.
- *
- * The only exception is category grade item which stores the raw grades directly.
- * Calculated grades do not use raw grades at all, the rawgrade changes there are not logged too.
+ * Updates final grade value for given user, this is a only way to update final
+ * grades from gradebook and import because it logs the change in history table
+ * and deals with overridden flag. This flag is set to prevent later overriding
+ * from raw grades submitted from modules.
*
* @param int $userid the graded user
- * @param mixed $rawgrade float value of raw grade - false means do not change
+ * @param mixed $finalgrade float value of final 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 mixed grade_grades object if ok, false if error
+ * @return boolean success
*/
- function update_raw_grade($userid, $rawgrade=false, $source='manual', $note=NULL, $feedback=false, $feedbackformat=FORMAT_MOODLE, $usermodified=null) {
- global $CFG, $USER;
- require_once($CFG->libdir.'/eventslib.php');
+ function update_final_grade($userid, $finalgrade=false, $source=NULL, $note=NULL, $feedback=false, $feedbackformat=FORMAT_MOODLE, $usermodified=null) {
+ global $USER;
if (empty($usermodified)) {
$usermodified = $USER->id;
}
- // calculated grades can not be updated
- if ($this->is_calculated()) {
+ // no grading used or locked
+ if ($this->gradetype == GRADE_TYPE_NONE or $this->is_locked()) {
return false;
}
- // TODO: we should IMO prevent modification of raw grades for course and categroy item too because
- // there is no way to prevent overriding of it
+ if (!$grade = grade_grades::fetch(array('itemid'=>$this->id, 'userid'=>$userid))) {
+ $grade = new grade_grades(array('itemid'=>$this->id, 'userid'=>$userid), false);
+ }
- // do not allow grade updates when item locked - this prevents fetching of grade from db
- if ($this->is_locked()) {
+ $grade->grade_item =& $this; // prevent db fetching of this grade_item
+ $oldgrade = new object();
+ $oldgrade->finalgrade = $grade->finalgrade;
+ $oldgrade->rawgrade = $grade->rawgrade;
+ $oldgrade->rawgrademin = $grade->rawgrademin;
+ $oldgrade->rawgrademax = $grade->rawgrademax;
+ $oldgrade->rawscaleid = $grade->rawscaleid;
+ $oldgrade->overridden = $grade->overridden;
+
+ if ($grade->is_locked()) {
+ // do not update locked grades at all
+ return false;
+ }
+
+ if (!empty($grade->locktime) and $grade->locktime < time()) {
+ // do not update grades that should be already locked
+ // this does not solve all problems, cron is still needed to recalculate the final grades periodically
+ return false;
+ }
+
+ if ($finalgrade !== false) {
+ $grade->finalgrade = $finalgrade;
+ // if we can update the raw grade, do update it
+ if (!$this->is_normal_item() or $this->plusfactor != 0 or $this->multfactor != 1
+ or !events_is_registered('grade_updated', $this->itemtype.'/'.$this->itemmodule)) {
+ if (!$grade->overridden) {
+ $grade->overridden = time();
+ }
+ } else {
+ $grade->rawgrade = $finalgrade;
+ // copy current grademin/max and scale
+ $grade->rawgrademin = $this->grademin;
+ $grade->rawgrademax = $this->grademax;
+ $grade->rawscaleid = $this->scaleid;
+ }
+ }
+
+ if (empty($grade->id)) {
+ $result = (boolean)$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->overridden !== $oldgrade->overridden) {
+
+ $result = $grade->update($source);
+ }
+
+ // do we have comment from teacher?
+ if ($result and $feedback !== false) {
+ $result = $grade->update_feedback($feedback, $feedbackformat, $usermodified);
+ }
+
+ 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();
+ }
+ }
+
+ if ($result and !$grade->overridden) {
+ $this->trigger_raw_updated($grade, $source);
+ }
+
+ return $result;
+ }
+
+
+ /**
+ * 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;
+ }
+
+ // calculated grades can not be updated; course and category can not be updated because they are aggregated
+ if ($this->is_calculated() or !$this->is_normal_item() or $this->gradetype == GRADE_TYPE_NONE or $this->is_locked()) {
return false;
}
if (!$this->needsupdate) {
$course_item = grade_item::fetch_course_item($this->courseid);
if (!$course_item->needsupdate) {
- if (!grade_update_final_grades($this->courseid, $userid, $this)) {
+ if (!grade_regrade_final_grades($this->courseid, $userid, $this)) {
$this->force_regrading();
}
} else {
}
if ($result) {
+ $this->trigger_raw_updated($grade, $source);
+ }
- // trigger grade_updated event notification
- $eventdata = new object();
-
- $eventdata->source = $source;
- $eventdata->itemid = $this->id;
- $eventdata->courseid = $this->courseid;
- $eventdata->itemtype = $this->itemtype;
- $eventdata->itemmodule = $this->itemmodule;
- $eventdata->iteminstance = $this->iteminstance;
- $eventdata->itemnumber = $this->itemnumber;
- $eventdata->idnumber = $this->idnumber;
- $eventdata->userid = $grade->userid;
- $eventdata->rawgrade = $grade->rawgrade;
-
- // load existing text annotation
- if ($grade_text = $grade->load_text()) {
- $eventdata->feedback = $grade_text->feedback;
- $eventdata->feedbackformat = $grade_text->feedbackformat;
- $eventdata->information = $grade_text->information;
- $eventdata->informationformat = $grade_text->informationformat;
- }
-
- events_trigger('grade_updated', $eventdata);
+ return $result;
+ }
- return $grade;
+ /**
+ * Internal function used by update_final/raw_grade() only.
+ */
+ function trigger_raw_updated($grade, $source) {
+ global $CFG;
+ require_once($CFG->libdir.'/eventslib.php');
- } else {
- return false;
- }
+ // trigger grade_updated event notification
+ $eventdata = new object();
+
+ $eventdata->source = $source;
+ $eventdata->itemid = $this->id;
+ $eventdata->courseid = $this->courseid;
+ $eventdata->itemtype = $this->itemtype;
+ $eventdata->itemmodule = $this->itemmodule;
+ $eventdata->iteminstance = $this->iteminstance;
+ $eventdata->itemnumber = $this->itemnumber;
+ $eventdata->idnumber = $this->idnumber;
+ $eventdata->userid = $grade->userid;
+ $eventdata->rawgrade = $grade->rawgrade;
+
+ // load existing text annotation
+ if ($grade_text = $grade->load_text()) {
+ $eventdata->feedback = $grade_text->feedback;
+ $eventdata->feedbackformat = $grade_text->feedbackformat;
+ $eventdata->information = $grade_text->information;
+ $eventdata->informationformat = $grade_text->informationformat;
+ }
+
+ events_trigger('grade_updated', $eventdata);
}
/**
$oldgrade->rawgrade = $grade->rawgrade;
}
- // no need to recalculate locked grades
- if ($grade->is_locked()) {
+ // no need to recalculate locked or overridden grades
+ if ($grade->is_locked() or $grade->is_overridden()) {
return;
}
* @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_update_final_grades($courseid, $userid=null, $updated_item=null) {
+function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null) {
$course_item = grade_item::fetch_course_item($courseid);
//oki - let's update, calculate or aggregate :-)
if ($doupdate) {
- $result = $grade_item->update_final_grades($userid);
+ $result = $grade_item->regrade_final_grades($userid);
if ($result === true) {
$grade_item->regrading_finished();
/**
* Test update of all final grades
*/
- function test_grade_item_update_final_grades() {
+ function test_grade_item_regrade_final_grades() {
$grade_item = new grade_item($this->grade_items[0]);
- $this->assertTrue(method_exists($grade_item, 'update_final_grades'));
- $this->assertEqual(true, $grade_item->update_final_grades());
+ $this->assertTrue(method_exists($grade_item, 'regrade_final_grades'));
+ $this->assertEqual(true, $grade_item->regrade_final_grades());
//TODO: add more tests
}
background-color: #dddddd;
}
+#grade-report td.overridden {
+ background-color: #efefef;
+}
+
/***
*** Login
***/