Commit | Line | Data |
---|---|---|
1f8c8f61 PC |
1 | <?php |
2 | // This file is part of Moodle - http://moodle.org/ | |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | /** | |
18 | * External assign API | |
19 | * | |
20 | * @package mod_assign | |
21 | * @since Moodle 2.4 | |
22 | * @copyright 2012 Paul Charsley | |
23 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
24 | */ | |
25 | ||
26 | defined('MOODLE_INTERNAL') || die; | |
27 | ||
28 | require_once("$CFG->libdir/externallib.php"); | |
29 | ||
30 | /** | |
31 | * Assign functions | |
32 | */ | |
33 | class mod_assign_external extends external_api { | |
34 | ||
35 | /** | |
36 | * Describes the parameters for get_grades | |
37 | * @return external_external_function_parameters | |
38 | * @since Moodle 2.4 | |
39 | */ | |
40 | public static function get_grades_parameters() { | |
41 | return new external_function_parameters( | |
42 | array( | |
43 | 'assignmentids' => new external_multiple_structure( | |
44 | new external_value(PARAM_INT, 'assignment id'), | |
45 | '1 or more assignment ids', | |
46 | VALUE_REQUIRED), | |
47 | 'since' => new external_value(PARAM_INT, | |
48 | 'timestamp, only return records where timemodified >= since', | |
49 | VALUE_DEFAULT, 0) | |
50 | ) | |
51 | ); | |
52 | } | |
53 | ||
54 | /** | |
55 | * Returns grade information from assign_grades for the requested assignment ids | |
56 | * @param array of ints $assignmentids | |
57 | * @param int $since only return records with timemodified >= since | |
58 | * @return array of grade records for each requested assignment | |
59 | * @since Moodle 2.4 | |
60 | */ | |
61 | public static function get_grades($assignmentids, $since = 0) { | |
62 | global $DB; | |
63 | $params = self::validate_parameters(self::get_grades_parameters(), | |
64 | array('assignmentids' => $assignmentids, | |
65 | 'since' => $since)); | |
66 | ||
67 | $assignments = array(); | |
68 | $warnings = array(); | |
69 | $requestedassignmentids = $params['assignmentids']; | |
70 | ||
71 | // Check the user is allowed to get the grades for the assignments requested. | |
72 | $placeholders = array(); | |
73 | list($sqlassignmentids, $placeholders) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); | |
74 | $sql = "SELECT cm.id, cm.instance FROM {course_modules} cm JOIN {modules} md ON md.id = cm.module ". | |
75 | "WHERE md.name = :modname AND cm.instance ".$sqlassignmentids; | |
76 | $placeholders['modname'] = 'assign'; | |
77 | $cms = $DB->get_records_sql($sql, $placeholders); | |
78 | foreach ($cms as $cm) { | |
79 | try { | |
80 | $context = context_module::instance($cm->id); | |
81 | self::validate_context($context); | |
82 | require_capability('mod/assign:grade', $context); | |
83 | } catch (Exception $e) { | |
84 | $requestedassignmentids = array_diff($requestedassignmentids, array($cm->instance)); | |
85 | $warning = array(); | |
86 | $warning['item'] = 'assignment'; | |
87 | $warning['itemid'] = $cm->instance; | |
88 | $warning['warningcode'] = '1'; | |
89 | $warning['message'] = 'No access rights in module context'; | |
90 | $warnings[] = $warning; | |
91 | } | |
92 | } | |
93 | ||
94 | // Create the query and populate an array of grade records from the recordset results. | |
95 | if (count ($requestedassignmentids) > 0) { | |
96 | $placeholders = array(); | |
97 | list($inorequalsql, $placeholders) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); | |
a13fbf5f DW |
98 | list($inorequalsql2, $placeholders2) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); |
99 | ||
100 | $grademaxattempt = 'SELECT mxg.userid, MAX(mxg.attemptnumber) AS maxattempt | |
101 | FROM {assign_grades} mxg | |
102 | WHERE mxg.assignment ' . $inorequalsql2 . ' GROUP BY mxg.userid'; | |
103 | ||
1f8c8f61 | 104 | $sql = "SELECT ag.id,ag.assignment,ag.userid,ag.timecreated,ag.timemodified,". |
df211804 | 105 | "ag.grader,ag.grade ". |
1f8c8f61 | 106 | "FROM {assign_grades} ag ". |
a13fbf5f DW |
107 | "JOIN ( " . $grademaxattempt . " ) gmx ON ag.userid = gmx.userid". |
108 | " WHERE ag.assignment ".$inorequalsql. | |
1f8c8f61 | 109 | " AND ag.timemodified >= :since". |
a13fbf5f | 110 | " AND ag.attemptnumber = gmx.maxattempt" . |
1f8c8f61 PC |
111 | " ORDER BY ag.assignment, ag.id"; |
112 | $placeholders['since'] = $params['since']; | |
a13fbf5f DW |
113 | // Combine the parameters. |
114 | $placeholders += $placeholders2; | |
1f8c8f61 PC |
115 | $rs = $DB->get_recordset_sql($sql, $placeholders); |
116 | $currentassignmentid = null; | |
117 | $assignment = null; | |
118 | foreach ($rs as $rd) { | |
119 | $grade = array(); | |
120 | $grade['id'] = $rd->id; | |
121 | $grade['userid'] = $rd->userid; | |
122 | $grade['timecreated'] = $rd->timecreated; | |
123 | $grade['timemodified'] = $rd->timemodified; | |
124 | $grade['grader'] = $rd->grader; | |
125 | $grade['grade'] = (string)$rd->grade; | |
1f8c8f61 PC |
126 | |
127 | if (is_null($currentassignmentid) || ($rd->assignment != $currentassignmentid )) { | |
128 | if (!is_null($assignment)) { | |
129 | $assignments[] = $assignment; | |
130 | } | |
131 | $assignment = array(); | |
132 | $assignment['assignmentid'] = $rd->assignment; | |
133 | $assignment['grades'] = array(); | |
134 | $requestedassignmentids = array_diff($requestedassignmentids, array($rd->assignment)); | |
135 | } | |
136 | $assignment['grades'][] = $grade; | |
137 | ||
138 | $currentassignmentid = $rd->assignment; | |
139 | } | |
140 | if (!is_null($assignment)) { | |
141 | $assignments[] = $assignment; | |
142 | } | |
143 | $rs->close(); | |
144 | } | |
145 | foreach ($requestedassignmentids as $assignmentid) { | |
146 | $warning = array(); | |
147 | $warning['item'] = 'assignment'; | |
148 | $warning['itemid'] = $assignmentid; | |
149 | $warning['warningcode'] = '3'; | |
150 | $warning['message'] = 'No grades found'; | |
151 | $warnings[] = $warning; | |
152 | } | |
153 | ||
154 | $result = array(); | |
155 | $result['assignments'] = $assignments; | |
156 | $result['warnings'] = $warnings; | |
157 | return $result; | |
158 | } | |
159 | ||
160 | /** | |
161 | * Creates an assign_grades external_single_structure | |
162 | * @return external_single_structure | |
163 | * @since Moodle 2.4 | |
164 | */ | |
165 | private static function assign_grades() { | |
166 | return new external_single_structure( | |
167 | array ( | |
168 | 'assignmentid' => new external_value(PARAM_INT, 'assignment id'), | |
169 | 'grades' => new external_multiple_structure(new external_single_structure( | |
170 | array( | |
171 | 'id' => new external_value(PARAM_INT, 'grade id'), | |
172 | 'userid' => new external_value(PARAM_INT, 'student id'), | |
173 | 'timecreated' => new external_value(PARAM_INT, 'grade creation time'), | |
174 | 'timemodified' => new external_value(PARAM_INT, 'grade last modified time'), | |
175 | 'grader' => new external_value(PARAM_INT, 'grader'), | |
df211804 | 176 | 'grade' => new external_value(PARAM_TEXT, 'grade') |
1f8c8f61 PC |
177 | ) |
178 | ) | |
179 | ) | |
180 | ) | |
181 | ); | |
182 | } | |
183 | ||
184 | /** | |
185 | * Describes the get_grades return value | |
186 | * @return external_single_structure | |
187 | * @since Moodle 2.4 | |
188 | */ | |
189 | public static function get_grades_returns() { | |
190 | return new external_single_structure( | |
191 | array( | |
192 | 'assignments' => new external_multiple_structure(self::assign_grades(), 'list of assignment grade information'), | |
8118dbd0 | 193 | 'warnings' => new external_warnings('item is always \'assignment\'', |
b0da618b | 194 | 'when errorcode is 3 then itemid is an assignment id. When errorcode is 1, itemid is a course module id', |
8118dbd0 | 195 | 'errorcode can be 3 (no grades found) or 1 (no permission to get grades)') |
1f8c8f61 PC |
196 | ) |
197 | ); | |
198 | } | |
199 | ||
1378838e PC |
200 | /** |
201 | * Returns description of method parameters | |
2ea4312a | 202 | * |
1378838e PC |
203 | * @return external_function_parameters |
204 | * @since Moodle 2.4 | |
205 | */ | |
206 | public static function get_assignments_parameters() { | |
207 | return new external_function_parameters( | |
208 | array( | |
209 | 'courseids' => new external_multiple_structure( | |
210 | new external_value(PARAM_INT, 'course id'), | |
211 | '0 or more course ids', | |
212 | VALUE_DEFAULT, array() | |
213 | ), | |
214 | 'capabilities' => new external_multiple_structure( | |
215 | new external_value(PARAM_CAPABILITY, 'capability'), | |
216 | 'list of capabilities used to filter courses', | |
217 | VALUE_DEFAULT, array() | |
218 | ) | |
219 | ) | |
220 | ); | |
221 | } | |
222 | ||
223 | /** | |
224 | * Returns an array of courses the user is enrolled in, and for each course all of the assignments that the user can | |
225 | * view within that course. | |
2ea4312a | 226 | * |
1378838e PC |
227 | * @param array $courseids An optional array of course ids. If provided only assignments within the given course |
228 | * will be returned. If the user is not enrolled in a given course a warning will be generated and returned. | |
229 | * @param array $capabilities An array of additional capability checks you wish to be made on the course context. | |
230 | * @return An array of courses and warnings. | |
231 | * @since Moodle 2.4 | |
232 | */ | |
233 | public static function get_assignments($courseids = array(), $capabilities = array()) { | |
234 | global $USER, $DB; | |
235 | ||
236 | $params = self::validate_parameters( | |
237 | self::get_assignments_parameters(), | |
238 | array('courseids' => $courseids, 'capabilities' => $capabilities) | |
239 | ); | |
240 | ||
241 | $warnings = array(); | |
242 | $fields = 'sortorder,shortname,fullname,timemodified'; | |
243 | $courses = enrol_get_users_courses($USER->id, true, $fields); | |
244 | // Used to test for ids that have been requested but can't be returned. | |
245 | if (count($params['courseids']) > 0) { | |
246 | foreach ($params['courseids'] as $courseid) { | |
247 | if (!in_array($courseid, array_keys($courses))) { | |
248 | unset($courses[$courseid]); | |
249 | $warnings[] = array( | |
250 | 'item' => 'course', | |
251 | 'itemid' => $courseid, | |
252 | 'warningcode' => '2', | |
253 | 'message' => 'User is not enrolled or does not have requested capability' | |
254 | ); | |
255 | } | |
256 | } | |
257 | } | |
258 | foreach ($courses as $id => $course) { | |
259 | if (count($params['courseids']) > 0 && !in_array($id, $params['courseids'])) { | |
260 | unset($courses[$id]); | |
261 | } | |
262 | $context = context_course::instance($id); | |
263 | try { | |
264 | self::validate_context($context); | |
1378838e PC |
265 | } catch (Exception $e) { |
266 | unset($courses[$id]); | |
267 | $warnings[] = array( | |
268 | 'item' => 'course', | |
269 | 'itemid' => $id, | |
270 | 'warningcode' => '1', | |
271 | 'message' => 'No access rights in course context '.$e->getMessage().$e->getTraceAsString() | |
272 | ); | |
273 | continue; | |
274 | } | |
275 | if (count($params['capabilities']) > 0 && !has_all_capabilities($params['capabilities'], $context)) { | |
276 | unset($courses[$id]); | |
277 | } | |
278 | } | |
279 | $extrafields='m.id as assignmentid, m.course, m.nosubmissions, m.submissiondrafts, m.sendnotifications, '. | |
280 | 'm.sendlatenotifications, m.duedate, m.allowsubmissionsfromdate, m.grade, m.timemodified, '. | |
281 | 'm.completionsubmit, m.cutoffdate, m.teamsubmission, m.requireallteammemberssubmit, '. | |
282 | 'm.teamsubmissiongroupingid, m.blindmarking, m.revealidentities, m.requiresubmissionstatement'; | |
283 | $coursearray = array(); | |
284 | foreach ($courses as $id => $course) { | |
285 | $assignmentarray = array(); | |
286 | // Get a list of assignments for the course. | |
287 | if ($modules = get_coursemodules_in_course('assign', $courses[$id]->id, $extrafields)) { | |
288 | foreach ($modules as $module) { | |
289 | $context = context_module::instance($module->id); | |
290 | try { | |
291 | self::validate_context($context); | |
292 | require_capability('mod/assign:view', $context); | |
293 | } catch (Exception $e) { | |
294 | $warnings[] = array( | |
295 | 'item' => 'module', | |
296 | 'itemid' => $module->id, | |
297 | 'warningcode' => '1', | |
298 | 'message' => 'No access rights in module context' | |
299 | ); | |
300 | continue; | |
301 | } | |
302 | $configrecords = $DB->get_recordset('assign_plugin_config', array('assignment' => $module->assignmentid)); | |
303 | $configarray = array(); | |
304 | foreach ($configrecords as $configrecord) { | |
305 | $configarray[] = array( | |
306 | 'id' => $configrecord->id, | |
307 | 'assignment' => $configrecord->assignment, | |
308 | 'plugin' => $configrecord->plugin, | |
309 | 'subtype' => $configrecord->subtype, | |
310 | 'name' => $configrecord->name, | |
311 | 'value' => $configrecord->value | |
312 | ); | |
313 | } | |
314 | $configrecords->close(); | |
315 | ||
316 | $assignmentarray[]= array( | |
317 | 'id' => $module->assignmentid, | |
318 | 'cmid' => $module->id, | |
319 | 'course' => $module->course, | |
320 | 'name' => $module->name, | |
321 | 'nosubmissions' => $module->nosubmissions, | |
322 | 'submissiondrafts' => $module->submissiondrafts, | |
323 | 'sendnotifications' => $module->sendnotifications, | |
324 | 'sendlatenotifications' => $module->sendlatenotifications, | |
325 | 'duedate' => $module->duedate, | |
326 | 'allowsubmissionsfromdate' => $module->allowsubmissionsfromdate, | |
327 | 'grade' => $module->grade, | |
328 | 'timemodified' => $module->timemodified, | |
329 | 'completionsubmit' => $module->completionsubmit, | |
330 | 'cutoffdate' => $module->cutoffdate, | |
331 | 'teamsubmission' => $module->teamsubmission, | |
332 | 'requireallteammemberssubmit' => $module->requireallteammemberssubmit, | |
333 | 'teamsubmissiongroupingid' => $module->teamsubmissiongroupingid, | |
334 | 'blindmarking' => $module->blindmarking, | |
335 | 'revealidentities' => $module->revealidentities, | |
336 | 'requiresubmissionstatement' => $module->requiresubmissionstatement, | |
337 | 'configs' => $configarray | |
338 | ); | |
339 | } | |
340 | } | |
341 | $coursearray[]= array( | |
342 | 'id' => $courses[$id]->id, | |
343 | 'fullname' => $courses[$id]->fullname, | |
344 | 'shortname' => $courses[$id]->shortname, | |
345 | 'timemodified' => $courses[$id]->timemodified, | |
346 | 'assignments' => $assignmentarray | |
347 | ); | |
348 | } | |
349 | ||
350 | $result = array( | |
351 | 'courses' => $coursearray, | |
352 | 'warnings' => $warnings | |
353 | ); | |
354 | return $result; | |
355 | } | |
356 | ||
357 | /** | |
358 | * Creates an assignment external_single_structure | |
2ea4312a | 359 | * |
1378838e PC |
360 | * @return external_single_structure |
361 | * @since Moodle 2.4 | |
362 | */ | |
363 | private static function get_assignments_assignment_structure() { | |
364 | return new external_single_structure( | |
365 | array( | |
366 | 'id' => new external_value(PARAM_INT, 'assignment id'), | |
367 | 'course' => new external_value(PARAM_INT, 'course id'), | |
368 | 'name' => new external_value(PARAM_TEXT, 'assignment name'), | |
369 | 'nosubmissions' => new external_value(PARAM_INT, 'no submissions'), | |
370 | 'submissiondrafts' => new external_value(PARAM_INT, 'submissions drafts'), | |
371 | 'sendnotifications' => new external_value(PARAM_INT, 'send notifications'), | |
372 | 'sendlatenotifications' => new external_value(PARAM_INT, 'send notifications'), | |
373 | 'duedate' => new external_value(PARAM_INT, 'assignment due date'), | |
374 | 'allowsubmissionsfromdate' => new external_value(PARAM_INT, 'allow submissions from date'), | |
375 | 'grade' => new external_value(PARAM_INT, 'grade type'), | |
376 | 'timemodified' => new external_value(PARAM_INT, 'last time assignment was modified'), | |
377 | 'completionsubmit' => new external_value(PARAM_INT, 'if enabled, set activity as complete following submission'), | |
378 | 'cutoffdate' => new external_value(PARAM_INT, 'date after which submission is not accepted without an extension'), | |
379 | 'teamsubmission' => new external_value(PARAM_INT, 'if enabled, students submit as a team'), | |
380 | 'requireallteammemberssubmit' => new external_value(PARAM_INT, 'if enabled, all team members must submit'), | |
381 | 'teamsubmissiongroupingid' => new external_value(PARAM_INT, 'the grouping id for the team submission groups'), | |
382 | 'blindmarking' => new external_value(PARAM_INT, 'if enabled, hide identities until reveal identities actioned'), | |
383 | 'revealidentities' => new external_value(PARAM_INT, 'show identities for a blind marking assignment'), | |
384 | 'requiresubmissionstatement' => new external_value(PARAM_INT, 'student must accept submission statement'), | |
385 | 'configs' => new external_multiple_structure(self::get_assignments_config_structure(), 'configuration settings') | |
386 | ), 'assignment information object'); | |
387 | } | |
388 | ||
389 | /** | |
390 | * Creates an assign_plugin_config external_single_structure | |
2ea4312a | 391 | * |
1378838e PC |
392 | * @return external_single_structure |
393 | * @since Moodle 2.4 | |
394 | */ | |
395 | private static function get_assignments_config_structure() { | |
396 | return new external_single_structure( | |
397 | array( | |
398 | 'id' => new external_value(PARAM_INT, 'assign_plugin_config id'), | |
399 | 'assignment' => new external_value(PARAM_INT, 'assignment id'), | |
400 | 'plugin' => new external_value(PARAM_TEXT, 'plugin'), | |
401 | 'subtype' => new external_value(PARAM_TEXT, 'subtype'), | |
402 | 'name' => new external_value(PARAM_TEXT, 'name'), | |
403 | 'value' => new external_value(PARAM_TEXT, 'value') | |
404 | ), 'assignment configuration object' | |
405 | ); | |
406 | } | |
407 | ||
408 | /** | |
409 | * Creates a course external_single_structure | |
2ea4312a | 410 | * |
1378838e | 411 | * @return external_single_structure |
2ea4312a | 412 | * @since Moodle 2.4 |
1378838e PC |
413 | */ |
414 | private static function get_assignments_course_structure() { | |
415 | return new external_single_structure( | |
416 | array( | |
417 | 'id' => new external_value(PARAM_INT, 'course id'), | |
418 | 'fullname' => new external_value(PARAM_TEXT, 'course full name'), | |
419 | 'shortname' => new external_value(PARAM_TEXT, 'course short name'), | |
420 | 'timemodified' => new external_value(PARAM_INT, 'last time modified'), | |
421 | 'assignments' => new external_multiple_structure(self::get_assignments_assignment_structure(), 'assignment info') | |
422 | ), 'course information object' | |
423 | ); | |
424 | } | |
425 | ||
2ea4312a | 426 | /** |
1378838e | 427 | * Describes the return value for get_assignments |
2ea4312a | 428 | * |
1378838e PC |
429 | * @return external_single_structure |
430 | * @since Moodle 2.4 | |
431 | */ | |
432 | public static function get_assignments_returns() { | |
433 | return new external_single_structure( | |
434 | array( | |
435 | 'courses' => new external_multiple_structure(self::get_assignments_course_structure(), 'list of courses'), | |
8118dbd0 JM |
436 | 'warnings' => new external_warnings('item can be \'course\' (errorcode 1 or 2) or \'module\' (errorcode 1)', |
437 | 'When item is a course then itemid is a course id. When the item is a module then itemid is a module id', | |
438 | 'errorcode can be 1 (no access rights) or 2 (not enrolled or no permissions)') | |
1378838e PC |
439 | ) |
440 | ); | |
441 | } | |
c144959c PC |
442 | |
443 | /** | |
444 | * Describes the parameters for get_submissions | |
445 | * | |
446 | * @return external_external_function_parameters | |
2d971403 | 447 | * @since Moodle 2.5 |
c144959c PC |
448 | */ |
449 | public static function get_submissions_parameters() { | |
450 | return new external_function_parameters( | |
451 | array( | |
452 | 'assignmentids' => new external_multiple_structure( | |
453 | new external_value(PARAM_INT, 'assignment id'), | |
454 | '1 or more assignment ids', | |
455 | VALUE_REQUIRED), | |
456 | 'status' => new external_value(PARAM_ALPHA, 'status', VALUE_DEFAULT, ''), | |
457 | 'since' => new external_value(PARAM_INT, 'submitted since', VALUE_DEFAULT, 0), | |
458 | 'before' => new external_value(PARAM_INT, 'submitted before', VALUE_DEFAULT, 0) | |
459 | ) | |
460 | ); | |
461 | } | |
462 | ||
463 | /** | |
464 | * Returns submissions for the requested assignment ids | |
465 | * | |
466 | * @param array of ints $assignmentids | |
467 | * @param string $status only return submissions with this status | |
468 | * @param int $since only return submissions with timemodified >= since | |
469 | * @param int $before only return submissions with timemodified <= before | |
470 | * @return array of submissions for each requested assignment | |
2d971403 | 471 | * @since Moodle 2.5 |
c144959c PC |
472 | */ |
473 | public static function get_submissions($assignmentids, $status = '', $since = 0, $before = 0) { | |
474 | global $DB, $CFG; | |
475 | require_once("$CFG->dirroot/mod/assign/locallib.php"); | |
476 | $params = self::validate_parameters(self::get_submissions_parameters(), | |
477 | array('assignmentids' => $assignmentids, | |
478 | 'status' => $status, | |
479 | 'since' => $since, | |
480 | 'before' => $before)); | |
481 | ||
482 | $warnings = array(); | |
483 | $assignments = array(); | |
484 | ||
485 | // Check the user is allowed to get the submissions for the assignments requested. | |
486 | $placeholders = array(); | |
487 | list($inorequalsql, $placeholders) = $DB->get_in_or_equal($params['assignmentids'], SQL_PARAMS_NAMED); | |
488 | $sql = "SELECT cm.id, cm.instance FROM {course_modules} cm JOIN {modules} md ON md.id = cm.module ". | |
489 | "WHERE md.name = :modname AND cm.instance ".$inorequalsql; | |
490 | $placeholders['modname'] = 'assign'; | |
491 | $cms = $DB->get_records_sql($sql, $placeholders); | |
492 | $assigns = array(); | |
493 | foreach ($cms as $cm) { | |
494 | try { | |
495 | $context = context_module::instance($cm->id); | |
496 | self::validate_context($context); | |
497 | require_capability('mod/assign:grade', $context); | |
498 | $assign = new assign($context, null, null); | |
499 | $assigns[] = $assign; | |
500 | } catch (Exception $e) { | |
501 | $warnings[] = array( | |
502 | 'item' => 'assignment', | |
503 | 'itemid' => $cm->instance, | |
504 | 'warningcode' => '1', | |
505 | 'message' => 'No access rights in module context' | |
506 | ); | |
507 | } | |
508 | } | |
509 | ||
510 | foreach ($assigns as $assign) { | |
511 | $submissions = array(); | |
512 | $submissionplugins = $assign->get_submission_plugins(); | |
a13fbf5f DW |
513 | $placeholders = array('assignid1' => $assign->get_instance()->id, |
514 | 'assignid2' => $assign->get_instance()->id); | |
515 | ||
516 | $submissionmaxattempt = 'SELECT mxs.userid, MAX(mxs.attemptnumber) AS maxattempt | |
517 | FROM {assign_submission} mxs | |
518 | WHERE mxs.assignment = :assignid1 GROUP BY mxs.userid'; | |
519 | ||
c144959c PC |
520 | $sql = "SELECT mas.id, mas.assignment,mas.userid,". |
521 | "mas.timecreated,mas.timemodified,mas.status,mas.groupid ". | |
522 | "FROM {assign_submission} mas ". | |
a13fbf5f DW |
523 | "JOIN ( " . $submissionmaxattempt . " ) smx ON mas.userid = smx.userid ". |
524 | "WHERE mas.assignment = :assignid2 AND mas.attemptnumber = smx.maxattempt"; | |
c144959c PC |
525 | |
526 | if (!empty($params['status'])) { | |
527 | $placeholders['status'] = $params['status']; | |
528 | $sql = $sql." AND mas.status = :status"; | |
529 | } | |
530 | if (!empty($params['before'])) { | |
531 | $placeholders['since'] = $params['since']; | |
532 | $placeholders['before'] = $params['before']; | |
533 | $sql = $sql." AND mas.timemodified BETWEEN :since AND :before"; | |
534 | } else { | |
535 | $placeholders['since'] = $params['since']; | |
536 | $sql = $sql." AND mas.timemodified >= :since"; | |
537 | } | |
538 | ||
539 | $submissionrecords = $DB->get_records_sql($sql, $placeholders); | |
540 | ||
541 | if (!empty($submissionrecords)) { | |
542 | $fs = get_file_storage(); | |
543 | foreach ($submissionrecords as $submissionrecord) { | |
544 | $submission = array( | |
545 | 'id' => $submissionrecord->id, | |
546 | 'userid' => $submissionrecord->userid, | |
547 | 'timecreated' => $submissionrecord->timecreated, | |
548 | 'timemodified' => $submissionrecord->timemodified, | |
549 | 'status' => $submissionrecord->status, | |
550 | 'groupid' => $submissionrecord->groupid | |
551 | ); | |
552 | foreach ($submissionplugins as $submissionplugin) { | |
553 | $plugin = array( | |
554 | 'name' => $submissionplugin->get_name(), | |
555 | 'type' => $submissionplugin->get_type() | |
556 | ); | |
557 | // Subtype is 'assignsubmission', type is currently 'file' or 'onlinetext'. | |
558 | $component = $submissionplugin->get_subtype().'_'.$submissionplugin->get_type(); | |
559 | ||
560 | $fileareas = $submissionplugin->get_file_areas(); | |
561 | foreach ($fileareas as $filearea => $name) { | |
562 | $fileareainfo = array('area' => $filearea); | |
563 | $files = $fs->get_area_files( | |
564 | $assign->get_context()->id, | |
565 | $component, | |
566 | $filearea, | |
567 | $submissionrecord->id, | |
568 | "timemodified", | |
569 | false | |
570 | ); | |
571 | foreach ($files as $file) { | |
572 | $filepath = array('filepath' => $file->get_filepath().$file->get_filename()); | |
573 | $fileareainfo['files'][] = $filepath; | |
574 | } | |
575 | $plugin['fileareas'][] = $fileareainfo; | |
576 | } | |
577 | ||
578 | $editorfields = $submissionplugin->get_editor_fields(); | |
579 | foreach ($editorfields as $name => $description) { | |
580 | $editorfieldinfo = array( | |
581 | 'name' => $name, | |
582 | 'description' => $description, | |
583 | 'text' => $submissionplugin->get_editor_text($name, $submissionrecord->id), | |
584 | 'format' => $submissionplugin->get_editor_format($name, $submissionrecord->id) | |
585 | ); | |
586 | $plugin['editorfields'][] = $editorfieldinfo; | |
587 | } | |
588 | ||
589 | $submission['plugins'][] = $plugin; | |
590 | } | |
591 | $submissions[] = $submission; | |
592 | } | |
593 | } else { | |
594 | $warnings[] = array( | |
595 | 'item' => 'module', | |
596 | 'itemid' => $assign->get_instance()->id, | |
597 | 'warningcode' => '3', | |
598 | 'message' => 'No submissions found' | |
599 | ); | |
600 | } | |
601 | ||
602 | $assignments[] = array( | |
603 | 'assignmentid' => $assign->get_instance()->id, | |
604 | 'submissions' => $submissions | |
605 | ); | |
606 | ||
607 | } | |
608 | ||
609 | $result = array( | |
610 | 'assignments' => $assignments, | |
611 | 'warnings' => $warnings | |
612 | ); | |
613 | return $result; | |
614 | } | |
615 | ||
616 | /** | |
617 | * Creates an assign_submissions external_single_structure | |
618 | * | |
619 | * @return external_single_structure | |
2d971403 | 620 | * @since Moodle 2.5 |
c144959c PC |
621 | */ |
622 | private static function get_submissions_structure() { | |
623 | return new external_single_structure( | |
624 | array ( | |
625 | 'assignmentid' => new external_value(PARAM_INT, 'assignment id'), | |
626 | 'submissions' => new external_multiple_structure( | |
627 | new external_single_structure( | |
628 | array( | |
629 | 'id' => new external_value(PARAM_INT, 'submission id'), | |
630 | 'userid' => new external_value(PARAM_INT, 'student id'), | |
631 | 'timecreated' => new external_value(PARAM_INT, 'submission creation time'), | |
632 | 'timemodified' => new external_value(PARAM_INT, 'submission last modified time'), | |
633 | 'status' => new external_value(PARAM_TEXT, 'submission status'), | |
634 | 'groupid' => new external_value(PARAM_INT, 'group id'), | |
635 | 'plugins' => new external_multiple_structure( | |
636 | new external_single_structure( | |
637 | array( | |
638 | 'type' => new external_value(PARAM_TEXT, 'submission plugin type'), | |
639 | 'name' => new external_value(PARAM_TEXT, 'submission plugin name'), | |
640 | 'fileareas' => new external_multiple_structure( | |
641 | new external_single_structure( | |
642 | array ( | |
643 | 'area' => new external_value (PARAM_TEXT, 'file area'), | |
644 | 'files' => new external_multiple_structure( | |
645 | new external_single_structure( | |
646 | array ( | |
647 | 'filepath' => new external_value (PARAM_TEXT, 'file path') | |
648 | ) | |
649 | ), 'files', VALUE_OPTIONAL | |
650 | ) | |
651 | ) | |
652 | ), 'fileareas', VALUE_OPTIONAL | |
653 | ), | |
654 | 'editorfields' => new external_multiple_structure( | |
655 | new external_single_structure( | |
656 | array( | |
657 | 'name' => new external_value(PARAM_TEXT, 'field name'), | |
658 | 'description' => new external_value(PARAM_TEXT, 'field description'), | |
9f780282 DP |
659 | 'text' => new external_value (PARAM_RAW, 'field value'), |
660 | 'format' => new external_format_value ('text') | |
c144959c PC |
661 | ) |
662 | ) | |
663 | , 'editorfields', VALUE_OPTIONAL | |
664 | ) | |
665 | ) | |
666 | ) | |
667 | , 'plugins', VALUE_OPTIONAL | |
668 | ) | |
669 | ) | |
670 | ) | |
671 | ) | |
672 | ) | |
673 | ); | |
674 | } | |
675 | ||
676 | /** | |
677 | * Describes the get_submissions return value | |
678 | * | |
679 | * @return external_single_structure | |
2d971403 | 680 | * @since Moodle 2.5 |
c144959c PC |
681 | */ |
682 | public static function get_submissions_returns() { | |
683 | return new external_single_structure( | |
684 | array( | |
685 | 'assignments' => new external_multiple_structure(self::get_submissions_structure(), 'assignment submissions'), | |
686 | 'warnings' => new external_warnings() | |
687 | ) | |
688 | ); | |
689 | } | |
1f8c8f61 | 690 | } |