See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 and 403]
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 * Completion external API 19 * 20 * @package core_completion 21 * @category external 22 * @copyright 2015 Juan Leyva <juan@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 * @since Moodle 2.9 25 */ 26 27 defined('MOODLE_INTERNAL') || die; 28 29 require_once("$CFG->libdir/externallib.php"); 30 require_once("$CFG->libdir/completionlib.php"); 31 32 /** 33 * Completion external functions 34 * 35 * @package core_completion 36 * @category external 37 * @copyright 2015 Juan Leyva <juan@moodle.com> 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 * @since Moodle 2.9 40 */ 41 class core_completion_external extends external_api { 42 43 /** 44 * Describes the parameters for update_activity_completion_status_manually. 45 * 46 * @return external_function_parameters 47 * @since Moodle 2.9 48 */ 49 public static function update_activity_completion_status_manually_parameters() { 50 return new external_function_parameters ( 51 array( 52 'cmid' => new external_value(PARAM_INT, 'course module id'), 53 'completed' => new external_value(PARAM_BOOL, 'activity completed or not'), 54 ) 55 ); 56 } 57 58 /** 59 * Update completion status for the current user in an activity, only for activities with manual tracking. 60 * @param int $cmid Course module id 61 * @param bool $completed Activity completed or not 62 * @return array Result and possible warnings 63 * @since Moodle 2.9 64 * @throws moodle_exception 65 */ 66 public static function update_activity_completion_status_manually($cmid, $completed) { 67 68 // Validate and normalize parameters. 69 $params = self::validate_parameters(self::update_activity_completion_status_manually_parameters(), 70 array('cmid' => $cmid, 'completed' => $completed)); 71 $cmid = $params['cmid']; 72 $completed = $params['completed']; 73 74 $warnings = array(); 75 76 $context = context_module::instance($cmid); 77 self::validate_context($context); 78 require_capability('moodle/course:togglecompletion', $context); 79 80 list($course, $cm) = get_course_and_cm_from_cmid($cmid); 81 82 // Set up completion object and check it is enabled. 83 $completion = new completion_info($course); 84 if (!$completion->is_enabled()) { 85 throw new moodle_exception('completionnotenabled', 'completion'); 86 } 87 88 // Check completion state is manual. 89 if ($cm->completion != COMPLETION_TRACKING_MANUAL) { 90 throw new moodle_exception('cannotmanualctrack', 'error'); 91 } 92 93 $targetstate = ($completed) ? COMPLETION_COMPLETE : COMPLETION_INCOMPLETE; 94 $completion->update_state($cm, $targetstate); 95 96 $result = array(); 97 $result['status'] = true; 98 $result['warnings'] = $warnings; 99 return $result; 100 } 101 102 /** 103 * Describes the update_activity_completion_status_manually return value. 104 * 105 * @return external_single_structure 106 * @since Moodle 2.9 107 */ 108 public static function update_activity_completion_status_manually_returns() { 109 110 return new external_single_structure( 111 array( 112 'status' => new external_value(PARAM_BOOL, 'status, true if success'), 113 'warnings' => new external_warnings(), 114 ) 115 ); 116 } 117 118 /** 119 * Describes the parameters for override_activity_completion_status. 120 * 121 * @return external_external_function_parameters 122 * @since Moodle 3.4 123 */ 124 public static function override_activity_completion_status_parameters() { 125 return new external_function_parameters ( 126 array( 127 'userid' => new external_value(PARAM_INT, 'user id'), 128 'cmid' => new external_value(PARAM_INT, 'course module id'), 129 'newstate' => new external_value(PARAM_INT, 'the new activity completion state'), 130 ) 131 ); 132 } 133 134 /** 135 * Update completion status for a user in an activity. 136 * @param int $userid User id 137 * @param int $cmid Course module id 138 * @param int $newstate Activity completion 139 * @return array Array containing the current (updated) completion status. 140 * @since Moodle 3.4 141 * @throws moodle_exception 142 */ 143 public static function override_activity_completion_status($userid, $cmid, $newstate) { 144 // Validate and normalize parameters. 145 $params = self::validate_parameters(self::override_activity_completion_status_parameters(), 146 array('userid' => $userid, 'cmid' => $cmid, 'newstate' => $newstate)); 147 $userid = $params['userid']; 148 $cmid = $params['cmid']; 149 $newstate = $params['newstate']; 150 151 $context = context_module::instance($cmid); 152 self::validate_context($context); 153 154 list($course, $cm) = get_course_and_cm_from_cmid($cmid); 155 156 // Set up completion object and check it is enabled. 157 $completion = new completion_info($course); 158 if (!$completion->is_enabled()) { 159 throw new moodle_exception('completionnotenabled', 'completion'); 160 } 161 162 // Update completion state and get the new state back. 163 $completion->update_state($cm, $newstate, $userid, true); 164 $completiondata = $completion->get_data($cm, false, $userid); 165 166 // Return the current state of completion. 167 return [ 168 'cmid' => $completiondata->coursemoduleid, 169 'userid' => $completiondata->userid, 170 'state' => $completiondata->completionstate, 171 'timecompleted' => $completiondata->timemodified, 172 'overrideby' => $completiondata->overrideby, 173 'tracking' => $completion->is_enabled($cm) 174 ]; 175 } 176 177 /** 178 * Describes the override_activity_completion_status return value. 179 * 180 * @return external_single_structure 181 * @since Moodle 3.4 182 */ 183 public static function override_activity_completion_status_returns() { 184 185 return new external_single_structure( 186 array( 187 'cmid' => new external_value(PARAM_INT, 'The course module id'), 188 'userid' => new external_value(PARAM_INT, 'The user id to which the completion info belongs'), 189 'state' => new external_value(PARAM_INT, 'The current completion state.'), 190 'timecompleted' => new external_value(PARAM_INT, 'time of completion'), 191 'overrideby' => new external_value(PARAM_INT, 'The user id who has overriden the status, or null'), 192 'tracking' => new external_value(PARAM_INT, 'type of tracking: 193 0 means none, 1 manual, 2 automatic'), 194 ) 195 ); 196 } 197 198 /** 199 * Returns description of method parameters 200 * 201 * @return external_function_parameters 202 * @since Moodle 2.9 203 */ 204 public static function get_activities_completion_status_parameters() { 205 return new external_function_parameters( 206 array( 207 'courseid' => new external_value(PARAM_INT, 'Course ID'), 208 'userid' => new external_value(PARAM_INT, 'User ID'), 209 ) 210 ); 211 } 212 213 /** 214 * Get Activities completion status 215 * 216 * @param int $courseid ID of the Course 217 * @param int $userid ID of the User 218 * @return array of activities progress and warnings 219 * @throws moodle_exception 220 * @since Moodle 2.9 221 * @throws moodle_exception 222 */ 223 public static function get_activities_completion_status($courseid, $userid) { 224 global $CFG, $USER, $PAGE; 225 require_once($CFG->libdir . '/grouplib.php'); 226 227 $warnings = array(); 228 $arrayparams = array( 229 'courseid' => $courseid, 230 'userid' => $userid, 231 ); 232 233 $params = self::validate_parameters(self::get_activities_completion_status_parameters(), $arrayparams); 234 235 $course = get_course($params['courseid']); 236 $user = core_user::get_user($params['userid'], '*', MUST_EXIST); 237 core_user::require_active_user($user); 238 239 $context = context_course::instance($course->id); 240 self::validate_context($context); 241 242 // Check that current user have permissions to see this user's activities. 243 if ($user->id != $USER->id) { 244 require_capability('report/progress:view', $context); 245 if (!groups_user_groups_visible($course, $user->id)) { 246 // We are not in the same group! 247 throw new moodle_exception('accessdenied', 'admin'); 248 } 249 } 250 251 $completion = new completion_info($course); 252 $activities = $completion->get_activities(); 253 254 $results = array(); 255 foreach ($activities as $activity) { 256 // Check if current user has visibility on this activity. 257 if (!$activity->uservisible) { 258 continue; 259 } 260 // Get progress information and state (we must use get_data because it works for all user roles in course). 261 $exporter = new \core_completion\external\completion_info_exporter( 262 $course, 263 $activity, 264 $userid, 265 ); 266 $renderer = $PAGE->get_renderer('core'); 267 $data = (array)$exporter->export($renderer); 268 $results[] = array_merge([ 269 'cmid' => $activity->id, 270 'modname' => $activity->modname, 271 'instance' => $activity->instance, 272 'tracking' => $activity->completion, 273 ], $data); 274 } 275 276 $results = array( 277 'statuses' => $results, 278 'warnings' => $warnings 279 ); 280 return $results; 281 } 282 283 /** 284 * Returns description of method result value 285 * 286 * @return external_description 287 * @since Moodle 2.9 288 */ 289 public static function get_activities_completion_status_returns() { 290 return new external_single_structure( 291 array( 292 'statuses' => new external_multiple_structure( 293 new external_single_structure( 294 [ 295 'cmid' => new external_value(PARAM_INT, 'course module ID'), 296 'modname' => new external_value(PARAM_PLUGIN, 'activity module name'), 297 'instance' => new external_value(PARAM_INT, 'instance ID'), 298 'state' => new external_value(PARAM_INT, 299 "Completion state value: 300 0 means incomplete, 301 1 complete, 302 2 complete pass, 303 3 complete fail" 304 ), 305 'timecompleted' => new external_value(PARAM_INT, 306 'timestamp for completed activity'), 307 'tracking' => new external_value(PARAM_INT, 308 "type of tracking: 309 0 means none, 310 1 manual, 311 2 automatic" 312 ), 313 'overrideby' => new external_value(PARAM_INT, 314 'The user id who has overriden the status, or null', VALUE_OPTIONAL), 315 'valueused' => new external_value(PARAM_BOOL, 316 'Whether the completion status affects the availability of another activity.', 317 VALUE_OPTIONAL), 318 'hascompletion' => new external_value(PARAM_BOOL, 319 'Whether this activity module has completion enabled', 320 VALUE_OPTIONAL), 321 'isautomatic' => new external_value(PARAM_BOOL, 322 'Whether this activity module instance tracks completion automatically.', 323 VALUE_OPTIONAL), 324 'istrackeduser' => new external_value(PARAM_BOOL, 325 'Whether completion is being tracked for this user.', 326 VALUE_OPTIONAL), 327 'uservisible' => new external_value(PARAM_BOOL, 328 'Whether this activity is visible to the user.', 329 VALUE_OPTIONAL), 330 'details' => new external_multiple_structure( 331 new external_single_structure( 332 [ 333 'rulename' => new external_value(PARAM_TEXT, 'Rule name'), 334 'rulevalue' => new external_single_structure( 335 [ 336 'status' => new external_value(PARAM_INT, 'Completion status'), 337 'description' => new external_value(PARAM_TEXT, 'Completion description'), 338 ] 339 ) 340 ] 341 ), 342 'Completion status details', 343 VALUE_DEFAULT, 344 [] 345 ), 346 347 ], 'Activity' 348 ), 'List of activities status' 349 ), 350 'warnings' => new external_warnings() 351 ) 352 ); 353 } 354 355 /** 356 * Returns description of method parameters 357 * 358 * @return external_function_parameters 359 * @since Moodle 2.9 360 */ 361 public static function get_course_completion_status_parameters() { 362 return new external_function_parameters( 363 array( 364 'courseid' => new external_value(PARAM_INT, 'Course ID'), 365 'userid' => new external_value(PARAM_INT, 'User ID'), 366 ) 367 ); 368 } 369 /** 370 * Get Course completion status 371 * 372 * @param int $courseid ID of the Course 373 * @param int $userid ID of the User 374 * @return array of course completion status and warnings 375 * @since Moodle 2.9 376 * @throws moodle_exception 377 */ 378 public static function get_course_completion_status($courseid, $userid) { 379 global $CFG, $USER; 380 require_once($CFG->libdir . '/grouplib.php'); 381 382 $warnings = array(); 383 $arrayparams = array( 384 'courseid' => $courseid, 385 'userid' => $userid, 386 ); 387 $params = self::validate_parameters(self::get_course_completion_status_parameters(), $arrayparams); 388 389 $course = get_course($params['courseid']); 390 $user = core_user::get_user($params['userid'], '*', MUST_EXIST); 391 core_user::require_active_user($user); 392 393 $context = context_course::instance($course->id); 394 self::validate_context($context); 395 396 // Can current user see user's course completion status? 397 // This check verifies if completion is enabled because $course is mandatory. 398 if (!completion_can_view_data($user->id, $course)) { 399 throw new moodle_exception('cannotviewreport'); 400 } 401 402 // The previous function doesn't check groups. 403 if ($user->id != $USER->id) { 404 if (!groups_user_groups_visible($course, $user->id)) { 405 // We are not in the same group! 406 throw new moodle_exception('accessdenied', 'admin'); 407 } 408 } 409 410 $info = new completion_info($course); 411 412 // Check this user is enroled. 413 if (!$info->is_tracked_user($user->id)) { 414 if ($USER->id == $user->id) { 415 throw new moodle_exception('notenroled', 'completion'); 416 } else { 417 throw new moodle_exception('usernotenroled', 'completion'); 418 } 419 } 420 421 $completions = $info->get_completions($user->id); 422 if (empty($completions)) { 423 throw new moodle_exception('nocriteriaset', 'completion'); 424 } 425 426 // Load course completion. 427 $completionparams = array( 428 'userid' => $user->id, 429 'course' => $course->id, 430 ); 431 $ccompletion = new completion_completion($completionparams); 432 433 $completionrows = array(); 434 // Loop through course criteria. 435 foreach ($completions as $completion) { 436 $criteria = $completion->get_criteria(); 437 438 $completionrow = array(); 439 $completionrow['type'] = $criteria->criteriatype; 440 $completionrow['title'] = $criteria->get_title(); 441 $completionrow['status'] = $completion->get_status(); 442 $completionrow['complete'] = $completion->is_complete(); 443 $completionrow['timecompleted'] = $completion->timecompleted; 444 $completionrow['details'] = $criteria->get_details($completion); 445 $completionrows[] = $completionrow; 446 } 447 448 $result = array( 449 'completed' => $info->is_course_complete($user->id), 450 'aggregation' => $info->get_aggregation_method(), 451 'completions' => $completionrows 452 ); 453 454 $results = array( 455 'completionstatus' => $result, 456 'warnings' => $warnings 457 ); 458 return $results; 459 460 } 461 /** 462 * Returns description of method result value 463 * 464 * @return external_description 465 * @since Moodle 2.9 466 */ 467 public static function get_course_completion_status_returns() { 468 return new external_single_structure( 469 array( 470 'completionstatus' => new external_single_structure( 471 array( 472 'completed' => new external_value(PARAM_BOOL, 'true if the course is complete, false otherwise'), 473 'aggregation' => new external_value(PARAM_INT, 'aggregation method 1 means all, 2 means any'), 474 'completions' => new external_multiple_structure( 475 new external_single_structure( 476 array( 477 'type' => new external_value(PARAM_INT, 'Completion criteria type'), 478 'title' => new external_value(PARAM_TEXT, 'Completion criteria Title'), 479 'status' => new external_value(PARAM_NOTAGS, 'Completion status (Yes/No) a % or number'), 480 'complete' => new external_value(PARAM_BOOL, 'Completion status (true/false)'), 481 'timecompleted' => new external_value(PARAM_INT, 'Timestamp for criteria completetion'), 482 'details' => new external_single_structure( 483 array( 484 'type' => new external_value(PARAM_TEXT, 'Type description'), 485 'criteria' => new external_value(PARAM_RAW, 'Criteria description'), 486 'requirement' => new external_value(PARAM_TEXT, 'Requirement description'), 487 'status' => new external_value(PARAM_RAW, 'Status description, can be anything'), 488 ), 'details'), 489 ), 'Completions' 490 ), '' 491 ) 492 ), 'Course status' 493 ), 494 'warnings' => new external_warnings() 495 ), 'Course completion status' 496 ); 497 } 498 499 /** 500 * Describes the parameters for mark_course_self_completed. 501 * 502 * @return external_function_parameters 503 * @since Moodle 3.0 504 */ 505 public static function mark_course_self_completed_parameters() { 506 return new external_function_parameters ( 507 array( 508 'courseid' => new external_value(PARAM_INT, 'Course ID') 509 ) 510 ); 511 } 512 513 /** 514 * Update the course completion status for the current user (if course self-completion is enabled). 515 * 516 * @param int $courseid Course id 517 * @return array Result and possible warnings 518 * @since Moodle 3.0 519 * @throws moodle_exception 520 */ 521 public static function mark_course_self_completed($courseid) { 522 global $USER; 523 524 $warnings = array(); 525 $params = self::validate_parameters(self::mark_course_self_completed_parameters(), 526 array('courseid' => $courseid)); 527 528 $course = get_course($params['courseid']); 529 $context = context_course::instance($course->id); 530 self::validate_context($context); 531 532 // Set up completion object and check it is enabled. 533 $completion = new completion_info($course); 534 if (!$completion->is_enabled()) { 535 throw new moodle_exception('completionnotenabled', 'completion'); 536 } 537 538 if (!$completion->is_tracked_user($USER->id)) { 539 throw new moodle_exception('nottracked', 'completion'); 540 } 541 542 $completion = $completion->get_completion($USER->id, COMPLETION_CRITERIA_TYPE_SELF); 543 544 // Self completion criteria not enabled. 545 if (!$completion) { 546 throw new moodle_exception('noselfcompletioncriteria', 'completion'); 547 } 548 549 // Check if the user has already marked himself as complete. 550 if ($completion->is_complete()) { 551 throw new moodle_exception('useralreadymarkedcomplete', 'completion'); 552 } 553 554 // Mark the course complete. 555 $completion->mark_complete(); 556 557 $result = array(); 558 $result['status'] = true; 559 $result['warnings'] = $warnings; 560 return $result; 561 } 562 563 /** 564 * Describes the mark_course_self_completed return value. 565 * 566 * @return external_single_structure 567 * @since Moodle 3.0 568 */ 569 public static function mark_course_self_completed_returns() { 570 571 return new external_single_structure( 572 array( 573 'status' => new external_value(PARAM_BOOL, 'status, true if success'), 574 'warnings' => new external_warnings(), 575 ) 576 ); 577 } 578 579 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body