Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 310 and 401] [Versions 310 and 402] [Versions 310 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; 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 257 // Check if current user has visibility on this activity. 258 if (!$activity->uservisible) { 259 continue; 260 } 261 262 // Get progress information and state (we must use get_data because it works for all user roles in course). 263 $activitycompletiondata = $completion->get_data($activity, true, $user->id); 264 265 $results[] = array( 266 'cmid' => $activity->id, 267 'modname' => $activity->modname, 268 'instance' => $activity->instance, 269 'state' => $activitycompletiondata->completionstate, 270 'timecompleted' => $activitycompletiondata->timemodified, 271 'tracking' => $activity->completion, 272 'overrideby' => $activitycompletiondata->overrideby, 273 'valueused' => core_availability\info::completion_value_used($course, $activity->id) 274 ); 275 } 276 277 $results = array( 278 'statuses' => $results, 279 'warnings' => $warnings 280 ); 281 return $results; 282 } 283 284 /** 285 * Returns description of method result value 286 * 287 * @return external_description 288 * @since Moodle 2.9 289 */ 290 public static function get_activities_completion_status_returns() { 291 return new external_single_structure( 292 array( 293 'statuses' => new external_multiple_structure( 294 new external_single_structure( 295 array( 296 'cmid' => new external_value(PARAM_INT, 'comment ID'), 297 'modname' => new external_value(PARAM_PLUGIN, 'activity module name'), 298 'instance' => new external_value(PARAM_INT, 'instance ID'), 299 'state' => new external_value(PARAM_INT, 'completion state value: 300 0 means incomplete, 1 complete, 301 2 complete pass, 3 complete fail'), 302 'timecompleted' => new external_value(PARAM_INT, 'timestamp for completed activity'), 303 'tracking' => new external_value(PARAM_INT, 'type of tracking: 304 0 means none, 1 manual, 2 automatic'), 305 'overrideby' => new external_value(PARAM_INT, 'The user id who has overriden the status, or null', 306 VALUE_OPTIONAL), 307 'valueused' => new external_value(PARAM_BOOL, 'Whether the completion status affects the availability 308 of another activity.', VALUE_OPTIONAL), 309 ), 'Activity' 310 ), 'List of activities status' 311 ), 312 'warnings' => new external_warnings() 313 ) 314 ); 315 } 316 317 /** 318 * Returns description of method parameters 319 * 320 * @return external_function_parameters 321 * @since Moodle 2.9 322 */ 323 public static function get_course_completion_status_parameters() { 324 return new external_function_parameters( 325 array( 326 'courseid' => new external_value(PARAM_INT, 'Course ID'), 327 'userid' => new external_value(PARAM_INT, 'User ID'), 328 ) 329 ); 330 } 331 /** 332 * Get Course completion status 333 * 334 * @param int $courseid ID of the Course 335 * @param int $userid ID of the User 336 * @return array of course completion status and warnings 337 * @since Moodle 2.9 338 * @throws moodle_exception 339 */ 340 public static function get_course_completion_status($courseid, $userid) { 341 global $CFG, $USER; 342 require_once($CFG->libdir . '/grouplib.php'); 343 344 $warnings = array(); 345 $arrayparams = array( 346 'courseid' => $courseid, 347 'userid' => $userid, 348 ); 349 $params = self::validate_parameters(self::get_course_completion_status_parameters(), $arrayparams); 350 351 $course = get_course($params['courseid']); 352 $user = core_user::get_user($params['userid'], '*', MUST_EXIST); 353 core_user::require_active_user($user); 354 355 $context = context_course::instance($course->id); 356 self::validate_context($context); 357 358 // Can current user see user's course completion status? 359 // This check verifies if completion is enabled because $course is mandatory. 360 if (!completion_can_view_data($user->id, $course)) { 361 throw new moodle_exception('cannotviewreport'); 362 } 363 364 // The previous function doesn't check groups. 365 if ($user->id != $USER->id) { 366 if (!groups_user_groups_visible($course, $user->id)) { 367 // We are not in the same group! 368 throw new moodle_exception('accessdenied', 'admin'); 369 } 370 } 371 372 $info = new completion_info($course); 373 374 // Check this user is enroled. 375 if (!$info->is_tracked_user($user->id)) { 376 if ($USER->id == $user->id) { 377 throw new moodle_exception('notenroled', 'completion'); 378 } else { 379 throw new moodle_exception('usernotenroled', 'completion'); 380 } 381 } 382 383 $completions = $info->get_completions($user->id); 384 if (empty($completions)) { 385 throw new moodle_exception('nocriteriaset', 'completion'); 386 } 387 388 // Load course completion. 389 $completionparams = array( 390 'userid' => $user->id, 391 'course' => $course->id, 392 ); 393 $ccompletion = new completion_completion($completionparams); 394 395 $completionrows = array(); 396 // Loop through course criteria. 397 foreach ($completions as $completion) { 398 $criteria = $completion->get_criteria(); 399 400 $completionrow = array(); 401 $completionrow['type'] = $criteria->criteriatype; 402 $completionrow['title'] = $criteria->get_title(); 403 $completionrow['status'] = $completion->get_status(); 404 $completionrow['complete'] = $completion->is_complete(); 405 $completionrow['timecompleted'] = $completion->timecompleted; 406 $completionrow['details'] = $criteria->get_details($completion); 407 $completionrows[] = $completionrow; 408 } 409 410 $result = array( 411 'completed' => $info->is_course_complete($user->id), 412 'aggregation' => $info->get_aggregation_method(), 413 'completions' => $completionrows 414 ); 415 416 $results = array( 417 'completionstatus' => $result, 418 'warnings' => $warnings 419 ); 420 return $results; 421 422 } 423 /** 424 * Returns description of method result value 425 * 426 * @return external_description 427 * @since Moodle 2.9 428 */ 429 public static function get_course_completion_status_returns() { 430 return new external_single_structure( 431 array( 432 'completionstatus' => new external_single_structure( 433 array( 434 'completed' => new external_value(PARAM_BOOL, 'true if the course is complete, false otherwise'), 435 'aggregation' => new external_value(PARAM_INT, 'aggregation method 1 means all, 2 means any'), 436 'completions' => new external_multiple_structure( 437 new external_single_structure( 438 array( 439 'type' => new external_value(PARAM_INT, 'Completion criteria type'), 440 'title' => new external_value(PARAM_TEXT, 'Completion criteria Title'), 441 'status' => new external_value(PARAM_NOTAGS, 'Completion status (Yes/No) a % or number'), 442 'complete' => new external_value(PARAM_BOOL, 'Completion status (true/false)'), 443 'timecompleted' => new external_value(PARAM_INT, 'Timestamp for criteria completetion'), 444 'details' => new external_single_structure( 445 array( 446 'type' => new external_value(PARAM_TEXT, 'Type description'), 447 'criteria' => new external_value(PARAM_RAW, 'Criteria description'), 448 'requirement' => new external_value(PARAM_TEXT, 'Requirement description'), 449 'status' => new external_value(PARAM_RAW, 'Status description, can be anything'), 450 ), 'details'), 451 ), 'Completions' 452 ), '' 453 ) 454 ), 'Course status' 455 ), 456 'warnings' => new external_warnings() 457 ), 'Course completion status' 458 ); 459 } 460 461 /** 462 * Describes the parameters for mark_course_self_completed. 463 * 464 * @return external_function_parameters 465 * @since Moodle 3.0 466 */ 467 public static function mark_course_self_completed_parameters() { 468 return new external_function_parameters ( 469 array( 470 'courseid' => new external_value(PARAM_INT, 'Course ID') 471 ) 472 ); 473 } 474 475 /** 476 * Update the course completion status for the current user (if course self-completion is enabled). 477 * 478 * @param int $courseid Course id 479 * @return array Result and possible warnings 480 * @since Moodle 3.0 481 * @throws moodle_exception 482 */ 483 public static function mark_course_self_completed($courseid) { 484 global $USER; 485 486 $warnings = array(); 487 $params = self::validate_parameters(self::mark_course_self_completed_parameters(), 488 array('courseid' => $courseid)); 489 490 $course = get_course($params['courseid']); 491 $context = context_course::instance($course->id); 492 self::validate_context($context); 493 494 // Set up completion object and check it is enabled. 495 $completion = new completion_info($course); 496 if (!$completion->is_enabled()) { 497 throw new moodle_exception('completionnotenabled', 'completion'); 498 } 499 500 if (!$completion->is_tracked_user($USER->id)) { 501 throw new moodle_exception('nottracked', 'completion'); 502 } 503 504 $completion = $completion->get_completion($USER->id, COMPLETION_CRITERIA_TYPE_SELF); 505 506 // Self completion criteria not enabled. 507 if (!$completion) { 508 throw new moodle_exception('noselfcompletioncriteria', 'completion'); 509 } 510 511 // Check if the user has already marked himself as complete. 512 if ($completion->is_complete()) { 513 throw new moodle_exception('useralreadymarkedcomplete', 'completion'); 514 } 515 516 // Mark the course complete. 517 $completion->mark_complete(); 518 519 $result = array(); 520 $result['status'] = true; 521 $result['warnings'] = $warnings; 522 return $result; 523 } 524 525 /** 526 * Describes the mark_course_self_completed return value. 527 * 528 * @return external_single_structure 529 * @since Moodle 3.0 530 */ 531 public static function mark_course_self_completed_returns() { 532 533 return new external_single_structure( 534 array( 535 'status' => new external_value(PARAM_BOOL, 'status, true if success'), 536 'warnings' => new external_warnings(), 537 ) 538 ); 539 } 540 541 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body