Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]
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 VALUE_DEFAULT, 343 [] 344 ), 345 346 ], 'Activity' 347 ), 'List of activities status' 348 ), 349 'warnings' => new external_warnings() 350 ) 351 ); 352 } 353 354 /** 355 * Returns description of method parameters 356 * 357 * @return external_function_parameters 358 * @since Moodle 2.9 359 */ 360 public static function get_course_completion_status_parameters() { 361 return new external_function_parameters( 362 array( 363 'courseid' => new external_value(PARAM_INT, 'Course ID'), 364 'userid' => new external_value(PARAM_INT, 'User ID'), 365 ) 366 ); 367 } 368 /** 369 * Get Course completion status 370 * 371 * @param int $courseid ID of the Course 372 * @param int $userid ID of the User 373 * @return array of course completion status and warnings 374 * @since Moodle 2.9 375 * @throws moodle_exception 376 */ 377 public static function get_course_completion_status($courseid, $userid) { 378 global $CFG, $USER; 379 require_once($CFG->libdir . '/grouplib.php'); 380 381 $warnings = array(); 382 $arrayparams = array( 383 'courseid' => $courseid, 384 'userid' => $userid, 385 ); 386 $params = self::validate_parameters(self::get_course_completion_status_parameters(), $arrayparams); 387 388 $course = get_course($params['courseid']); 389 $user = core_user::get_user($params['userid'], '*', MUST_EXIST); 390 core_user::require_active_user($user); 391 392 $context = context_course::instance($course->id); 393 self::validate_context($context); 394 395 // Can current user see user's course completion status? 396 // This check verifies if completion is enabled because $course is mandatory. 397 if (!completion_can_view_data($user->id, $course)) { 398 throw new moodle_exception('cannotviewreport'); 399 } 400 401 // The previous function doesn't check groups. 402 if ($user->id != $USER->id) { 403 if (!groups_user_groups_visible($course, $user->id)) { 404 // We are not in the same group! 405 throw new moodle_exception('accessdenied', 'admin'); 406 } 407 } 408 409 $info = new completion_info($course); 410 411 // Check this user is enroled. 412 if (!$info->is_tracked_user($user->id)) { 413 if ($USER->id == $user->id) { 414 throw new moodle_exception('notenroled', 'completion'); 415 } else { 416 throw new moodle_exception('usernotenroled', 'completion'); 417 } 418 } 419 420 $completions = $info->get_completions($user->id); 421 if (empty($completions)) { 422 throw new moodle_exception('nocriteriaset', 'completion'); 423 } 424 425 // Load course completion. 426 $completionparams = array( 427 'userid' => $user->id, 428 'course' => $course->id, 429 ); 430 $ccompletion = new completion_completion($completionparams); 431 432 $completionrows = array(); 433 // Loop through course criteria. 434 foreach ($completions as $completion) { 435 $criteria = $completion->get_criteria(); 436 437 $completionrow = array(); 438 $completionrow['type'] = $criteria->criteriatype; 439 $completionrow['title'] = $criteria->get_title(); 440 $completionrow['status'] = $completion->get_status(); 441 $completionrow['complete'] = $completion->is_complete(); 442 $completionrow['timecompleted'] = $completion->timecompleted; 443 $completionrow['details'] = $criteria->get_details($completion); 444 $completionrows[] = $completionrow; 445 } 446 447 $result = array( 448 'completed' => $info->is_course_complete($user->id), 449 'aggregation' => $info->get_aggregation_method(), 450 'completions' => $completionrows 451 ); 452 453 $results = array( 454 'completionstatus' => $result, 455 'warnings' => $warnings 456 ); 457 return $results; 458 459 } 460 /** 461 * Returns description of method result value 462 * 463 * @return external_description 464 * @since Moodle 2.9 465 */ 466 public static function get_course_completion_status_returns() { 467 return new external_single_structure( 468 array( 469 'completionstatus' => new external_single_structure( 470 array( 471 'completed' => new external_value(PARAM_BOOL, 'true if the course is complete, false otherwise'), 472 'aggregation' => new external_value(PARAM_INT, 'aggregation method 1 means all, 2 means any'), 473 'completions' => new external_multiple_structure( 474 new external_single_structure( 475 array( 476 'type' => new external_value(PARAM_INT, 'Completion criteria type'), 477 'title' => new external_value(PARAM_TEXT, 'Completion criteria Title'), 478 'status' => new external_value(PARAM_NOTAGS, 'Completion status (Yes/No) a % or number'), 479 'complete' => new external_value(PARAM_BOOL, 'Completion status (true/false)'), 480 'timecompleted' => new external_value(PARAM_INT, 'Timestamp for criteria completetion'), 481 'details' => new external_single_structure( 482 array( 483 'type' => new external_value(PARAM_TEXT, 'Type description'), 484 'criteria' => new external_value(PARAM_RAW, 'Criteria description'), 485 'requirement' => new external_value(PARAM_TEXT, 'Requirement description'), 486 'status' => new external_value(PARAM_RAW, 'Status description, can be anything'), 487 ), 'details'), 488 ), 'Completions' 489 ), '' 490 ) 491 ), 'Course status' 492 ), 493 'warnings' => new external_warnings() 494 ), 'Course completion status' 495 ); 496 } 497 498 /** 499 * Describes the parameters for mark_course_self_completed. 500 * 501 * @return external_function_parameters 502 * @since Moodle 3.0 503 */ 504 public static function mark_course_self_completed_parameters() { 505 return new external_function_parameters ( 506 array( 507 'courseid' => new external_value(PARAM_INT, 'Course ID') 508 ) 509 ); 510 } 511 512 /** 513 * Update the course completion status for the current user (if course self-completion is enabled). 514 * 515 * @param int $courseid Course id 516 * @return array Result and possible warnings 517 * @since Moodle 3.0 518 * @throws moodle_exception 519 */ 520 public static function mark_course_self_completed($courseid) { 521 global $USER; 522 523 $warnings = array(); 524 $params = self::validate_parameters(self::mark_course_self_completed_parameters(), 525 array('courseid' => $courseid)); 526 527 $course = get_course($params['courseid']); 528 $context = context_course::instance($course->id); 529 self::validate_context($context); 530 531 // Set up completion object and check it is enabled. 532 $completion = new completion_info($course); 533 if (!$completion->is_enabled()) { 534 throw new moodle_exception('completionnotenabled', 'completion'); 535 } 536 537 if (!$completion->is_tracked_user($USER->id)) { 538 throw new moodle_exception('nottracked', 'completion'); 539 } 540 541 $completion = $completion->get_completion($USER->id, COMPLETION_CRITERIA_TYPE_SELF); 542 543 // Self completion criteria not enabled. 544 if (!$completion) { 545 throw new moodle_exception('noselfcompletioncriteria', 'completion'); 546 } 547 548 // Check if the user has already marked himself as complete. 549 if ($completion->is_complete()) { 550 throw new moodle_exception('useralreadymarkedcomplete', 'completion'); 551 } 552 553 // Mark the course complete. 554 $completion->mark_complete(); 555 556 $result = array(); 557 $result['status'] = true; 558 $result['warnings'] = $warnings; 559 return $result; 560 } 561 562 /** 563 * Describes the mark_course_self_completed return value. 564 * 565 * @return external_single_structure 566 * @since Moodle 3.0 567 */ 568 public static function mark_course_self_completed_returns() { 569 570 return new external_single_structure( 571 array( 572 'status' => new external_value(PARAM_BOOL, 'status, true if success'), 573 'warnings' => new external_warnings(), 574 ) 575 ); 576 } 577 578 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body