Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

MDL-31890 added core_grading_get_gradingform_instances web service

function
  • Loading branch information...
commit 9028d9b513fa2e6f673ab875bb53a8056778d21b 1 parent ee78814
pcharsle pcharsle authored
181 grade/externallib.php
View
@@ -15,9 +15,9 @@
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
- * External assign API
+ * External grading API
*
- * @package core_grade
+ * @package core_grading
* @since Moodle 2.5
* @copyright 2013 Paul Charsley
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
@@ -29,9 +29,9 @@
require_once("$CFG->dirroot/grade/grading/lib.php");
/**
- * core grade functions
+ * core grading functions
*/
-class core_grade_external extends external_api {
+class core_grading_external extends external_api {
/**
* Describes the parameters for get_definitions
@@ -290,4 +290,177 @@ private static function get_grading_methods() {
return $methods;
}
+ /**
+ * Describes the parameters for get_gradingform_instances
+ *
+ * @return external_function_parameters
+ * @since Moodle 2.6
+ */
+ public static function get_gradingform_instances_parameters () {
+ return new external_function_parameters(
+ array(
+ 'definitionid' => new external_value(PARAM_INT, 'definition id'),
+ 'since' => new external_value(PARAM_INT, 'submitted since', VALUE_DEFAULT, 0)
+ )
+ );
+ }
+
+ /**
+ * Returns the instances and fillings for the requested definition id
+ *
+ * @param int $definitionid
+ * @param int $since only return instances with timemodified >= since
+ * @return array of grading instances with fillings for the definition id
+ * @since Moodle 2.6
+ */
+ public static function get_gradingform_instances ($definitionid, $since = 0) {
+ global $DB, $CFG;
+ require_once("$CFG->dirroot/grade/grading/form/lib.php");
+ $params = self::validate_parameters(self::get_gradingform_instances_parameters(),
+ array('definitionid' => $definitionid,
+ 'since' => $since));
+ $instances = array();
+ $warnings = array();
+
+ $definition = $DB->get_record('grading_definitions',
+ array('id' => $params['definitionid']),
+ 'areaid,method', MUST_EXIST);
+ $area = $DB->get_record('grading_areas',
+ array('id' => $definition->areaid),
+ 'contextid,component', MUST_EXIST);
+
+ $context = context::instance_by_id($area->contextid);
+ require_capability('moodle/grade:managegradingforms', $context);
+
+ $gradingmanager = get_grading_manager($definition->areaid);
+ $controller = $gradingmanager->get_controller($definition->method);
+ $activeinstances = $controller->get_all_active_instances ($params['since']);
+ $details = $controller->get_external_instance_filling_details();
+ if ($details == null) {
+ $warnings[] = array(
+ 'item' => 'definition',
+ 'itemid' => $params['definitionid'],
+ 'message' => 'Fillings unavailable because get_external_instance_filling_details is not defined',
+ 'warningcode' => '1'
+ );
+ }
+ $getfilling = null;
+ if (method_exists('gradingform_'.$definition->method.'_instance', 'get_'.$definition->method.'_filling')) {
+ $getfilling = 'get_'.$definition->method.'_filling';
+ } else {
+ $warnings[] = array(
+ 'item' => 'definition',
+ 'itemid' => $params['definitionid'],
+ 'message' => 'Fillings unavailable because get_'.$definition->method.'_filling is not defined',
+ 'warningcode' => '1'
+ );
+ }
+ foreach ($activeinstances as $activeinstance) {
+ $instance = array();
+ $instance['id'] = $activeinstance->get_id();
+ $instance['raterid'] = $activeinstance->get_data('raterid');
+ $instance['itemid'] = $activeinstance->get_data('itemid');
+ $instance['rawgrade'] = $activeinstance->get_data('rawgrade');
+ $instance['status'] = $activeinstance->get_data('status');
+ $instance['feedback'] = $activeinstance->get_data('feedback');
+ $instance['feedbackformat'] = $activeinstance->get_data('feedbackformat');
+ // Format the feedback text field.
+ $formattedtext = external_format_text($activeinstance->get_data('feedback'),
+ $activeinstance->get_data('feedbackformat'),
+ $context->id,
+ $area->component,
+ 'feedback',
+ $params['definitionid']);
+ $instance['feedback'] = $formattedtext[0];
+ $instance['feedbackformat'] = $formattedtext[1];
+ $instance['timemodified'] = $activeinstance->get_data('timemodified');
+
+ if ($details != null && $getfilling != null) {
+ $fillingdata = $activeinstance->$getfilling();
+ $filling = array();
+ foreach ($details as $key => $value) {
+ $filling[$key] = self::format_text($fillingdata[$key],
+ $context->id,
+ $area->component,
+ $params['definitionid']);
+ }
+ $instance[$definition->method] = $filling;
+ }
+ $instances[] = $instance;
+ }
+ $result = array(
+ 'instances' => $instances,
+ 'warnings' => $warnings
+ );
+ return $result;
+ }
+
+ /**
+ * Creates a grading instance
+ *
+ * @return external_single_structure
+ * @since Moodle 2.6
+ */
+ private static function grading_instance() {
+ global $CFG;
+ $instance = array();
+ $instance['id'] = new external_value(PARAM_INT, 'instance id');
+ $instance['raterid'] = new external_value(PARAM_INT, 'rater id');
+ $instance['itemid'] = new external_value(PARAM_INT, 'item id');
+ $instance['rawgrade'] = new external_value(PARAM_TEXT, 'raw grade', VALUE_OPTIONAL);
+ $instance['status'] = new external_value(PARAM_INT, 'status');
+ $instance['feedback'] = new external_value(PARAM_RAW, 'feedback', VALUE_OPTIONAL);
+ $instance['feedbackformat'] = new external_format_value('feedback', VALUE_OPTIONAL);
+ $instance['timemodified'] = new external_value(PARAM_INT, 'modified time');
+ foreach (self::get_grading_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 ($details != null) {
+ $items = array();
+ foreach ($details as $key => $value) {
+ $details[$key]->required = VALUE_OPTIONAL;
+ $items[$key] = $value;
+ }
+ $instance[$method] = new external_single_structure($items, 'items', VALUE_OPTIONAL);
+ }
+ }
+ return new external_single_structure($instance);
+ }
+
+ /**
+ * Describes the get_gradingform_instances return value
+ *
+ * @return external_single_structure
+ * @since Moodle 2.6
+ */
+ public static function get_gradingform_instances_returns () {
+ return new external_single_structure(
+ array(
+ 'instances' => new external_multiple_structure(self::grading_instance(), 'list of grading instances'),
+ 'warnings' => new external_warnings()
+ )
+ );
+ }
+
+}
+
+/**
+ * @since Moodle 2.6
+ * @deprecated See MDL-30085. Please do not use this class any more.
+ * @see core_grading_external
+ */
+class core_grade_external extends external_api {
+
+ public static function get_definitions_parameters () {
+ return core_grading_external::get_definitions_parameters();
+ }
+
+ public static function get_definitions ($cmids, $areaname, $activeonly = false) {
+ return core_grading_external::get_definitions($cmids, $areaname, $activeonly = false);
+ }
+
+ public static function get_definitions_returns() {
+ return core_grading_external::get_definitions_returns();
+ }
+
}
25 grade/grading/form/guide/lib.php
View
@@ -683,6 +683,31 @@ public static function get_external_definition_details() {
);
return array('guide_criteria' => $guide_criteria, 'guide_comment' => $guide_comment);
}
+
+ /**
+ * Returns an array that defines the structure of the guide's filling. This function is used by
+ * the web service function core_grading_external::get_gradingform_instances().
+ *
+ * @return An array containing a single key/value pair with the 'criteria' external_multiple_structure
+ * @see gradingform_controller::get_external_instance_filling_details()
+ * @since Moodle 2.6
+ */
+ public static function get_external_instance_filling_details() {
+ $criteria = new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'id' => new external_value(PARAM_INT, 'filling id'),
+ 'criterionid' => new external_value(PARAM_INT, 'criterion id'),
+ 'levelid' => new external_value(PARAM_INT, 'level id', VALUE_OPTIONAL),
+ 'remark' => new external_value(PARAM_RAW, 'remark', VALUE_OPTIONAL),
+ 'remarkformat' => new external_format_value('remark', VALUE_OPTIONAL),
+ 'score' => new external_value(PARAM_FLOAT, 'maximum score')
+ )
+ ), 'filling', VALUE_OPTIONAL
+ );
+ return array ('criteria' => $criteria);
+ }
+
}
/**
39 grade/grading/form/lib.php
View
@@ -432,6 +432,27 @@ public function get_active_instances($itemid) {
}
/**
+ * Returns an array of all active instances for this definition.
+ * (intentionally does not return instances with status NEEDUPDATE)
+ *
+ * @param int since only return instances with timemodified >= since
+ * @return array of gradingform_instance objects
+ */
+ public function get_all_active_instances($since = 0) {
+ global $DB;
+ $conditions = array ($this->definition->id,
+ gradingform_instance::INSTANCE_STATUS_ACTIVE,
+ $since);
+ $where = "definitionid = ? AND status = ? AND timemodified >= ?";
+ $records = $DB->get_records_select('grading_instances', $where, $conditions);
+ $rv = array();
+ foreach ($records as $record) {
+ $rv[] = $this->get_instance($record);
+ }
+ return $rv;
+ }
+
+ /**
* Returns true if there are already people who has been graded on this definition.
* In this case plugins may restrict changes of the grading definition
*
@@ -680,6 +701,24 @@ public function render_grade($page, $itemid, $gradinginfo, $defaultcontent, $can
public static function get_external_definition_details() {
return null;
}
+
+ /**
+ * Overridden by sub classes that wish to make instance filling details available to web services.
+ * When not overridden, only instance filling data common to all grading methods is made available.
+ * When overriding, the return value should be an array containing one or more key/value pairs.
+ * These key/value pairs should match the filling data returned by the get_<method>_filling() function
+ * in the gradingform_instance subclass.
+ * For examples, look at:
+ * $gradingform_rubric_controller->get_external_instance_filling_details()
+ * $gradingform_guide_controller->get_external_instance_filling_details()
+ *
+ * @return array An array of one or more key/value pairs containing the external_multiple_structure/s
+ * corresponding to the definition returned by $gradingform_<method>_instance->get_<method>_filling()
+ * @since Moodle 2.6
+ */
+ public static function get_external_instance_filling_details() {
+ return null;
+ }
}
/**
23 grade/grading/form/rubric/lib.php
View
@@ -688,6 +688,29 @@ public static function get_external_definition_details() {
return array('rubric_criteria' => $rubric_criteria);
}
+ /**
+ * Returns an array that defines the structure of the rubric's filling. This function is used by
+ * the web service function core_grading_external::get_gradingform_instances().
+ *
+ * @return An array containing a single key/value pair with the 'criteria' external_multiple_structure
+ * @see gradingform_controller::get_external_instance_filling_details()
+ * @since Moodle 2.6
+ */
+ public static function get_external_instance_filling_details() {
+ $criteria = new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'id' => new external_value(PARAM_INT, 'filling id'),
+ 'criterionid' => new external_value(PARAM_INT, 'criterion id'),
+ 'levelid' => new external_value(PARAM_INT, 'level id', VALUE_OPTIONAL),
+ 'remark' => new external_value(PARAM_RAW, 'remark', VALUE_OPTIONAL),
+ 'remarkformat' => new external_format_value('remark', VALUE_OPTIONAL)
+ )
+ ), 'filling', VALUE_OPTIONAL
+ );
+ return array ('criteria' => $criteria);
+ }
+
}
/**
149 grade/tests/externallib_test.php
View
@@ -21,14 +21,14 @@
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
- * External core grade functions unit tests
+ * Unit tests for the grading API at /grade/externallib.php
*
- * @package core_grade
+ * @package core_grading
* @category external
* @copyright 2013 Paul Charsley
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-class core_grade_externallib_testcase extends externallib_advanced_testcase {
+class core_grading_externallib_testcase extends externallib_advanced_testcase {
/**
* Tests set up
@@ -58,10 +58,10 @@ public function test_get_definitions () {
$cm = self::getDataGenerator()->create_module('assign', $assigndata);
// Create manual enrolment record.
- $manual_enrol_data['enrol'] = 'manual';
- $manual_enrol_data['status'] = 0;
- $manual_enrol_data['courseid'] = $course->id;
- $enrolid = $DB->insert_record('enrol', $manual_enrol_data);
+ $manualenroldata['enrol'] = 'manual';
+ $manualenroldata['status'] = 0;
+ $manualenroldata['courseid'] = $course->id;
+ $enrolid = $DB->insert_record('enrol', $manualenroldata);
// Create a teacher and give them capabilities.
$coursecontext = context_course::instance($course->id);
@@ -70,10 +70,10 @@ public function test_get_definitions () {
$this->assignUserCapability('mod/assign:grade', $modulecontext->id, $roleid);
// Create the teacher's enrolment record.
- $user_enrolment_data['status'] = 0;
- $user_enrolment_data['enrolid'] = $enrolid;
- $user_enrolment_data['userid'] = $USER->id;
- $DB->insert_record('user_enrolments', $user_enrolment_data);
+ $userenrolmentdata['status'] = 0;
+ $userenrolmentdata['enrolid'] = $enrolid;
+ $userenrolmentdata['userid'] = $USER->id;
+ $DB->insert_record('user_enrolments', $userenrolmentdata);
// Create a grading area.
$gradingarea = array(
@@ -148,7 +148,7 @@ public function test_get_definitions () {
// Call the external function.
$cmids = array ($cm->id);
$areaname = 'submissions';
- $result = core_grade_external::get_definitions($cmids, $areaname);
+ $result = core_grading_external::get_definitions($cmids, $areaname);
$this->assertEquals(1, count($result['areas']));
$this->assertEquals(1, count($result['areas'][0]['definitions']));
@@ -181,4 +181,129 @@ public function test_get_definitions () {
$this->assertTrue($found);
}
+ /**
+ * Test get_gradingform_instances
+ */
+ public function test_get_gradingform_instances () {
+ global $DB, $CFG, $USER;
+
+ $this->resetAfterTest(true);
+ // Create a course and assignment.
+ $coursedata['idnumber'] = 'idnumbercourse';
+ $coursedata['fullname'] = 'Lightwork Course';
+ $coursedata['summary'] = 'Lightwork Course description';
+ $coursedata['summaryformat'] = FORMAT_MOODLE;
+ $course = self::getDataGenerator()->create_course($coursedata);
+
+ $assigndata['course'] = $course->id;
+ $assigndata['name'] = 'lightwork assignment';
+
+ $assign = self::getDataGenerator()->create_module('assign', $assigndata);
+
+ // Create manual enrolment record.
+ $manualenroldata['enrol'] = 'manual';
+ $manualenroldata['status'] = 0;
+ $manualenroldata['courseid'] = $course->id;
+ $enrolid = $DB->insert_record('enrol', $manualenroldata);
+
+ // Create a teacher and give them capabilities.
+ $coursecontext = context_course::instance($course->id);
+ $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $coursecontext->id, 3);
+ $modulecontext = context_module::instance($assign->id);
+ $this->assignUserCapability('mod/assign:grade', $modulecontext->id, $roleid);
+
+ // Create the teacher's enrolment record.
+ $userenrolmentdata['status'] = 0;
+ $userenrolmentdata['enrolid'] = $enrolid;
+ $userenrolmentdata['userid'] = $USER->id;
+ $DB->insert_record('user_enrolments', $userenrolmentdata);
+
+ // Create a student with an assignment grade.
+ $student = self::getDataGenerator()->create_user();
+ $assigngrade = new stdClass();
+ $assigngrade->assignment = $assign->id;
+ $assigngrade->userid = $student->id;
+ $assigngrade->timecreated = time();
+ $assigngrade->timemodified = $assigngrade->timecreated;
+ $assigngrade->grader = $USER->id;
+ $assigngrade->grade = 50;
+ $assigngrade->attemptnumber = 0;
+ $gid = $DB->insert_record('assign_grades', $assigngrade);
+
+ // Create a grading area.
+ $gradingarea = array(
+ 'contextid' => $modulecontext->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' => $USER->id,
+ 'timemodified' => 1,
+ 'usermodified' => $USER->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);
+ $rubriclevel = array (
+ 'criterionid' => $criterionid,
+ 'score' => 50,
+ 'definition' => 'pass',
+ 'definitionformat' => 0
+ );
+ $levelid = $DB->insert_record('gradingform_rubric_levels', $rubriclevel);
+
+ // Create a grading instance.
+ $instance = array (
+ 'definitionid' => $definitionid,
+ 'raterid' => $USER->id,
+ 'itemid' => $gid,
+ 'status' => 1,
+ 'feedbackformat' => 0,
+ 'timemodified' => 1
+ );
+ $instanceid = $DB->insert_record('grading_instances', $instance);
+
+ // Create a filling.
+ $filling = array (
+ 'instanceid' => $instanceid,
+ 'criterionid' => $criterionid,
+ 'levelid' => $levelid,
+ 'remark' => 'excellent work',
+ 'remarkformat' => 0
+ );
+ $DB->insert_record('gradingform_rubric_fillings', $filling);
+
+ // Call the external function.
+ $result = core_grading_external::get_gradingform_instances($definitionid, 0);
+
+ $this->assertEquals(1, count($result['instances']));
+ $this->assertEquals($USER->id, $result['instances'][0]['raterid']);
+ $this->assertEquals($gid, $result['instances'][0]['itemid']);
+ $this->assertEquals(1, $result['instances'][0]['status']);
+ $this->assertEquals(1, $result['instances'][0]['timemodified']);
+ $this->assertEquals(1, count($result['instances'][0]['rubric']));
+ $this->assertEquals(1, count($result['instances'][0]['rubric']['criteria']));
+ $criteria = $result['instances'][0]['rubric']['criteria'];
+ $this->assertEquals($criterionid, $criteria[$criterionid]['criterionid']);
+ $this->assertEquals($levelid, $criteria[$criterionid]['levelid']);
+ $this->assertEquals('excellent work', $criteria[$criterionid]['remark']);
+ }
}
20 lib/db/services.php
View
@@ -782,13 +782,29 @@
'capabilities'=> 'moodle/notes:manage',
),
- // === grade related functions ===
+ // === grading related functions ===
+
+ 'core_grading_get_definitions' => array(
+ 'classname' => 'core_grading_external',
+ 'methodname' => 'get_definitions',
+ 'classpath' => 'grade/externallib.php',
+ 'description' => 'Get grading definitions',
+ 'type' => 'read'
+ ),
'core_grade_get_definitions' => array(
'classname' => 'core_grade_external',
'methodname' => 'get_definitions',
'classpath' => 'grade/externallib.php',
- 'description' => 'Get grading definitions',
+ 'description' => 'DEPRECATED: this deprecated function will be removed in a future version. This function has been renamed as core_grading_get_definitions()',
+ 'type' => 'read'
+ ),
+
+ 'core_grading_get_gradingform_instances' => array(
+ 'classname' => 'core_grading_external',
+ 'methodname' => 'get_gradingform_instances',
+ 'classpath' => 'grade/externallib.php',
+ 'description' => 'Get grading form instances',
'type' => 'read'
),
Please sign in to comment.
Something went wrong with that request. Please try again.