From 29932b211287985c8e3235e52fc78782528309a2 Mon Sep 17 00:00:00 2001
From: Paul Charsley
Date: Thu, 19 Dec 2013 09:39:22 +1300
Subject: [PATCH] MDL-42425 modify mod_assign_save_grade to process advanced
grading data
---
mod/assign/db/services.php | 8 +
mod/assign/externallib.php | 201 ++++++++++++++++-
mod/assign/tests/externallib_test.php | 299 +++++++++++++++++++++++++-
mod/assign/upgrade.txt | 5 +
mod/assign/version.php | 2 +-
5 files changed, 505 insertions(+), 10 deletions(-)
diff --git a/mod/assign/db/services.php b/mod/assign/db/services.php
index cc7056feb3f..3061e78812b 100644
--- a/mod/assign/db/services.php
+++ b/mod/assign/db/services.php
@@ -122,6 +122,14 @@ $functions = array(
'type' => 'write'
),
+ 'mod_assign_save_grades' => array(
+ 'classname' => 'mod_assign_external',
+ 'methodname' => 'save_grades',
+ 'classpath' => 'mod/assign/externallib.php',
+ 'description' => 'Save multiple grade updates for an assignment.',
+ 'type' => 'write'
+ ),
+
'mod_assign_save_user_extensions' => array(
'classname' => 'mod_assign_external',
'methodname' => 'save_user_extensions',
diff --git a/mod/assign/externallib.php b/mod/assign/externallib.php
index cf582ce86d8..4b795b89997 100644
--- a/mod/assign/externallib.php
+++ b/mod/assign/externallib.php
@@ -1644,6 +1644,7 @@ class mod_assign_external extends external_api {
public static function save_grade_parameters() {
global $CFG;
require_once("$CFG->dirroot/mod/assign/locallib.php");
+ require_once("$CFG->dirroot/grade/grading/lib.php");
$instance = new assign(null, null, null);
$pluginfeedbackparams = array();
@@ -1654,20 +1655,41 @@ class mod_assign_external extends external_api {
}
}
+ $advancedgradingdata = array();
+ $methods = array_keys(grading_manager::available_methods(false));
+ foreach ($methods as $method) {
+ require_once($CFG->dirroot.'/grade/grading/form/'.$method.'/lib.php');
+ $details = call_user_func('gradingform_'.$method.'_controller::get_external_instance_filling_details');
+ if (!empty($details)) {
+ $items = array();
+ foreach ($details as $key => $value) {
+ $value->required = VALUE_OPTIONAL;
+ unset($value->content->keys['id']);
+ $items[$key] = new external_multiple_structure (new external_single_structure(
+ array(
+ 'criterionid' => new external_value(PARAM_INT, 'criterion id'),
+ 'fillings' => $value
+ )
+ ));
+ }
+ $advancedgradingdata[$method] = new external_single_structure($items, 'items', VALUE_OPTIONAL);
+ }
+ }
+
return new external_function_parameters(
array(
'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
'userid' => new external_value(PARAM_INT, 'The student id to operate on'),
- 'grade' => new external_value(PARAM_FLOAT, 'The new grade for this user'),
+ 'grade' => new external_value(PARAM_FLOAT, 'The new grade for this user. Ignored if advanced grading used'),
'attemptnumber' => new external_value(PARAM_INT, 'The attempt number (-1 means latest attempt)'),
'addattempt' => new external_value(PARAM_BOOL, 'Allow another attempt if the attempt reopen method is manual'),
'workflowstate' => new external_value(PARAM_ALPHA, 'The next marking workflow state'),
'applytoall' => new external_value(PARAM_BOOL, 'If true, this grade will be applied ' .
'to all members ' .
'of the group (for group assignments).'),
- 'plugindata' => new external_single_structure(
- $pluginfeedbackparams
- )
+ 'plugindata' => new external_single_structure($pluginfeedbackparams, 'plugin data', VALUE_DEFAULT, array()),
+ 'advancedgradingdata' => new external_single_structure($advancedgradingdata, 'advanced grading data',
+ VALUE_DEFAULT, array())
)
);
}
@@ -1683,6 +1705,7 @@ class mod_assign_external extends external_api {
* @param string $workflowstate New workflow state
* @param bool $applytoall Apply the grade to all members of the group
* @param array $plugindata Custom data used by plugins
+ * @param array $advancedgradingdata Advanced grading data
* @return null
* @since Moodle 2.6
*/
@@ -1693,7 +1716,8 @@ class mod_assign_external extends external_api {
$addattempt,
$workflowstate,
$applytoall,
- $plugindata) {
+ $plugindata = array(),
+ $advancedgradingdata = array()) {
global $CFG, $USER;
require_once("$CFG->dirroot/mod/assign/locallib.php");
@@ -1705,7 +1729,8 @@ class mod_assign_external extends external_api {
'workflowstate' => $workflowstate,
'addattempt' => $addattempt,
'applytoall' => $applytoall,
- 'plugindata' => $plugindata));
+ 'plugindata' => $plugindata,
+ 'advancedgradingdata' => $advancedgradingdata));
$cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
$context = context_module::instance($cm->id);
@@ -1720,6 +1745,21 @@ class mod_assign_external extends external_api {
$gradedata->applytoall = $applytoall;
$gradedata->grade = $grade;
+ if (!empty($advancedgradingdata)) {
+ $advancedgrading = array();
+ $criteria = reset($advancedgradingdata);
+ foreach ($criteria as $key => $criterion) {
+ $details = array();
+ foreach ($criterion as $value) {
+ foreach ($value['fillings'] as $filling) {
+ $details[$value['criterionid']] = $filling;
+ }
+ }
+ $advancedgrading[$key] = $details;
+ }
+ $gradedata->advancedgrading = $advancedgrading;
+ }
+
$assignment->save_grade($userid, $gradedata);
return null;
@@ -1735,6 +1775,155 @@ class mod_assign_external extends external_api {
return null;
}
+ /**
+ * Describes the parameters for save_grades
+ * @return external_external_function_parameters
+ * @since Moodle 2.7
+ */
+ public static function save_grades_parameters() {
+ global $CFG;
+ require_once("$CFG->dirroot/mod/assign/locallib.php");
+ require_once("$CFG->dirroot/grade/grading/lib.php");
+ $instance = new assign(null, null, null);
+ $pluginfeedbackparams = array();
+
+ foreach ($instance->get_feedback_plugins() as $plugin) {
+ $pluginparams = $plugin->get_external_parameters();
+ if (!empty($pluginparams)) {
+ $pluginfeedbackparams = array_merge($pluginfeedbackparams, $pluginparams);
+ }
+ }
+
+ $advancedgradingdata = array();
+ $methods = array_keys(grading_manager::available_methods(false));
+ foreach ($methods as $method) {
+ require_once($CFG->dirroot.'/grade/grading/form/'.$method.'/lib.php');
+ $details = call_user_func('gradingform_'.$method.'_controller::get_external_instance_filling_details');
+ if (!empty($details)) {
+ $items = array();
+ foreach ($details as $key => $value) {
+ $value->required = VALUE_OPTIONAL;
+ unset($value->content->keys['id']);
+ $items[$key] = new external_multiple_structure (new external_single_structure(
+ array(
+ 'criterionid' => new external_value(PARAM_INT, 'criterion id'),
+ 'fillings' => $value
+ )
+ ));
+ }
+ $advancedgradingdata[$method] = new external_single_structure($items, 'items', VALUE_OPTIONAL);
+ }
+ }
+
+ return new external_function_parameters(
+ array(
+ 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'),
+ 'applytoall' => new external_value(PARAM_BOOL, 'If true, this grade will be applied ' .
+ 'to all members ' .
+ 'of the group (for group assignments).'),
+ 'grades' => new external_multiple_structure(
+ new external_single_structure(
+ array (
+ 'userid' => new external_value(PARAM_INT, 'The student id to operate on'),
+ 'grade' => new external_value(PARAM_FLOAT, 'The new grade for this user'),
+ 'attemptnumber' => new external_value(PARAM_INT, 'The attempt number (-1 means latest attempt)'),
+ 'addattempt' => new external_value(PARAM_BOOL, 'Allow another attempt if manual attempt reopen method'),
+ 'workflowstate' => new external_value(PARAM_ALPHA, 'The next marking workflow state'),
+ 'plugindata' => new external_single_structure($pluginfeedbackparams, 'plugin data',
+ VALUE_DEFAULT, array()),
+ 'advancedgradingdata' => new external_single_structure($advancedgradingdata, 'advanced grading data',
+ VALUE_DEFAULT, array())
+ )
+ )
+ )
+ )
+ );
+ }
+
+ /**
+ * Save multiple student grades for a single assignment.
+ *
+ * @param int $assignmentid The id of the assignment
+ * @param boolean $applytoall If set to true and this is a team assignment,
+ * apply the grade to all members of the group
+ * @param array $grades grade data for one or more students that includes
+ * userid - The id of the student being graded
+ * grade - The grade
+ * attemptnumber - The attempt number
+ * addattempt - Allow another attempt
+ * workflowstate - New workflow state
+ * plugindata - optional feedback data used by plugins
+ * advancedgradingdata - optional Advanced grading data
+ * @throws invalid_parameter_exception if multiple grades are supplied for
+ * a team assignment that has $applytoall set to true
+ * @return null
+ * @since Moodle 2.7
+ */
+ public static function save_grades($assignmentid, $applytoall = false, $grades) {
+ global $CFG, $USER;
+ require_once("$CFG->dirroot/mod/assign/locallib.php");
+
+ $params = self::validate_parameters(self::save_grades_parameters(),
+ array('assignmentid' => $assignmentid,
+ 'applytoall' => $applytoall,
+ 'grades' => $grades));
+
+ $cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST);
+ $context = context_module::instance($cm->id);
+
+ $assignment = new assign($context, $cm, null);
+ if ($assignment->get_instance()->teamsubmission && $applytoall) {
+ // Check that only 1 user per submission group is provided.
+ $groupids = array();
+ foreach ($grades as $gradeinfo) {
+ $group = $assignment->get_submission_group($gradeinfo['userid']);
+ if (in_array($group->id, $groupids)) {
+ throw new invalid_parameter_exception('Multiple grades for the same team have been supplied '
+ .' this is not permitted when the applytoall flag is set');
+ } else {
+ $groupids[] = $group->id;
+ }
+ }
+ }
+
+ foreach ($grades as $gradeinfo) {
+ $gradedata = (object)$gradeinfo['plugindata'];
+ $gradedata->addattempt = $gradeinfo['addattempt'];
+ $gradedata->attemptnumber = $gradeinfo['attemptnumber'];
+ $gradedata->workflowstate = $gradeinfo['workflowstate'];
+ $gradedata->applytoall = $applytoall;
+ $gradedata->grade = $gradeinfo['grade'];
+
+ if (!empty($gradeinfo['advancedgradingdata'])) {
+ $advancedgrading = array();
+ $criteria = reset($gradeinfo['advancedgradingdata']);
+ foreach ($criteria as $key => $criterion) {
+ $details = array();
+ foreach ($criterion as $value) {
+ foreach ($value['fillings'] as $filling) {
+ $details[$value['criterionid']] = $filling;
+ }
+ }
+ $advancedgrading[$key] = $details;
+ }
+ $gradedata->advancedgrading = $advancedgrading;
+ }
+ $assignment->save_grade($gradeinfo['userid'], $gradedata);
+ }
+
+ return null;
+ }
+
+ /**
+ * Describes the return value for save_grades
+ *
+ * @return external_single_structure
+ * @since Moodle 2.7
+ */
+ public static function save_grades_returns() {
+ return null;
+ }
+
/**
* Describes the parameters for copy_previous_attempt
* @return external_external_function_parameters
diff --git a/mod/assign/tests/externallib_test.php b/mod/assign/tests/externallib_test.php
index 5ab2faa7d6c..b27db1898bb 100644
--- a/mod/assign/tests/externallib_test.php
+++ b/mod/assign/tests/externallib_test.php
@@ -916,7 +916,7 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
$student1 = self::getDataGenerator()->create_user();
$student2 = self::getDataGenerator()->create_user();
- $studentrole = $DB->get_record('role', array('shortname'=>'student'));
+ $studentrole = $DB->get_record('role', array('shortname' => 'student'));
$this->getDataGenerator()->enrol_user($student1->id,
$course->id,
$studentrole->id);
@@ -945,8 +945,8 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
// Now try a grade.
$feedbackpluginparams = array();
$feedbackpluginparams['files_filemanager'] = $draftidfile;
- $feedbackeditorparams = array('text'=>'Yeeha!',
- 'format'=>1);
+ $feedbackeditorparams = array('text' => 'Yeeha!',
+ 'format' => 1);
$feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams;
$result = mod_assign_external::save_grade($instance->id,
$student1->id,
@@ -965,6 +965,299 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
$this->assertEquals($result['assignments'][0]['grades'][0]['grade'], '50.0');
}
+ /**
+ * Test save grades with advanced grading data
+ */
+ public function test_save_grades_with_advanced_grading() {
+ global $DB, $USER;
+
+ $this->resetAfterTest(true);
+ // Create a course and assignment and users.
+ $course = self::getDataGenerator()->create_course();
+
+ $teacher = self::getDataGenerator()->create_user();
+ $teacherrole = $DB->get_record('role', array('shortname' => 'teacher'));
+ $this->getDataGenerator()->enrol_user($teacher->id,
+ $course->id,
+ $teacherrole->id);
+
+ $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
+ $params['course'] = $course->id;
+ $params['assignfeedback_file_enabled'] = 0;
+ $params['assignfeedback_comments_enabled'] = 0;
+ $instance = $generator->create_instance($params);
+ $cm = get_coursemodule_from_instance('assign', $instance->id);
+ $context = context_module::instance($cm->id);
+
+ $assign = new assign($context, $cm, $course);
+
+ $student1 = self::getDataGenerator()->create_user();
+ $student2 = self::getDataGenerator()->create_user();
+ $studentrole = $DB->get_record('role', array('shortname' => 'student'));
+ $this->getDataGenerator()->enrol_user($student1->id,
+ $course->id,
+ $studentrole->id);
+ $this->getDataGenerator()->enrol_user($student2->id,
+ $course->id,
+ $studentrole->id);
+
+ $this->setUser($teacher);
+
+ $feedbackpluginparams = array();
+ $feedbackpluginparams['files_filemanager'] = 0;
+ $feedbackeditorparams = array('text' => '', 'format' => 1);
+ $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams;
+
+ // Create advanced grading data.
+ // Create grading area.
+ $gradingarea = array(
+ 'contextid' => $context->id,
+ 'component' => 'mod_assign',
+ 'areaname' => 'submissions',
+ 'activemethod' => 'rubric'
+ );
+ $areaid = $DB->insert_record('grading_areas', $gradingarea);
+
+ // Create a rubric grading definition.
+ $rubricdefinition = array (
+ 'areaid' => $areaid,
+ 'method' => 'rubric',
+ 'name' => 'test',
+ 'status' => 20,
+ 'copiedfromid' => 1,
+ 'timecreated' => 1,
+ 'usercreated' => $teacher->id,
+ 'timemodified' => 1,
+ 'usermodified' => $teacher->id,
+ 'timecopied' => 0
+ );
+ $definitionid = $DB->insert_record('grading_definitions', $rubricdefinition);
+
+ // Create a criterion with a level.
+ $rubriccriteria = array (
+ 'definitionid' => $definitionid,
+ 'sortorder' => 1,
+ 'description' => 'Demonstrate an understanding of disease control',
+ 'descriptionformat' => 0
+ );
+ $criterionid = $DB->insert_record('gradingform_rubric_criteria', $rubriccriteria);
+ $rubriclevel1 = array (
+ 'criterionid' => $criterionid,
+ 'score' => 50,
+ 'definition' => 'pass',
+ 'definitionformat' => 0
+ );
+ $rubriclevel2 = array (
+ 'criterionid' => $criterionid,
+ 'score' => 100,
+ 'definition' => 'excellent',
+ 'definitionformat' => 0
+ );
+ $rubriclevel3 = array (
+ 'criterionid' => $criterionid,
+ 'score' => 0,
+ 'definition' => 'fail',
+ 'definitionformat' => 0
+ );
+ $levelid1 = $DB->insert_record('gradingform_rubric_levels', $rubriclevel1);
+ $levelid2 = $DB->insert_record('gradingform_rubric_levels', $rubriclevel2);
+ $levelid3 = $DB->insert_record('gradingform_rubric_levels', $rubriclevel3);
+
+ // Create the filling.
+ $student1filling = array (
+ 'criterionid' => $criterionid,
+ 'levelid' => $levelid1,
+ 'remark' => 'well done you passed',
+ 'remarkformat' => 0
+ );
+
+ $student2filling = array (
+ 'criterionid' => $criterionid,
+ 'levelid' => $levelid2,
+ 'remark' => 'Excellent work',
+ 'remarkformat' => 0
+ );
+
+ $student1criteria = array(array('criterionid' => $criterionid, 'fillings' => array($student1filling)));
+ $student1advancedgradingdata = array('rubric' => array('criteria' => $student1criteria));
+
+ $student2criteria = array(array('criterionid' => $criterionid, 'fillings' => array($student2filling)));
+ $student2advancedgradingdata = array('rubric' => array('criteria' => $student2criteria));
+
+ $grades = array();
+ $student1gradeinfo = array();
+ $student1gradeinfo['userid'] = $student1->id;
+ $student1gradeinfo['grade'] = 0; // Ignored since advanced grading is being used.
+ $student1gradeinfo['attemptnumber'] = -1;
+ $student1gradeinfo['addattempt'] = true;
+ $student1gradeinfo['workflowstate'] = 'released';
+ $student1gradeinfo['plugindata'] = $feedbackpluginparams;
+ $student1gradeinfo['advancedgradingdata'] = $student1advancedgradingdata;
+ $grades[] = $student1gradeinfo;
+
+ $student2gradeinfo = array();
+ $student2gradeinfo['userid'] = $student2->id;
+ $student2gradeinfo['grade'] = 0; // Ignored since advanced grading is being used.
+ $student2gradeinfo['attemptnumber'] = -1;
+ $student2gradeinfo['addattempt'] = true;
+ $student2gradeinfo['workflowstate'] = 'released';
+ $student2gradeinfo['plugindata'] = $feedbackpluginparams;
+ $student2gradeinfo['advancedgradingdata'] = $student2advancedgradingdata;
+ $grades[] = $student2gradeinfo;
+
+ $result = mod_assign_external::save_grades($instance->id, false, $grades);
+ // No warnings.
+ $this->assertEquals(0, count($result));
+
+ $result = mod_assign_external::get_grades(array($instance->id));
+
+ $this->assertCount(2, $result['assignments'][0]['grades']);
+
+ foreach ($result['assignments'][0]['grades'] as $grade) {
+ if ($grade['userid'] == $student1->id) {
+ $this->assertEquals($grade['grade'], '50.0');
+ } else if ($grade['userid'] == $student2->id) {
+ $this->assertEquals($grade['grade'], '100.0');
+ } else {
+ $this->fail("Unexpected student id");
+ }
+ }
+ }
+
+ /**
+ * Test save grades for a team submission
+ */
+ public function test_save_grades_with_group_submission() {
+ global $DB, $USER, $CFG;
+ require_once($CFG->dirroot . '/group/lib.php');
+
+ $this->resetAfterTest(true);
+ // Create a course and assignment and users.
+ $course = self::getDataGenerator()->create_course();
+
+ $teacher = self::getDataGenerator()->create_user();
+ $teacherrole = $DB->get_record('role', array('shortname' => 'teacher'));
+ $this->getDataGenerator()->enrol_user($teacher->id,
+ $course->id,
+ $teacherrole->id);
+
+ $groupingdata = array();
+ $groupingdata['courseid'] = $course->id;
+ $groupingdata['name'] = 'Group assignment grouping';
+
+ $grouping = self::getDataGenerator()->create_grouping($groupingdata);
+
+ $group1data = array();
+ $group1data['courseid'] = $course->id;
+ $group1data['name'] = 'Team 1';
+ $group2data = array();
+ $group2data['courseid'] = $course->id;
+ $group2data['name'] = 'Team 2';
+
+ $group1 = self::getDataGenerator()->create_group($group1data);
+ $group2 = self::getDataGenerator()->create_group($group2data);
+
+ groups_assign_grouping($grouping->id, $group1->id);
+ groups_assign_grouping($grouping->id, $group2->id);
+
+ $generator = $this->getDataGenerator()->get_plugin_generator('mod_assign');
+ $params['course'] = $course->id;
+ $params['teamsubmission'] = 1;
+ $params['teamsubmissiongroupingid'] = $grouping->id;
+ $instance = $generator->create_instance($params);
+ $cm = get_coursemodule_from_instance('assign', $instance->id);
+ $context = context_module::instance($cm->id);
+
+ $assign = new assign($context, $cm, $course);
+
+ $student1 = self::getDataGenerator()->create_user();
+ $student2 = self::getDataGenerator()->create_user();
+ $student3 = self::getDataGenerator()->create_user();
+ $student4 = self::getDataGenerator()->create_user();
+ $studentrole = $DB->get_record('role', array('shortname' => 'student'));
+ $this->getDataGenerator()->enrol_user($student1->id,
+ $course->id,
+ $studentrole->id);
+ $this->getDataGenerator()->enrol_user($student2->id,
+ $course->id,
+ $studentrole->id);
+ $this->getDataGenerator()->enrol_user($student3->id,
+ $course->id,
+ $studentrole->id);
+ $this->getDataGenerator()->enrol_user($student4->id,
+ $course->id,
+ $studentrole->id);
+
+ groups_add_member($group1->id, $student1->id);
+ groups_add_member($group1->id, $student2->id);
+ groups_add_member($group1->id, $student3->id);
+ groups_add_member($group2->id, $student4->id);
+ $this->setUser($teacher);
+
+ $feedbackpluginparams = array();
+ $feedbackpluginparams['files_filemanager'] = 0;
+ $feedbackeditorparams = array('text' => '', 'format' => 1);
+ $feedbackpluginparams['assignfeedbackcomments_editor'] = $feedbackeditorparams;
+
+ $grades1 = array();
+ $student1gradeinfo = array();
+ $student1gradeinfo['userid'] = $student1->id;
+ $student1gradeinfo['grade'] = 50;
+ $student1gradeinfo['attemptnumber'] = -1;
+ $student1gradeinfo['addattempt'] = true;
+ $student1gradeinfo['workflowstate'] = 'released';
+ $student1gradeinfo['plugindata'] = $feedbackpluginparams;
+ $grades1[] = $student1gradeinfo;
+
+ $student2gradeinfo = array();
+ $student2gradeinfo['userid'] = $student2->id;
+ $student2gradeinfo['grade'] = 75;
+ $student2gradeinfo['attemptnumber'] = -1;
+ $student2gradeinfo['addattempt'] = true;
+ $student2gradeinfo['workflowstate'] = 'released';
+ $student2gradeinfo['plugindata'] = $feedbackpluginparams;
+ $grades1[] = $student2gradeinfo;
+
+ $this->setExpectedException('invalid_parameter_exception');
+ // Expect an exception since 2 grades have been submitted for the same team.
+ $result = mod_assign_external::save_grades($instance->id, true, $grades1);
+
+ $grades2 = array();
+ $student3gradeinfo = array();
+ $student3gradeinfo['userid'] = $student3->id;
+ $student3gradeinfo['grade'] = 50;
+ $student3gradeinfo['attemptnumber'] = -1;
+ $student3gradeinfo['addattempt'] = true;
+ $student3gradeinfo['workflowstate'] = 'released';
+ $student3gradeinfo['plugindata'] = $feedbackpluginparams;
+ $grades2[] = $student3gradeinfo;
+
+ $student4gradeinfo = array();
+ $student4gradeinfo['userid'] = $student4->id;
+ $student4gradeinfo['grade'] = 75;
+ $student4gradeinfo['attemptnumber'] = -1;
+ $student4gradeinfo['addattempt'] = true;
+ $student4gradeinfo['workflowstate'] = 'released';
+ $student4gradeinfo['plugindata'] = $feedbackpluginparams;
+ $grades2[] = $student4gradeinfo;
+ $result = mod_assign_external::save_grades($instance->id, true, $grades2);
+ // There should be no warnings.
+ $this->assertEquals(0, count($result));
+ $result = mod_assign_external::get_grades(array($instance->id));
+
+ $this->assertCount(2, $result['assignments'][0]['grades']);
+
+ foreach ($result['assignments'][0]['grades'] as $grade) {
+ if ($grade['userid'] == $student3->id) {
+ $this->assertEquals($grade['grade'], '50.0');
+ } else if ($grade['userid'] == $student4->id) {
+ $this->assertEquals($grade['grade'], '75.0');
+ } else {
+ $this->fail("Unexpected student id");
+ }
+ }
+ }
+
/**
* Test copy_previous_attempt
*/
diff --git a/mod/assign/upgrade.txt b/mod/assign/upgrade.txt
index 44c2f892be6..90c1205b059 100644
--- a/mod/assign/upgrade.txt
+++ b/mod/assign/upgrade.txt
@@ -1,5 +1,10 @@
This files describes API changes in the assign code.
+=== 2.7 ===
+* Web service function mod_assign_save_grade has an additional optional parameter $advancedgradingdata which allows
+ advanced grading data to be used.
+* A new web service function mod_assign_save_grades has been added which allows multiple grades to be processed.
+
=== 2.6 ===
* To see submission/grades of inactive users, user should have moodle/course:viewsuspendedusers capability.
* count_* functions will return only active participants.
diff --git a/mod/assign/version.php b/mod/assign/version.php
index 266f34f16e7..1e8f15b436f 100644
--- a/mod/assign/version.php
+++ b/mod/assign/version.php
@@ -25,7 +25,7 @@
defined('MOODLE_INTERNAL') || die();
$module->component = 'mod_assign'; // Full name of the plugin (used for diagnostics).
-$module->version = 2013110500; // The current module version (Date: YYYYMMDDXX).
+$module->version = 2013110501; // The current module version (Date: YYYYMMDDXX).
$module->requires = 2013110500; // Requires this Moodle version.
$module->cron = 60;
--
2.43.0