From c144959c4d8a8776f4e8e843dd641a0b2d19f0cc Mon Sep 17 00:00:00 2001
From: Paul Charsley
Date: Tue, 30 Oct 2012 15:15:25 +1300
Subject: [PATCH] MDL-31682 added mod_assign_get_submissions web service
function
---
mod/assign/db/services.php | 8 +
mod/assign/externallib.php | 241 ++++++++++++++++++++++++++
mod/assign/tests/externallib_test.php | 77 ++++++++
mod/assign/version.php | 2 +-
4 files changed, 327 insertions(+), 1 deletion(-)
diff --git a/mod/assign/db/services.php b/mod/assign/db/services.php
index b7fc5d13b80..4d8ab30f1e4 100644
--- a/mod/assign/db/services.php
+++ b/mod/assign/db/services.php
@@ -39,5 +39,13 @@ $functions = array(
'classpath' => 'mod/assign/externallib.php',
'description' => 'Returns the courses and assignments for the users capability',
'type' => 'read'
+ ),
+
+ 'mod_assign_get_submissions' => array(
+ 'classname' => 'mod_assign_external',
+ 'methodname' => 'get_submissions',
+ 'classpath' => 'mod/assign/externallib.php',
+ 'description' => 'Returns the submissions for assignments',
+ 'type' => 'read'
)
);
diff --git a/mod/assign/externallib.php b/mod/assign/externallib.php
index a7a2e80014e..00a055f0a2b 100644
--- a/mod/assign/externallib.php
+++ b/mod/assign/externallib.php
@@ -429,4 +429,245 @@ class mod_assign_external extends external_api {
)
);
}
+
+ /**
+ * Describes the parameters for get_submissions
+ *
+ * @return external_external_function_parameters
+ * @since Moodle 2.4
+ */
+ public static function get_submissions_parameters() {
+ return new external_function_parameters(
+ array(
+ 'assignmentids' => new external_multiple_structure(
+ new external_value(PARAM_INT, 'assignment id'),
+ '1 or more assignment ids',
+ VALUE_REQUIRED),
+ 'status' => new external_value(PARAM_ALPHA, 'status', VALUE_DEFAULT, ''),
+ 'since' => new external_value(PARAM_INT, 'submitted since', VALUE_DEFAULT, 0),
+ 'before' => new external_value(PARAM_INT, 'submitted before', VALUE_DEFAULT, 0)
+ )
+ );
+ }
+
+ /**
+ * Returns submissions for the requested assignment ids
+ *
+ * @param array of ints $assignmentids
+ * @param string $status only return submissions with this status
+ * @param int $since only return submissions with timemodified >= since
+ * @param int $before only return submissions with timemodified <= before
+ * @return array of submissions for each requested assignment
+ * @since Moodle 2.4
+ */
+ public static function get_submissions($assignmentids, $status = '', $since = 0, $before = 0) {
+ global $DB, $CFG;
+ require_once("$CFG->dirroot/mod/assign/locallib.php");
+ $params = self::validate_parameters(self::get_submissions_parameters(),
+ array('assignmentids' => $assignmentids,
+ 'status' => $status,
+ 'since' => $since,
+ 'before' => $before));
+
+ $warnings = array();
+ $assignments = array();
+
+ // Check the user is allowed to get the submissions for the assignments requested.
+ $placeholders = array();
+ list($inorequalsql, $placeholders) = $DB->get_in_or_equal($params['assignmentids'], SQL_PARAMS_NAMED);
+ $sql = "SELECT cm.id, cm.instance FROM {course_modules} cm JOIN {modules} md ON md.id = cm.module ".
+ "WHERE md.name = :modname AND cm.instance ".$inorequalsql;
+ $placeholders['modname'] = 'assign';
+ $cms = $DB->get_records_sql($sql, $placeholders);
+ $assigns = array();
+ foreach ($cms as $cm) {
+ try {
+ $context = context_module::instance($cm->id);
+ self::validate_context($context);
+ require_capability('mod/assign:grade', $context);
+ $assign = new assign($context, null, null);
+ $assigns[] = $assign;
+ } catch (Exception $e) {
+ $warnings[] = array(
+ 'item' => 'assignment',
+ 'itemid' => $cm->instance,
+ 'warningcode' => '1',
+ 'message' => 'No access rights in module context'
+ );
+ }
+ }
+
+ foreach ($assigns as $assign) {
+ $submissions = array();
+ $submissionplugins = $assign->get_submission_plugins();
+ $placeholders = array('assignment' => $assign->get_instance()->id);
+ $sql = "SELECT mas.id, mas.assignment,mas.userid,".
+ "mas.timecreated,mas.timemodified,mas.status,mas.groupid ".
+ "FROM {assign_submission} mas ".
+ "WHERE mas.assignment = :assignment";
+
+ if (!empty($params['status'])) {
+ $placeholders['status'] = $params['status'];
+ $sql = $sql." AND mas.status = :status";
+ }
+ if (!empty($params['before'])) {
+ $placeholders['since'] = $params['since'];
+ $placeholders['before'] = $params['before'];
+ $sql = $sql." AND mas.timemodified BETWEEN :since AND :before";
+ } else {
+ $placeholders['since'] = $params['since'];
+ $sql = $sql." AND mas.timemodified >= :since";
+ }
+
+ $submissionrecords = $DB->get_records_sql($sql, $placeholders);
+
+ if (!empty($submissionrecords)) {
+ $fs = get_file_storage();
+ foreach ($submissionrecords as $submissionrecord) {
+ $submission = array(
+ 'id' => $submissionrecord->id,
+ 'userid' => $submissionrecord->userid,
+ 'timecreated' => $submissionrecord->timecreated,
+ 'timemodified' => $submissionrecord->timemodified,
+ 'status' => $submissionrecord->status,
+ 'groupid' => $submissionrecord->groupid
+ );
+ foreach ($submissionplugins as $submissionplugin) {
+ $plugin = array(
+ 'name' => $submissionplugin->get_name(),
+ 'type' => $submissionplugin->get_type()
+ );
+ // Subtype is 'assignsubmission', type is currently 'file' or 'onlinetext'.
+ $component = $submissionplugin->get_subtype().'_'.$submissionplugin->get_type();
+
+ $fileareas = $submissionplugin->get_file_areas();
+ foreach ($fileareas as $filearea => $name) {
+ $fileareainfo = array('area' => $filearea);
+ $files = $fs->get_area_files(
+ $assign->get_context()->id,
+ $component,
+ $filearea,
+ $submissionrecord->id,
+ "timemodified",
+ false
+ );
+ foreach ($files as $file) {
+ $filepath = array('filepath' => $file->get_filepath().$file->get_filename());
+ $fileareainfo['files'][] = $filepath;
+ }
+ $plugin['fileareas'][] = $fileareainfo;
+ }
+
+ $editorfields = $submissionplugin->get_editor_fields();
+ foreach ($editorfields as $name => $description) {
+ $editorfieldinfo = array(
+ 'name' => $name,
+ 'description' => $description,
+ 'text' => $submissionplugin->get_editor_text($name, $submissionrecord->id),
+ 'format' => $submissionplugin->get_editor_format($name, $submissionrecord->id)
+ );
+ $plugin['editorfields'][] = $editorfieldinfo;
+ }
+
+ $submission['plugins'][] = $plugin;
+ }
+ $submissions[] = $submission;
+ }
+ } else {
+ $warnings[] = array(
+ 'item' => 'module',
+ 'itemid' => $assign->get_instance()->id,
+ 'warningcode' => '3',
+ 'message' => 'No submissions found'
+ );
+ }
+
+ $assignments[] = array(
+ 'assignmentid' => $assign->get_instance()->id,
+ 'submissions' => $submissions
+ );
+
+ }
+
+ $result = array(
+ 'assignments' => $assignments,
+ 'warnings' => $warnings
+ );
+ return $result;
+ }
+
+ /**
+ * Creates an assign_submissions external_single_structure
+ *
+ * @return external_single_structure
+ * @since Moodle 2.4
+ */
+ private static function get_submissions_structure() {
+ return new external_single_structure(
+ array (
+ 'assignmentid' => new external_value(PARAM_INT, 'assignment id'),
+ 'submissions' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'id' => new external_value(PARAM_INT, 'submission id'),
+ 'userid' => new external_value(PARAM_INT, 'student id'),
+ 'timecreated' => new external_value(PARAM_INT, 'submission creation time'),
+ 'timemodified' => new external_value(PARAM_INT, 'submission last modified time'),
+ 'status' => new external_value(PARAM_TEXT, 'submission status'),
+ 'groupid' => new external_value(PARAM_INT, 'group id'),
+ 'plugins' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'type' => new external_value(PARAM_TEXT, 'submission plugin type'),
+ 'name' => new external_value(PARAM_TEXT, 'submission plugin name'),
+ 'fileareas' => new external_multiple_structure(
+ new external_single_structure(
+ array (
+ 'area' => new external_value (PARAM_TEXT, 'file area'),
+ 'files' => new external_multiple_structure(
+ new external_single_structure(
+ array (
+ 'filepath' => new external_value (PARAM_TEXT, 'file path')
+ )
+ ), 'files', VALUE_OPTIONAL
+ )
+ )
+ ), 'fileareas', VALUE_OPTIONAL
+ ),
+ 'editorfields' => new external_multiple_structure(
+ new external_single_structure(
+ array(
+ 'name' => new external_value(PARAM_TEXT, 'field name'),
+ 'description' => new external_value(PARAM_TEXT, 'field description'),
+ 'text' => new external_value (PARAM_TEXT, 'field value'),
+ 'format' => new external_value (PARAM_INT, 'field format')
+ )
+ )
+ , 'editorfields', VALUE_OPTIONAL
+ )
+ )
+ )
+ , 'plugins', VALUE_OPTIONAL
+ )
+ )
+ )
+ )
+ )
+ );
+ }
+
+ /**
+ * Describes the get_submissions return value
+ *
+ * @return external_single_structure
+ * @since Moodle 2.4
+ */
+ public static function get_submissions_returns() {
+ return new external_single_structure(
+ array(
+ 'assignments' => new external_multiple_structure(self::get_submissions_structure(), 'assignment submissions'),
+ 'warnings' => new external_warnings()
+ )
+ );
+ }
}
diff --git a/mod/assign/tests/externallib_test.php b/mod/assign/tests/externallib_test.php
index 7ea9298158c..3e8399f7e4c 100644
--- a/mod/assign/tests/externallib_test.php
+++ b/mod/assign/tests/externallib_test.php
@@ -182,4 +182,81 @@ class mod_assign_external_testcase extends externallib_advanced_testcase {
$this->assertEquals(0, count($result['courses']));
$this->assertEquals(1, count($result['warnings']));
}
+
+ /**
+ * Test get_submissions
+ */
+ public function test_get_submissions () {
+ global $DB, $USER;
+
+ $this->resetAfterTest(true);
+ // Create a course and assignment.
+ $coursedata['idnumber'] = 'idnumbercourse1';
+ $coursedata['fullname'] = 'Lightwork Course 1';
+ $coursedata['summary'] = 'Lightwork Course 1 description';
+ $coursedata['summaryformat'] = FORMAT_MOODLE;
+ $course1 = self::getDataGenerator()->create_course($coursedata);
+
+ $assigndata['course'] = $course1->id;
+ $assigndata['name'] = 'lightwork assignment';
+
+ $assign1 = self::getDataGenerator()->create_module('assign', $assigndata);
+
+ // Create a student with an online text submission.
+ $student = self::getDataGenerator()->create_user();
+ $submission = new stdClass();
+ $submission->assignment = $assign1->id;
+ $submission->userid = $student->id;
+ $submission->timecreated = time();
+ $submission->timemodified = $submission->timecreated;
+ $submission->status = 'submitted';
+ $sid = $DB->insert_record('assign_submission', $submission);
+ $submission->id = $sid;
+
+ $onlinetextsubmission = new stdClass();
+ $onlinetextsubmission->onlinetext = "online test text";
+ $onlinetextsubmission->onlineformat = 1;
+ $onlinetextsubmission->submission = $submission->id;
+ $onlinetextsubmission->assignment = $assign1->id;
+ $DB->insert_record('assignsubmission_onlinetext', $onlinetextsubmission);
+
+ // Create manual enrolment record.
+ $manual_enrol_data['enrol'] = 'manual';
+ $manual_enrol_data['status'] = 0;
+ $manual_enrol_data['courseid'] = $course1->id;
+ $enrolid = $DB->insert_record('enrol', $manual_enrol_data);
+
+ // Create a teacher and give them capabilities.
+ $context = context_course::instance($course1->id);
+ $roleid = $this->assignUserCapability('moodle/course:viewparticipants', $context->id, 3);
+ $context = context_module::instance($assign1->id);
+ $this->assignUserCapability('mod/assign:grade', $context->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);
+
+ $assignmentids[] = $assign1->id;
+ $result = mod_assign_external::get_submissions($assignmentids);
+
+ // Check the online text submission is returned.
+ $this->assertEquals(1, count($result['assignments']));
+ $assignment = $result['assignments'][0];
+ $this->assertEquals($assign1->id, $assignment['assignmentid']);
+ $this->assertEquals(1, count($assignment['submissions']));
+ $submission = $assignment['submissions'][0];
+ $this->assertEquals($sid, $submission['id']);
+ $this->assertGreaterThanOrEqual(3, count($submission['plugins']));
+ $plugins = $submission['plugins'];
+ foreach ($plugins as $plugin) {
+ $foundonlinetext = false;
+ if ($plugin['type'] == 'onlinetext') {
+ $foundonlinetext = true;
+ break;
+ }
+ }
+ $this->assertTrue($foundonlinetext);
+ }
}
diff --git a/mod/assign/version.php b/mod/assign/version.php
index 10457b52ffd..863e1c25ff1 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 = 2012112900; // The current module version (Date: YYYYMMDDXX)
+$module->version = 2012112901; // The current module version (Date: YYYYMMDDXX)
$module->requires = 2012112900; // Requires this Moodle version
$module->cron = 60;