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