Skip to content

Commit

Permalink
MDL-48634 grades: Add an option to rescale when changing the maxgrade
Browse files Browse the repository at this point in the history
  • Loading branch information
Damyon Wiese authored and mdjnelson committed Feb 5, 2016
1 parent 9d5d9c6 commit d629c60
Show file tree
Hide file tree
Showing 12 changed files with 422 additions and 11 deletions.
42 changes: 41 additions & 1 deletion course/modlib.php
Expand Up @@ -453,6 +453,11 @@ function can_update_moduleinfo($cm) {
function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) {
global $DB, $CFG;

$data = new stdClass();
if ($mform) {
$data = $mform->get_data();
}

// Attempt to include module library before we make any changes to DB.
include_modulelib($moduleinfo->modulename);

Expand Down Expand Up @@ -523,9 +528,44 @@ function update_moduleinfo($cm, $moduleinfo, $course, $mform = null) {
$moduleinfo->introformat = $moduleinfo->introeditor['format'];
unset($moduleinfo->introeditor);
}
// Get the a copy of the grade_item before it is modified incase we need to scale the grades.
$oldgradeitem = null;
$newgradeitem = null;
if (!empty($data->grade_rescalegrades)) {
// Fetch the grade item before it is updated.
$oldgradeitem = grade_item::fetch(array('itemtype' => 'mod',
'itemmodule' => $moduleinfo->modulename,
'iteminstance' => $moduleinfo->instance,
'itemnumber' => 0,
'courseid' => $moduleinfo->course));
}

$updateinstancefunction = $moduleinfo->modulename."_update_instance";
if (!$updateinstancefunction($moduleinfo, $mform)) {
print_error('cannotupdatemod', '', course_get_url($course, $cw->section), $moduleinfo->modulename);
print_error('cannotupdatemod', '', course_get_url($course, $cm->section), $moduleinfo->modulename);
}

// This needs to happen AFTER the grademin/grademax have already been updated.
if (!empty($data->grade_rescalegrades)) {
// Get the grade_item after the update call the activity to scale the grades.
$newgradeitem = grade_item::fetch(array('itemtype' => 'mod',
'itemmodule' => $moduleinfo->modulename,
'iteminstance' => $moduleinfo->instance,
'itemnumber' => 0,
'courseid' => $moduleinfo->course));
if ($newgradeitem && $oldgradeitem->gradetype == GRADE_TYPE_VALUE && $newgradeitem->gradetype == GRADE_TYPE_VALUE) {
$params = array(
$course,
$cm,
$oldgradeitem->grademin,
$oldgradeitem->grademax,
$newgradeitem->grademin,
$newgradeitem->grademax
);
if (!component_callback('mod_' . $moduleinfo->modulename, 'rescale_activity_grades', $params)) {
print_error('cannotreprocessgrades', '', course_get_url($course, $cm->section), $moduleinfo->modulename);
}
}
}

// Make sure visibility is set correctly (in particular in calendar).
Expand Down
20 changes: 18 additions & 2 deletions course/moodleform_mod.php
Expand Up @@ -109,9 +109,9 @@ protected function init_features() {
$this->_features->defaultcompletion = plugin_supports('mod', $this->_modname, FEATURE_MODEDIT_DEFAULT_COMPLETION, true);
$this->_features->rating = plugin_supports('mod', $this->_modname, FEATURE_RATE, false);
$this->_features->showdescription = plugin_supports('mod', $this->_modname, FEATURE_SHOW_DESCRIPTION, false);

$this->_features->gradecat = ($this->_features->outcomes or $this->_features->hasgrades);
$this->_features->advancedgrading = plugin_supports('mod', $this->_modname, FEATURE_ADVANCED_GRADING, false);
$this->_features->canrescale = (component_callback_exists('mod_' . $this->_modname, 'rescale_activity_grades') !== false);
}

/**
Expand Down Expand Up @@ -641,6 +641,11 @@ function standard_hidden_coursemodule_elements(){
public function standard_grading_coursemodule_elements() {
global $COURSE, $CFG;
$mform =& $this->_form;
$isupdate = !empty($this->_cm);
$gradeoptions = array('isupdate' => $isupdate,
'currentgrade' => false,
'hasgrades' => false,
'canrescale' => $this->_features->canrescale);

if ($this->_features->hasgrades) {

Expand All @@ -650,7 +655,18 @@ public function standard_grading_coursemodule_elements() {

//if supports grades and grades arent being handled via ratings
if (!$this->_features->rating) {
$mform->addElement('modgrade', 'grade', get_string('grade'));

if ($isupdate) {
$gradeitem = grade_item::fetch(array('itemtype' => 'mod',
'itemmodule' => $this->_cm->modname,
'iteminstance' => $this->_cm->instance,
'itemnumber' => 0,
'courseid' => $COURSE->id));

$gradeoptions['currentgrade'] = $gradeitem->grademax;
$gradeoptions['hasgrades'] = $gradeitem->has_grades();
}
$mform->addElement('modgrade', 'grade', get_string('grade'), $gradeoptions);
$mform->addHelpButton('grade', 'modgrade', 'grades');
$mform->setDefault('grade', $CFG->gradepointdefault);
}
Expand Down
8 changes: 8 additions & 0 deletions grade/edit/tree/item.php
Expand Up @@ -156,6 +156,8 @@
}

$grade_item = new grade_item(array('id'=>$id, 'courseid'=>$courseid));
$oldmin = $grade_item->grademin;
$oldmax = $grade_item->grademax;
grade_item::set_properties($grade_item, $data);
$grade_item->outcomeid = null;

Expand All @@ -175,6 +177,12 @@

} else {
$grade_item->update();

if (!empty($data->rescalegrades)) {
$newmin = $grade_item->grademin;
$newmax = $grade_item->grademax;
$grade_item->rescale_grades_keep_percentage($oldmin, $oldmax, $newmin, $newmax, 'gradebook');
}
}

// update hiding flag
Expand Down
13 changes: 11 additions & 2 deletions grade/edit/tree/item_form.php
Expand Up @@ -97,6 +97,10 @@ function definition() {
$mform->setType('grademin', PARAM_RAW);
}

$mform->addElement('selectyesno', 'rescalegrades', get_string('modgraderescalegrades', 'grades'));
$mform->addHelpButton('rescalegrades', 'modgraderescalegrades', 'grades');
$mform->disabledIf('rescalegrades', 'gradetype', 'noteq', GRADE_TYPE_VALUE);

$mform->addElement('text', 'gradepass', get_string('gradepass', 'grades'));
$mform->addHelpButton('gradepass', 'gradepass', 'grades');
$mform->disabledIf('gradepass', 'gradetype', 'eq', GRADE_TYPE_NONE);
Expand Down Expand Up @@ -269,6 +273,7 @@ function definition_after_data() {
// the idnumber of grade itemnumber 0 is synced with course_modules
$mform->hardFreeze('idnumber');
}
$mform->removeElement('rescalegrades');
//$mform->removeElement('calculation');
}
}
Expand Down Expand Up @@ -342,6 +347,7 @@ function definition_after_data() {
// all new items are manual, children of course category
$mform->removeElement('plusfactor');
$mform->removeElement('multfactor');
$mform->removeElement('rescalegrades');
}

// no parent header for course category
Expand All @@ -353,12 +359,15 @@ function definition_after_data() {
/// perform extra validation before submission
function validation($data, $files) {
global $COURSE;
$grade_item = false;
if ($data['id']) {
$grade_item = new grade_item(array('id' => $data['id'], 'courseid' => $data['courseid']));
}

$errors = parent::validation($data, $files);

if (array_key_exists('idnumber', $data)) {
if ($data['id']) {
$grade_item = new grade_item(array('id'=>$data['id'], 'courseid'=>$data['courseid']));
if ($grade_item) {
if ($grade_item->itemtype == 'mod') {
$cm = get_coursemodule_from_instance($grade_item->itemmodule, $grade_item->iteminstance, $grade_item->courseid);
} else {
Expand Down
76 changes: 76 additions & 0 deletions grade/tests/behat/grade_grade_minmax_change.feature
@@ -0,0 +1,76 @@
@core @core_grades
Feature: We can change the maximum and minimum number of points for manual items with existing grades
In order to verify existing grades are modified as expected
As an teacher
I need to modify a grade item with exiting grades
I need to ensure existing grades are modified in an expected manner

Background:
Given the following "courses" exist:
| fullname | shortname | category | groupmode |
| Course 1 | C1 | 0 | 1 |
And the following "users" exist:
| username | firstname | lastname | email | idnumber |
| teacher1 | Teacher | 1 | teacher1@example.com | t1 |
| student1 | Student | 1 | student1@example.com | s1 |
| student2 | Student | 2 | student2@example.com | s2 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
| student1 | C1 | student |
| student2 | C1 | student |
And I log in as "teacher1"
And I am on site homepage
And I follow "Course 1"
And I navigate to "Grades" node in "Course administration"
And I navigate to "Gradebook setup" node in "Grade administration > Setup"
And I press "Add grade item"
And I set the following fields to these values:
| Item name | Manual item 1 |
| Minimum grade | 0 |
| Maximum grade | 100 |
And I press "Save changes"
And I navigate to "Course grade settings" node in "Grade administration > Setup"
And I set the field "Show weightings" to "Show"
And I set the field "Show contribution to course total" to "Show"
And I press "Save changes"

Scenario: Change maximum number of points on a graded item.
And I follow "Course 1"
And I navigate to "Grades" node in "Course administration"
And I turn editing mode on
And I give the grade "10.00" to the user "Student 1" for the grade item "Manual item 1"
And I give the grade "8.00" to the user "Student 2" for the grade item "Manual item 1"
And I press "Save changes"
When I navigate to "Gradebook setup" node in "Grade administration > Setup"
And I click on "Edit" "link" in the "Manual item 1" "table_row"
And I click on "Edit settings" "link" in the "Manual item 1" "table_row"
And I set the following fields to these values:
| Maximum grade | 10 |
| Rescale existing grades | No |
And I press "Save changes"
And I follow "User report"
And I select "Student 1" from the "Select all or one user" singleselect
Then the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Contribution to course total |
| Manual item 1 | 100.00 % | 10.00 | 100.00 % |
And I select "Student 2" from the "Select all or one user" singleselect
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Contribution to course total |
| Manual item 1 | 100.00 % | 8.00 | 80.00 % |
And I navigate to "Gradebook setup" node in "Grade administration > Setup"
And I click on "Edit" "link" in the "Manual item 1" "table_row"
And I click on "Edit settings" "link" in the "Manual item 1" "table_row"
And I set the following fields to these values:
| Maximum grade | 20 |
| Rescale existing grades | Yes |
And I press "Save changes"
And I follow "User report"
And I select "Student 1" from the "Select all or one user" singleselect
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Contribution to course total |
| Manual item 1 | 100.00 % | 20.00 | 100.00 % |
And I select "Student 2" from the "Select all or one user" singleselect
And the following should exist in the "user-grade" table:
| Grade item | Calculated weight | Grade | Contribution to course total |
| Manual item 1 | 100.00 % | 16.00 | 80.00 % |
1 change: 1 addition & 0 deletions lang/en/error.php
Expand Up @@ -123,6 +123,7 @@
$string['cannotreadtmpfile'] = 'Error reading temporary file';
$string['cannotreaduploadfile'] = 'Could not read uploaded file';
$string['cannotremovefrommeta'] = 'Could not remove the selected course from this meta course!';
$string['cannotreprocessgrades'] = 'Could not reprocess grades for this activity {$a}';
$string['cannotresetguestpwd'] = 'You cannot reset the guest password';
$string['cannotresetmail'] = 'Error resetting password and mailing you';
$string['cannotresetthisrole'] = 'Cannot reset this role';
Expand Down
14 changes: 12 additions & 2 deletions lang/en/grades.php
Expand Up @@ -472,11 +472,21 @@
$string['missingitemtypeoreid'] = 'Array key (itemtype or eid) missing from 2nd param of grade_edit_tree_column_select::get_item_cell($item, $params)';
$string['missingscale'] = 'Scale must be selected';
$string['mode'] = 'Mode';
$string['modgradeerrorbadpoint'] = 'Invalid Grade Value. This must be an integer between 1 and {$a}';
$string['modgradeerrorbadscale'] = 'Invalid scale selected. Please make sure you select a scale from the selections below.';
$string['modgrade'] = 'Grade';
$string['modgrade_help'] = 'Select the type of grading used for this activity. If "scale" is chosen, you can then choose the scale from the "scale" dropdown. If using "point" grading, you can then enter the maximum grade available for this activity.';
$string['modgradedonotmodify'] = 'Do not modify existing grades';
$string['modgradeerrorbadpoint'] = 'Invalid Grade Value. This must be an integer between 0 and {$a}';
$string['modgradeerrorbadscale'] = 'Invalid scale selected. Please make sure you select a scale from the selections below.';
$string['modgrademaxgrade'] = 'Maximum points';
$string['modgraderescalegrades'] = 'Rescale existing grades';
$string['modgraderescalegrades_help'] = 'Changing the maximum points value for an activity has an effect on the percentage of any existing grades for that activity. If this "Rescale existing grades" option is enabled, all existing grades will be scaled so that the same percentage grade is maintained.
Example (with "Rescale existing grades" set to "Yes"):
A student grade of "6 / 10 ( 60 % )" would change to "12 / 20 ( 60 % )" when the maximum points is changed to 20.
';
$string['modgraderescalegrades_link'] = 'Scaling_Activity_Grades';
$string['modgradetype'] = 'Type';
$string['modgradetypenone'] = 'None';
$string['modgradetypepoint'] = 'Point';
Expand Down

0 comments on commit d629c60

Please sign in to comment.