mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 05:58:34 +01:00
various locking improvements and fixes, cron locktime support stilll missing
This commit is contained in:
parent
1a5bcabd3c
commit
fb0e357051
@ -62,7 +62,7 @@ switch ($action) {
|
||||
if ($type == 'grade' and empty($object->id)) {
|
||||
$object->insert();
|
||||
}
|
||||
$object->set_locked(1);
|
||||
$object->set_locked(1, true, true);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -74,7 +74,7 @@ switch ($action) {
|
||||
if ($type == 'grade' and empty($object->id)) {
|
||||
$object->insert();
|
||||
}
|
||||
$object->set_locked(0);
|
||||
$object->set_locked(0, true, true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -95,6 +95,10 @@ if ($grade = get_record('grade_grades', 'itemid', $grade_item->id, 'userid', $us
|
||||
$grade->hiddenuntil = 0;
|
||||
}
|
||||
|
||||
if ($grade_item->is_locked()) {
|
||||
$grade->locked = 1;
|
||||
}
|
||||
|
||||
$mform->set_data($grade);
|
||||
|
||||
} else {
|
||||
@ -109,14 +113,22 @@ if ($mform->is_cancelled()) {
|
||||
$old_grade_grade = new grade_grade(array('userid'=>$data->userid, 'itemid'=>$grade_item->id), true); //might not exist yet
|
||||
|
||||
// fix no grade for scales
|
||||
if ($grade_item->gradetype == GRADE_TYPE_SCALE and $data->finalgrade < 1) {
|
||||
if (!isset($data->finalgrade)) {
|
||||
$data->finalgrade = $old_grade_grade->finalgrade;
|
||||
|
||||
} else if ($grade_item->gradetype == GRADE_TYPE_SCALE and $data->finalgrade < 1) {
|
||||
$data->finalgrade = NULL;
|
||||
}
|
||||
|
||||
if (!isset($data->feedback)) {
|
||||
$data->feedback = $old_grade_grade->feedback;
|
||||
$data->feedbackformat = $old_grade_grade->feedbackformat;
|
||||
}
|
||||
// update final grade or feedback
|
||||
$grade_item->update_final_grade($data->userid, $data->finalgrade, NULL, 'editgrade', $data->feedback, $data->feedbackformat);
|
||||
|
||||
$grade_grade = grade_grade::fetch(array('userid'=>$data->userid, 'itemid'=>$grade_item->id));
|
||||
$grade_grade->grade_item =& $grade_item; // no db fetching
|
||||
|
||||
if (has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:hide', $context)) {
|
||||
if (empty($data->hidden)) {
|
||||
@ -130,34 +142,44 @@ if ($mform->is_cancelled()) {
|
||||
}
|
||||
}
|
||||
|
||||
if (has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:override', $context)) {
|
||||
if (isset($data->locked) and !$grade_item->is_locked()) {
|
||||
if (($old_grade_grade->locked or $old_grade_grade->locktime)
|
||||
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context))) {
|
||||
//ignore data
|
||||
|
||||
} else if ((!$old_grade_grade->locked and !$old_grade_grade->locktime)
|
||||
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context))) {
|
||||
//ignore data
|
||||
|
||||
} else {
|
||||
$grade_grade->set_locktime($data->locktime); //set_lock may reset locktime
|
||||
$grade_grade->set_locked($data->locked, false, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($data->excluded) and has_capability('moodle/grade:manage', $context)) {
|
||||
$grade_grade->set_excluded($data->excluded);
|
||||
}
|
||||
|
||||
if (isset($data->overridden) and has_capability('moodle/grade:manage', $context) or has_capability('moodle/grade:override', $context)) {
|
||||
// ignore overridden flag when changing final grade
|
||||
if ($old_grade_grade->finalgrade == $grade_grade->finalgrade) {
|
||||
if ($grade_grade->set_overridden($data->overridden) and empty($data->overridden)) {
|
||||
$grade_item->force_regrading(); // force regrading only when clearing the flag
|
||||
}
|
||||
$grade_grade->set_overridden($data->overridden);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_capability('moodle/grade:manage', $context)) {
|
||||
if ($grade_grade->set_excluded($data->excluded)) {
|
||||
$grade_item->force_regrading();
|
||||
}
|
||||
// detect cases when we need to do full regrading
|
||||
if ($old_grade_grade->excluded != $grade_grade->excluded) {
|
||||
$parent = $grade_item->get_parent_category();
|
||||
$parent->force_regrading();
|
||||
|
||||
} else if ($old_grade_grade->overridden != $grade_grade->overridden and empty($grade_grade->overridden)) { // only when unoverriding
|
||||
$grade_item->force_regrading();
|
||||
|
||||
} else if ($old_grade_grade->locktime != $grade_grade->locktime) {
|
||||
$grade_item->force_regrading();
|
||||
}
|
||||
|
||||
if (($old_grade_grade->locked or $old_grade_grade->locktime)
|
||||
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context))) {
|
||||
//ignore data
|
||||
|
||||
} else if ((!$old_grade_grade->locked and !$old_grade_grade->locktime)
|
||||
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context))) {
|
||||
//ignore data
|
||||
|
||||
} else {
|
||||
$grade_grade->set_locked($data->locked);
|
||||
$grade_grade->set_locktime($data->locktime);
|
||||
}
|
||||
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
|
@ -135,20 +135,33 @@ class edit_grade_form extends moodleform {
|
||||
}
|
||||
|
||||
$old_grade_grade = new grade_grade(array('itemid'=>$grade_item->id, 'userid'=>$userid));
|
||||
if (empty($old_grade_grade->id)) {
|
||||
$old_grade_grade->locked = $grade_item->locked;
|
||||
$old_grade_grade->locktime = $grade_item->locktime;
|
||||
}
|
||||
|
||||
if (($old_grade_grade->locked or $old_grade_grade->locktime)
|
||||
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context))) {
|
||||
$mform->hardFreeze('locked');
|
||||
$mform->hardFreeze('locktime');
|
||||
if ($old_grade_grade->is_locked()) {
|
||||
if ($grade_item->is_locked()) {
|
||||
$mform->hardFreeze('locked');
|
||||
$mform->hardFreeze('locktime');
|
||||
}
|
||||
|
||||
} else if ((!$old_grade_grade->locked and !$old_grade_grade->locktime)
|
||||
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context))) {
|
||||
$mform->hardFreeze('locked');
|
||||
$mform->hardFreeze('locktime');
|
||||
$mform->hardFreeze('overridden');
|
||||
$mform->hardFreeze('finalgrade');
|
||||
$mform->hardFreeze('feedback');
|
||||
|
||||
} else {
|
||||
if (empty($old_grade_grade->id)) {
|
||||
$old_grade_grade->locked = $grade_item->locked;
|
||||
$old_grade_grade->locktime = $grade_item->locktime;
|
||||
}
|
||||
|
||||
if (($old_grade_grade->locked or $old_grade_grade->locktime)
|
||||
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context))) {
|
||||
$mform->hardFreeze('locked');
|
||||
$mform->hardFreeze('locktime');
|
||||
|
||||
} else if ((!$old_grade_grade->locked and !$old_grade_grade->locktime)
|
||||
and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context))) {
|
||||
$mform->hardFreeze('locked');
|
||||
$mform->hardFreeze('locktime');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,8 @@ if ($item = get_record('grade_items', 'id', $id, 'courseid', $course->id)) {
|
||||
$item->hiddenuntil = 0;
|
||||
}
|
||||
|
||||
$item->locked = !empty($item->locked);
|
||||
|
||||
// Get Item preferences
|
||||
$item->pref_gradedisplaytype = grade_report::get_pref('gradedisplaytype', $id);
|
||||
$item->pref_decimalpoints = grade_report::get_pref('decimalpoints', $id);
|
||||
@ -58,6 +60,11 @@ if ($data = $mform->get_data(false)) {
|
||||
unset($data->hidden);
|
||||
unset($data->hiddenuntil);
|
||||
|
||||
$locked = empty($data->locked) ? 0: $data->locked;
|
||||
$locktime = empty($data->locktime) ? 0: $data->locktime;
|
||||
unset($data->locked);
|
||||
unset($data->locktime);
|
||||
|
||||
$grade_item = new grade_item(array('id'=>$id, 'courseid'=>$courseid));
|
||||
grade_item::set_properties($grade_item, $data);
|
||||
|
||||
@ -78,6 +85,9 @@ if ($data = $mform->get_data(false)) {
|
||||
$grade_item->set_hidden(1);
|
||||
}
|
||||
|
||||
$grade_item->set_locktime($locktime); // locktime first - it might be removed when unlocking
|
||||
$grade_item->set_locked($locked, false, true);
|
||||
|
||||
// Handle user preferences
|
||||
if (isset($data->pref_gradedisplaytype)) {
|
||||
if (!grade_report::set_pref('gradedisplaytype', $data->pref_gradedisplaytype, $grade_item->id)) {
|
||||
|
@ -41,6 +41,8 @@ if ($item = get_record('grade_items', 'id', $id, 'courseid', $course->id)) {
|
||||
$item->hiddenuntil = 0;
|
||||
}
|
||||
|
||||
$item->locked = !empty($item->locked);
|
||||
|
||||
$item->calculation = grade_item::denormalize_formula($item->calculation, $course->id);
|
||||
|
||||
if ($item->itemtype == 'mod') {
|
||||
@ -63,6 +65,11 @@ if ($data = $mform->get_data(false)) {
|
||||
unset($data->hidden);
|
||||
unset($data->hiddenuntil);
|
||||
|
||||
$locked = empty($data->locked) ? 0: $data->locked;
|
||||
$locktime = empty($data->locktime) ? 0: $data->locktime;
|
||||
unset($data->locked);
|
||||
unset($data->locktime);
|
||||
|
||||
$grade_item = new grade_item(array('id'=>$id, 'courseid'=>$courseid));
|
||||
grade_item::set_properties($grade_item, $data);
|
||||
|
||||
@ -130,6 +137,9 @@ if ($data = $mform->get_data(false)) {
|
||||
$grade_item->set_hidden(1);
|
||||
}
|
||||
|
||||
$grade_item->set_locktime($locktime); // locktime first - it might be removed when unlocking
|
||||
$grade_item->set_locked($locked, false, true);
|
||||
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
|
@ -864,9 +864,9 @@ class grade_tree {
|
||||
$icon = 'unlock';
|
||||
$tooltip = '';
|
||||
|
||||
if ($element['object']->locktime > 1) { // Change the icon and add a tooltip showing the date
|
||||
if ($element['type'] != 'category' and $element['object']->get_locktime() > 1) { // Change the icon and add a tooltip showing the date
|
||||
$icon = 'locktime';
|
||||
$tooltip = userdate($element['object']->locktime);
|
||||
$tooltip = userdate($element['object']->get_locktime());
|
||||
}
|
||||
|
||||
if (!has_capability('moodle/grade:manage', $this->context) and !has_capability('moodle/grade:unlock', $this->context)) {
|
||||
|
@ -221,7 +221,7 @@ $string['linkedactivity'] = 'Linked activity';
|
||||
$string['linkedactivityhelp'] = 'An optional activity this outcome item is linked to.';
|
||||
$string['lock'] = 'Lock';
|
||||
$string['locked'] = 'Locked';
|
||||
$string['locktime'] = 'Locked until';
|
||||
$string['locktime'] = 'Lock after';
|
||||
$string['lowest'] = 'Lowest';
|
||||
$string['lowgradeletter'] = 'Low';
|
||||
$string['mapfrom'] = 'Map from';
|
||||
|
@ -1009,28 +1009,32 @@ class grade_category extends grade_object {
|
||||
* Sets the grade_item's locked variable and updates the grade_item.
|
||||
* Method named after grade_item::set_locked().
|
||||
* @param int $locked 0, 1 or a timestamp int(10) after which date the item will be locked.
|
||||
* @param boolean $cascade lock/unlock child objects too
|
||||
* @param boolean $refresh refresh grades when unlocking
|
||||
* @return boolean success if category locked (not all children mayb be locked though)
|
||||
*/
|
||||
function set_locked($lockedstate, $refresh=true) {
|
||||
function set_locked($lockedstate, $cascade=false, $refresh=true) {
|
||||
$this->load_grade_item();
|
||||
|
||||
$result = $this->grade_item->set_locked($lockedstate, true);
|
||||
if ($children = grade_item::fetch_all(array('categoryid'=>$this->id))) {
|
||||
foreach($children as $child) {
|
||||
$child->set_locked($lockedstate, false);
|
||||
if (empty($lockedstate) and $refresh) {
|
||||
//refresh when unlocking
|
||||
$child->refresh_grades();
|
||||
$result = $this->grade_item->set_locked($lockedstate, $cascade, true);
|
||||
|
||||
if ($cascade) {
|
||||
//process all children - items and categories
|
||||
if ($children = grade_item::fetch_all(array('categoryid'=>$this->id))) {
|
||||
foreach($children as $child) {
|
||||
$child->set_locked($lockedstate, true, false);
|
||||
if (empty($lockedstate) and $refresh) {
|
||||
//refresh when unlocking
|
||||
$child->refresh_grades();
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($children = grade_category::fetch_all(array('parent'=>$this->id))) {
|
||||
foreach($children as $child) {
|
||||
$child->set_locked($lockedstate, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($children = grade_category::fetch_all(array('parent'=>$this->id))) {
|
||||
foreach($children as $child) {
|
||||
$child->set_locked($lockedstate, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
@ -159,9 +159,20 @@ class grade_grade extends grade_object {
|
||||
* @return object grade_item.
|
||||
*/
|
||||
function load_grade_item() {
|
||||
if (empty($this->grade_item) and !empty($this->itemid)) {
|
||||
if (empty($this->itemid)) {
|
||||
debugging('Missing itemid');
|
||||
$this->grade_item = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (empty($this->grade_item)) {
|
||||
$this->grade_item = grade_item::fetch(array('id'=>$this->itemid));
|
||||
|
||||
} else if ($this->grade_item->id != $this->itemid) {
|
||||
debugging('Itemid mismatch');
|
||||
$this->grade_item = grade_item::fetch(array('id'=>$this->itemid));
|
||||
}
|
||||
|
||||
return $this->grade_item;
|
||||
}
|
||||
|
||||
@ -254,17 +265,14 @@ class grade_grade extends grade_object {
|
||||
* Lock/unlock this grade.
|
||||
*
|
||||
* @param int $locked 0, 1 or a timestamp int(10) after which date the item will be locked.
|
||||
* @param boolean $cascade ignored param
|
||||
* @param boolean $refresh refresh grades when unlocking
|
||||
* @return boolean true if sucessful, false if can not set new lock state for grade
|
||||
*/
|
||||
function set_locked($lockedstate, $refresh=true) {
|
||||
function set_locked($lockedstate, $cascade=false, $refresh=true) {
|
||||
$this->load_grade_item();
|
||||
|
||||
if ($lockedstate) {
|
||||
if (!empty($this->locked)) {
|
||||
return true; // already locked
|
||||
}
|
||||
|
||||
if ($this->grade_item->needsupdate) {
|
||||
//can not lock grade if final not calculated!
|
||||
return false;
|
||||
@ -276,17 +284,13 @@ class grade_grade extends grade_object {
|
||||
return true;
|
||||
|
||||
} else {
|
||||
if (empty($this->locked)) {
|
||||
return true; // not locked
|
||||
}
|
||||
|
||||
if ($this->grade_item->is_locked()) {
|
||||
return false;
|
||||
if (!empty($this->locked) and $this->locktime < time()) {
|
||||
//we have to reset locktime or else it would lock up again
|
||||
$this->locktime = 0;
|
||||
}
|
||||
|
||||
// remove the locked flag
|
||||
$this->locked = 0;
|
||||
|
||||
$this->update();
|
||||
|
||||
if ($refresh) {
|
||||
@ -298,42 +302,79 @@ class grade_grade extends grade_object {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock the grade if needed - make sure this is called only when final grade is valid
|
||||
*/
|
||||
function check_locktime() {
|
||||
if (!empty($this->locked)) {
|
||||
return; // already locked - do not use is_locked() because we do not want the locking status of grade_item here
|
||||
}
|
||||
|
||||
if ($this->locktime and $this->locktime < time()) {
|
||||
$this->locked = time();
|
||||
$this->update('locktime');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Lock the grade if needed - make sure this is called only when final grades are valid
|
||||
* @param int $courseid
|
||||
* @param array $items array of all grade item ids (speedup only)
|
||||
* @return void
|
||||
*/
|
||||
function check_locktime_all($courseid, $items=null) {
|
||||
global $CFG;
|
||||
|
||||
if (!$items) {
|
||||
if (!$items = get_records('grade_items', 'courseid', $courseid, '', 'id')) {
|
||||
return; // no items?
|
||||
}
|
||||
$items = array_keys($items);
|
||||
}
|
||||
|
||||
$items_sql = implode(',', $items);
|
||||
|
||||
$now = time(); // no rounding needed, this is not supposed to be called every 10 seconds
|
||||
|
||||
if ($rs = get_recordset_select('grade_grades', "itemid IN ($items_sql) AND locked = 0 AND locktime > 0 AND locktime < $now")) {
|
||||
if ($rs->RecordCount() > 0) {
|
||||
while ($grade = rs_fetch_next_record($rs)) {
|
||||
$grade_grade = new grade_grade($grade, false);
|
||||
$grade_grade->locked = time();
|
||||
$grade_grade->update('locktime');
|
||||
}
|
||||
}
|
||||
rs_close($rs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locktime for this grade.
|
||||
*
|
||||
* @param int $locktime timestamp for lock to activate
|
||||
* @return boolean true if sucessful, false if can not set new lock state for grade
|
||||
* @return void
|
||||
*/
|
||||
function set_locktime($locktime) {
|
||||
$this->locktime = $locktime;
|
||||
$this->update();
|
||||
}
|
||||
|
||||
if ($locktime) {
|
||||
// if current locktime is before, no need to reset
|
||||
/**
|
||||
* Set the locktime for this grade.
|
||||
*
|
||||
* @return int $locktime timestamp for lock to activate
|
||||
*/
|
||||
function get_locktime() {
|
||||
$this->load_grade_item();
|
||||
|
||||
if ($this->locktime && $this->locktime <= $locktime) {
|
||||
return true;
|
||||
}
|
||||
$item_locktime = $this->grade_item->get_locktime();
|
||||
|
||||
/*
|
||||
if ($this->grade_item->needsupdate) {
|
||||
//can not lock grade if final not calculated!
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
$this->locktime = $locktime;
|
||||
$this->update();
|
||||
|
||||
return true;
|
||||
if (empty($this->locktime) or ($item_locktime and $item_locktime < $this->locktime)) {
|
||||
return $item_locktime;
|
||||
|
||||
} else {
|
||||
|
||||
// remove the locktime timestamp
|
||||
$this->locktime = 0;
|
||||
|
||||
$this->update();
|
||||
|
||||
return true;
|
||||
return $this->locktime;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,6 +266,7 @@ class grade_item extends grade_object {
|
||||
$outcomeiddiff = $db_item->outcomeid != $this->outcomeid;
|
||||
$multfactordiff = $db_item->multfactor != $this->multfactor;
|
||||
$plusfactordiff = $db_item->plusfactor != $this->plusfactor;
|
||||
$locktimediff = $db_item->locktime != $this->locktime;
|
||||
$acoefdiff = $db_item->aggregationcoef != $this->aggregationcoef;
|
||||
|
||||
$needsupdatediff = !$db_item->needsupdate && $this->needsupdate; // force regrading only if setting the flag first time
|
||||
@ -273,7 +274,7 @@ class grade_item extends grade_object {
|
||||
|
||||
return ($calculationdiff || $categorydiff || $gradetypediff || $grademaxdiff || $grademindiff || $scaleiddiff
|
||||
|| $outcomeiddiff || $multfactordiff || $plusfactordiff || $needsupdatediff
|
||||
|| $lockeddiff || $acoefdiff);
|
||||
|| $lockeddiff || $acoefdiff || $locktimediff);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -425,61 +426,46 @@ class grade_item extends grade_object {
|
||||
/**
|
||||
* Locks or unlocks this grade_item and (optionally) all its associated final grades.
|
||||
* @param int $locked 0, 1 or a timestamp int(10) after which date the item will be locked.
|
||||
* @param boolean $cascade lock/unlock child objects too
|
||||
* @param boolean $refresh refresh grades when unlocking
|
||||
* @return boolean true if grade_item all grades updated, false if at least one update fails
|
||||
*/
|
||||
function set_locked($lockedstate, $refresh=true) {
|
||||
function set_locked($lockedstate, $cascade=false, $refresh=true) {
|
||||
if ($lockedstate) {
|
||||
/// setting lock
|
||||
if (!empty($this->locked)) {
|
||||
return true; // already locked
|
||||
}
|
||||
|
||||
if ($this->needsupdate) {
|
||||
return false; // can not lock grade without first calculating final grade
|
||||
return false; // can not lock grade without first having final grade
|
||||
}
|
||||
|
||||
$this->locked = time();
|
||||
$this->update();
|
||||
|
||||
// this could be improved with direct SQL update
|
||||
$result = true;
|
||||
$grades = $this->get_final();
|
||||
foreach($grades as $g) {
|
||||
$grade = new grade_grade($g, false);
|
||||
$grade->grade_item =& $this;
|
||||
if (!$grade->set_locked(1, false)) {
|
||||
$result = false;
|
||||
if ($cascade) {
|
||||
$grades = $this->get_final();
|
||||
foreach($grades as $g) {
|
||||
$grade = new grade_grade($g, false);
|
||||
$grade->grade_item =& $this;
|
||||
$grade->set_locked(1, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
return true;
|
||||
|
||||
} else {
|
||||
/// removing lock
|
||||
if (empty($this->locked)) {
|
||||
return true; // not locked
|
||||
}
|
||||
|
||||
if (!empty($this->locktime) and $this->locktime < time()) {
|
||||
return false; // can not unlock grade item that should be already locked
|
||||
if (!empty($this->locked) and $this->locktime < time()) {
|
||||
//we have to reset locktime or else it would lock up again
|
||||
$this->locktime = 0;
|
||||
}
|
||||
|
||||
$this->locked = 0;
|
||||
$this->update();
|
||||
|
||||
// this could be improved with direct SQL update
|
||||
$result = true;
|
||||
if ($grades = grade_grade::fetch_all(array('itemid'=>$this->id))) {
|
||||
foreach($grades as $grade) {
|
||||
$grade->grade_item =& $this;
|
||||
|
||||
if (!empty($grade->locktime) and $grade->locktime < time()) {
|
||||
$result = false; // can not unlock grade that should be already locked
|
||||
}
|
||||
|
||||
if (!$grade->set_locked(0, false)) {
|
||||
$result = false;
|
||||
if ($cascade) {
|
||||
if ($grades = grade_grade::fetch_all(array('itemid'=>$this->id))) {
|
||||
foreach($grades as $grade) {
|
||||
$grade->grade_item =& $this;
|
||||
$grade->set_locked(0, null, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -489,47 +475,64 @@ class grade_item extends grade_object {
|
||||
$this->refresh_grades();
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locktime for this grade.
|
||||
* Lock the grade if needed - make sure this is called only when final grades are valid
|
||||
*/
|
||||
function check_locktime() {
|
||||
if (!empty($this->locked)) {
|
||||
return; // already locked
|
||||
}
|
||||
|
||||
if ($this->locktime and $this->locktime < time()) {
|
||||
$this->locked = time();
|
||||
$this->update('locktime');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock all grade items if needed - make sure this is called only when final grades are valid
|
||||
* @static
|
||||
* @param int $courseid
|
||||
* @return void
|
||||
*/
|
||||
function check_locktime_all($courseid) {
|
||||
global $CFG;
|
||||
|
||||
$now = time(); // no need to round it here, executed from cron only
|
||||
$sql = "SELECT * FROM {$CFG->prefix}grade_items
|
||||
WHERE courseid=$courseid AND locked = 0 AND locktime > 0 AND locktime < $now";
|
||||
|
||||
if ($items = get_records_sql($sql)) {
|
||||
foreach ($items as $item) {
|
||||
$grade_item = new grade_grade($item, false);
|
||||
$grade_item->locked = time();
|
||||
$grade_item->update('locktime');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locktime for this grade item.
|
||||
*
|
||||
* @param int $locktime timestamp for lock to activate
|
||||
* @return boolean true if sucessful, false if can not set new lock state for grade
|
||||
* @return void
|
||||
*/
|
||||
function set_locktime($locktime) {
|
||||
$this->locktime = $locktime;
|
||||
$this->update();
|
||||
}
|
||||
|
||||
if ($locktime) {
|
||||
// if current locktime is before, no need to reset
|
||||
|
||||
if ($this->locktime && $this->locktime <= $locktime) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
if ($this->grade_item->needsupdate) {
|
||||
//can not lock grade if final not calculated!
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
$this->locktime = $locktime;
|
||||
$this->update();
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
// remove the locktime timestamp
|
||||
$this->locktime = 0;
|
||||
|
||||
$this->update();
|
||||
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Set the locktime for this grade item.
|
||||
*
|
||||
* @return int $locktime timestamp for lock to activate
|
||||
*/
|
||||
function get_locktime() {
|
||||
return $this->locktime;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -579,11 +582,6 @@ class grade_item extends grade_object {
|
||||
$this->needsupdate = 0;
|
||||
//do not use $this->update() because we do not want this logged in grade_item_history
|
||||
set_field('grade_items', 'needsupdate', 0, 'id', $this->id);
|
||||
|
||||
if (!empty($this->locktime) and empty($this->locked) and $this->locktime < time()) {
|
||||
// time to lock this grade_item
|
||||
$this->set_locked(true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -640,12 +638,13 @@ class grade_item extends grade_object {
|
||||
if ($rs) {
|
||||
if ($rs->RecordCount() > 0) {
|
||||
while ($grade_record = rs_fetch_next_record($rs)) {
|
||||
$grade = new grade_grade($grade_record, false);
|
||||
|
||||
if (!empty($grade_record->locked) or !empty($grade_record->overridden)) {
|
||||
// this grade is locked - final grade must be ok
|
||||
continue;
|
||||
}
|
||||
|
||||
$grade = new grade_grade($grade_record, false);
|
||||
$grade->finalgrade = $this->adjust_grade($grade->rawgrade, $grade->rawgrademin, $grade->rawgrademax);
|
||||
|
||||
if ($grade_record->finalgrade !== $grade->finalgrade) {
|
||||
@ -653,13 +652,6 @@ class grade_item extends grade_object {
|
||||
$result = "Internal error updating final grade";
|
||||
}
|
||||
}
|
||||
|
||||
// time to lock this grade?
|
||||
if (!empty($grade->locktime) and empty($grade->locked) and $grade->locktime < time()) {
|
||||
$grade->locked = time();
|
||||
$grade->grade_item =& $this;
|
||||
$grade->set_locked(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
rs_close($rs);
|
||||
@ -1238,8 +1230,20 @@ class grade_item extends grade_object {
|
||||
if (!$grade = grade_grade::fetch(array('itemid'=>$this->id, 'userid'=>$userid))) {
|
||||
$grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid), false);
|
||||
}
|
||||
|
||||
$grade->grade_item =& $this; // prevent db fetching of this grade_item
|
||||
|
||||
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;
|
||||
@ -1248,17 +1252,6 @@ class grade_item extends grade_object {
|
||||
$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) {
|
||||
if (!is_null($finalgrade)) {
|
||||
$grade->finalgrade = bounded_number($this->grademin, $finalgrade, $this->grademax);
|
||||
@ -1266,7 +1259,10 @@ class grade_item extends grade_object {
|
||||
$grade->finalgrade = $finalgrade;
|
||||
}
|
||||
|
||||
if ($this->is_outcome_item()) {
|
||||
if ($this->is_manual_item() and !$this->is_calculated()) {
|
||||
// no overriding on manual grades - raw not used
|
||||
|
||||
} else if ($this->is_outcome_item() and !$this->is_calculated()) {
|
||||
// no updates of raw grades for outcomes - raw grades not used
|
||||
|
||||
} else if (!$this->is_normal_item() or $this->plusfactor != 0 or $this->multfactor != 1
|
||||
@ -1360,26 +1356,27 @@ class grade_item extends grade_object {
|
||||
if (!$grade = grade_grade::fetch(array('itemid'=>$this->id, 'userid'=>$userid))) {
|
||||
$grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid), false);
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
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
|
||||
$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;
|
||||
|
||||
// fist copy current grademin/max and scale
|
||||
$grade->rawgrademin = $this->grademin;
|
||||
$grade->rawgrademax = $this->grademax;
|
||||
@ -1600,6 +1597,10 @@ class grade_item extends grade_object {
|
||||
$grade->update('system');
|
||||
}
|
||||
|
||||
if ($result !== false) {
|
||||
//lock grade if needed
|
||||
}
|
||||
|
||||
if ($result === false) {
|
||||
return false;
|
||||
} else {
|
||||
|
@ -435,8 +435,7 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null)
|
||||
$depends_on = array();
|
||||
|
||||
// first mark all category and calculated items as needing regrading
|
||||
// this is slower, but 100% accurate - this function is called only when there is
|
||||
// a change in grading setup, update of individual grade does not trigger this function
|
||||
// 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;
|
||||
@ -480,8 +479,10 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null)
|
||||
|
||||
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;
|
||||
@ -508,6 +509,10 @@ function grade_regrade_final_grades($courseid, $userid=null, $updated_item=null)
|
||||
}
|
||||
|
||||
if (count($errors) == 0) {
|
||||
if (empty($userid)) {
|
||||
// do the locktime locking of grades, but only when doing full regrading
|
||||
grade_grade::check_locktime_all($courseid, $gids);
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return $errors;
|
||||
|
Loading…
x
Reference in New Issue
Block a user