Merge branch 'MDL-48634_master' of git://github.com/markn86/moodle
This commit is contained in:
+41
-1
@@ -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);
|
||||
|
||||
@@ -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) && $data->grade_rescalegrades == 'yes') {
|
||||
// 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) && $data->grade_rescalegrades == 'yes') {
|
||||
// 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).
|
||||
|
||||
@@ -109,9 +109,9 @@ abstract class moodleform_mod extends moodleform {
|
||||
$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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -405,7 +405,9 @@ abstract class moodleform_mod extends moodleform {
|
||||
|
||||
$permission=CAP_ALLOW;
|
||||
$rolenamestring = null;
|
||||
$isupdate = false;
|
||||
if (!empty($this->_cm)) {
|
||||
$isupdate = true;
|
||||
$context = context_module::instance($this->_cm->id);
|
||||
|
||||
$rolenames = get_role_names_with_caps_in_context($context, array('moodle/rating:rate', 'mod/'.$this->_cm->modname.':rate'));
|
||||
@@ -420,7 +422,25 @@ abstract class moodleform_mod extends moodleform {
|
||||
$mform->setDefault('assessed', 0);
|
||||
$mform->addHelpButton('assessed', 'aggregatetype', 'rating');
|
||||
|
||||
$mform->addElement('modgrade', 'scale', get_string('scale'), false);
|
||||
$gradeoptions = array('isupdate' => $isupdate,
|
||||
'currentgrade' => false,
|
||||
'hasgrades' => false,
|
||||
'canrescale' => $this->_features->canrescale,
|
||||
'useratings' => $this->_features->rating);
|
||||
if ($isupdate) {
|
||||
$gradeitem = grade_item::fetch(array('itemtype' => 'mod',
|
||||
'itemmodule' => $this->_cm->modname,
|
||||
'iteminstance' => $this->_cm->instance,
|
||||
'itemnumber' => 0,
|
||||
'courseid' => $COURSE->id));
|
||||
if ($gradeitem) {
|
||||
$gradeoptions['currentgrade'] = $gradeitem->grademax;
|
||||
$gradeoptions['currentgradetype'] = $gradeitem->gradetype;
|
||||
$gradeoptions['currentscaleid'] = $gradeitem->scaleid;
|
||||
$gradeoptions['hasgrades'] = $gradeitem->has_grades();
|
||||
}
|
||||
}
|
||||
$mform->addElement('modgrade', 'scale', get_string('scale'), $gradeoptions);
|
||||
$mform->disabledIf('scale', 'assessed', 'eq', 0);
|
||||
$mform->addHelpButton('scale', 'modgrade', 'grades');
|
||||
$mform->setDefault('scale', $CFG->gradepointdefault);
|
||||
@@ -641,6 +661,12 @@ abstract class moodleform_mod extends moodleform {
|
||||
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,
|
||||
'useratings' => $this->_features->rating);
|
||||
|
||||
if ($this->_features->hasgrades) {
|
||||
|
||||
@@ -650,7 +676,21 @@ abstract class moodleform_mod extends moodleform {
|
||||
|
||||
//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));
|
||||
if ($gradeitem) {
|
||||
$gradeoptions['currentgrade'] = $gradeitem->grademax;
|
||||
$gradeoptions['currentgradetype'] = $gradeitem->gradetype;
|
||||
$gradeoptions['currentscaleid'] = $gradeitem->scaleid;
|
||||
$gradeoptions['hasgrades'] = $gradeitem->has_grades();
|
||||
}
|
||||
}
|
||||
$mform->addElement('modgrade', 'grade', get_string('grade'), $gradeoptions);
|
||||
$mform->addHelpButton('grade', 'modgrade', 'grades');
|
||||
$mform->setDefault('grade', $CFG->gradepointdefault);
|
||||
}
|
||||
|
||||
@@ -156,6 +156,8 @@ if ($mform->is_cancelled()) {
|
||||
}
|
||||
|
||||
$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;
|
||||
|
||||
@@ -175,6 +177,12 @@ if ($mform->is_cancelled()) {
|
||||
|
||||
} else {
|
||||
$grade_item->update();
|
||||
|
||||
if (!empty($data->rescalegrades) && $data->rescalegrades == 'yes') {
|
||||
$newmin = $grade_item->grademin;
|
||||
$newmax = $grade_item->grademax;
|
||||
$grade_item->rescale_grades_keep_percentage($oldmin, $oldmax, $newmin, $newmax, 'gradebook');
|
||||
}
|
||||
}
|
||||
|
||||
// update hiding flag
|
||||
|
||||
@@ -51,6 +51,23 @@ class edit_item_form extends moodleform {
|
||||
$mform->addHelpButton('idnumber', 'idnumbermod');
|
||||
$mform->setType('idnumber', PARAM_RAW);
|
||||
|
||||
if (!empty($item->id)) {
|
||||
$gradeitem = new grade_item(array('id' => $item->id, 'courseid' => $item->courseid));
|
||||
// If grades exist set a message so the user knows why they can not alter the grade type or scale.
|
||||
// We could never change the grade type for external items, so only need to show this for manual grade items.
|
||||
if ($gradeitem->has_grades() && !$gradeitem->is_external_item()) {
|
||||
// Set a message so the user knows why they can not alter the grade type or scale.
|
||||
if ($gradeitem->gradetype == GRADE_TYPE_SCALE) {
|
||||
$gradesexistmsg = get_string('modgradecantchangegradetyporscalemsg', 'grades');
|
||||
} else {
|
||||
$gradesexistmsg = get_string('modgradecantchangegradetypemsg', 'grades');
|
||||
}
|
||||
|
||||
$gradesexisthtml = '<div class=\'alert\'>' . $gradesexistmsg . '</div>';
|
||||
$mform->addElement('static', 'gradesexistmsg', '', $gradesexisthtml);
|
||||
}
|
||||
}
|
||||
|
||||
// Manual grade items cannot have grade type GRADE_TYPE_NONE.
|
||||
$options = array(GRADE_TYPE_VALUE => get_string('typevalue', 'grades'),
|
||||
GRADE_TYPE_SCALE => get_string('typescale', 'grades'),
|
||||
@@ -85,6 +102,14 @@ class edit_item_form extends moodleform {
|
||||
$mform->addHelpButton('scaleid', 'typescale', 'grades');
|
||||
$mform->disabledIf('scaleid', 'gradetype', 'noteq', GRADE_TYPE_SCALE);
|
||||
|
||||
$choices = array();
|
||||
$choices[''] = get_string('choose');
|
||||
$choices['no'] = get_string('no');
|
||||
$choices['yes'] = get_string('yes');
|
||||
$mform->addElement('select', 'rescalegrades', get_string('modgraderescalegrades', 'grades'), $choices);
|
||||
$mform->addHelpButton('rescalegrades', 'modgraderescalegrades', 'grades');
|
||||
$mform->disabledIf('rescalegrades', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
|
||||
|
||||
$mform->addElement('text', 'grademax', get_string('grademax', 'grades'));
|
||||
$mform->addHelpButton('grademax', 'grademax', 'grades');
|
||||
$mform->disabledIf('grademax', 'gradetype', 'noteq', GRADE_TYPE_VALUE);
|
||||
@@ -269,7 +294,39 @@ class edit_item_form extends moodleform {
|
||||
// the idnumber of grade itemnumber 0 is synced with course_modules
|
||||
$mform->hardFreeze('idnumber');
|
||||
}
|
||||
//$mform->removeElement('calculation');
|
||||
|
||||
// For external items we can not change the grade type, even if no grades exist, so if it is set to
|
||||
// scale, then remove the grademax and grademin fields from the form - no point displaying them.
|
||||
if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
|
||||
$mform->removeElement('grademax');
|
||||
if ($mform->elementExists('grademin')) {
|
||||
$mform->removeElement('grademin');
|
||||
}
|
||||
} else { // Not using scale, so remove it.
|
||||
$mform->removeElement('scaleid');
|
||||
}
|
||||
|
||||
// Always remove the rescale grades element if it's an external item.
|
||||
$mform->removeElement('rescalegrades');
|
||||
} else if ($grade_item->has_grades()) {
|
||||
// Can't change the grade type or the scale if there are grades.
|
||||
$mform->hardFreeze('gradetype, scaleid');
|
||||
|
||||
// If we are using scales then remove the unnecessary rescale and grade fields.
|
||||
if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
|
||||
$mform->removeElement('rescalegrades');
|
||||
$mform->removeElement('grademax');
|
||||
if ($mform->elementExists('grademin')) {
|
||||
$mform->removeElement('grademin');
|
||||
}
|
||||
} else { // Remove the scale field.
|
||||
$mform->removeElement('scaleid');
|
||||
// Set the maximum grade to disabled unless a grade is chosen.
|
||||
$mform->disabledIf('grademax', 'rescalegrades', 'eq', '');
|
||||
}
|
||||
} else {
|
||||
// Remove the rescale element if there are no grades.
|
||||
$mform->removeElement('rescalegrades');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,6 +399,7 @@ class edit_item_form extends moodleform {
|
||||
// all new items are manual, children of course category
|
||||
$mform->removeElement('plusfactor');
|
||||
$mform->removeElement('multfactor');
|
||||
$mform->removeElement('rescalegrades');
|
||||
}
|
||||
|
||||
// no parent header for course category
|
||||
@@ -353,12 +411,15 @@ class edit_item_form extends moodleform {
|
||||
/// 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 {
|
||||
@@ -386,6 +447,31 @@ class edit_item_form extends moodleform {
|
||||
}
|
||||
}
|
||||
|
||||
// We do not want the user to be able to change the grade type or scale for this item if grades exist.
|
||||
if ($grade_item && $grade_item->has_grades()) {
|
||||
// Check that grade type is set - should never not be set unless form has been modified.
|
||||
if (!isset($data['gradetype'])) {
|
||||
$errors['gradetype'] = get_string('modgradecantchangegradetype', 'grades');
|
||||
} else if ($data['gradetype'] !== $grade_item->gradetype) { // Check if we are changing the grade type.
|
||||
$errors['gradetype'] = get_string('modgradecantchangegradetype', 'grades');
|
||||
} else if ($data['gradetype'] == GRADE_TYPE_SCALE) {
|
||||
// Check if we are changing the scale - can't do this when grades exist.
|
||||
if (isset($data['scaleid']) && ($data['scaleid'] !== $grade_item->scaleid)) {
|
||||
$errors['scaleid'] = get_string('modgradecantchangescale', 'grades');
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($grade_item) {
|
||||
if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
|
||||
if (grade_floats_different($data['grademin'], $grade_item->grademin) ||
|
||||
grade_floats_different($data['grademax'], $grade_item->grademax)) {
|
||||
if ($grade_item->has_grades() && empty($data['rescalegrades'])) {
|
||||
$errors['rescalegrades'] = get_string('mustchooserescaleyesorno', 'grades');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
|
||||
@@ -425,6 +425,7 @@ Feature: We can use calculated grade totals
|
||||
And I set the following settings for grade item "Manual item 2":
|
||||
| Extra credit | 0 |
|
||||
| Maximum grade | 200 |
|
||||
| Rescale existing grades | No |
|
||||
And I give the grade "21.00" to the user "Student 1" for the grade item "Manual item 2"
|
||||
And I press "Save changes"
|
||||
And I give the grade "20.00" to the user "Student 1" for the grade item "Manual item 2"
|
||||
@@ -435,6 +436,7 @@ Feature: We can use calculated grade totals
|
||||
And I set the following settings for grade item "Manual item 2":
|
||||
| Extra credit | 0 |
|
||||
| Maximum grade | 100 |
|
||||
| Rescale existing grades | No |
|
||||
And I give the grade "21.00" to the user "Student 1" for the grade item "Manual item 2"
|
||||
And I press "Save changes"
|
||||
And I give the grade "20.00" to the user "Student 1" for the grade item "Manual item 2"
|
||||
|
||||
@@ -145,6 +145,7 @@ Feature: Calculated grade items can be used in the gradebook
|
||||
| Course total | - | 112.50 | 0–150 | 75.00 % | - |
|
||||
And I navigate to "Gradebook setup" node in "Grade administration > Setup"
|
||||
And I set the following settings for grade item "calc item":
|
||||
| Rescale existing grades | No |
|
||||
| Maximum grade | 40 |
|
||||
And I follow "Grader report"
|
||||
And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1"
|
||||
|
||||
@@ -146,6 +146,7 @@ Feature: Gradebook calculations for calculated grade items before the fix 201506
|
||||
| Course total | - | 112.50 | 0–200 | 56.25 % | - |
|
||||
And I navigate to "Gradebook setup" node in "Grade administration > Setup"
|
||||
And I set the following settings for grade item "calc item":
|
||||
| Rescale existing grades | No |
|
||||
| Maximum grade | 40 |
|
||||
And I follow "Grader report"
|
||||
And I give the grade "65.00" to the user "Student 2" for the grade item "grade item 1"
|
||||
|
||||
@@ -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 % |
|
||||
@@ -0,0 +1,93 @@
|
||||
@core_grades
|
||||
Feature: Editing a grade item
|
||||
In order to ensure validation is provided to the teacher
|
||||
As a teacher
|
||||
I need to know why I can not add/edit values on the grade item form
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| student1 | Student | 1 | student1@example.com |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | groupmode |
|
||||
| Course 1 | C1 | 0 | 1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And I log in as "admin"
|
||||
And I navigate to "Scales" node in "Site administration > Grades"
|
||||
And I press "Add a new scale"
|
||||
And I set the following fields to these values:
|
||||
| Name | ABCDEF |
|
||||
| Scale | F,E,D,C,B,A |
|
||||
And I press "Save changes"
|
||||
And I press "Add a new scale"
|
||||
And I set the following fields to these values:
|
||||
| Name | Letter scale |
|
||||
| Scale | Disappointing, Good, Very good, Excellent |
|
||||
And I press "Save changes"
|
||||
And I am on site homepage
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Gradebook setup" node in "Course administration"
|
||||
And I press "Add grade item"
|
||||
And I set the following fields to these values:
|
||||
| Item name | MI 1 |
|
||||
And I press "Save changes"
|
||||
|
||||
Scenario: Being able to change the grade type, scale and maximum grade for a manual grade item when there are no grades
|
||||
Given I click on "Edit" "link" in the "MI 1" "table_row"
|
||||
When I click on "Edit settings" "link" in the "MI 1" "table_row"
|
||||
Then I should not see "Some grades have already been awarded, so the grade type"
|
||||
And I set the field "Grade type" to "Scale"
|
||||
And I press "Save changes"
|
||||
And I should see "Scale must be selected"
|
||||
And I set the field "Scale" to "ABCDEF"
|
||||
And I press "Save changes"
|
||||
And I should not see "You cannot change the type, as grades already exist for this item"
|
||||
And I click on "Edit" "link" in the "MI 1" "table_row"
|
||||
And I click on "Edit settings" "link" in the "MI 1" "table_row"
|
||||
And I should not see "Some grades have already been awarded, so the grade type"
|
||||
And I set the field "Scale" to "Letter scale"
|
||||
And I press "Save changes"
|
||||
And I should not see "You cannot change the scale, as grades already exist for this item"
|
||||
|
||||
Scenario: Attempting to change a manual item's grade type when grades already exist
|
||||
Given I navigate to "Grader report" node in "Grade administration"
|
||||
And I turn editing mode on
|
||||
And I give the grade "20.00" to the user "Student 1" for the grade item "MI 1"
|
||||
And I press "Save changes"
|
||||
And I navigate to "Gradebook setup" node in "Grade administration > Setup"
|
||||
And I click on "Edit" "link" in the "MI 1" "table_row"
|
||||
When I click on "Edit settings" "link" in the "MI 1" "table_row"
|
||||
Then I should see "Some grades have already been awarded, so the grade type cannot be changed. If you wish to change the maximum grade, you must first choose whether or not to rescale existing grades."
|
||||
And "//div[contains(concat(' ', normalize-space(@class), ' '), 'fstatic') and contains(text(), 'Value')]" "xpath_element" should exist
|
||||
|
||||
Scenario: Attempting to change a manual item's scale when grades already exist
|
||||
Given I click on "Edit" "link" in the "MI 1" "table_row"
|
||||
And I click on "Edit settings" "link" in the "MI 1" "table_row"
|
||||
And I set the field "Grade type" to "Scale"
|
||||
And I set the field "Scale" to "ABCDEF"
|
||||
And I press "Save changes"
|
||||
And I navigate to "Grader report" node in "Grade administration"
|
||||
And I turn editing mode on
|
||||
And I give the grade "C" to the user "Student 1" for the grade item "MI 1"
|
||||
And I press "Save changes"
|
||||
And I navigate to "Gradebook setup" node in "Grade administration > Setup"
|
||||
And I click on "Edit" "link" in the "MI 1" "table_row"
|
||||
When I click on "Edit settings" "link" in the "MI 1" "table_row"
|
||||
Then I should see "Some grades have already been awarded, so the grade type and scale cannot be changed."
|
||||
And "//div[contains(concat(' ', normalize-space(@class), ' '), 'fstatic') and contains(text(), 'ABCDEF')]" "xpath_element" should exist
|
||||
|
||||
Scenario: Attempting to change a manual item's maximum grade when no rescaling option has been chosen
|
||||
Given I navigate to "Grader report" node in "Grade administration"
|
||||
And I turn editing mode on
|
||||
And I give the grade "20.00" to the user "Student 1" for the grade item "MI 1"
|
||||
And I press "Save changes"
|
||||
And I navigate to "Gradebook setup" node in "Grade administration > Setup"
|
||||
And I click on "Edit" "link" in the "MI 1" "table_row"
|
||||
And I click on "Edit settings" "link" in the "MI 1" "table_row"
|
||||
And I set the field "Maximum grade" to "50"
|
||||
When I press "Save changes"
|
||||
Then I should see "You must choose whether to rescale existing grades or not."
|
||||
@@ -100,11 +100,13 @@ Feature: We can choose what min or max grade to use when aggregating grades.
|
||||
| Course total | - | 60.00 | 0–300 | 20.00 % | - |
|
||||
And I navigate to "Gradebook setup" node in "Grade administration > Setup"
|
||||
And I set the following settings for grade item "MI 1":
|
||||
| Maximum grade | 50.00 |
|
||||
| Minimum grade | 5.00 |
|
||||
| Maximum grade | 50.00 |
|
||||
| Minimum grade | 5.00 |
|
||||
| Rescale existing grades | No |
|
||||
And I set the following settings for grade item "MI 3":
|
||||
| Maximum grade | 50.00 |
|
||||
| Minimum grade | 5.00 |
|
||||
| Maximum grade | 50.00 |
|
||||
| Minimum grade | 5.00 |
|
||||
| Rescale existing grades | No |
|
||||
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:
|
||||
@@ -129,6 +131,7 @@ Feature: We can choose what min or max grade to use when aggregating grades.
|
||||
And I navigate to "Gradebook setup" node in "Grade administration > Setup"
|
||||
And I set the following settings for grade item "MI 5":
|
||||
| Maximum grade | 200.00 |
|
||||
| Rescale existing grades | No |
|
||||
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:
|
||||
|
||||
@@ -29,13 +29,13 @@ Feature: We can change the grading type and maximum grade point values
|
||||
And I expand all fieldsets
|
||||
And I set the field "grade[modgrade_type]" to "Point"
|
||||
Then the "Scale" "select" should be disabled
|
||||
And the "Maximum points" "field" should be enabled
|
||||
And the "Maximum grade" "field" should be enabled
|
||||
And I set the field "grade[modgrade_type]" to "Scale"
|
||||
And the "Maximum points" "field" should be disabled
|
||||
And the "Maximum grade" "field" should be disabled
|
||||
Then the "Scale" "select" should be enabled
|
||||
And I set the field "grade[modgrade_type]" to "None"
|
||||
Then the "Scale" "select" should be disabled
|
||||
And the "Maximum points" "field" should be disabled
|
||||
And the "Maximum grade" "field" should be disabled
|
||||
And I press "Save and return to course"
|
||||
|
||||
@javascript
|
||||
@@ -61,7 +61,7 @@ Feature: We can change the grading type and maximum grade point values
|
||||
And I press "Save and display"
|
||||
And I follow "Edit settings"
|
||||
Then the field "grade[modgrade_scale]" matches value "Separate and Connected ways of knowing"
|
||||
And the "Maximum points" "field" should be disabled
|
||||
And the "Maximum grade" "field" should be disabled
|
||||
And I press "Save and return to course"
|
||||
|
||||
@javascript
|
||||
@@ -73,7 +73,7 @@ Feature: We can change the grading type and maximum grade point values
|
||||
And I press "Save and display"
|
||||
And I follow "Edit settings"
|
||||
And the "Scale" "select" should be disabled
|
||||
And the "Maximum points" "field" should be disabled
|
||||
And the "Maximum grade" "field" should be disabled
|
||||
And I press "Save and return to course"
|
||||
|
||||
@javascript
|
||||
@@ -84,7 +84,7 @@ Feature: We can change the grading type and maximum grade point values
|
||||
And I set the field "grade[modgrade_type]" to "Point"
|
||||
And I set the field "grade[modgrade_point]" to "20000"
|
||||
And I press "Save and display"
|
||||
Then I should see "Invalid Grade Value. This must be an integer between 1 and 900"
|
||||
Then I should see "Invalid grade value. This must be an integer between 1 and 900"
|
||||
And I press "Cancel"
|
||||
|
||||
@javascript
|
||||
@@ -104,5 +104,5 @@ Feature: We can change the grading type and maximum grade point values
|
||||
And I follow "Test Assignment 1"
|
||||
And I follow "Edit settings"
|
||||
And I press "Save and display"
|
||||
Then I should see "Invalid Grade Value. This must be an integer between 1 and 100"
|
||||
Then I should see "Invalid grade value. This must be an integer between 1 and 100"
|
||||
And I press "Cancel"
|
||||
|
||||
@@ -37,7 +37,7 @@ Feature: Control the aggregation of the scales
|
||||
And I log out
|
||||
|
||||
@javascript
|
||||
Scenario Outline: Scales can be exluded from aggregation
|
||||
Scenario Outline: Scales can be excluded from aggregation
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I navigate to "Grades" node in "Course administration"
|
||||
|
||||
@@ -123,6 +123,7 @@ $string['cannotreadfile'] = 'Cannot read file ({$a})';
|
||||
$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';
|
||||
|
||||
+16
-3
@@ -472,11 +472,23 @@ $string['minimum_show_help'] = 'Minimum grade is used in calculating grades and
|
||||
$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['modgrademaxgrade'] = 'Maximum points';
|
||||
$string['modgradecantchangegradetype'] = 'You cannot change the type, as grades already exist for this item.';
|
||||
$string['modgradecantchangegradetypemsg'] = 'Some grades have already been awarded, so the grade type cannot be changed. If you wish to change the maximum grade, you must first choose whether or not to rescale existing grades.';
|
||||
$string['modgradecantchangegradetyporscalemsg'] = 'Some grades have already been awarded, so the grade type and scale cannot be changed.';
|
||||
$string['modgradecantchangescale'] = 'You cannot change the scale, as grades already exist for this item.';
|
||||
$string['modgradecantchangeratingmaxgrade'] = 'You cannot change the maximum grade when grades already exist for an activity with ratings.';
|
||||
$string['modgradedonotmodify'] = 'Do not modify existing grades';
|
||||
$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['modgrademaxgrade'] = 'Maximum grade';
|
||||
$string['modgraderescalegrades'] = 'Rescale existing grades';
|
||||
$string['modgraderescalegrades_help'] = 'When changing the maximum grades on a gradebook item you need to specify whether or not this will cause existing percentage grades to change as well.
|
||||
|
||||
If this is set to \'Yes\', any existing grades will be rescaled so that the percentage grade remains the same.
|
||||
|
||||
For example, if this option is set to \'Yes\', changing the maximum grade on an item from 10 to 20 would cause a grade of 6/10 (60%) to be rescaled to 12/20 (60%). With this option set to \'No\', the grade would change from 6/10 (60%) to 6/20 (30%), requiring manual adjustment of the grade items to ensure correct scores.';
|
||||
$string['modgradetype'] = 'Type';
|
||||
$string['modgradetypenone'] = 'None';
|
||||
$string['modgradetypepoint'] = 'Point';
|
||||
@@ -491,6 +503,7 @@ $string['mygrades'] = 'User menu grades link';
|
||||
$string['mygrades_desc'] = 'This setting allows for the option of linking to an external gradebook from the user menu.';
|
||||
$string['mypreferences'] = 'My preferences';
|
||||
$string['myreportpreferences'] = 'My report preferences';
|
||||
$string['mustchooserescaleyesorno'] = 'You must choose whether to rescale existing grades or not.';
|
||||
$string['navmethod'] = 'Navigation method';
|
||||
$string['neverdeletehistory'] = 'Never delete history';
|
||||
$string['newcategory'] = 'New category';
|
||||
|
||||
+217
-34
@@ -43,14 +43,48 @@ require_once($CFG->dirroot.'/lib/grade/grade_scale.php');
|
||||
* @copyright 2006 Jamie Pratt <[email protected]>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
class MoodleQuickForm_modgrade extends MoodleQuickForm_group {
|
||||
|
||||
/** @var boolean $isupdate Is this an add or an update ? */
|
||||
public $isupdate = false;
|
||||
|
||||
/** @var float $currentgrade The current grademax for the grade_item */
|
||||
public $currentgrade = false;
|
||||
|
||||
/** @var boolean $hasgrades Has this grade_item got any real grades (with values) */
|
||||
public $hasgrades = false;
|
||||
|
||||
/** @var boolean $canrescale Does this activity support rescaling grades? */
|
||||
public $canrescale = false;
|
||||
|
||||
/** @var int $currentscaleid The current scale id */
|
||||
public $currentscaleid = null;
|
||||
|
||||
/** @var string $currentgradetype The current gradetype - can either be 'none', 'scale', or 'point' */
|
||||
public $currentgradetype = 'none';
|
||||
|
||||
/** @var boolean $useratings Set to true if the activity is using ratings, false otherwise */
|
||||
public $useratings = false;
|
||||
|
||||
/** @var MoodleQuickForm_select $gradetypeformelement */
|
||||
private $gradetypeformelement;
|
||||
|
||||
/** @var MoodleQuickForm_select $scaleformelement */
|
||||
private $scaleformelement;
|
||||
|
||||
/** @var MoodleQuickForm_text $maxgradeformelement */
|
||||
private $maxgradeformelement;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param string $elementname Element's name
|
||||
* @param mixed $elementlabel Label(s) for an element
|
||||
* @param array $options Options to control the element's display. Not used.
|
||||
* @param array $options Options to control the element's display. Required - must contain the following options:
|
||||
* 'isupdate' - is this a new module or are we editing an existing one?
|
||||
* 'currentgrade' - the current grademax in the database for this gradeitem
|
||||
* 'hasgrades' - whether or not the grade_item has existing grade_grades
|
||||
* 'canrescale' - whether or not the activity supports rescaling grades
|
||||
* @param mixed $attributes Either a typical HTML attribute string or an associative array
|
||||
*/
|
||||
public function __construct($elementname = null, $elementlabel = null, $options = array(), $attributes = null) {
|
||||
@@ -59,6 +93,30 @@ class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
$this->_persistantFreeze = true;
|
||||
$this->_appendName = true;
|
||||
$this->_type = 'modgrade';
|
||||
$this->isupdate = !empty($options['isupdate']);
|
||||
if (isset($options['currentgrade'])) {
|
||||
$this->currentgrade = $options['currentgrade'];
|
||||
}
|
||||
if (isset($options['currentgradetype'])) {
|
||||
$gradetype = $options['currentgradetype'];
|
||||
switch ($gradetype) {
|
||||
case GRADE_TYPE_NONE :
|
||||
$this->currentgradetype = 'none';
|
||||
break;
|
||||
case GRADE_TYPE_SCALE :
|
||||
$this->currentgradetype = 'scale';
|
||||
break;
|
||||
case GRADE_TYPE_VALUE :
|
||||
$this->currentgradetype = 'point';
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isset($options['currentscaleid'])) {
|
||||
$this->currentscaleid = $options['currentscaleid'];
|
||||
}
|
||||
$this->hasgrades = !empty($options['hasgrades']);
|
||||
$this->canrescale = !empty($options['canrescale']);
|
||||
$this->useratings = !empty($options['useratings']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +133,7 @@ class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
* Create elements for this group.
|
||||
*/
|
||||
public function _createElements() {
|
||||
global $COURSE, $CFG;
|
||||
global $COURSE, $CFG, $OUTPUT;
|
||||
$attributes = $this->getAttributes();
|
||||
if (is_null($attributes)) {
|
||||
$attributes = array();
|
||||
@@ -89,17 +147,18 @@ class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
// Grade scale select box.
|
||||
$scales = get_scales_menu($COURSE->id);
|
||||
$langscale = get_string('modgradetypescale', 'grades');
|
||||
$scaleselect = @MoodleQuickForm::createElement('select', 'modgrade_scale', $langscale, $scales, $attributes);
|
||||
$scaleselect->setHiddenLabel = false;
|
||||
$scaleselectid = $this->generate_modgrade_subelement_id('modgrade_scale');
|
||||
$scaleselect->updateAttributes(array('id' => $scaleselectid));
|
||||
$this->scaleformelement = @MoodleQuickForm::createElement('select', 'modgrade_scale', $langscale,
|
||||
$scales, $attributes);
|
||||
$this->scaleformelement->setHiddenLabel = false;
|
||||
$scaleformelementid = $this->generate_modgrade_subelement_id('modgrade_scale');
|
||||
$this->scaleformelement->updateAttributes(array('id' => $scaleformelementid));
|
||||
|
||||
// Maximum grade textbox.
|
||||
$langmaxgrade = get_string('modgrademaxgrade', 'grades');
|
||||
$maxgrade = @MoodleQuickForm::createElement('text', 'modgrade_point', $langmaxgrade, array());
|
||||
$maxgrade->setHiddenLabel = false;
|
||||
$maxgradeid = $this->generate_modgrade_subelement_id('modgrade_point');
|
||||
$maxgrade->updateAttributes(array('id' => $maxgradeid));
|
||||
$this->maxgradeformelement = @MoodleQuickForm::createElement('text', 'modgrade_point', $langmaxgrade, array());
|
||||
$this->maxgradeformelement->setHiddenLabel = false;
|
||||
$maxgradeformelementid = $this->generate_modgrade_subelement_id('modgrade_point');
|
||||
$this->maxgradeformelement->updateAttributes(array('id' => $maxgradeformelementid));
|
||||
|
||||
// Grade type select box.
|
||||
$gradetype = array(
|
||||
@@ -108,30 +167,80 @@ class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
'point' => get_string('modgradetypepoint', 'grades'),
|
||||
);
|
||||
$langtype = get_string('modgradetype', 'grades');
|
||||
$typeselect = @MoodleQuickForm::createElement('select', 'modgrade_type', $langtype, $gradetype, $attributes, true);
|
||||
$typeselect->setHiddenLabel = false;
|
||||
$typeselectid = $this->generate_modgrade_subelement_id('modgrade_type');
|
||||
$typeselect->updateAttributes(array('id' => $typeselectid));
|
||||
$this->gradetypeformelement = @MoodleQuickForm::createElement('select', 'modgrade_type', $langtype, $gradetype,
|
||||
$attributes, true);
|
||||
$this->gradetypeformelement->setHiddenLabel = false;
|
||||
$gradetypeformelementid = $this->generate_modgrade_subelement_id('modgrade_type');
|
||||
$this->gradetypeformelement->updateAttributes(array('id' => $gradetypeformelementid));
|
||||
|
||||
if ($this->isupdate && $this->hasgrades) {
|
||||
$this->gradetypeformelement->updateAttributes(array('disabled' => 'disabled'));
|
||||
$this->scaleformelement->updateAttributes(array('disabled' => 'disabled'));
|
||||
|
||||
// Check box for options for processing existing grades.
|
||||
if ($this->canrescale) {
|
||||
$langrescalegrades = get_string('modgraderescalegrades', 'grades');
|
||||
$choices = array();
|
||||
$choices[''] = get_string('choose');
|
||||
$choices['no'] = get_string('no');
|
||||
$choices['yes'] = get_string('yes');
|
||||
$rescalegradesselect = @MoodleQuickForm::createElement('select',
|
||||
'modgrade_rescalegrades',
|
||||
$langrescalegrades,
|
||||
$choices);
|
||||
$rescalegradesselect->setHiddenLabel = false;
|
||||
$rescalegradesselectid = $this->generate_modgrade_subelement_id('modgrade_rescalegrades');
|
||||
$rescalegradesselect->updateAttributes(array('id' => $rescalegradesselectid));
|
||||
}
|
||||
}
|
||||
|
||||
// Add elements.
|
||||
if ($this->isupdate && $this->hasgrades) {
|
||||
// Set a message so the user knows why they can not alter the grade type or scale.
|
||||
if ($this->currentgradetype == 'scale') {
|
||||
$gradesexistmsg = get_string('modgradecantchangegradetyporscalemsg', 'grades');
|
||||
} else {
|
||||
$gradesexistmsg = get_string('modgradecantchangegradetypemsg', 'grades');
|
||||
}
|
||||
|
||||
$gradesexisthtml = '<div class=\'alert\'>' . $gradesexistmsg . '</div>';
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'gradesexistmsg', '', $gradesexisthtml);
|
||||
}
|
||||
|
||||
// Grade type select box.
|
||||
$label = html_writer::tag('label', $typeselect->getLabel(), array('for' => $typeselect->getAttribute('id')));
|
||||
$label = html_writer::tag('label', $this->gradetypeformelement->getLabel(),
|
||||
array('for' => $this->gradetypeformelement->getAttribute('id')));
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'gradetypelabel', '', ' '.$label);
|
||||
$this->_elements[] = $typeselect;
|
||||
$this->_elements[] = $this->gradetypeformelement;
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'gradetypespacer', '', '<br />');
|
||||
|
||||
// Grade scale select box.
|
||||
$label = html_writer::tag('label', $scaleselect->getLabel(), array('for' => $scaleselectid));
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'scalelabel', '', $label);
|
||||
$this->_elements[] = $scaleselect;
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'scalespacer', '', '<br />');
|
||||
// Only show the grade scale select box when applicable.
|
||||
if (!$this->isupdate || !$this->hasgrades || $this->currentgradetype == 'scale') {
|
||||
$label = html_writer::tag('label', $this->scaleformelement->getLabel(),
|
||||
array('for' => $this->scaleformelement->getAttribute('id')));
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'scalelabel', '', $label);
|
||||
$this->_elements[] = $this->scaleformelement;
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'scalespacer', '', '<br />');
|
||||
}
|
||||
|
||||
// Maximum grade textbox.
|
||||
$label = html_writer::tag('label', $maxgrade->getLabel(), array('for' => $maxgradeid));
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'pointlabel', '', $label);
|
||||
$this->_elements[] = $maxgrade;
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'pointspacer', '', '<br />');
|
||||
if ($this->isupdate && $this->hasgrades && $this->canrescale && $this->currentgradetype == 'point') {
|
||||
// We need to know how to apply any changes to maxgrade - ie to either update, or don't touch exising grades.
|
||||
$label = html_writer::tag('label', $rescalegradesselect->getLabel(),
|
||||
array('for' => $rescalegradesselect->getAttribute('id')));
|
||||
$labelhelp = new help_icon('modgraderescalegrades', 'grades');
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'scalelabel', '', $label . $OUTPUT->render($labelhelp));
|
||||
$this->_elements[] = $rescalegradesselect;
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'scalespacer', '', '<br />');
|
||||
}
|
||||
|
||||
// Only show the max points form element when applicable.
|
||||
if (!$this->isupdate || !$this->hasgrades || $this->currentgradetype == 'point') {
|
||||
$label = html_writer::tag('label', $this->maxgradeformelement->getLabel(),
|
||||
array('for' => $this->maxgradeformelement->getAttribute('id')));
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'pointlabel', '', $label);
|
||||
$this->_elements[] = $this->maxgradeformelement;
|
||||
$this->_elements[] = @MoodleQuickForm::createElement('static', 'pointspacer', '', '<br />');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,8 +265,9 @@ class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
$type = (isset($vals['modgrade_type'])) ? $vals['modgrade_type'] : 'none';
|
||||
$point = (isset($vals['modgrade_point'])) ? $vals['modgrade_point'] : null;
|
||||
$scale = (isset($vals['modgrade_scale'])) ? $vals['modgrade_scale'] : null;
|
||||
$rescalegrades = (isset($vals['modgrade_rescalegrades'])) ? $vals['modgrade_rescalegrades'] : null;
|
||||
$return = $this->process_value($type, $scale, $point);
|
||||
return array($this->getName() => $return);
|
||||
return array($this->getName() => $return, $this->getName() . '_rescalegrades' => $rescalegrades);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,11 +341,54 @@ class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
// Set disable actions.
|
||||
$caller->disabledIf($name.'[modgrade_scale]', $name.'[modgrade_type]', 'neq', 'scale');
|
||||
$caller->disabledIf($name.'[modgrade_point]', $name.'[modgrade_type]', 'neq', 'point');
|
||||
$caller->disabledIf($name.'[modgrade_rescalegrades]', $name.'[modgrade_type]', 'neq', 'point');
|
||||
|
||||
// Set validation rules for the sub-elements belonging to this element.
|
||||
// A handy note: the parent scope of a closure is the function in which the closure was declared.
|
||||
// Because of this using $this is safe despite the closures being called statically.
|
||||
// A nasty magic hack!
|
||||
$checkgradetypechange = function($val) {
|
||||
// Nothing is affected by changes to the grade type if there are no grades yet.
|
||||
if (!$this->hasgrades) {
|
||||
return true;
|
||||
}
|
||||
// Check if we are changing the grade type when grades are present.
|
||||
if (isset($val['modgrade_type']) && $val['modgrade_type'] !== $this->currentgradetype) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
$checkscalechange = function($val) {
|
||||
// Nothing is affected by changes to the scale if there are no grades yet.
|
||||
if (!$this->hasgrades) {
|
||||
return true;
|
||||
}
|
||||
// Check if we are changing the scale type when grades are present.
|
||||
if (isset($val['modgrade_type']) && $val['modgrade_type'] === 'scale') {
|
||||
if (isset($val['modgrade_scale']) && ($val['modgrade_scale'] !== $this->currentscaleid)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
$checkmaxgradechange = function($val) {
|
||||
// Nothing is affected by changes to the max grade if there are no grades yet.
|
||||
if (!$this->hasgrades) {
|
||||
return true;
|
||||
}
|
||||
// If we are not using ratings we can change the max grade.
|
||||
if (!$this->useratings) {
|
||||
return true;
|
||||
}
|
||||
// Check if we are changing the max grade if we are using ratings and there is a grade.
|
||||
if (isset($val['modgrade_type']) && $val['modgrade_type'] === 'point') {
|
||||
if (isset($val['modgrade_point']) &&
|
||||
grade_floats_different($this->currentgrade, $val['modgrade_point'])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
$checkmaxgrade = function($val) {
|
||||
// Closure to validate a max points value. See the note above about scope if this confuses you.
|
||||
if (isset($val['modgrade_type']) && $val['modgrade_type'] === 'point') {
|
||||
@@ -257,13 +410,39 @@ class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
return true;
|
||||
};
|
||||
|
||||
$checkrescale = function($val) {
|
||||
// Nothing is affected by changes to grademax if there are no grades yet.
|
||||
if (!$this->isupdate || !$this->hasgrades || !$this->canrescale) {
|
||||
return true;
|
||||
}
|
||||
// Closure to validate a scale value. See the note above about scope if this confuses you.
|
||||
if (isset($val['modgrade_type']) && $val['modgrade_type'] === 'point') {
|
||||
// Work out if the value was actually changed in the form.
|
||||
if (grade_floats_different($this->currentgrade, $val['modgrade_point'])) {
|
||||
if (empty($val['modgrade_rescalegrades'])) {
|
||||
// This was an "edit", the grademax was changed and the process existing setting was not set.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
$cantchangegradetype = get_string('modgradecantchangegradetype', 'grades');
|
||||
$cantchangemaxgrade = get_string('modgradecantchangeratingmaxgrade', 'grades');
|
||||
$maxgradeexceeded = get_string('modgradeerrorbadpoint', 'grades', get_config('core', 'gradepointmax'));
|
||||
$invalidscale = get_string('modgradeerrorbadscale', 'grades');
|
||||
$cantchangescale = get_string('modgradecantchangescale', 'grades');
|
||||
$mustchooserescale = get_string('mustchooserescaleyesorno', 'grades');
|
||||
// When creating the rules the sixth arg is $force, we set it to true because otherwise the form
|
||||
// will attempt to validate the existence of the element, we don't want this because the element
|
||||
// is being created right now and doesn't actually exist as a registered element yet.
|
||||
$caller->addRule($name, $cantchangegradetype, 'callback', $checkgradetypechange, 'server', false, true);
|
||||
$caller->addRule($name, $cantchangemaxgrade, 'callback', $checkmaxgradechange, 'server', false, true);
|
||||
$caller->addRule($name, $maxgradeexceeded, 'callback', $checkmaxgrade, 'server', false, true);
|
||||
$caller->addRule($name, $invalidscale, 'callback', $checkvalidscale, 'server', false, true);
|
||||
$caller->addRule($name, $cantchangescale, 'callback', $checkscalechange, 'server', false, true);
|
||||
$caller->addRule($name, $mustchooserescale, 'callback', $checkrescale, 'server', false, true);
|
||||
|
||||
break;
|
||||
|
||||
@@ -273,6 +452,10 @@ class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
// In this case we expect an int that is going to translate to a scale if negative, or to max points
|
||||
// if positive.
|
||||
|
||||
// Set the maximum points field to disabled if the rescale option has not been chosen and there are grades.
|
||||
$caller->disabledIf($this->getName() . '[modgrade_point]', $this->getName() .
|
||||
'[modgrade_rescalegrades]', 'eq', '');
|
||||
|
||||
// A constant value should be given as an int.
|
||||
// The default value should be an int and should really be $CFG->gradepointdefault.
|
||||
$value = $this->_findValue($caller->_constantValues);
|
||||
@@ -298,15 +481,15 @@ class MoodleQuickForm_modgrade extends MoodleQuickForm_group{
|
||||
if (!empty($this->_elements)) {
|
||||
if (!empty($value)) {
|
||||
if ($value < 0) {
|
||||
$this->_elements[1]->setValue('scale');
|
||||
$this->_elements[4]->setValue(($value * -1));
|
||||
$this->gradetypeformelement->setValue('scale');
|
||||
$this->scaleformelement->setValue(($value * -1));
|
||||
} else if ($value > 0) {
|
||||
$this->_elements[1]->setValue('point');
|
||||
$this->_elements[7]->setValue($value);
|
||||
$this->gradetypeformelement->setValue('point');
|
||||
$this->maxgradeformelement->setValue($value);
|
||||
}
|
||||
} else {
|
||||
$this->_elements[1]->setValue('none');
|
||||
$this->_elements[7]->setValue('');
|
||||
$this->gradetypeformelement->setValue('none');
|
||||
$this->maxgradeformelement->setValue('');
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
@core_form
|
||||
Feature: Using the activity grade form element
|
||||
In order to ensure validation is provided to the teacher
|
||||
As a teacher
|
||||
I need to know why I can not add/edit values in the form element
|
||||
|
||||
Background:
|
||||
Given the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| student1 | Student | 1 | student1@example.com |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname | category | groupmode |
|
||||
| Course 1 | C1 | 0 | 1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
|
||||
Scenario: Being able to change the grade type, scale and maximum grade when there are no grades
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Scales" node in "Site administration > Grades"
|
||||
And I press "Add a new scale"
|
||||
And I set the following fields to these values:
|
||||
| Name | ABCDEF |
|
||||
| Scale | F,E,D,C,B,A |
|
||||
And I press "Save changes"
|
||||
And I press "Add a new scale"
|
||||
And I set the following fields to these values:
|
||||
| Name | Letter scale |
|
||||
| Scale | Disappointing, Good, Very good, Excellent |
|
||||
And I press "Save changes"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "Forum" to section "1" and I fill the form with:
|
||||
| Forum name | Test forum name |
|
||||
| Forum type | Standard forum for general use |
|
||||
| Description | Test forum description |
|
||||
| Aggregate type | Average of ratings |
|
||||
| scale[modgrade_type] | Point |
|
||||
| scale[modgrade_point] | 100 |
|
||||
| Group mode | No groups |
|
||||
And I follow "Test forum name"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
When I expand all fieldsets
|
||||
Then I should not see "Some grades have already been awarded, so the grade type"
|
||||
And I set the field "scale[modgrade_type]" to "Scale"
|
||||
And I set the field "scale[modgrade_scale]" to "ABCDEF"
|
||||
And I press "Save and display"
|
||||
And I should not see "You cannot change the type, as grades already exist for this item"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I expand all fieldsets
|
||||
And I should not see "Some grades have already been awarded, so the grade type"
|
||||
And I set the field "scale[modgrade_scale]" to "Letter scale"
|
||||
And I press "Save and display"
|
||||
And I should not see "You cannot change the scale, as grades already exist for this item"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
And I expand all fieldsets
|
||||
And I should not see "Some grades have already been awarded, so the grade type"
|
||||
And I set the field "scale[modgrade_type]" to "Point"
|
||||
And I set the field "Maximum grade" to "50"
|
||||
And I press "Save and display"
|
||||
And I should not see "You must choose whether to rescale existing grades or not"
|
||||
|
||||
Scenario: Attempting to change the grade type when grades already exist
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "Assignment" to section "1" and I fill the form with:
|
||||
| Assignment name | Test assignment name |
|
||||
| Description | Test assignment description |
|
||||
And I follow "Test assignment name"
|
||||
And I follow "View/grade all submissions"
|
||||
And I click on "Grade Student 1" "link" in the "Student 1" "table_row"
|
||||
And I set the field "Grade out of 100" to "50"
|
||||
And I press "Save changes"
|
||||
And I press "Continue"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
When I expand all fieldsets
|
||||
Then I should see "Some grades have already been awarded, so the grade type cannot be changed. If you wish to change the maximum grade, you must first choose whether or not to rescale existing grades."
|
||||
And I set the field "grade[modgrade_type]" to "Scale"
|
||||
And I press "Save and display"
|
||||
And I should see "You cannot change the type, as grades already exist for this item"
|
||||
|
||||
Scenario: Attempting to change the scale when grades already exist
|
||||
Given I log in as "admin"
|
||||
And I navigate to "Scales" node in "Site administration > Grades"
|
||||
And I press "Add a new scale"
|
||||
And I set the following fields to these values:
|
||||
| Name | ABCDEF |
|
||||
| Scale | F,E,D,C,B,A |
|
||||
And I press "Save changes"
|
||||
And I press "Add a new scale"
|
||||
And I set the following fields to these values:
|
||||
| Name | Letter scale |
|
||||
| Scale | Disappointing, Good, Very good, Excellent |
|
||||
And I press "Save changes"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "Assignment" to section "1" and I fill the form with:
|
||||
| Assignment name | Test assignment name |
|
||||
| Description | Test assignment description |
|
||||
| grade[modgrade_type] | Scale |
|
||||
| grade[modgrade_scale] | ABCDEF |
|
||||
And I follow "Course 1"
|
||||
And I follow "Test assignment name"
|
||||
And I follow "View/grade all submissions"
|
||||
And I click on "Grade Student 1" "link" in the "Student 1" "table_row"
|
||||
And I set the field "Grade" to "C"
|
||||
And I press "Save changes"
|
||||
And I press "Continue"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
When I expand all fieldsets
|
||||
Then I should see "Some grades have already been awarded, so the grade type and scale cannot be changed"
|
||||
And I set the field "grade[modgrade_scale]" to "Letter scale"
|
||||
And I press "Save and display"
|
||||
And I should see "You cannot change the scale, as grades already exist for this item"
|
||||
|
||||
Scenario: Attempting to change the maximum grade when ratings exist
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "Forum" to section "1" and I fill the form with:
|
||||
| Forum name | Test forum name |
|
||||
| Forum type | Standard forum for general use |
|
||||
| Description | Test forum description |
|
||||
| Aggregate type | Average of ratings |
|
||||
| scale[modgrade_type] | Point |
|
||||
| scale[modgrade_point] | 100 |
|
||||
| Group mode | No groups |
|
||||
And I log out
|
||||
And I log in as "student1"
|
||||
And I follow "Course 1"
|
||||
And I follow "Test forum name"
|
||||
And I press "Add a new discussion topic"
|
||||
And I set the following fields to these values:
|
||||
| Subject | Discussion subject |
|
||||
| Message | Discussion message |
|
||||
And I press "Post to forum"
|
||||
And I follow "Continue"
|
||||
And I log out
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I follow "Test forum name"
|
||||
And I follow "Discussion subject"
|
||||
And I set the field "rating" to "100"
|
||||
And I press "Rate"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
When I expand all fieldsets
|
||||
Then I should see "Some grades have already been awarded, so the grade type cannot be changed. If you wish to change the maximum grade, you must first choose whether or not to rescale existing grades."
|
||||
And I set the field "Maximum grade" to "50"
|
||||
And I press "Save and display"
|
||||
And I should see "You cannot change the maximum grade when grades already exist for an activity with ratings"
|
||||
|
||||
Scenario: Attempting to change the maximum grade when no rescaling option has been chosen
|
||||
Given I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "Assignment" to section "1" and I fill the form with:
|
||||
| Assignment name | Test assignment name |
|
||||
| Description | Test assignment description |
|
||||
And I follow "Course 1"
|
||||
And I follow "Test assignment name"
|
||||
And I follow "View/grade all submissions"
|
||||
And I click on "Grade Student 1" "link" in the "Student 1" "table_row"
|
||||
And I set the field "Grade out of 100" to "50"
|
||||
And I press "Save changes"
|
||||
And I press "Continue"
|
||||
And I click on "Edit settings" "link" in the "Administration" "block"
|
||||
When I expand all fieldsets
|
||||
Then I should see "Some grades have already been awarded, so the grade type cannot be changed. If you wish to change the maximum grade, you must first choose whether or not to rescale existing grades."
|
||||
And I set the field "Maximum grade" to "50"
|
||||
And I press "Save and display"
|
||||
And I should see "You must choose whether to rescale existing grades or not"
|
||||
@@ -354,6 +354,20 @@ class grade_item extends grade_object {
|
||||
return grade_object::fetch_helper('grade_items', 'grade_item', $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check to see if there are any existing grades for this grade_item.
|
||||
*
|
||||
* @return boolean - true if there are valid grades for this grade_item.
|
||||
*/
|
||||
public function has_grades() {
|
||||
global $DB;
|
||||
|
||||
$count = $DB->count_records_select('grade_grades',
|
||||
'itemid = :gradeitemid AND finalgrade IS NOT NULL',
|
||||
array('gradeitemid' => $this->id));
|
||||
return $count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds and returns all grade_item instances based on params.
|
||||
*
|
||||
@@ -775,9 +789,9 @@ class grade_item extends grade_object {
|
||||
}
|
||||
|
||||
// Standardise score to the new grade range
|
||||
// NOTE: this is not compatible with current assignment grading
|
||||
$isassignmentmodule = ($this->itemmodule == 'assignment') || ($this->itemmodule == 'assign');
|
||||
if (!$isassignmentmodule && ($rawmin != $this->grademin or $rawmax != $this->grademax)) {
|
||||
// NOTE: skip if the activity provides a manual rescaling option.
|
||||
$manuallyrescale = (component_callback_exists('mod_' . $this->itemmodule, 'rescale_activity_grades') !== false);
|
||||
if (!$manuallyrescale && ($rawmin != $this->grademin or $rawmax != $this->grademax)) {
|
||||
$rawgrade = grade_grade::standardise_score($rawgrade, $rawmin, $rawmax, $this->grademin, $this->grademax);
|
||||
}
|
||||
|
||||
@@ -801,8 +815,10 @@ class grade_item extends grade_object {
|
||||
}
|
||||
|
||||
// Convert scale if needed
|
||||
// NOTE: this is not compatible with current assignment grading
|
||||
if ($this->itemmodule != 'assignment' and ($rawmin != $this->grademin or $rawmax != $this->grademax)) {
|
||||
// NOTE: skip if the activity provides a manual rescaling option.
|
||||
$manuallyrescale = (component_callback_exists('mod_' . $this->itemmodule, 'rescale_activity_grades') !== false);
|
||||
if (!$manuallyrescale && ($rawmin != $this->grademin or $rawmax != $this->grademax)) {
|
||||
// This should never happen because scales are locked if they are in use.
|
||||
$rawgrade = grade_grade::standardise_score($rawgrade, $rawmin, $rawmax, $this->grademin, $this->grademax);
|
||||
}
|
||||
|
||||
@@ -819,6 +835,60 @@ class grade_item extends grade_object {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the rawgrademax and rawgrademin for all grade_grades records for this item.
|
||||
* Scale every rawgrade to maintain the percentage. This function should be called
|
||||
* after the gradeitem has been updated to the new min and max values.
|
||||
*
|
||||
* @param float $oldgrademin The previous grade min value
|
||||
* @param float $oldgrademax The previous grade max value
|
||||
* @param float $newgrademin The new grade min value
|
||||
* @param float $newgrademax The new grade max value
|
||||
* @param string $source from where was the object inserted (mod/forum, manual, etc.)
|
||||
* @return bool True on success
|
||||
*/
|
||||
public function rescale_grades_keep_percentage($oldgrademin, $oldgrademax, $newgrademin, $newgrademax, $source = null) {
|
||||
global $DB;
|
||||
|
||||
if (empty($this->id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($oldgrademax <= $oldgrademin) {
|
||||
// Grades cannot be scaled.
|
||||
return false;
|
||||
}
|
||||
$scale = ($newgrademax - $newgrademin) / ($oldgrademax - $oldgrademin);
|
||||
if (($newgrademax - $newgrademin) <= 1) {
|
||||
// We would lose too much precision, lets bail.
|
||||
return false;
|
||||
}
|
||||
|
||||
$rs = $DB->get_recordset('grade_grades', array('itemid' => $this->id));
|
||||
|
||||
foreach ($rs as $graderecord) {
|
||||
// For each record, create an object to work on.
|
||||
$grade = new grade_grade($graderecord, false);
|
||||
// Set this object in the item so it doesn't re-fetch it.
|
||||
$grade->grade_item = $this;
|
||||
|
||||
// Updating the raw grade automatically updates the min/max.
|
||||
if ($this->is_raw_used()) {
|
||||
$rawgrade = (($grade->rawgrade - $oldgrademin) * $scale) + $newgrademin;
|
||||
$this->update_raw_grade(false, $rawgrade, $source, false, FORMAT_MOODLE, null, null, null, $grade);
|
||||
} else {
|
||||
$finalgrade = (($grade->finalgrade - $oldgrademin) * $scale) + $newgrademin;
|
||||
$this->update_final_grade($grade->userid, $finalgrade, $source);
|
||||
}
|
||||
}
|
||||
$rs->close();
|
||||
|
||||
// Mark this item for regrading.
|
||||
$this->force_regrading();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this grade_item's needsupdate to true. Also marks the course item as needing update.
|
||||
*
|
||||
@@ -1649,6 +1719,8 @@ class grade_item extends grade_object {
|
||||
$oldgrade->overridden = $grade->overridden;
|
||||
$oldgrade->feedback = $grade->feedback;
|
||||
$oldgrade->feedbackformat = $grade->feedbackformat;
|
||||
$oldgrade->rawgrademin = $grade->rawgrademin;
|
||||
$oldgrade->rawgrademax = $grade->rawgrademax;
|
||||
|
||||
// MDL-31713 rawgramemin and max must be up to date so conditional access %'s works properly.
|
||||
$grade->rawgrademin = $this->grademin;
|
||||
@@ -1687,6 +1759,8 @@ class grade_item extends grade_object {
|
||||
} else if (grade_floats_different($grade->finalgrade, $oldgrade->finalgrade)
|
||||
or $grade->feedback !== $oldgrade->feedback
|
||||
or $grade->feedbackformat != $oldgrade->feedbackformat
|
||||
or grade_floats_different($grade->rawgrademin, $oldgrade->rawgrademin)
|
||||
or grade_floats_different($grade->rawgrademax, $oldgrade->rawgrademax)
|
||||
or ($oldgrade->overridden == 0 and $grade->overridden > 0)) {
|
||||
$grade->timemodified = time(); // hack alert - date graded
|
||||
$result = $grade->update($source);
|
||||
|
||||
@@ -50,6 +50,7 @@ class core_grade_item_testcase extends grade_base_testcase {
|
||||
$this->sub_test_grade_item_load_item_category();
|
||||
$this->sub_test_grade_item_regrade_final_grades();
|
||||
$this->sub_test_grade_item_adjust_raw_grade();
|
||||
$this->sub_test_grade_item_rescale_grades_keep_percentage();
|
||||
$this->sub_test_grade_item_set_locked();
|
||||
$this->sub_test_grade_item_is_locked();
|
||||
$this->sub_test_grade_item_set_hidden();
|
||||
@@ -371,6 +372,46 @@ class core_grade_item_testcase extends grade_base_testcase {
|
||||
$this->assertEquals(round(1.6), round($grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)));
|
||||
}
|
||||
|
||||
protected function sub_test_grade_item_rescale_grades_keep_percentage() {
|
||||
global $DB;
|
||||
$gradeitem = new grade_item($this->grade_items[10], false); // 10 is the manual grade item.
|
||||
|
||||
// Create some grades to go with the grade item.
|
||||
$gradeids = array();
|
||||
$grade = new stdClass();
|
||||
$grade->itemid = $gradeitem->id;
|
||||
$grade->userid = $this->user[2]->id;
|
||||
$grade->finalgrade = 10;
|
||||
$grade->rawgrademax = $gradeitem->grademax;
|
||||
$grade->rawgrademin = $gradeitem->grademin;
|
||||
$grade->timecreated = time();
|
||||
$grade->timemodified = time();
|
||||
$gradeids[] = $DB->insert_record('grade_grades', $grade);
|
||||
|
||||
$grade->userid = $this->user[3]->id;
|
||||
$grade->finalgrade = 50;
|
||||
$grade->rawgrademax = $gradeitem->grademax;
|
||||
$grade->rawgrademin = $gradeitem->grademin;
|
||||
$gradeids[] = $DB->insert_record('grade_grades', $grade);
|
||||
|
||||
// Run the function.
|
||||
$gradeitem->grademax = 33;
|
||||
$gradeitem->grademin = 3;
|
||||
$gradeitem->update();
|
||||
$gradeitem->rescale_grades_keep_percentage(0, 100, 3, 33, 'test');
|
||||
|
||||
// Check that the grades were updated to match the grade item.
|
||||
$grade = $DB->get_record('grade_grades', array('id' => $gradeids[0]));
|
||||
$this->assertEquals($gradeitem->grademax, $grade->rawgrademax, 'Max grade mismatch', 0.0001);
|
||||
$this->assertEquals($gradeitem->grademin, $grade->rawgrademin, 'Min grade mismatch', 0.0001);
|
||||
$this->assertEquals(6, $grade->finalgrade, 'Min grade mismatch', 0.0001);
|
||||
|
||||
$grade = $DB->get_record('grade_grades', array('id' => $gradeids[1]));
|
||||
$this->assertEquals($gradeitem->grademax, $grade->rawgrademax, 'Max grade mismatch', 0.0001);
|
||||
$this->assertEquals($gradeitem->grademin, $grade->rawgrademin, 'Min grade mismatch', 0.0001);
|
||||
$this->assertEquals(18, $grade->finalgrade, 'Min grade mismatch', 0.0001);
|
||||
}
|
||||
|
||||
protected function sub_test_grade_item_set_locked() {
|
||||
// Getting a grade_item from the DB as set_locked() will fail if the grade items needs to be updated
|
||||
// also needs to have at least one grade_grade or $grade_item->get_final(1) returns null.
|
||||
|
||||
@@ -1315,6 +1315,52 @@ function assign_user_complete($course, $user, $coursemodule, $assign) {
|
||||
echo $assignment->view_student_summary($user, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rescale all grades for this activity and push the new grades to the gradebook.
|
||||
*
|
||||
* @param stdClass $course Course db record
|
||||
* @param stdClass $cm Course module db record
|
||||
* @param float $oldmin
|
||||
* @param float $oldmax
|
||||
* @param float $newmin
|
||||
* @param float $newmax
|
||||
*/
|
||||
function assign_rescale_activity_grades($course, $cm, $oldmin, $oldmax, $newmin, $newmax) {
|
||||
global $DB;
|
||||
|
||||
if ($oldmax <= $oldmin) {
|
||||
// Grades cannot be scaled.
|
||||
return false;
|
||||
}
|
||||
$scale = ($newmax - $newmin) / ($oldmax - $oldmin);
|
||||
if (($newmax - $newmin) <= 1) {
|
||||
// We would lose too much precision, lets bail.
|
||||
return false;
|
||||
}
|
||||
|
||||
$params = array(
|
||||
'p1' => $oldmin,
|
||||
'p2' => $scale,
|
||||
'p3' => $newmin,
|
||||
'a' => $cm->instance
|
||||
);
|
||||
|
||||
$sql = 'UPDATE {assign_grades} set grade = (((grade - :p1) * :p2) + :p3) where assignment = :a';
|
||||
$dbupdate = $DB->execute($sql, $params);
|
||||
if (!$dbupdate) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now re-push all grades to the gradebook.
|
||||
$dbparams = array('id' => $cm->instance);
|
||||
$assign = $DB->get_record('assign', $dbparams);
|
||||
$assign->cmidnumber = $cm->idnumber;
|
||||
|
||||
assign_update_grades($assign);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the grade information for the assignment for this user.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
@mod @mod_assign
|
||||
Feature: Check that the assignment grade can be rescaled when the max grade is changed
|
||||
In order to ensure that the percentages are not affected by changes to the max grade
|
||||
As a teacher
|
||||
I need to rescale all grades when updating the max grade
|
||||
|
||||
Background:
|
||||
Given the following "courses" exist:
|
||||
| fullname | shortname | category | groupmode |
|
||||
| Course 1 | C1 | 0 | 1 |
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| teacher1 | Teacher | 1 | teacher1@example.com |
|
||||
| student1 | Student | 1 | student10@example.com |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| teacher1 | C1 | editingteacher |
|
||||
| student1 | C1 | student |
|
||||
And the following "groups" exist:
|
||||
| name | course | idnumber |
|
||||
| Group 1 | C1 | G1 |
|
||||
And I log in as "teacher1"
|
||||
And I follow "Course 1"
|
||||
And I turn editing mode on
|
||||
And I add a "Assignment" to section "1" and I fill the form with:
|
||||
| Assignment name | Test assignment name |
|
||||
| Description | Test assignment description |
|
||||
And I follow "Test assignment name"
|
||||
And I follow "View/grade all submissions"
|
||||
And I click on "Grade Student 1" "link" in the "Student 1" "table_row"
|
||||
And I set the field "Grade out of 100" to "40"
|
||||
And I press "Save changes"
|
||||
And I press "Continue"
|
||||
And "Student 1" row "Grade" column of "generaltable" table should contain "40.00"
|
||||
|
||||
Scenario: Update the max grade for an assignment without rescaling existing grades
|
||||
Given I follow "Edit settings"
|
||||
And I expand all fieldsets
|
||||
And I set the field "Maximum grade" to "80"
|
||||
And I set the field "Rescale existing grades" to "No"
|
||||
When I press "Save and display"
|
||||
And I follow "View/grade all submissions"
|
||||
Then "Student 1" row "Grade" column of "generaltable" table should contain "40.00"
|
||||
|
||||
Scenario: Update the max grade for an assignment rescaling existing grades
|
||||
Given I follow "Edit settings"
|
||||
And I expand all fieldsets
|
||||
And I set the field "Maximum grade" to "50"
|
||||
And I set the field "Rescale existing grades" to "Yes"
|
||||
When I press "Save and display"
|
||||
And I follow "View/grade all submissions"
|
||||
Then "Student 1" row "Grade" column of "generaltable" table should contain "20.00"
|
||||
|
||||
Scenario: A rescale existing grades is not needed when keeping max grade unchanged
|
||||
Given I follow "Edit settings"
|
||||
And I expand all fieldsets
|
||||
And I set the field "Maximum grade" to "100"
|
||||
When I press "Save and display"
|
||||
Then I should not see "You must choose whether to rescale existing grades or not."
|
||||
|
||||
Scenario: A rescale existing grades must be selected when max grade changes
|
||||
Given I follow "Edit settings"
|
||||
And I expand all fieldsets
|
||||
And I set the field "Maximum grade" to "50"
|
||||
When I press "Save and display"
|
||||
Then I should see "You must choose whether to rescale existing grades or not."
|
||||
Reference in New Issue
Block a user