MDL-47011 core_grade: added the ability to override grade_item weight

This commit is contained in:
Andrew Davis 2014-08-31 19:08:50 +08:00 committed by Adrian Greeve
parent a2f1f65db4
commit 45da536113
7 changed files with 63 additions and 5 deletions

View File

@ -240,6 +240,21 @@ if ($data = data_submitted() and confirm_sesskey()) {
$grade_edit_tree->move_elements($elements, $returnurl);
}
// Preload grade_items so we can determine if weights have been manually changed or been automatically adjusted.
// As soon as we touch one grade item the others will be re-weighted automatically.
$oldgradeitems = Array();
foreach ($data as $key => $value) {
if (preg_match('/^(aggregationcoef2)_([0-9]+)$/', $key, $matches)) {
$param = $matches[1];
$aid = $matches[2];
$value = unformat_float($value);
$value = clean_param($value, PARAM_FLOAT);
$oldgradeitems[$aid] = grade_item::fetch(array('id' => $aid, 'courseid' => $courseid));
}
}
// Category and item field updates
foreach ($data as $key => $value) {
// Grade category text inputs
@ -267,12 +282,17 @@ if ($data = data_submitted() and confirm_sesskey()) {
$value = unformat_float($value);
$value = clean_param($value, PARAM_FLOAT);
$grade_item = grade_item::fetch(array('id'=>$aid, 'courseid'=>$courseid));
$grade_item = $oldgradeitems[$aid];
if ($param === 'grademax' and $value < $grade_item->grademin) {
// better not allow values lower than grade min
$value = $grade_item->grademin;
}
if ($param === 'aggregationcoef2' && round($grade_item->aggregationcoef2, 4) != round($value, 4)) {
$grade_item->weightoverride = 1;
}
$grade_item->$param = $value;
$grade_item->update();

View File

@ -396,10 +396,14 @@ class grade_edit_tree {
get_string('extracreditvalue', 'grades', $item->itemname).'</label>
<input type="checkbox" id="extracredit_'.$item->id.'" name="extracredit_'.$item->id.'" value="1" '."$checked />\n";
} else if ($aggcoef == 'aggregationcoefextrasum' && $type == 'weight') {
$label = '';
if ($item->weightoverride) {
$label = get_string('adjusted', 'grades');
}
return '<label class="accesshide" for="aggregationcoef_'.$item->id.'">'.
get_string('weight', 'grades', $item->itemname).'</label>'.
'<input type="text" size="6" id="aggregationcoef2_'.$item->id.'" name="aggregationcoef2_'.$item->id.'"
value="'.grade_edit_tree::format_number($item->aggregationcoef2).'" />';
value="'.grade_edit_tree::format_number($item->aggregationcoef2).'" />'.$label;
} else {
return '';
}

View File

@ -34,6 +34,7 @@ $string['additem'] = 'Add grade item';
$string['addoutcome'] = 'Add an outcome';
$string['addoutcomeitem'] = 'Add outcome item';
$string['addscale'] = 'Add a scale';
$string['adjusted'] = 'Adjusted';
$string['aggregateextracreditmean'] = 'Mean of grades (with extra credits)';
$string['aggregatemax'] = 'Highest grade';
$string['aggregatemean'] = 'Mean of grades';

View File

@ -1725,6 +1725,7 @@
<FIELD NAME="locked" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="1 is locked, &amp;gt; 1 is a date to lock until (prevents update)"/>
<FIELD NAME="locktime" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="lock all final grades after this date"/>
<FIELD NAME="needsupdate" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="If this flag is set, then the whole column will be recalculated"/>
<FIELD NAME="weightoverride" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="The first time this grade_item was created"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="The last time this grade_item was modified"/>
</FIELDS>

View File

@ -3874,6 +3874,18 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2014082700.01);
}
if ($oldversion < 2014082700.02) {
// Define the field weightoverride to be added to grade_items.
$table = new xmldb_table('grade_items');
$field = new xmldb_field('weightoverride', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'needsupdate');
if (!$dbman->field_exists($table, $field)) {
$dbman->add_field($table, $field);
}
upgrade_main_savepoint(true, 2014082700.02);
}
return true;
}

View File

@ -1044,6 +1044,10 @@ class grade_category extends grade_object {
// Calculate the sum of the grademax's of all the items within this category.
$totalgrademax = 0;
// Out of 1, how much weight has been manually overriden by a user?
$totaloverriddenweight = 0;
$totaloverriddengrademax = 0;
foreach ($children as $sortorder => $child) {
$grade_item = null;
@ -1052,9 +1056,16 @@ class grade_category extends grade_object {
} else if ($child['type'] == 'category') {
$grade_item = $child['object']->load_grade_item();
}
$totalgrademax += $grade_item->grademax;
if ($grade_item->weightoverride) {
$totaloverriddenweight += $grade_item->aggregationcoef2;
$totaloverriddengrademax += $grade_item->grademax;
}
}
$totalgrademax -= $totaloverriddengrademax;
reset($children);
foreach ($children as $sortorder => $child) {
$grade_item = null;
@ -1064,8 +1075,12 @@ class grade_category extends grade_object {
} else if ($child['type'] == 'category') {
$grade_item = $child['object']->load_grade_item();
}
$grade_item->aggregationcoef2 = $grade_item->grademax/$totalgrademax;
$grade_item->update();
if (!$grade_item->weightoverride) {
// Calculate this item's weight as a percentage of the non-overridden total grade maxes
// then convert it to a proportion of the available non-overriden weight.
$grade_item->aggregationcoef2 = ($grade_item->grademax/$totalgrademax) * (1 - $totaloverriddenweight);
$grade_item->update();
}
}
}

View File

@ -51,7 +51,7 @@ class grade_item extends grade_object {
'itemnumber', 'iteminfo', 'idnumber', 'calculation', 'gradetype', 'grademax', 'grademin',
'scaleid', 'outcomeid', 'gradepass', 'multfactor', 'plusfactor', 'aggregationcoef',
'aggregationcoef2', 'sortorder', 'display', 'decimals', 'hidden', 'locked', 'locktime',
'needsupdate', 'timecreated', 'timemodified');
'needsupdate', 'weightoverride', 'timecreated', 'timemodified');
/**
* The course this grade_item belongs to.
@ -246,6 +246,11 @@ class grade_item extends grade_object {
*/
public $needsupdate = 1;
/**
* If set, the grade item's weight has been overridden by a user and should not be automatically adjusted.
*/
public $weightoverride = 0;
/**
* Cached dependson array
* @var array An array of cached grade item dependencies.