[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 * @copyright 2012 Paul Charsley 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class mod_assign_external extends external_api { 36 37 /** 38 * Generate a warning in a standard structure for a known failure. 39 * 40 * @param int $assignmentid - The assignment 41 * @param string $warningcode - The key for the warning message 42 * @param string $detail - A description of the error 43 * @return array - Warning structure containing item, itemid, warningcode, message 44 */ 45 private static function generate_warning($assignmentid, $warningcode, $detail) { 46 $warningmessages = array( 47 'couldnotlock'=>'Could not lock the submission for this user.', 48 'couldnotunlock'=>'Could not unlock the submission for this user.', 49 'couldnotsubmitforgrading'=>'Could not submit assignment for grading.', 50 'couldnotrevealidentities'=>'Could not reveal identities.', 51 'couldnotgrantextensions'=>'Could not grant submission date extensions.', 52 'couldnotrevert'=>'Could not revert submission to draft.', 53 'invalidparameters'=>'Invalid parameters.', 54 'couldnotsavesubmission'=>'Could not save submission.', 55 'couldnotsavegrade'=>'Could not save grade.' 56 ); 57 58 $message = $warningmessages[$warningcode]; 59 if (empty($message)) { 60 $message = 'Unknown warning type.'; 61 } 62 63 return array('item'=>$detail, 64 'itemid'=>$assignmentid, 65 'warningcode'=>$warningcode, 66 'message'=>$message); 67 } 68 69 /** 70 * Describes the parameters for get_grades 71 * @return external_external_function_parameters 72 * @since Moodle 2.4 73 */ 74 public static function get_grades_parameters() { 75 return new external_function_parameters( 76 array( 77 'assignmentids' => new external_multiple_structure( 78 new external_value(PARAM_INT, 'assignment id'), 79 '1 or more assignment ids', 80 VALUE_REQUIRED), 81 'since' => new external_value(PARAM_INT, 82 'timestamp, only return records where timemodified >= since', 83 VALUE_DEFAULT, 0) 84 ) 85 ); 86 } 87 88 /** 89 * Returns grade information from assign_grades for the requested assignment ids 90 * @param int[] $assignmentids 91 * @param int $since only return records with timemodified >= since 92 * @return array of grade records for each requested assignment 93 * @since Moodle 2.4 94 */ 95 public static function get_grades($assignmentids, $since = 0) { 96 global $DB; 97 $params = self::validate_parameters(self::get_grades_parameters(), 98 array('assignmentids' => $assignmentids, 99 'since' => $since)); 100 101 $assignments = array(); 102 $warnings = array(); 103 $requestedassignmentids = $params['assignmentids']; 104 105 // Check the user is allowed to get the grades for the assignments requested. 106 $placeholders = array(); 107 list($sqlassignmentids, $placeholders) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); 108 $sql = "SELECT cm.id, cm.instance FROM {course_modules} cm JOIN {modules} md ON md.id = cm.module ". 109 "WHERE md.name = :modname AND cm.instance ".$sqlassignmentids; 110 $placeholders['modname'] = 'assign'; 111 $cms = $DB->get_records_sql($sql, $placeholders); 112 foreach ($cms as $cm) { 113 try { 114 $context = context_module::instance($cm->id); 115 self::validate_context($context); 116 require_capability('mod/assign:grade', $context); 117 } catch (Exception $e) { 118 $requestedassignmentids = array_diff($requestedassignmentids, array($cm->instance)); 119 $warning = array(); 120 $warning['item'] = 'assignment'; 121 $warning['itemid'] = $cm->instance; 122 $warning['warningcode'] = '1'; 123 $warning['message'] = 'No access rights in module context'; 124 $warnings[] = $warning; 125 } 126 } 127 128 // Create the query and populate an array of grade records from the recordset results. 129 if (count ($requestedassignmentids) > 0) { 130 $placeholders = array(); 131 list($inorequalsql, $placeholders) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); 132 133 $sql = "SELECT ag.id, 134 ag.assignment, 135 ag.userid, 136 ag.timecreated, 137 ag.timemodified, 138 ag.grader, 139 ag.grade, 140 ag.attemptnumber 141 FROM {assign_grades} ag, {assign_submission} s 142 WHERE s.assignment $inorequalsql 143 AND s.userid = ag.userid 144 AND s.latest = 1 145 AND s.attemptnumber = ag.attemptnumber 146 AND ag.timemodified >= :since 147 AND ag.assignment = s.assignment 148 ORDER BY ag.assignment, ag.id"; 149 150 $placeholders['since'] = $params['since']; 151 $rs = $DB->get_recordset_sql($sql, $placeholders); 152 $currentassignmentid = null; 153 $assignment = null; 154 foreach ($rs as $rd) { 155 $grade = array(); 156 $grade['id'] = $rd->id; 157 $grade['userid'] = $rd->userid; 158 $grade['timecreated'] = $rd->timecreated; 159 $grade['timemodified'] = $rd->timemodified; 160 $grade['grader'] = $rd->grader; 161 $grade['attemptnumber'] = $rd->attemptnumber; 162 $grade['grade'] = (string)$rd->grade; 163 164 if (is_null($currentassignmentid) || ($rd->assignment != $currentassignmentid )) { 165 if (!is_null($assignment)) { 166 $assignments[] = $assignment; 167 } 168 $assignment = array(); 169 $assignment['assignmentid'] = $rd->assignment; 170 $assignment['grades'] = array(); 171 $requestedassignmentids = array_diff($requestedassignmentids, array($rd->assignment)); 172 } 173 $assignment['grades'][] = $grade; 174 175 $currentassignmentid = $rd->assignment; 176 } 177 if (!is_null($assignment)) { 178 $assignments[] = $assignment; 179 } 180 $rs->close(); 181 } 182 foreach ($requestedassignmentids as $assignmentid) { 183 $warning = array(); 184 $warning['item'] = 'assignment'; 185 $warning['itemid'] = $assignmentid; 186 $warning['warningcode'] = '3'; 187 $warning['message'] = 'No grades found'; 188 $warnings[] = $warning; 189 } 190 191 $result = array(); 192 $result['assignments'] = $assignments; 193 $result['warnings'] = $warnings; 194 return $result; 195 } 196 197 /** 198 * Creates an assign_grades external_single_structure 199 * @return external_single_structure 200 * @since Moodle 2.4 201 */ 202 private static function assign_grades() { 203 return new external_single_structure( 204 array ( 205 'assignmentid' => new external_value(PARAM_INT, 'assignment id'), 206 'grades' => new external_multiple_structure(new external_single_structure( 207 array( 208 'id' => new external_value(PARAM_INT, 'grade id'), 209 'userid' => new external_value(PARAM_INT, 'student id'), 210 'attemptnumber' => new external_value(PARAM_INT, 'attempt number'), 211 'timecreated' => new external_value(PARAM_INT, 'grade creation time'), 212 'timemodified' => new external_value(PARAM_INT, 'grade last modified time'), 213 'grader' => new external_value(PARAM_INT, 'grader'), 214 'grade' => new external_value(PARAM_TEXT, 'grade') 215 ) 216 ) 217 ) 218 ) 219 ); 220 } 221 222 /** 223 * Describes the get_grades return value 224 * @return external_single_structure 225 * @since Moodle 2.4 226 */ 227 public static function get_grades_returns() { 228 return new external_single_structure( 229 array( 230 'assignments' => new external_multiple_structure(self::assign_grades(), 'list of assignment grade information'), 231 'warnings' => new external_warnings('item is always \'assignment\'', 232 'when errorcode is 3 then itemid is an assignment id. When errorcode is 1, itemid is a course module id', 233 'errorcode can be 3 (no grades found) or 1 (no permission to get grades)') 234 ) 235 ); 236 } 237 238 /** 239 * Returns description of method parameters 240 * 241 * @return external_function_parameters 242 * @since Moodle 2.4 243 */ 244 public static function get_assignments_parameters() { 245 return new external_function_parameters( 246 array( 247 'courseids' => new external_multiple_structure( 248 new external_value(PARAM_INT, 'course id'), 249 '0 or more course ids', 250 VALUE_DEFAULT, array() 251 ), 252 'capabilities' => new external_multiple_structure( 253 new external_value(PARAM_CAPABILITY, 'capability'), 254 'list of capabilities used to filter courses', 255 VALUE_DEFAULT, array() 256 ) 257 ) 258 ); 259 } 260 261 /** 262 * Returns an array of courses the user is enrolled in, and for each course all of the assignments that the user can 263 * view within that course. 264 * 265 * @param array $courseids An optional array of course ids. If provided only assignments within the given course 266 * will be returned. If the user is not enrolled in a given course a warning will be generated and returned. 267 * @param array $capabilities An array of additional capability checks you wish to be made on the course context. 268 * @return An array of courses and warnings. 269 * @since Moodle 2.4 270 */ 271 public static function get_assignments($courseids = array(), $capabilities = array()) { 272 global $USER, $DB; 273 274 $params = self::validate_parameters( 275 self::get_assignments_parameters(), 276 array('courseids' => $courseids, 'capabilities' => $capabilities) 277 ); 278 279 $warnings = array(); 280 $fields = 'sortorder,shortname,fullname,timemodified'; 281 $courses = enrol_get_users_courses($USER->id, true, $fields); 282 // Used to test for ids that have been requested but can't be returned. 283 if (count($params['courseids']) > 0) { 284 foreach ($params['courseids'] as $courseid) { 285 if (!in_array($courseid, array_keys($courses))) { 286 unset($courses[$courseid]); 287 $warnings[] = array( 288 'item' => 'course', 289 'itemid' => $courseid, 290 'warningcode' => '2', 291 'message' => 'User is not enrolled or does not have requested capability' 292 ); 293 } 294 } 295 } 296 foreach ($courses as $id => $course) { 297 if (count($params['courseids']) > 0 && !in_array($id, $params['courseids'])) { 298 unset($courses[$id]); 299 } 300 $context = context_course::instance($id); 301 try { 302 self::validate_context($context); 303 } catch (Exception $e) { 304 unset($courses[$id]); 305 $warnings[] = array( 306 'item' => 'course', 307 'itemid' => $id, 308 'warningcode' => '1', 309 'message' => 'No access rights in course context '.$e->getMessage().$e->getTraceAsString() 310 ); 311 continue; 312 } 313 if (count($params['capabilities']) > 0 && !has_all_capabilities($params['capabilities'], $context)) { 314 unset($courses[$id]); 315 } 316 } 317 $extrafields='m.id as assignmentid, ' . 318 'm.course, ' . 319 'm.nosubmissions, ' . 320 'm.submissiondrafts, ' . 321 'm.sendnotifications, '. 322 'm.sendlatenotifications, ' . 323 'm.sendstudentnotifications, ' . 324 'm.duedate, ' . 325 'm.allowsubmissionsfromdate, '. 326 'm.grade, ' . 327 'm.timemodified, '. 328 'm.completionsubmit, ' . 329 'm.cutoffdate, ' . 330 'm.teamsubmission, ' . 331 'm.requireallteammemberssubmit, '. 332 'm.teamsubmissiongroupingid, ' . 333 'm.blindmarking, ' . 334 'm.revealidentities, ' . 335 'm.attemptreopenmethod, '. 336 'm.maxattempts, ' . 337 'm.markingworkflow, ' . 338 'm.markingallocation, ' . 339 'm.requiresubmissionstatement'; 340 $coursearray = array(); 341 foreach ($courses as $id => $course) { 342 $assignmentarray = array(); 343 // Get a list of assignments for the course. 344 if ($modules = get_coursemodules_in_course('assign', $courses[$id]->id, $extrafields)) { 345 foreach ($modules as $module) { 346 $context = context_module::instance($module->id); 347 try { 348 self::validate_context($context); 349 require_capability('mod/assign:view', $context); 350 } catch (Exception $e) { 351 $warnings[] = array( 352 'item' => 'module', 353 'itemid' => $module->id, 354 'warningcode' => '1', 355 'message' => 'No access rights in module context' 356 ); 357 continue; 358 } 359 $configrecords = $DB->get_recordset('assign_plugin_config', array('assignment' => $module->assignmentid)); 360 $configarray = array(); 361 foreach ($configrecords as $configrecord) { 362 $configarray[] = array( 363 'id' => $configrecord->id, 364 'assignment' => $configrecord->assignment, 365 'plugin' => $configrecord->plugin, 366 'subtype' => $configrecord->subtype, 367 'name' => $configrecord->name, 368 'value' => $configrecord->value 369 ); 370 } 371 $configrecords->close(); 372 373 $assignmentarray[]= array( 374 'id' => $module->assignmentid, 375 'cmid' => $module->id, 376 'course' => $module->course, 377 'name' => $module->name, 378 'nosubmissions' => $module->nosubmissions, 379 'submissiondrafts' => $module->submissiondrafts, 380 'sendnotifications' => $module->sendnotifications, 381 'sendlatenotifications' => $module->sendlatenotifications, 382 'sendstudentnotifications' => $module->sendstudentnotifications, 383 'duedate' => $module->duedate, 384 'allowsubmissionsfromdate' => $module->allowsubmissionsfromdate, 385 'grade' => $module->grade, 386 'timemodified' => $module->timemodified, 387 'completionsubmit' => $module->completionsubmit, 388 'cutoffdate' => $module->cutoffdate, 389 'teamsubmission' => $module->teamsubmission, 390 'requireallteammemberssubmit' => $module->requireallteammemberssubmit, 391 'teamsubmissiongroupingid' => $module->teamsubmissiongroupingid, 392 'blindmarking' => $module->blindmarking, 393 'revealidentities' => $module->revealidentities, 394 'attemptreopenmethod' => $module->attemptreopenmethod, 395 'maxattempts' => $module->maxattempts, 396 'markingworkflow' => $module->markingworkflow, 397 'markingallocation' => $module->markingallocation, 398 'requiresubmissionstatement' => $module->requiresubmissionstatement, 399 'configs' => $configarray 400 ); 401 } 402 } 403 $coursearray[]= array( 404 'id' => $courses[$id]->id, 405 'fullname' => $courses[$id]->fullname, 406 'shortname' => $courses[$id]->shortname, 407 'timemodified' => $courses[$id]->timemodified, 408 'assignments' => $assignmentarray 409 ); 410 } 411 412 $result = array( 413 'courses' => $coursearray, 414 'warnings' => $warnings 415 ); 416 return $result; 417 } 418 419 /** 420 * Creates an assignment external_single_structure 421 * 422 * @return external_single_structure 423 * @since Moodle 2.4 424 */ 425 private static function get_assignments_assignment_structure() { 426 return new external_single_structure( 427 array( 428 'id' => new external_value(PARAM_INT, 'assignment id'), 429 'cmid' => new external_value(PARAM_INT, 'course module id'), 430 'course' => new external_value(PARAM_INT, 'course id'), 431 'name' => new external_value(PARAM_TEXT, 'assignment name'), 432 'nosubmissions' => new external_value(PARAM_INT, 'no submissions'), 433 'submissiondrafts' => new external_value(PARAM_INT, 'submissions drafts'), 434 'sendnotifications' => new external_value(PARAM_INT, 'send notifications'), 435 'sendlatenotifications' => new external_value(PARAM_INT, 'send notifications'), 436 'sendstudentnotifications' => new external_value(PARAM_INT, 'send student notifications (default)'), 437 'duedate' => new external_value(PARAM_INT, 'assignment due date'), 438 'allowsubmissionsfromdate' => new external_value(PARAM_INT, 'allow submissions from date'), 439 'grade' => new external_value(PARAM_INT, 'grade type'), 440 'timemodified' => new external_value(PARAM_INT, 'last time assignment was modified'), 441 'completionsubmit' => new external_value(PARAM_INT, 'if enabled, set activity as complete following submission'), 442 'cutoffdate' => new external_value(PARAM_INT, 'date after which submission is not accepted without an extension'), 443 'teamsubmission' => new external_value(PARAM_INT, 'if enabled, students submit as a team'), 444 'requireallteammemberssubmit' => new external_value(PARAM_INT, 'if enabled, all team members must submit'), 445 'teamsubmissiongroupingid' => new external_value(PARAM_INT, 'the grouping id for the team submission groups'), 446 'blindmarking' => new external_value(PARAM_INT, 'if enabled, hide identities until reveal identities actioned'), 447 'revealidentities' => new external_value(PARAM_INT, 'show identities for a blind marking assignment'), 448 'attemptreopenmethod' => new external_value(PARAM_TEXT, 'method used to control opening new attempts'), 449 'maxattempts' => new external_value(PARAM_INT, 'maximum number of attempts allowed'), 450 'markingworkflow' => new external_value(PARAM_INT, 'enable marking workflow'), 451 'markingallocation' => new external_value(PARAM_INT, 'enable marking allocation'), 452 'requiresubmissionstatement' => new external_value(PARAM_INT, 'student must accept submission statement'), 453 'configs' => new external_multiple_structure(self::get_assignments_config_structure(), 'configuration settings') 454 ), 'assignment information object'); 455 } 456 457 /** 458 * Creates an assign_plugin_config external_single_structure 459 * 460 * @return external_single_structure 461 * @since Moodle 2.4 462 */ 463 private static function get_assignments_config_structure() { 464 return new external_single_structure( 465 array( 466 'id' => new external_value(PARAM_INT, 'assign_plugin_config id'), 467 'assignment' => new external_value(PARAM_INT, 'assignment id'), 468 'plugin' => new external_value(PARAM_TEXT, 'plugin'), 469 'subtype' => new external_value(PARAM_TEXT, 'subtype'), 470 'name' => new external_value(PARAM_TEXT, 'name'), 471 'value' => new external_value(PARAM_TEXT, 'value') 472 ), 'assignment configuration object' 473 ); 474 } 475 476 /** 477 * Creates a course external_single_structure 478 * 479 * @return external_single_structure 480 * @since Moodle 2.4 481 */ 482 private static function get_assignments_course_structure() { 483 return new external_single_structure( 484 array( 485 'id' => new external_value(PARAM_INT, 'course id'), 486 'fullname' => new external_value(PARAM_TEXT, 'course full name'), 487 'shortname' => new external_value(PARAM_TEXT, 'course short name'), 488 'timemodified' => new external_value(PARAM_INT, 'last time modified'), 489 'assignments' => new external_multiple_structure(self::get_assignments_assignment_structure(), 'assignment info') 490 ), 'course information object' 491 ); 492 } 493 494 /** 495 * Describes the return value for get_assignments 496 * 497 * @return external_single_structure 498 * @since Moodle 2.4 499 */ 500 public static function get_assignments_returns() { 501 return new external_single_structure( 502 array( 503 'courses' => new external_multiple_structure(self::get_assignments_course_structure(), 'list of courses'), 504 'warnings' => new external_warnings('item can be \'course\' (errorcode 1 or 2) or \'module\' (errorcode 1)', 505 'When item is a course then itemid is a course id. When the item is a module then itemid is a module id', 506 'errorcode can be 1 (no access rights) or 2 (not enrolled or no permissions)') 507 ) 508 ); 509 } 510 511 /** 512 * Describes the parameters for get_submissions 513 * 514 * @return external_external_function_parameters 515 * @since Moodle 2.5 516 */ 517 public static function get_submissions_parameters() { 518 return new external_function_parameters( 519 array( 520 'assignmentids' => new external_multiple_structure( 521 new external_value(PARAM_INT, 'assignment id'), 522 '1 or more assignment ids', 523 VALUE_REQUIRED), 524 'status' => new external_value(PARAM_ALPHA, 'status', VALUE_DEFAULT, ''), 525 'since' => new external_value(PARAM_INT, 'submitted since', VALUE_DEFAULT, 0), 526 'before' => new external_value(PARAM_INT, 'submitted before', VALUE_DEFAULT, 0) 527 ) 528 ); 529 } 530 531 /** 532 * Returns submissions for the requested assignment ids 533 * 534 * @param int[] $assignmentids 535 * @param string $status only return submissions with this status 536 * @param int $since only return submissions with timemodified >= since 537 * @param int $before only return submissions with timemodified <= before 538 * @return array of submissions for each requested assignment 539 * @since Moodle 2.5 540 */ 541 public static function get_submissions($assignmentids, $status = '', $since = 0, $before = 0) { 542 global $DB, $CFG; 543 require_once("$CFG->dirroot/mod/assign/locallib.php"); 544 $params = self::validate_parameters(self::get_submissions_parameters(), 545 array('assignmentids' => $assignmentids, 546 'status' => $status, 547 'since' => $since, 548 'before' => $before)); 549 550 $warnings = array(); 551 $assignments = array(); 552 553 // Check the user is allowed to get the submissions for the assignments requested. 554 $placeholders = array(); 555 list($inorequalsql, $placeholders) = $DB->get_in_or_equal($params['assignmentids'], SQL_PARAMS_NAMED); 556 $sql = "SELECT cm.id, cm.instance FROM {course_modules} cm JOIN {modules} md ON md.id = cm.module ". 557 "WHERE md.name = :modname AND cm.instance ".$inorequalsql; 558 $placeholders['modname'] = 'assign'; 559 $cms = $DB->get_records_sql($sql, $placeholders); 560 $assigns = array(); 561 foreach ($cms as $cm) { 562 try { 563 $context = context_module::instance($cm->id); 564 self::validate_context($context); 565 require_capability('mod/assign:grade', $context); 566 $assign = new assign($context, null, null); 567 $assigns[] = $assign; 568 } catch (Exception $e) { 569 $warnings[] = array( 570 'item' => 'assignment', 571 'itemid' => $cm->instance, 572 'warningcode' => '1', 573 'message' => 'No access rights in module context' 574 ); 575 } 576 } 577 578 foreach ($assigns as $assign) { 579 $submissions = array(); 580 $submissionplugins = $assign->get_submission_plugins(); 581 $placeholders = array('assignid1' => $assign->get_instance()->id, 582 'assignid2' => $assign->get_instance()->id); 583 584 $submissionmaxattempt = 'SELECT mxs.userid, MAX(mxs.attemptnumber) AS maxattempt 585 FROM {assign_submission} mxs 586 WHERE mxs.assignment = :assignid1 GROUP BY mxs.userid'; 587 588 $sql = "SELECT mas.id, mas.assignment,mas.userid,". 589 "mas.timecreated,mas.timemodified,mas.status,mas.groupid,mas.attemptnumber ". 590 "FROM {assign_submission} mas ". 591 "JOIN ( " . $submissionmaxattempt . " ) smx ON mas.userid = smx.userid ". 592 "WHERE mas.assignment = :assignid2 AND mas.attemptnumber = smx.maxattempt"; 593 594 if (!empty($params['status'])) { 595 $placeholders['status'] = $params['status']; 596 $sql = $sql." AND mas.status = :status"; 597 } 598 if (!empty($params['before'])) { 599 $placeholders['since'] = $params['since']; 600 $placeholders['before'] = $params['before']; 601 $sql = $sql." AND mas.timemodified BETWEEN :since AND :before"; 602 } else { 603 $placeholders['since'] = $params['since']; 604 $sql = $sql." AND mas.timemodified >= :since"; 605 } 606 607 $submissionrecords = $DB->get_records_sql($sql, $placeholders); 608 609 if (!empty($submissionrecords)) { 610 $fs = get_file_storage(); 611 foreach ($submissionrecords as $submissionrecord) { 612 $submission = array( 613 'id' => $submissionrecord->id, 614 'userid' => $submissionrecord->userid, 615 'timecreated' => $submissionrecord->timecreated, 616 'timemodified' => $submissionrecord->timemodified, 617 'status' => $submissionrecord->status, 618 'attemptnumber' => $submissionrecord->attemptnumber, 619 'groupid' => $submissionrecord->groupid 620 ); 621 foreach ($submissionplugins as $submissionplugin) { 622 $plugin = array( 623 'name' => $submissionplugin->get_name(), 624 'type' => $submissionplugin->get_type() 625 ); 626 // Subtype is 'assignsubmission', type is currently 'file' or 'onlinetext'. 627 $component = $submissionplugin->get_subtype().'_'.$submissionplugin->get_type(); 628 629 $fileareas = $submissionplugin->get_file_areas(); 630 foreach ($fileareas as $filearea => $name) { 631 $fileareainfo = array('area' => $filearea); 632 $files = $fs->get_area_files( 633 $assign->get_context()->id, 634 $component, 635 $filearea, 636 $submissionrecord->id, 637 "timemodified", 638 false 639 ); 640 foreach ($files as $file) { 641 $filepath = $file->get_filepath().$file->get_filename(); 642 $fileurl = file_encode_url($CFG->wwwroot . '/webservice/pluginfile.php', '/' . $assign->get_context()->id . 643 '/' . $component. '/'. $filearea . '/' . $submissionrecord->id . $filepath); 644 $fileinfo = array( 645 'filepath' => $filepath, 646 'fileurl' => $fileurl 647 ); 648 $fileareainfo['files'][] = $fileinfo; 649 } 650 $plugin['fileareas'][] = $fileareainfo; 651 } 652 653 $editorfields = $submissionplugin->get_editor_fields(); 654 foreach ($editorfields as $name => $description) { 655 $editorfieldinfo = array( 656 'name' => $name, 657 'description' => $description, 658 'text' => $submissionplugin->get_editor_text($name, $submissionrecord->id), 659 'format' => $submissionplugin->get_editor_format($name, $submissionrecord->id) 660 ); 661 $plugin['editorfields'][] = $editorfieldinfo; 662 } 663 664 $submission['plugins'][] = $plugin; 665 } 666 $submissions[] = $submission; 667 } 668 } else { 669 $warnings[] = array( 670 'item' => 'module', 671 'itemid' => $assign->get_instance()->id, 672 'warningcode' => '3', 673 'message' => 'No submissions found' 674 ); 675 } 676 677 $assignments[] = array( 678 'assignmentid' => $assign->get_instance()->id, 679 'submissions' => $submissions 680 ); 681 682 } 683 684 $result = array( 685 'assignments' => $assignments, 686 'warnings' => $warnings 687 ); 688 return $result; 689 } 690 691 /** 692 * Creates an assign_submissions external_single_structure 693 * 694 * @return external_single_structure 695 * @since Moodle 2.5 696 */ 697 private static function get_submissions_structure() { 698 return new external_single_structure( 699 array ( 700 'assignmentid' => new external_value(PARAM_INT, 'assignment id'), 701 'submissions' => new external_multiple_structure( 702 new external_single_structure( 703 array( 704 'id' => new external_value(PARAM_INT, 'submission id'), 705 'userid' => new external_value(PARAM_INT, 'student id'), 706 'attemptnumber' => new external_value(PARAM_INT, 'attempt number'), 707 'timecreated' => new external_value(PARAM_INT, 'submission creation time'), 708 'timemodified' => new external_value(PARAM_INT, 'submission last modified time'), 709 'status' => new external_value(PARAM_TEXT, 'submission status'), 710 'groupid' => new external_value(PARAM_INT, 'group id'), 711 'plugins' => new external_multiple_structure( 712 new external_single_structure( 713 array( 714 'type' => new external_value(PARAM_TEXT, 'submission plugin type'), 715 'name' => new external_value(PARAM_TEXT, 'submission plugin name'), 716 'fileareas' => new external_multiple_structure( 717 new external_single_structure( 718 array ( 719 'area' => new external_value (PARAM_TEXT, 'file area'), 720 'files' => new external_multiple_structure( 721 new external_single_structure( 722 array ( 723 'filepath' => new external_value (PARAM_TEXT, 'file path'), 724 'fileurl' => new external_value (PARAM_URL, 'file download url', 725 VALUE_OPTIONAL) 726 ) 727 ), 'files', VALUE_OPTIONAL 728 ) 729 ) 730 ), 'fileareas', VALUE_OPTIONAL 731 ), 732 'editorfields' => new external_multiple_structure( 733 new external_single_structure( 734 array( 735 'name' => new external_value(PARAM_TEXT, 'field name'), 736 'description' => new external_value(PARAM_TEXT, 'field description'), 737 'text' => new external_value (PARAM_RAW, 'field value'), 738 'format' => new external_format_value ('text') 739 ) 740 ) 741 , 'editorfields', VALUE_OPTIONAL 742 ) 743 ) 744 ) 745 , 'plugins', VALUE_OPTIONAL 746 ) 747 ) 748 ) 749 ) 750 ) 751 ); 752 } 753 754 /** 755 * Describes the get_submissions return value 756 * 757 * @return external_single_structure 758 * @since Moodle 2.5 759 */ 760 public static function get_submissions_returns() { 761 return new external_single_structure( 762 array( 763 'assignments' => new external_multiple_structure(self::get_submissions_structure(), 'assignment submissions'), 764 'warnings' => new external_warnings() 765 ) 766 ); 767 } 768 769 /** 770 * Describes the parameters for set_user_flags 771 * @return external_function_parameters 772 * @since Moodle 2.6 773 */ 774 public static function set_user_flags_parameters() { 775 return new external_function_parameters( 776 array( 777 'assignmentid' => new external_value(PARAM_INT, 'assignment id'), 778 'userflags' => new external_multiple_structure( 779 new external_single_structure( 780 array( 781 'userid' => new external_value(PARAM_INT, 'student id'), 782 'locked' => new external_value(PARAM_INT, 'locked', VALUE_OPTIONAL), 783 'mailed' => new external_value(PARAM_INT, 'mailed', VALUE_OPTIONAL), 784 'extensionduedate' => new external_value(PARAM_INT, 'extension due date', VALUE_OPTIONAL), 785 'workflowstate' => new external_value(PARAM_TEXT, 'marking workflow state', VALUE_OPTIONAL), 786 'allocatedmarker' => new external_value(PARAM_INT, 'allocated marker', VALUE_OPTIONAL) 787 ) 788 ) 789 ) 790 ) 791 ); 792 } 793 794 /** 795 * Create or update user_flags records 796 * 797 * @param int $assignmentid the assignment for which the userflags are created or updated 798 * @param array $userflags An array of userflags to create or update 799 * @return array containing success or failure information for each record 800 * @since Moodle 2.6 801 */ 802 public static function set_user_flags($assignmentid, $userflags = array()) { 803 global $CFG, $DB; 804 require_once($CFG->dirroot . "/mod/assign/locallib.php"); 805 806 $params = self::validate_parameters(self::set_user_flags_parameters(), 807 array('assignmentid' => $assignmentid, 808 'userflags' => $userflags)); 809 810 // Load assignment if it exists and if the user has the capability. 811 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 812 $context = context_module::instance($cm->id); 813 self::validate_context($context); 814 require_capability('mod/assign:grade', $context); 815 $assign = new assign($context, null, null); 816 817 $results = array(); 818 foreach ($params['userflags'] as $userflag) { 819 $success = true; 820 $result = array(); 821 822 $record = $assign->get_user_flags($userflag['userid'], false); 823 if ($record) { 824 if (isset($userflag['locked'])) { 825 $record->locked = $userflag['locked']; 826 } 827 if (isset($userflag['mailed'])) { 828 $record->mailed = $userflag['mailed']; 829 } 830 if (isset($userflag['extensionduedate'])) { 831 $record->extensionduedate = $userflag['extensionduedate']; 832 } 833 if (isset($userflag['workflowstate'])) { 834 $record->workflowstate = $userflag['workflowstate']; 835 } 836 if (isset($userflag['allocatedmarker'])) { 837 $record->allocatedmarker = $userflag['allocatedmarker']; 838 } 839 if ($assign->update_user_flags($record)) { 840 $result['id'] = $record->id; 841 $result['userid'] = $userflag['userid']; 842 } else { 843 $result['id'] = $record->id; 844 $result['userid'] = $userflag['userid']; 845 $result['errormessage'] = 'Record created but values could not be set'; 846 } 847 } else { 848 $record = $assign->get_user_flags($userflag['userid'], true); 849 $setfields = isset($userflag['locked']) 850 || isset($userflag['mailed']) 851 || isset($userflag['extensionduedate']) 852 || isset($userflag['workflowstate']) 853 || isset($userflag['allocatedmarker']); 854 if ($record) { 855 if ($setfields) { 856 if (isset($userflag['locked'])) { 857 $record->locked = $userflag['locked']; 858 } 859 if (isset($userflag['mailed'])) { 860 $record->mailed = $userflag['mailed']; 861 } 862 if (isset($userflag['extensionduedate'])) { 863 $record->extensionduedate = $userflag['extensionduedate']; 864 } 865 if (isset($userflag['workflowstate'])) { 866 $record->workflowstate = $userflag['workflowstate']; 867 } 868 if (isset($userflag['allocatedmarker'])) { 869 $record->allocatedmarker = $userflag['allocatedmarker']; 870 } 871 if ($assign->update_user_flags($record)) { 872 $result['id'] = $record->id; 873 $result['userid'] = $userflag['userid']; 874 } else { 875 $result['id'] = $record->id; 876 $result['userid'] = $userflag['userid']; 877 $result['errormessage'] = 'Record created but values could not be set'; 878 } 879 } else { 880 $result['id'] = $record->id; 881 $result['userid'] = $userflag['userid']; 882 } 883 } else { 884 $result['id'] = -1; 885 $result['userid'] = $userflag['userid']; 886 $result['errormessage'] = 'Record could not be created'; 887 } 888 } 889 890 $results[] = $result; 891 } 892 return $results; 893 } 894 895 /** 896 * Describes the set_user_flags return value 897 * @return external_multiple_structure 898 * @since Moodle 2.6 899 */ 900 public static function set_user_flags_returns() { 901 return new external_multiple_structure( 902 new external_single_structure( 903 array( 904 'id' => new external_value(PARAM_INT, 'id of record if successful, -1 for failure'), 905 'userid' => new external_value(PARAM_INT, 'userid of record'), 906 'errormessage' => new external_value(PARAM_TEXT, 'Failure error message', VALUE_OPTIONAL) 907 ) 908 ) 909 ); 910 } 911 912 /** 913 * Describes the parameters for get_user_flags 914 * @return external_function_parameters 915 * @since Moodle 2.6 916 */ 917 public static function get_user_flags_parameters() { 918 return new external_function_parameters( 919 array( 920 'assignmentids' => new external_multiple_structure( 921 new external_value(PARAM_INT, 'assignment id'), 922 '1 or more assignment ids', 923 VALUE_REQUIRED) 924 ) 925 ); 926 } 927 928 /** 929 * Returns user flag information from assign_user_flags for the requested assignment ids 930 * @param int[] $assignmentids 931 * @return array of user flag records for each requested assignment 932 * @since Moodle 2.6 933 */ 934 public static function get_user_flags($assignmentids) { 935 global $DB; 936 $params = self::validate_parameters(self::get_user_flags_parameters(), 937 array('assignmentids' => $assignmentids)); 938 939 $assignments = array(); 940 $warnings = array(); 941 $requestedassignmentids = $params['assignmentids']; 942 943 // Check the user is allowed to get the user flags for the assignments requested. 944 $placeholders = array(); 945 list($sqlassignmentids, $placeholders) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); 946 $sql = "SELECT cm.id, cm.instance FROM {course_modules} cm JOIN {modules} md ON md.id = cm.module ". 947 "WHERE md.name = :modname AND cm.instance ".$sqlassignmentids; 948 $placeholders['modname'] = 'assign'; 949 $cms = $DB->get_records_sql($sql, $placeholders); 950 foreach ($cms as $cm) { 951 try { 952 $context = context_module::instance($cm->id); 953 self::validate_context($context); 954 require_capability('mod/assign:grade', $context); 955 } catch (Exception $e) { 956 $requestedassignmentids = array_diff($requestedassignmentids, array($cm->instance)); 957 $warning = array(); 958 $warning['item'] = 'assignment'; 959 $warning['itemid'] = $cm->instance; 960 $warning['warningcode'] = '1'; 961 $warning['message'] = 'No access rights in module context'; 962 $warnings[] = $warning; 963 } 964 } 965 966 // Create the query and populate an array of assign_user_flags records from the recordset results. 967 if (count ($requestedassignmentids) > 0) { 968 $placeholders = array(); 969 list($inorequalsql, $placeholders) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); 970 971 $sql = "SELECT auf.id,auf.assignment,auf.userid,auf.locked,auf.mailed,". 972 "auf.extensionduedate,auf.workflowstate,auf.allocatedmarker ". 973 "FROM {assign_user_flags} auf ". 974 "WHERE auf.assignment ".$inorequalsql. 975 " ORDER BY auf.assignment, auf.id"; 976 977 $rs = $DB->get_recordset_sql($sql, $placeholders); 978 $currentassignmentid = null; 979 $assignment = null; 980 foreach ($rs as $rd) { 981 $userflag = array(); 982 $userflag['id'] = $rd->id; 983 $userflag['userid'] = $rd->userid; 984 $userflag['locked'] = $rd->locked; 985 $userflag['mailed'] = $rd->mailed; 986 $userflag['extensionduedate'] = $rd->extensionduedate; 987 $userflag['workflowstate'] = $rd->workflowstate; 988 $userflag['allocatedmarker'] = $rd->allocatedmarker; 989 990 if (is_null($currentassignmentid) || ($rd->assignment != $currentassignmentid )) { 991 if (!is_null($assignment)) { 992 $assignments[] = $assignment; 993 } 994 $assignment = array(); 995 $assignment['assignmentid'] = $rd->assignment; 996 $assignment['userflags'] = array(); 997 $requestedassignmentids = array_diff($requestedassignmentids, array($rd->assignment)); 998 } 999 $assignment['userflags'][] = $userflag; 1000 1001 $currentassignmentid = $rd->assignment; 1002 } 1003 if (!is_null($assignment)) { 1004 $assignments[] = $assignment; 1005 } 1006 $rs->close(); 1007 1008 } 1009 1010 foreach ($requestedassignmentids as $assignmentid) { 1011 $warning = array(); 1012 $warning['item'] = 'assignment'; 1013 $warning['itemid'] = $assignmentid; 1014 $warning['warningcode'] = '3'; 1015 $warning['message'] = 'No user flags found'; 1016 $warnings[] = $warning; 1017 } 1018 1019 $result = array(); 1020 $result['assignments'] = $assignments; 1021 $result['warnings'] = $warnings; 1022 return $result; 1023 } 1024 1025 /** 1026 * Creates an assign_user_flags external_single_structure 1027 * @return external_single_structure 1028 * @since Moodle 2.6 1029 */ 1030 private static function assign_user_flags() { 1031 return new external_single_structure( 1032 array ( 1033 'assignmentid' => new external_value(PARAM_INT, 'assignment id'), 1034 'userflags' => new external_multiple_structure(new external_single_structure( 1035 array( 1036 'id' => new external_value(PARAM_INT, 'user flag id'), 1037 'userid' => new external_value(PARAM_INT, 'student id'), 1038 'locked' => new external_value(PARAM_INT, 'locked'), 1039 'mailed' => new external_value(PARAM_INT, 'mailed'), 1040 'extensionduedate' => new external_value(PARAM_INT, 'extension due date'), 1041 'workflowstate' => new external_value(PARAM_TEXT, 'marking workflow state', VALUE_OPTIONAL), 1042 'allocatedmarker' => new external_value(PARAM_INT, 'allocated marker') 1043 ) 1044 ) 1045 ) 1046 ) 1047 ); 1048 } 1049 1050 /** 1051 * Describes the get_user_flags return value 1052 * @return external_single_structure 1053 * @since Moodle 2.6 1054 */ 1055 public static function get_user_flags_returns() { 1056 return new external_single_structure( 1057 array( 1058 'assignments' => new external_multiple_structure(self::assign_user_flags(), 'list of assign user flag information'), 1059 'warnings' => new external_warnings('item is always \'assignment\'', 1060 'when errorcode is 3 then itemid is an assignment id. When errorcode is 1, itemid is a course module id', 1061 'errorcode can be 3 (no user flags found) or 1 (no permission to get user flags)') 1062 ) 1063 ); 1064 } 1065 1066 /** 1067 * Describes the parameters for get_user_mappings 1068 * @return external_function_parameters 1069 * @since Moodle 2.6 1070 */ 1071 public static function get_user_mappings_parameters() { 1072 return new external_function_parameters( 1073 array( 1074 'assignmentids' => new external_multiple_structure( 1075 new external_value(PARAM_INT, 'assignment id'), 1076 '1 or more assignment ids', 1077 VALUE_REQUIRED) 1078 ) 1079 ); 1080 } 1081 1082 /** 1083 * Returns user mapping information from assign_user_mapping for the requested assignment ids 1084 * @param int[] $assignmentids 1085 * @return array of user mapping records for each requested assignment 1086 * @since Moodle 2.6 1087 */ 1088 public static function get_user_mappings($assignmentids) { 1089 global $DB; 1090 $params = self::validate_parameters(self::get_user_mappings_parameters(), 1091 array('assignmentids' => $assignmentids)); 1092 1093 $assignments = array(); 1094 $warnings = array(); 1095 $requestedassignmentids = $params['assignmentids']; 1096 1097 // Check the user is allowed to get the mappings for the assignments requested. 1098 $placeholders = array(); 1099 list($sqlassignmentids, $placeholders) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); 1100 $sql = "SELECT cm.id, cm.instance FROM {course_modules} cm JOIN {modules} md ON md.id = cm.module ". 1101 "WHERE md.name = :modname AND cm.instance ".$sqlassignmentids; 1102 $placeholders['modname'] = 'assign'; 1103 $cms = $DB->get_records_sql($sql, $placeholders); 1104 foreach ($cms as $cm) { 1105 try { 1106 $context = context_module::instance($cm->id); 1107 self::validate_context($context); 1108 require_capability('mod/assign:revealidentities', $context); 1109 } catch (Exception $e) { 1110 $requestedassignmentids = array_diff($requestedassignmentids, array($cm->instance)); 1111 $warning = array(); 1112 $warning['item'] = 'assignment'; 1113 $warning['itemid'] = $cm->instance; 1114 $warning['warningcode'] = '1'; 1115 $warning['message'] = 'No access rights in module context'; 1116 $warnings[] = $warning; 1117 } 1118 } 1119 1120 // Create the query and populate an array of assign_user_mapping records from the recordset results. 1121 if (count ($requestedassignmentids) > 0) { 1122 $placeholders = array(); 1123 list($inorequalsql, $placeholders) = $DB->get_in_or_equal($requestedassignmentids, SQL_PARAMS_NAMED); 1124 1125 $sql = "SELECT aum.id,aum.assignment,aum.userid ". 1126 "FROM {assign_user_mapping} aum ". 1127 "WHERE aum.assignment ".$inorequalsql. 1128 " ORDER BY aum.assignment, aum.id"; 1129 1130 $rs = $DB->get_recordset_sql($sql, $placeholders); 1131 $currentassignmentid = null; 1132 $assignment = null; 1133 foreach ($rs as $rd) { 1134 $mapping = array(); 1135 $mapping['id'] = $rd->id; 1136 $mapping['userid'] = $rd->userid; 1137 1138 if (is_null($currentassignmentid) || ($rd->assignment != $currentassignmentid )) { 1139 if (!is_null($assignment)) { 1140 $assignments[] = $assignment; 1141 } 1142 $assignment = array(); 1143 $assignment['assignmentid'] = $rd->assignment; 1144 $assignment['mappings'] = array(); 1145 $requestedassignmentids = array_diff($requestedassignmentids, array($rd->assignment)); 1146 } 1147 $assignment['mappings'][] = $mapping; 1148 1149 $currentassignmentid = $rd->assignment; 1150 } 1151 if (!is_null($assignment)) { 1152 $assignments[] = $assignment; 1153 } 1154 $rs->close(); 1155 1156 } 1157 1158 foreach ($requestedassignmentids as $assignmentid) { 1159 $warning = array(); 1160 $warning['item'] = 'assignment'; 1161 $warning['itemid'] = $assignmentid; 1162 $warning['warningcode'] = '3'; 1163 $warning['message'] = 'No mappings found'; 1164 $warnings[] = $warning; 1165 } 1166 1167 $result = array(); 1168 $result['assignments'] = $assignments; 1169 $result['warnings'] = $warnings; 1170 return $result; 1171 } 1172 1173 /** 1174 * Creates an assign_user_mappings external_single_structure 1175 * @return external_single_structure 1176 * @since Moodle 2.6 1177 */ 1178 private static function assign_user_mappings() { 1179 return new external_single_structure( 1180 array ( 1181 'assignmentid' => new external_value(PARAM_INT, 'assignment id'), 1182 'mappings' => new external_multiple_structure(new external_single_structure( 1183 array( 1184 'id' => new external_value(PARAM_INT, 'user mapping id'), 1185 'userid' => new external_value(PARAM_INT, 'student id') 1186 ) 1187 ) 1188 ) 1189 ) 1190 ); 1191 } 1192 1193 /** 1194 * Describes the get_user_mappings return value 1195 * @return external_single_structure 1196 * @since Moodle 2.6 1197 */ 1198 public static function get_user_mappings_returns() { 1199 return new external_single_structure( 1200 array( 1201 'assignments' => new external_multiple_structure(self::assign_user_mappings(), 'list of assign user mapping data'), 1202 'warnings' => new external_warnings('item is always \'assignment\'', 1203 'when errorcode is 3 then itemid is an assignment id. When errorcode is 1, itemid is a course module id', 1204 'errorcode can be 3 (no user mappings found) or 1 (no permission to get user mappings)') 1205 ) 1206 ); 1207 } 1208 1209 /** 1210 * Describes the parameters for lock_submissions 1211 * @return external_external_function_parameters 1212 * @since Moodle 2.6 1213 */ 1214 public static function lock_submissions_parameters() { 1215 return new external_function_parameters( 1216 array( 1217 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 1218 'userids' => new external_multiple_structure( 1219 new external_value(PARAM_INT, 'user id'), 1220 '1 or more user ids', 1221 VALUE_REQUIRED), 1222 ) 1223 ); 1224 } 1225 1226 /** 1227 * Locks (prevent updates to) submissions in this assignment. 1228 * 1229 * @param int $assignmentid The id of the assignment 1230 * @param array $userids Array of user ids to lock 1231 * @return array of warnings for each submission that could not be locked. 1232 * @since Moodle 2.6 1233 */ 1234 public static function lock_submissions($assignmentid, $userids) { 1235 global $CFG; 1236 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1237 1238 $params = self::validate_parameters(self::lock_submissions_parameters(), 1239 array('assignmentid' => $assignmentid, 1240 'userids' => $userids)); 1241 1242 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 1243 $context = context_module::instance($cm->id); 1244 self::validate_context($context); 1245 1246 $assignment = new assign($context, $cm, null); 1247 1248 $warnings = array(); 1249 foreach ($params['userids'] as $userid) { 1250 if (!$assignment->lock_submission($userid)) { 1251 $detail = 'User id: ' . $userid . ', Assignment id: ' . $params['assignmentid']; 1252 $warnings[] = self::generate_warning($params['assignmentid'], 1253 'couldnotlock', 1254 $detail); 1255 } 1256 } 1257 1258 return $warnings; 1259 } 1260 1261 /** 1262 * Describes the return value for lock_submissions 1263 * 1264 * @return external_single_structure 1265 * @since Moodle 2.6 1266 */ 1267 public static function lock_submissions_returns() { 1268 return new external_multiple_structure( 1269 new external_warnings() 1270 ); 1271 } 1272 1273 /** 1274 * Describes the parameters for revert_submissions_to_draft 1275 * @return external_external_function_parameters 1276 * @since Moodle 2.6 1277 */ 1278 public static function revert_submissions_to_draft_parameters() { 1279 return new external_function_parameters( 1280 array( 1281 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 1282 'userids' => new external_multiple_structure( 1283 new external_value(PARAM_INT, 'user id'), 1284 '1 or more user ids', 1285 VALUE_REQUIRED), 1286 ) 1287 ); 1288 } 1289 1290 /** 1291 * Reverts a list of user submissions to draft for a single assignment. 1292 * 1293 * @param int $assignmentid The id of the assignment 1294 * @param array $userids Array of user ids to revert 1295 * @return array of warnings for each submission that could not be reverted. 1296 * @since Moodle 2.6 1297 */ 1298 public static function revert_submissions_to_draft($assignmentid, $userids) { 1299 global $CFG; 1300 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1301 1302 $params = self::validate_parameters(self::revert_submissions_to_draft_parameters(), 1303 array('assignmentid' => $assignmentid, 1304 'userids' => $userids)); 1305 1306 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 1307 $context = context_module::instance($cm->id); 1308 self::validate_context($context); 1309 1310 $assignment = new assign($context, $cm, null); 1311 1312 $warnings = array(); 1313 foreach ($params['userids'] as $userid) { 1314 if (!$assignment->revert_to_draft($userid)) { 1315 $detail = 'User id: ' . $userid . ', Assignment id: ' . $params['assignmentid']; 1316 $warnings[] = self::generate_warning($params['assignmentid'], 1317 'couldnotrevert', 1318 $detail); 1319 } 1320 } 1321 1322 return $warnings; 1323 } 1324 1325 /** 1326 * Describes the return value for revert_submissions_to_draft 1327 * 1328 * @return external_single_structure 1329 * @since Moodle 2.6 1330 */ 1331 public static function revert_submissions_to_draft_returns() { 1332 return new external_multiple_structure( 1333 new external_warnings() 1334 ); 1335 } 1336 1337 /** 1338 * Describes the parameters for unlock_submissions 1339 * @return external_external_function_parameters 1340 * @since Moodle 2.6 1341 */ 1342 public static function unlock_submissions_parameters() { 1343 return new external_function_parameters( 1344 array( 1345 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 1346 'userids' => new external_multiple_structure( 1347 new external_value(PARAM_INT, 'user id'), 1348 '1 or more user ids', 1349 VALUE_REQUIRED), 1350 ) 1351 ); 1352 } 1353 1354 /** 1355 * Locks (prevent updates to) submissions in this assignment. 1356 * 1357 * @param int $assignmentid The id of the assignment 1358 * @param array $userids Array of user ids to lock 1359 * @return array of warnings for each submission that could not be locked. 1360 * @since Moodle 2.6 1361 */ 1362 public static function unlock_submissions($assignmentid, $userids) { 1363 global $CFG; 1364 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1365 1366 $params = self::validate_parameters(self::unlock_submissions_parameters(), 1367 array('assignmentid' => $assignmentid, 1368 'userids' => $userids)); 1369 1370 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 1371 $context = context_module::instance($cm->id); 1372 self::validate_context($context); 1373 1374 $assignment = new assign($context, $cm, null); 1375 1376 $warnings = array(); 1377 foreach ($params['userids'] as $userid) { 1378 if (!$assignment->unlock_submission($userid)) { 1379 $detail = 'User id: ' . $userid . ', Assignment id: ' . $params['assignmentid']; 1380 $warnings[] = self::generate_warning($params['assignmentid'], 1381 'couldnotunlock', 1382 $detail); 1383 } 1384 } 1385 1386 return $warnings; 1387 } 1388 1389 /** 1390 * Describes the return value for unlock_submissions 1391 * 1392 * @return external_single_structure 1393 * @since Moodle 2.6 1394 */ 1395 public static function unlock_submissions_returns() { 1396 return new external_multiple_structure( 1397 new external_warnings() 1398 ); 1399 } 1400 1401 /** 1402 * Describes the parameters for submit_for_grading 1403 * @return external_external_function_parameters 1404 * @since Moodle 2.6 1405 */ 1406 public static function submit_for_grading_parameters() { 1407 return new external_function_parameters( 1408 array( 1409 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 1410 'acceptsubmissionstatement' => new external_value(PARAM_BOOL, 'Accept the assignment submission statement') 1411 ) 1412 ); 1413 } 1414 1415 /** 1416 * Submit the logged in users assignment for grading. 1417 * 1418 * @param int $assignmentid The id of the assignment 1419 * @return array of warnings to indicate any errors. 1420 * @since Moodle 2.6 1421 */ 1422 public static function submit_for_grading($assignmentid, $acceptsubmissionstatement) { 1423 global $CFG, $USER; 1424 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1425 1426 $params = self::validate_parameters(self::submit_for_grading_parameters(), 1427 array('assignmentid' => $assignmentid, 1428 'acceptsubmissionstatement' => $acceptsubmissionstatement)); 1429 1430 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 1431 $context = context_module::instance($cm->id); 1432 self::validate_context($context); 1433 1434 $assignment = new assign($context, $cm, null); 1435 1436 $warnings = array(); 1437 $data = new stdClass(); 1438 $data->submissionstatement = $params['acceptsubmissionstatement']; 1439 $notices = array(); 1440 1441 if (!$assignment->submit_for_grading($data, $notices)) { 1442 $detail = 'User id: ' . $USER->id . ', Assignment id: ' . $params['assignmentid'] . ' Notices:' . implode(', ', $notices); 1443 $warnings[] = self::generate_warning($params['assignmentid'], 1444 'couldnotsubmitforgrading', 1445 $detail); 1446 } 1447 1448 return $warnings; 1449 } 1450 1451 /** 1452 * Describes the return value for submit_for_grading 1453 * 1454 * @return external_single_structure 1455 * @since Moodle 2.6 1456 */ 1457 public static function submit_for_grading_returns() { 1458 return new external_multiple_structure( 1459 new external_warnings() 1460 ); 1461 } 1462 1463 /** 1464 * Describes the parameters for save_user_extensions 1465 * @return external_external_function_parameters 1466 * @since Moodle 2.6 1467 */ 1468 public static function save_user_extensions_parameters() { 1469 return new external_function_parameters( 1470 array( 1471 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 1472 'userids' => new external_multiple_structure( 1473 new external_value(PARAM_INT, 'user id'), 1474 '1 or more user ids', 1475 VALUE_REQUIRED), 1476 'dates' => new external_multiple_structure( 1477 new external_value(PARAM_INT, 'dates'), 1478 '1 or more extension dates (timestamp)', 1479 VALUE_REQUIRED), 1480 ) 1481 ); 1482 } 1483 1484 /** 1485 * Grant extension dates to students for an assignment. 1486 * 1487 * @param int $assignmentid The id of the assignment 1488 * @param array $userids Array of user ids to grant extensions to 1489 * @param array $dates Array of extension dates 1490 * @return array of warnings for each extension date that could not be granted 1491 * @since Moodle 2.6 1492 */ 1493 public static function save_user_extensions($assignmentid, $userids, $dates) { 1494 global $CFG; 1495 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1496 1497 $params = self::validate_parameters(self::save_user_extensions_parameters(), 1498 array('assignmentid' => $assignmentid, 1499 'userids' => $userids, 1500 'dates' => $dates)); 1501 1502 if (count($params['userids']) != count($params['dates'])) { 1503 $detail = 'Length of userids and dates parameters differ.'; 1504 $warnings[] = self::generate_warning($params['assignmentid'], 1505 'invalidparameters', 1506 $detail); 1507 1508 return $warnings; 1509 } 1510 1511 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 1512 $context = context_module::instance($cm->id); 1513 self::validate_context($context); 1514 1515 $assignment = new assign($context, $cm, null); 1516 1517 $warnings = array(); 1518 foreach ($params['userids'] as $idx => $userid) { 1519 $duedate = $params['dates'][$idx]; 1520 if (!$assignment->save_user_extension($userid, $duedate)) { 1521 $detail = 'User id: ' . $userid . ', Assignment id: ' . $params['assignmentid'] . ', Extension date: ' . $duedate; 1522 $warnings[] = self::generate_warning($params['assignmentid'], 1523 'couldnotgrantextensions', 1524 $detail); 1525 } 1526 } 1527 1528 return $warnings; 1529 } 1530 1531 /** 1532 * Describes the return value for save_user_extensions 1533 * 1534 * @return external_single_structure 1535 * @since Moodle 2.6 1536 */ 1537 public static function save_user_extensions_returns() { 1538 return new external_multiple_structure( 1539 new external_warnings() 1540 ); 1541 } 1542 1543 /** 1544 * Describes the parameters for reveal_identities 1545 * @return external_external_function_parameters 1546 * @since Moodle 2.6 1547 */ 1548 public static function reveal_identities_parameters() { 1549 return new external_function_parameters( 1550 array( 1551 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on') 1552 ) 1553 ); 1554 } 1555 1556 /** 1557 * Reveal the identities of anonymous students to markers for a single assignment. 1558 * 1559 * @param int $assignmentid The id of the assignment 1560 * @return array of warnings to indicate any errors. 1561 * @since Moodle 2.6 1562 */ 1563 public static function reveal_identities($assignmentid) { 1564 global $CFG, $USER; 1565 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1566 1567 $params = self::validate_parameters(self::reveal_identities_parameters(), 1568 array('assignmentid' => $assignmentid)); 1569 1570 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 1571 $context = context_module::instance($cm->id); 1572 self::validate_context($context); 1573 1574 $assignment = new assign($context, $cm, null); 1575 1576 $warnings = array(); 1577 if (!$assignment->reveal_identities()) { 1578 $detail = 'User id: ' . $USER->id . ', Assignment id: ' . $params['assignmentid']; 1579 $warnings[] = self::generate_warning($params['assignmentid'], 1580 'couldnotrevealidentities', 1581 $detail); 1582 } 1583 1584 return $warnings; 1585 } 1586 1587 /** 1588 * Describes the return value for reveal_identities 1589 * 1590 * @return external_single_structure 1591 * @since Moodle 2.6 1592 */ 1593 public static function reveal_identities_returns() { 1594 return new external_multiple_structure( 1595 new external_warnings() 1596 ); 1597 } 1598 1599 /** 1600 * Describes the parameters for save_submission 1601 * @return external_external_function_parameters 1602 * @since Moodle 2.6 1603 */ 1604 public static function save_submission_parameters() { 1605 global $CFG; 1606 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1607 $instance = new assign(null, null, null); 1608 $pluginsubmissionparams = array(); 1609 1610 foreach ($instance->get_submission_plugins() as $plugin) { 1611 $pluginparams = $plugin->get_external_parameters(); 1612 if (!empty($pluginparams)) { 1613 $pluginsubmissionparams = array_merge($pluginsubmissionparams, $pluginparams); 1614 } 1615 } 1616 1617 return new external_function_parameters( 1618 array( 1619 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 1620 'plugindata' => new external_single_structure( 1621 $pluginsubmissionparams 1622 ) 1623 ) 1624 ); 1625 } 1626 1627 /** 1628 * Save a student submission for a single assignment 1629 * 1630 * @param int $assignmentid The id of the assignment 1631 * @param array $plugindata - The submitted data for plugins 1632 * @return array of warnings to indicate any errors 1633 * @since Moodle 2.6 1634 */ 1635 public static function save_submission($assignmentid, $plugindata) { 1636 global $CFG, $USER; 1637 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1638 1639 $params = self::validate_parameters(self::save_submission_parameters(), 1640 array('assignmentid' => $assignmentid, 1641 'plugindata' => $plugindata)); 1642 1643 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 1644 $context = context_module::instance($cm->id); 1645 self::validate_context($context); 1646 1647 $assignment = new assign($context, $cm, null); 1648 1649 $notices = array(); 1650 1651 $submissiondata = (object)$params['plugindata']; 1652 1653 $assignment->save_submission($submissiondata, $notices); 1654 1655 $warnings = array(); 1656 foreach ($notices as $notice) { 1657 $warnings[] = self::generate_warning($params['assignmentid'], 1658 'couldnotsavesubmission', 1659 $notice); 1660 } 1661 1662 return $warnings; 1663 } 1664 1665 /** 1666 * Describes the return value for save_submission 1667 * 1668 * @return external_single_structure 1669 * @since Moodle 2.6 1670 */ 1671 public static function save_submission_returns() { 1672 return new external_multiple_structure( 1673 new external_warnings() 1674 ); 1675 } 1676 1677 /** 1678 * Describes the parameters for save_grade 1679 * @return external_external_function_parameters 1680 * @since Moodle 2.6 1681 */ 1682 public static function save_grade_parameters() { 1683 global $CFG; 1684 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1685 require_once("$CFG->dirroot/grade/grading/lib.php"); 1686 $instance = new assign(null, null, null); 1687 $pluginfeedbackparams = array(); 1688 1689 foreach ($instance->get_feedback_plugins() as $plugin) { 1690 $pluginparams = $plugin->get_external_parameters(); 1691 if (!empty($pluginparams)) { 1692 $pluginfeedbackparams = array_merge($pluginfeedbackparams, $pluginparams); 1693 } 1694 } 1695 1696 $advancedgradingdata = array(); 1697 $methods = array_keys(grading_manager::available_methods(false)); 1698 foreach ($methods as $method) { 1699 require_once($CFG->dirroot.'/grade/grading/form/'.$method.'/lib.php'); 1700 $details = call_user_func('gradingform_'.$method.'_controller::get_external_instance_filling_details'); 1701 if (!empty($details)) { 1702 $items = array(); 1703 foreach ($details as $key => $value) { 1704 $value->required = VALUE_OPTIONAL; 1705 unset($value->content->keys['id']); 1706 $items[$key] = new external_multiple_structure (new external_single_structure( 1707 array( 1708 'criterionid' => new external_value(PARAM_INT, 'criterion id'), 1709 'fillings' => $value 1710 ) 1711 )); 1712 } 1713 $advancedgradingdata[$method] = new external_single_structure($items, 'items', VALUE_OPTIONAL); 1714 } 1715 } 1716 1717 return new external_function_parameters( 1718 array( 1719 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 1720 'userid' => new external_value(PARAM_INT, 'The student id to operate on'), 1721 'grade' => new external_value(PARAM_FLOAT, 'The new grade for this user. Ignored if advanced grading used'), 1722 'attemptnumber' => new external_value(PARAM_INT, 'The attempt number (-1 means latest attempt)'), 1723 'addattempt' => new external_value(PARAM_BOOL, 'Allow another attempt if the attempt reopen method is manual'), 1724 'workflowstate' => new external_value(PARAM_ALPHA, 'The next marking workflow state'), 1725 'applytoall' => new external_value(PARAM_BOOL, 'If true, this grade will be applied ' . 1726 'to all members ' . 1727 'of the group (for group assignments).'), 1728 'plugindata' => new external_single_structure($pluginfeedbackparams, 'plugin data', VALUE_DEFAULT, array()), 1729 'advancedgradingdata' => new external_single_structure($advancedgradingdata, 'advanced grading data', 1730 VALUE_DEFAULT, array()) 1731 ) 1732 ); 1733 } 1734 1735 /** 1736 * Save a student grade for a single assignment. 1737 * 1738 * @param int $assignmentid The id of the assignment 1739 * @param int $userid The id of the user 1740 * @param float $grade The grade (ignored if the assignment uses advanced grading) 1741 * @param int $attemptnumber The attempt number 1742 * @param bool $addattempt Allow another attempt 1743 * @param string $workflowstate New workflow state 1744 * @param bool $applytoall Apply the grade to all members of the group 1745 * @param array $plugindata Custom data used by plugins 1746 * @param array $advancedgradingdata Advanced grading data 1747 * @return null 1748 * @since Moodle 2.6 1749 */ 1750 public static function save_grade($assignmentid, 1751 $userid, 1752 $grade, 1753 $attemptnumber, 1754 $addattempt, 1755 $workflowstate, 1756 $applytoall, 1757 $plugindata = array(), 1758 $advancedgradingdata = array()) { 1759 global $CFG, $USER; 1760 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1761 1762 $params = self::validate_parameters(self::save_grade_parameters(), 1763 array('assignmentid' => $assignmentid, 1764 'userid' => $userid, 1765 'grade' => $grade, 1766 'attemptnumber' => $attemptnumber, 1767 'workflowstate' => $workflowstate, 1768 'addattempt' => $addattempt, 1769 'applytoall' => $applytoall, 1770 'plugindata' => $plugindata, 1771 'advancedgradingdata' => $advancedgradingdata)); 1772 1773 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 1774 $context = context_module::instance($cm->id); 1775 self::validate_context($context); 1776 1777 $assignment = new assign($context, $cm, null); 1778 1779 $gradedata = (object)$params['plugindata']; 1780 1781 $gradedata->addattempt = $params['addattempt']; 1782 $gradedata->attemptnumber = $params['attemptnumber']; 1783 $gradedata->workflowstate = $params['workflowstate']; 1784 $gradedata->applytoall = $params['applytoall']; 1785 $gradedata->grade = $params['grade']; 1786 1787 if (!empty($params['advancedgradingdata'])) { 1788 $advancedgrading = array(); 1789 $criteria = reset($params['advancedgradingdata']); 1790 foreach ($criteria as $key => $criterion) { 1791 $details = array(); 1792 foreach ($criterion as $value) { 1793 foreach ($value['fillings'] as $filling) { 1794 $details[$value['criterionid']] = $filling; 1795 } 1796 } 1797 $advancedgrading[$key] = $details; 1798 } 1799 $gradedata->advancedgrading = $advancedgrading; 1800 } 1801 1802 $assignment->save_grade($params['userid'], $gradedata); 1803 1804 return null; 1805 } 1806 1807 /** 1808 * Describes the return value for save_grade 1809 * 1810 * @return external_single_structure 1811 * @since Moodle 2.6 1812 */ 1813 public static function save_grade_returns() { 1814 return null; 1815 } 1816 1817 /** 1818 * Describes the parameters for save_grades 1819 * @return external_external_function_parameters 1820 * @since Moodle 2.7 1821 */ 1822 public static function save_grades_parameters() { 1823 global $CFG; 1824 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1825 require_once("$CFG->dirroot/grade/grading/lib.php"); 1826 $instance = new assign(null, null, null); 1827 $pluginfeedbackparams = array(); 1828 1829 foreach ($instance->get_feedback_plugins() as $plugin) { 1830 $pluginparams = $plugin->get_external_parameters(); 1831 if (!empty($pluginparams)) { 1832 $pluginfeedbackparams = array_merge($pluginfeedbackparams, $pluginparams); 1833 } 1834 } 1835 1836 $advancedgradingdata = array(); 1837 $methods = array_keys(grading_manager::available_methods(false)); 1838 foreach ($methods as $method) { 1839 require_once($CFG->dirroot.'/grade/grading/form/'.$method.'/lib.php'); 1840 $details = call_user_func('gradingform_'.$method.'_controller::get_external_instance_filling_details'); 1841 if (!empty($details)) { 1842 $items = array(); 1843 foreach ($details as $key => $value) { 1844 $value->required = VALUE_OPTIONAL; 1845 unset($value->content->keys['id']); 1846 $items[$key] = new external_multiple_structure (new external_single_structure( 1847 array( 1848 'criterionid' => new external_value(PARAM_INT, 'criterion id'), 1849 'fillings' => $value 1850 ) 1851 )); 1852 } 1853 $advancedgradingdata[$method] = new external_single_structure($items, 'items', VALUE_OPTIONAL); 1854 } 1855 } 1856 1857 return new external_function_parameters( 1858 array( 1859 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 1860 'applytoall' => new external_value(PARAM_BOOL, 'If true, this grade will be applied ' . 1861 'to all members ' . 1862 'of the group (for group assignments).'), 1863 'grades' => new external_multiple_structure( 1864 new external_single_structure( 1865 array ( 1866 'userid' => new external_value(PARAM_INT, 'The student id to operate on'), 1867 'grade' => new external_value(PARAM_FLOAT, 'The new grade for this user. '. 1868 'Ignored if advanced grading used'), 1869 'attemptnumber' => new external_value(PARAM_INT, 'The attempt number (-1 means latest attempt)'), 1870 'addattempt' => new external_value(PARAM_BOOL, 'Allow another attempt if manual attempt reopen method'), 1871 'workflowstate' => new external_value(PARAM_ALPHA, 'The next marking workflow state'), 1872 'plugindata' => new external_single_structure($pluginfeedbackparams, 'plugin data', 1873 VALUE_DEFAULT, array()), 1874 'advancedgradingdata' => new external_single_structure($advancedgradingdata, 'advanced grading data', 1875 VALUE_DEFAULT, array()) 1876 ) 1877 ) 1878 ) 1879 ) 1880 ); 1881 } 1882 1883 /** 1884 * Save multiple student grades for a single assignment. 1885 * 1886 * @param int $assignmentid The id of the assignment 1887 * @param boolean $applytoall If set to true and this is a team assignment, 1888 * apply the grade to all members of the group 1889 * @param array $grades grade data for one or more students that includes 1890 * userid - The id of the student being graded 1891 * grade - The grade (ignored if the assignment uses advanced grading) 1892 * attemptnumber - The attempt number 1893 * addattempt - Allow another attempt 1894 * workflowstate - New workflow state 1895 * plugindata - Custom data used by plugins 1896 * advancedgradingdata - Optional Advanced grading data 1897 * @throws invalid_parameter_exception if multiple grades are supplied for 1898 * a team assignment that has $applytoall set to true 1899 * @return null 1900 * @since Moodle 2.7 1901 */ 1902 public static function save_grades($assignmentid, $applytoall = false, $grades) { 1903 global $CFG, $USER; 1904 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1905 1906 $params = self::validate_parameters(self::save_grades_parameters(), 1907 array('assignmentid' => $assignmentid, 1908 'applytoall' => $applytoall, 1909 'grades' => $grades)); 1910 1911 $cm = get_coursemodule_from_instance('assign', $params['assignmentid'], 0, false, MUST_EXIST); 1912 $context = context_module::instance($cm->id); 1913 self::validate_context($context); 1914 $assignment = new assign($context, $cm, null); 1915 1916 if ($assignment->get_instance()->teamsubmission && $params['applytoall']) { 1917 // Check that only 1 user per submission group is provided. 1918 $groupids = array(); 1919 foreach ($params['grades'] as $gradeinfo) { 1920 $group = $assignment->get_submission_group($gradeinfo['userid']); 1921 if (in_array($group->id, $groupids)) { 1922 throw new invalid_parameter_exception('Multiple grades for the same team have been supplied ' 1923 .' this is not permitted when the applytoall flag is set'); 1924 } else { 1925 $groupids[] = $group->id; 1926 } 1927 } 1928 } 1929 1930 foreach ($params['grades'] as $gradeinfo) { 1931 $gradedata = (object)$gradeinfo['plugindata']; 1932 $gradedata->addattempt = $gradeinfo['addattempt']; 1933 $gradedata->attemptnumber = $gradeinfo['attemptnumber']; 1934 $gradedata->workflowstate = $gradeinfo['workflowstate']; 1935 $gradedata->applytoall = $params['applytoall']; 1936 $gradedata->grade = $gradeinfo['grade']; 1937 1938 if (!empty($gradeinfo['advancedgradingdata'])) { 1939 $advancedgrading = array(); 1940 $criteria = reset($gradeinfo['advancedgradingdata']); 1941 foreach ($criteria as $key => $criterion) { 1942 $details = array(); 1943 foreach ($criterion as $value) { 1944 foreach ($value['fillings'] as $filling) { 1945 $details[$value['criterionid']] = $filling; 1946 } 1947 } 1948 $advancedgrading[$key] = $details; 1949 } 1950 $gradedata->advancedgrading = $advancedgrading; 1951 } 1952 $assignment->save_grade($gradeinfo['userid'], $gradedata); 1953 } 1954 1955 return null; 1956 } 1957 1958 /** 1959 * Describes the return value for save_grades 1960 * 1961 * @return external_single_structure 1962 * @since Moodle 2.7 1963 */ 1964 public static function save_grades_returns() { 1965 return null; 1966 } 1967 1968 /** 1969 * Describes the parameters for copy_previous_attempt 1970 * @return external_external_function_parameters 1971 * @since Moodle 2.6 1972 */ 1973 public static function copy_previous_attempt_parameters() { 1974 return new external_function_parameters( 1975 array( 1976 'assignmentid' => new external_value(PARAM_INT, 'The assignment id to operate on'), 1977 ) 1978 ); 1979 } 1980 1981 /** 1982 * Copy a students previous attempt to a new attempt. 1983 * 1984 * @param int $assignmentid 1985 * @return array of warnings to indicate any errors. 1986 * @since Moodle 2.6 1987 */ 1988 public static function copy_previous_attempt($assignmentid) { 1989 global $CFG, $USER; 1990 require_once("$CFG->dirroot/mod/assign/locallib.php"); 1991 1992 $params = self::validate_parameters(self::copy_previous_attempt_parameters(), 1993 array('assignmentid' => $assignmentid)); 1994 1995 $cm = get_coursemodule_from_instance('assign', $assignmentid, 0, false, MUST_EXIST); 1996 $context = context_module::instance($cm->id); 1997 self::validate_context($context); 1998 1999 $assignment = new assign($context, $cm, null); 2000 2001 $notices = array(); 2002 2003 $assignment->copy_previous_attempt($submissiondata, $notices); 2004 2005 $warnings = array(); 2006 foreach ($notices as $notice) { 2007 $warnings[] = self::generate_warning($assignmentid, 2008 'couldnotcopyprevioussubmission', 2009 $notice); 2010 } 2011 2012 return $warnings; 2013 } 2014 2015 /** 2016 * Describes the return value for save_submission 2017 * 2018 * @return external_single_structure 2019 * @since Moodle 2.6 2020 */ 2021 public static function copy_previous_attempt_returns() { 2022 return new external_multiple_structure( 2023 new external_warnings() 2024 ); 2025 } 2026 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |