MDL-61502 questions: add filter tests to gapselect question type.
[moodle.git] / enrol / externallib.php
blob15f3dd9713cfc5b17779c24de14593de3b1e3359
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.
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/>.
18 /**
19 * External course participation api.
21 * This api is mostly read only, the actual enrol and unenrol
22 * support is in each enrol plugin.
24 * @package core_enrol
25 * @category external
26 * @copyright 2010 Jerome Mouneyrac
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30 defined('MOODLE_INTERNAL') || die();
32 require_once("$CFG->libdir/externallib.php");
34 /**
35 * Enrol external functions
37 * @package core_enrol
38 * @category external
39 * @copyright 2011 Jerome Mouneyrac
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41 * @since Moodle 2.2
43 class core_enrol_external extends external_api {
45 /**
46 * Returns description of method parameters
48 * @return external_function_parameters
49 * @since Moodle 2.4
51 public static function get_enrolled_users_with_capability_parameters() {
52 return new external_function_parameters(
53 array (
54 'coursecapabilities' => new external_multiple_structure(
55 new external_single_structure(
56 array (
57 'courseid' => new external_value(PARAM_INT, 'Course ID number in the Moodle course table'),
58 'capabilities' => new external_multiple_structure(
59 new external_value(PARAM_CAPABILITY, 'Capability name, such as mod/forum:viewdiscussion')),
62 , 'course id and associated capability name'),
63 'options' => new external_multiple_structure(
64 new external_single_structure(
65 array(
66 'name' => new external_value(PARAM_ALPHANUMEXT, 'option name'),
67 'value' => new external_value(PARAM_RAW, 'option value')
69 ), 'Option names:
70 * groupid (integer) return only users in this group id. Requires \'moodle/site:accessallgroups\' .
71 * onlyactive (integer) only users with active enrolments. Requires \'moodle/course:enrolreview\' .
72 * userfields (\'string, string, ...\') return only the values of these user fields.
73 * limitfrom (integer) sql limit from.
74 * limitnumber (integer) max number of users per course and capability.', VALUE_DEFAULT, array())
79 /**
80 * Return users that have the capabilities for each course specified. For each course and capability specified,
81 * a list of the users that are enrolled in the course and have that capability are returned.
83 * @param array $coursecapabilities array of course ids and associated capability names {courseid, {capabilities}}
84 * @return array An array of arrays describing users for each associated courseid and capability
85 * @since Moodle 2.4
87 public static function get_enrolled_users_with_capability($coursecapabilities, $options) {
88 global $CFG, $DB;
89 require_once($CFG->dirroot . "/user/lib.php");
91 if (empty($coursecapabilities)) {
92 throw new invalid_parameter_exception('Parameter can not be empty');
94 $params = self::validate_parameters(self::get_enrolled_users_with_capability_parameters(),
95 array ('coursecapabilities' => $coursecapabilities, 'options'=>$options));
96 $result = array();
97 $userlist = array();
98 $groupid = 0;
99 $onlyactive = false;
100 $userfields = array();
101 $limitfrom = 0;
102 $limitnumber = 0;
103 foreach ($params['options'] as $option) {
104 switch ($option['name']) {
105 case 'groupid':
106 $groupid = (int)$option['value'];
107 break;
108 case 'onlyactive':
109 $onlyactive = !empty($option['value']);
110 break;
111 case 'userfields':
112 $thefields = explode(',', $option['value']);
113 foreach ($thefields as $f) {
114 $userfields[] = clean_param($f, PARAM_ALPHANUMEXT);
116 break;
117 case 'limitfrom' :
118 $limitfrom = clean_param($option['value'], PARAM_INT);
119 break;
120 case 'limitnumber' :
121 $limitnumber = clean_param($option['value'], PARAM_INT);
122 break;
126 foreach ($params['coursecapabilities'] as $coursecapability) {
127 $courseid = $coursecapability['courseid'];
128 $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
129 $coursecontext = context_course::instance($courseid);
130 if (!$coursecontext) {
131 throw new moodle_exception('cannotfindcourse', 'error', '', null,
132 'The course id ' . $courseid . ' doesn\'t exist.');
134 if ($courseid == SITEID) {
135 $context = context_system::instance();
136 } else {
137 $context = $coursecontext;
139 try {
140 self::validate_context($context);
141 } catch (Exception $e) {
142 $exceptionparam = new stdClass();
143 $exceptionparam->message = $e->getMessage();
144 $exceptionparam->courseid = $params['courseid'];
145 throw new moodle_exception(get_string('errorcoursecontextnotvalid' , 'webservice', $exceptionparam));
148 if ($courseid == SITEID) {
149 require_capability('moodle/site:viewparticipants', $context);
150 } else {
151 require_capability('moodle/course:viewparticipants', $context);
153 // The accessallgroups capability is needed to use this option.
154 if (!empty($groupid) && groups_is_member($groupid)) {
155 require_capability('moodle/site:accessallgroups', $coursecontext);
157 // The course:enrolereview capability is needed to use this option.
158 if ($onlyactive) {
159 require_capability('moodle/course:enrolreview', $coursecontext);
162 // To see the permissions of others role:review capability is required.
163 require_capability('moodle/role:review', $coursecontext);
164 foreach ($coursecapability['capabilities'] as $capability) {
165 $courseusers['courseid'] = $courseid;
166 $courseusers['capability'] = $capability;
168 list($enrolledsql, $enrolledparams) = get_enrolled_sql($coursecontext, $capability, $groupid, $onlyactive);
170 $sql = "SELECT u.* FROM {user} u WHERE u.id IN ($enrolledsql) ORDER BY u.id ASC";
172 $enrolledusers = $DB->get_recordset_sql($sql, $enrolledparams, $limitfrom, $limitnumber);
173 $users = array();
174 foreach ($enrolledusers as $courseuser) {
175 if ($userdetails = user_get_user_details($courseuser, $course, $userfields)) {
176 $users[] = $userdetails;
179 $enrolledusers->close();
180 $courseusers['users'] = $users;
181 $result[] = $courseusers;
184 return $result;
188 * Returns description of method result value
190 * @return external_multiple_structure
191 * @since Moodle 2.4
193 public static function get_enrolled_users_with_capability_returns() {
194 return new external_multiple_structure( new external_single_structure (
195 array (
196 'courseid' => new external_value(PARAM_INT, 'Course ID number in the Moodle course table'),
197 'capability' => new external_value(PARAM_CAPABILITY, 'Capability name'),
198 'users' => new external_multiple_structure(
199 new external_single_structure(
200 array(
201 'id' => new external_value(PARAM_INT, 'ID of the user'),
202 'username' => new external_value(PARAM_RAW, 'Username', VALUE_OPTIONAL),
203 'firstname' => new external_value(PARAM_NOTAGS, 'The first name(s) of the user', VALUE_OPTIONAL),
204 'lastname' => new external_value(PARAM_NOTAGS, 'The family name of the user', VALUE_OPTIONAL),
205 'fullname' => new external_value(PARAM_NOTAGS, 'The fullname of the user'),
206 'email' => new external_value(PARAM_TEXT, 'Email address', VALUE_OPTIONAL),
207 'address' => new external_value(PARAM_MULTILANG, 'Postal address', VALUE_OPTIONAL),
208 'phone1' => new external_value(PARAM_NOTAGS, 'Phone 1', VALUE_OPTIONAL),
209 'phone2' => new external_value(PARAM_NOTAGS, 'Phone 2', VALUE_OPTIONAL),
210 'icq' => new external_value(PARAM_NOTAGS, 'icq number', VALUE_OPTIONAL),
211 'skype' => new external_value(PARAM_NOTAGS, 'skype id', VALUE_OPTIONAL),
212 'yahoo' => new external_value(PARAM_NOTAGS, 'yahoo id', VALUE_OPTIONAL),
213 'aim' => new external_value(PARAM_NOTAGS, 'aim id', VALUE_OPTIONAL),
214 'msn' => new external_value(PARAM_NOTAGS, 'msn number', VALUE_OPTIONAL),
215 'department' => new external_value(PARAM_TEXT, 'department', VALUE_OPTIONAL),
216 'institution' => new external_value(PARAM_TEXT, 'institution', VALUE_OPTIONAL),
217 'interests' => new external_value(PARAM_TEXT, 'user interests (separated by commas)', VALUE_OPTIONAL),
218 'firstaccess' => new external_value(PARAM_INT, 'first access to the site (0 if never)', VALUE_OPTIONAL),
219 'lastaccess' => new external_value(PARAM_INT, 'last access to the site (0 if never)', VALUE_OPTIONAL),
220 'description' => new external_value(PARAM_RAW, 'User profile description', VALUE_OPTIONAL),
221 'descriptionformat' => new external_value(PARAM_INT, 'User profile description format', VALUE_OPTIONAL),
222 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL),
223 'url' => new external_value(PARAM_URL, 'URL of the user', VALUE_OPTIONAL),
224 'country' => new external_value(PARAM_ALPHA, 'Country code of the user, such as AU or CZ', VALUE_OPTIONAL),
225 'profileimageurlsmall' => new external_value(PARAM_URL, 'User image profile URL - small', VALUE_OPTIONAL),
226 'profileimageurl' => new external_value(PARAM_URL, 'User image profile URL - big', VALUE_OPTIONAL),
227 'customfields' => new external_multiple_structure(
228 new external_single_structure(
229 array(
230 'type' => new external_value(PARAM_ALPHANUMEXT, 'The type of the custom field'),
231 'value' => new external_value(PARAM_RAW, 'The value of the custom field'),
232 'name' => new external_value(PARAM_RAW, 'The name of the custom field'),
233 'shortname' => new external_value(PARAM_RAW, 'The shortname of the custom field'),
235 ), 'User custom fields (also known as user profil fields)', VALUE_OPTIONAL),
236 'groups' => new external_multiple_structure(
237 new external_single_structure(
238 array(
239 'id' => new external_value(PARAM_INT, 'group id'),
240 'name' => new external_value(PARAM_RAW, 'group name'),
241 'description' => new external_value(PARAM_RAW, 'group description'),
243 ), 'user groups', VALUE_OPTIONAL),
244 'roles' => new external_multiple_structure(
245 new external_single_structure(
246 array(
247 'roleid' => new external_value(PARAM_INT, 'role id'),
248 'name' => new external_value(PARAM_RAW, 'role name'),
249 'shortname' => new external_value(PARAM_ALPHANUMEXT, 'role shortname'),
250 'sortorder' => new external_value(PARAM_INT, 'role sortorder')
252 ), 'user roles', VALUE_OPTIONAL),
253 'preferences' => new external_multiple_structure(
254 new external_single_structure(
255 array(
256 'name' => new external_value(PARAM_RAW, 'The name of the preferences'),
257 'value' => new external_value(PARAM_RAW, 'The value of the custom field'),
259 ), 'User preferences', VALUE_OPTIONAL),
260 'enrolledcourses' => new external_multiple_structure(
261 new external_single_structure(
262 array(
263 'id' => new external_value(PARAM_INT, 'Id of the course'),
264 'fullname' => new external_value(PARAM_RAW, 'Fullname of the course'),
265 'shortname' => new external_value(PARAM_RAW, 'Shortname of the course')
267 ), 'Courses where the user is enrolled - limited by which courses the user is able to see', VALUE_OPTIONAL)
269 ), 'List of users that are enrolled in the course and have the specified capability'),
276 * Returns description of method parameters
278 * @return external_function_parameters
280 public static function get_users_courses_parameters() {
281 return new external_function_parameters(
282 array(
283 'userid' => new external_value(PARAM_INT, 'user id'),
289 * Get list of courses user is enrolled in (only active enrolments are returned).
290 * Please note the current user must be able to access the course, otherwise the course is not included.
292 * @param int $userid
293 * @return array of courses
295 public static function get_users_courses($userid) {
296 global $USER, $DB;
298 // Do basic automatic PARAM checks on incoming data, using params description
299 // If any problems are found then exceptions are thrown with helpful error messages
300 $params = self::validate_parameters(self::get_users_courses_parameters(), array('userid'=>$userid));
302 $courses = enrol_get_users_courses($params['userid'], true, 'id, shortname, fullname, idnumber, visible,
303 summary, summaryformat, format, showgrades, lang, enablecompletion, category, startdate, enddate');
304 $result = array();
306 foreach ($courses as $course) {
307 $context = context_course::instance($course->id, IGNORE_MISSING);
308 try {
309 self::validate_context($context);
310 } catch (Exception $e) {
311 // current user can not access this course, sorry we can not disclose who is enrolled in this course!
312 continue;
315 if ($userid != $USER->id and !has_capability('moodle/course:viewparticipants', $context)) {
316 // we need capability to view participants
317 continue;
320 list($enrolledsqlselect, $enrolledparams) = get_enrolled_sql($context);
321 $enrolledsql = "SELECT COUNT('x') FROM ($enrolledsqlselect) enrolleduserids";
322 $enrolledusercount = $DB->count_records_sql($enrolledsql, $enrolledparams);
324 list($course->summary, $course->summaryformat) =
325 external_format_text($course->summary, $course->summaryformat, $context->id, 'course', 'summary', null);
326 $course->fullname = external_format_string($course->fullname, $context->id);
327 $course->shortname = external_format_string($course->shortname, $context->id);
329 $progress = null;
330 if ($course->enablecompletion) {
331 $progress = \core_completion\progress::get_course_progress_percentage($course);
334 $result[] = array(
335 'id' => $course->id,
336 'shortname' => $course->shortname,
337 'fullname' => $course->fullname,
338 'idnumber' => $course->idnumber,
339 'visible' => $course->visible,
340 'enrolledusercount' => $enrolledusercount,
341 'summary' => $course->summary,
342 'summaryformat' => $course->summaryformat,
343 'format' => $course->format,
344 'showgrades' => $course->showgrades,
345 'lang' => clean_param($course->lang, PARAM_LANG),
346 'enablecompletion' => $course->enablecompletion,
347 'category' => $course->category,
348 'progress' => $progress,
349 'startdate' => $course->startdate,
350 'enddate' => $course->enddate,
354 return $result;
358 * Returns description of method result value
360 * @return external_description
362 public static function get_users_courses_returns() {
363 return new external_multiple_structure(
364 new external_single_structure(
365 array(
366 'id' => new external_value(PARAM_INT, 'id of course'),
367 'shortname' => new external_value(PARAM_RAW, 'short name of course'),
368 'fullname' => new external_value(PARAM_RAW, 'long name of course'),
369 'enrolledusercount' => new external_value(PARAM_INT, 'Number of enrolled users in this course'),
370 'idnumber' => new external_value(PARAM_RAW, 'id number of course'),
371 'visible' => new external_value(PARAM_INT, '1 means visible, 0 means hidden course'),
372 'summary' => new external_value(PARAM_RAW, 'summary', VALUE_OPTIONAL),
373 'summaryformat' => new external_format_value('summary', VALUE_OPTIONAL),
374 'format' => new external_value(PARAM_PLUGIN, 'course format: weeks, topics, social, site', VALUE_OPTIONAL),
375 'showgrades' => new external_value(PARAM_BOOL, 'true if grades are shown, otherwise false', VALUE_OPTIONAL),
376 'lang' => new external_value(PARAM_LANG, 'forced course language', VALUE_OPTIONAL),
377 'enablecompletion' => new external_value(PARAM_BOOL, 'true if completion is enabled, otherwise false',
378 VALUE_OPTIONAL),
379 'category' => new external_value(PARAM_INT, 'course category id', VALUE_OPTIONAL),
380 'progress' => new external_value(PARAM_FLOAT, 'Progress percentage', VALUE_OPTIONAL),
381 'startdate' => new external_value(PARAM_INT, 'Timestamp when the course start', VALUE_OPTIONAL),
382 'enddate' => new external_value(PARAM_INT, 'Timestamp when the course end', VALUE_OPTIONAL),
389 * Returns description of method parameters
391 * @return external_function_parameters
393 public static function get_enrolled_users_parameters() {
394 return new external_function_parameters(
395 array(
396 'courseid' => new external_value(PARAM_INT, 'course id'),
397 'options' => new external_multiple_structure(
398 new external_single_structure(
399 array(
400 'name' => new external_value(PARAM_ALPHANUMEXT, 'option name'),
401 'value' => new external_value(PARAM_RAW, 'option value')
403 ), 'Option names:
404 * withcapability (string) return only users with this capability. This option requires \'moodle/role:review\' on the course context.
405 * groupid (integer) return only users in this group id. If the course has groups enabled and this param
406 isn\'t defined, returns all the viewable users.
407 This option requires \'moodle/site:accessallgroups\' on the course context if the
408 user doesn\'t belong to the group.
409 * onlyactive (integer) return only users with active enrolments and matching time restrictions. This option requires \'moodle/course:enrolreview\' on the course context.
410 * userfields (\'string, string, ...\') return only the values of these user fields.
411 * limitfrom (integer) sql limit from.
412 * limitnumber (integer) maximum number of returned users.
413 * sortby (string) sort by id, firstname or lastname. For ordering like the site does, use siteorder.
414 * sortdirection (string) ASC or DESC',
415 VALUE_DEFAULT, array()),
421 * Get course participants details
423 * @param int $courseid course id
424 * @param array $options options {
425 * 'name' => option name
426 * 'value' => option value
428 * @return array An array of users
430 public static function get_enrolled_users($courseid, $options = array()) {
431 global $CFG, $USER, $DB;
432 require_once($CFG->dirroot . "/user/lib.php");
434 $params = self::validate_parameters(
435 self::get_enrolled_users_parameters(),
436 array(
437 'courseid'=>$courseid,
438 'options'=>$options
441 $withcapability = '';
442 $groupid = 0;
443 $onlyactive = false;
444 $userfields = array();
445 $limitfrom = 0;
446 $limitnumber = 0;
447 $sortby = 'us.id';
448 $sortparams = array();
449 $sortdirection = 'ASC';
450 foreach ($options as $option) {
451 switch ($option['name']) {
452 case 'withcapability':
453 $withcapability = $option['value'];
454 break;
455 case 'groupid':
456 $groupid = (int)$option['value'];
457 break;
458 case 'onlyactive':
459 $onlyactive = !empty($option['value']);
460 break;
461 case 'userfields':
462 $thefields = explode(',', $option['value']);
463 foreach ($thefields as $f) {
464 $userfields[] = clean_param($f, PARAM_ALPHANUMEXT);
466 break;
467 case 'limitfrom' :
468 $limitfrom = clean_param($option['value'], PARAM_INT);
469 break;
470 case 'limitnumber' :
471 $limitnumber = clean_param($option['value'], PARAM_INT);
472 break;
473 case 'sortby':
474 $sortallowedvalues = array('id', 'firstname', 'lastname', 'siteorder');
475 if (!in_array($option['value'], $sortallowedvalues)) {
476 throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $option['value'] . '),' .
477 'allowed values are: ' . implode(',', $sortallowedvalues));
479 if ($option['value'] == 'siteorder') {
480 list($sortby, $sortparams) = users_order_by_sql('us');
481 } else {
482 $sortby = 'us.' . $option['value'];
484 break;
485 case 'sortdirection':
486 $sortdirection = strtoupper($option['value']);
487 $directionallowedvalues = array('ASC', 'DESC');
488 if (!in_array($sortdirection, $directionallowedvalues)) {
489 throw new invalid_parameter_exception('Invalid value for sortdirection parameter
490 (value: ' . $sortdirection . '),' . 'allowed values are: ' . implode(',', $directionallowedvalues));
492 break;
496 $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
497 $coursecontext = context_course::instance($courseid, IGNORE_MISSING);
498 if ($courseid == SITEID) {
499 $context = context_system::instance();
500 } else {
501 $context = $coursecontext;
503 try {
504 self::validate_context($context);
505 } catch (Exception $e) {
506 $exceptionparam = new stdClass();
507 $exceptionparam->message = $e->getMessage();
508 $exceptionparam->courseid = $params['courseid'];
509 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
512 if ($courseid == SITEID) {
513 require_capability('moodle/site:viewparticipants', $context);
514 } else {
515 require_capability('moodle/course:viewparticipants', $context);
517 // to overwrite this parameter, you need role:review capability
518 if ($withcapability) {
519 require_capability('moodle/role:review', $coursecontext);
521 // need accessallgroups capability if you want to overwrite this option
522 if (!empty($groupid) && !groups_is_member($groupid)) {
523 require_capability('moodle/site:accessallgroups', $coursecontext);
525 // to overwrite this option, you need course:enrolereview permission
526 if ($onlyactive) {
527 require_capability('moodle/course:enrolreview', $coursecontext);
530 list($enrolledsql, $enrolledparams) = get_enrolled_sql($coursecontext, $withcapability, $groupid, $onlyactive);
531 $ctxselect = ', ' . context_helper::get_preload_record_columns_sql('ctx');
532 $ctxjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel)";
533 $enrolledparams['contextlevel'] = CONTEXT_USER;
535 $groupjoin = '';
536 if (empty($groupid) && groups_get_course_groupmode($course) == SEPARATEGROUPS &&
537 !has_capability('moodle/site:accessallgroups', $coursecontext)) {
538 // Filter by groups the user can view.
539 $usergroups = groups_get_user_groups($course->id);
540 if (!empty($usergroups['0'])) {
541 list($groupsql, $groupparams) = $DB->get_in_or_equal($usergroups['0'], SQL_PARAMS_NAMED);
542 $groupjoin = "JOIN {groups_members} gm ON (u.id = gm.userid AND gm.groupid $groupsql)";
543 $enrolledparams = array_merge($enrolledparams, $groupparams);
544 } else {
545 // User doesn't belong to any group, so he can't see any user. Return an empty array.
546 return array();
549 $sql = "SELECT us.*
550 FROM {user} us
551 JOIN (
552 SELECT DISTINCT u.id $ctxselect
553 FROM {user} u $ctxjoin $groupjoin
554 WHERE u.id IN ($enrolledsql)
555 ) q ON q.id = us.id
556 ORDER BY $sortby $sortdirection";
557 $enrolledparams = array_merge($enrolledparams, $sortparams);
558 $enrolledusers = $DB->get_recordset_sql($sql, $enrolledparams, $limitfrom, $limitnumber);
559 $users = array();
560 foreach ($enrolledusers as $user) {
561 context_helper::preload_from_record($user);
562 if ($userdetails = user_get_user_details($user, $course, $userfields)) {
563 $users[] = $userdetails;
566 $enrolledusers->close();
568 return $users;
572 * Returns description of method result value
574 * @return external_description
576 public static function get_enrolled_users_returns() {
577 return new external_multiple_structure(
578 new external_single_structure(
579 array(
580 'id' => new external_value(PARAM_INT, 'ID of the user'),
581 'username' => new external_value(PARAM_RAW, 'Username policy is defined in Moodle security config', VALUE_OPTIONAL),
582 'firstname' => new external_value(PARAM_NOTAGS, 'The first name(s) of the user', VALUE_OPTIONAL),
583 'lastname' => new external_value(PARAM_NOTAGS, 'The family name of the user', VALUE_OPTIONAL),
584 'fullname' => new external_value(PARAM_NOTAGS, 'The fullname of the user'),
585 'email' => new external_value(PARAM_TEXT, 'An email address - allow email as root@localhost', VALUE_OPTIONAL),
586 'address' => new external_value(PARAM_TEXT, 'Postal address', VALUE_OPTIONAL),
587 'phone1' => new external_value(PARAM_NOTAGS, 'Phone 1', VALUE_OPTIONAL),
588 'phone2' => new external_value(PARAM_NOTAGS, 'Phone 2', VALUE_OPTIONAL),
589 'icq' => new external_value(PARAM_NOTAGS, 'icq number', VALUE_OPTIONAL),
590 'skype' => new external_value(PARAM_NOTAGS, 'skype id', VALUE_OPTIONAL),
591 'yahoo' => new external_value(PARAM_NOTAGS, 'yahoo id', VALUE_OPTIONAL),
592 'aim' => new external_value(PARAM_NOTAGS, 'aim id', VALUE_OPTIONAL),
593 'msn' => new external_value(PARAM_NOTAGS, 'msn number', VALUE_OPTIONAL),
594 'department' => new external_value(PARAM_TEXT, 'department', VALUE_OPTIONAL),
595 'institution' => new external_value(PARAM_TEXT, 'institution', VALUE_OPTIONAL),
596 'idnumber' => new external_value(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution', VALUE_OPTIONAL),
597 'interests' => new external_value(PARAM_TEXT, 'user interests (separated by commas)', VALUE_OPTIONAL),
598 'firstaccess' => new external_value(PARAM_INT, 'first access to the site (0 if never)', VALUE_OPTIONAL),
599 'lastaccess' => new external_value(PARAM_INT, 'last access to the site (0 if never)', VALUE_OPTIONAL),
600 'description' => new external_value(PARAM_RAW, 'User profile description', VALUE_OPTIONAL),
601 'descriptionformat' => new external_format_value('description', VALUE_OPTIONAL),
602 'city' => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL),
603 'url' => new external_value(PARAM_URL, 'URL of the user', VALUE_OPTIONAL),
604 'country' => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL),
605 'profileimageurlsmall' => new external_value(PARAM_URL, 'User image profile URL - small version', VALUE_OPTIONAL),
606 'profileimageurl' => new external_value(PARAM_URL, 'User image profile URL - big version', VALUE_OPTIONAL),
607 'customfields' => new external_multiple_structure(
608 new external_single_structure(
609 array(
610 'type' => new external_value(PARAM_ALPHANUMEXT, 'The type of the custom field - text field, checkbox...'),
611 'value' => new external_value(PARAM_RAW, 'The value of the custom field'),
612 'name' => new external_value(PARAM_RAW, 'The name of the custom field'),
613 'shortname' => new external_value(PARAM_RAW, 'The shortname of the custom field - to be able to build the field class in the code'),
615 ), 'User custom fields (also known as user profil fields)', VALUE_OPTIONAL),
616 'groups' => new external_multiple_structure(
617 new external_single_structure(
618 array(
619 'id' => new external_value(PARAM_INT, 'group id'),
620 'name' => new external_value(PARAM_RAW, 'group name'),
621 'description' => new external_value(PARAM_RAW, 'group description'),
622 'descriptionformat' => new external_format_value('description'),
624 ), 'user groups', VALUE_OPTIONAL),
625 'roles' => new external_multiple_structure(
626 new external_single_structure(
627 array(
628 'roleid' => new external_value(PARAM_INT, 'role id'),
629 'name' => new external_value(PARAM_RAW, 'role name'),
630 'shortname' => new external_value(PARAM_ALPHANUMEXT, 'role shortname'),
631 'sortorder' => new external_value(PARAM_INT, 'role sortorder')
633 ), 'user roles', VALUE_OPTIONAL),
634 'preferences' => new external_multiple_structure(
635 new external_single_structure(
636 array(
637 'name' => new external_value(PARAM_RAW, 'The name of the preferences'),
638 'value' => new external_value(PARAM_RAW, 'The value of the custom field'),
640 ), 'User preferences', VALUE_OPTIONAL),
641 'enrolledcourses' => new external_multiple_structure(
642 new external_single_structure(
643 array(
644 'id' => new external_value(PARAM_INT, 'Id of the course'),
645 'fullname' => new external_value(PARAM_RAW, 'Fullname of the course'),
646 'shortname' => new external_value(PARAM_RAW, 'Shortname of the course')
648 ), 'Courses where the user is enrolled - limited by which courses the user is able to see', VALUE_OPTIONAL)
655 * Returns description of get_course_enrolment_methods() parameters
657 * @return external_function_parameters
659 public static function get_course_enrolment_methods_parameters() {
660 return new external_function_parameters(
661 array(
662 'courseid' => new external_value(PARAM_INT, 'Course id')
668 * Get list of active course enrolment methods for current user.
670 * @param int $courseid
671 * @return array of course enrolment methods
672 * @throws moodle_exception
674 public static function get_course_enrolment_methods($courseid) {
675 global $DB;
677 $params = self::validate_parameters(self::get_course_enrolment_methods_parameters(), array('courseid' => $courseid));
678 self::validate_context(context_system::instance());
680 $course = $DB->get_record('course', array('id' => $params['courseid']), '*', MUST_EXIST);
681 $context = context_course::instance($course->id);
682 if (!$course->visible and !has_capability('moodle/course:viewhiddencourses', $context)) {
683 throw new moodle_exception('coursehidden');
686 $result = array();
687 $enrolinstances = enrol_get_instances($params['courseid'], true);
688 foreach ($enrolinstances as $enrolinstance) {
689 if ($enrolplugin = enrol_get_plugin($enrolinstance->enrol)) {
690 if ($instanceinfo = $enrolplugin->get_enrol_info($enrolinstance)) {
691 $result[] = (array) $instanceinfo;
695 return $result;
699 * Returns description of get_course_enrolment_methods() result value
701 * @return external_description
703 public static function get_course_enrolment_methods_returns() {
704 return new external_multiple_structure(
705 new external_single_structure(
706 array(
707 'id' => new external_value(PARAM_INT, 'id of course enrolment instance'),
708 'courseid' => new external_value(PARAM_INT, 'id of course'),
709 'type' => new external_value(PARAM_PLUGIN, 'type of enrolment plugin'),
710 'name' => new external_value(PARAM_RAW, 'name of enrolment plugin'),
711 'status' => new external_value(PARAM_RAW, 'status of enrolment plugin'),
712 'wsfunction' => new external_value(PARAM_ALPHANUMEXT, 'webservice function to get more information', VALUE_OPTIONAL),
720 * Role external functions
722 * @package core_role
723 * @category external
724 * @copyright 2011 Jerome Mouneyrac
725 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
726 * @since Moodle 2.2
728 class core_role_external extends external_api {
731 * Returns description of method parameters
733 * @return external_function_parameters
735 public static function assign_roles_parameters() {
736 return new external_function_parameters(
737 array(
738 'assignments' => new external_multiple_structure(
739 new external_single_structure(
740 array(
741 'roleid' => new external_value(PARAM_INT, 'Role to assign to the user'),
742 'userid' => new external_value(PARAM_INT, 'The user that is going to be assigned'),
743 'contextid' => new external_value(PARAM_INT, 'The context to assign the user role in', VALUE_OPTIONAL),
744 'contextlevel' => new external_value(PARAM_ALPHA, 'The context level to assign the user role in
745 (block, course, coursecat, system, user, module)', VALUE_OPTIONAL),
746 'instanceid' => new external_value(PARAM_INT, 'The Instance id of item where the role needs to be assigned', VALUE_OPTIONAL),
755 * Manual role assignments to users
757 * @param array $assignments An array of manual role assignment
759 public static function assign_roles($assignments) {
760 global $DB;
762 // Do basic automatic PARAM checks on incoming data, using params description
763 // If any problems are found then exceptions are thrown with helpful error messages
764 $params = self::validate_parameters(self::assign_roles_parameters(), array('assignments'=>$assignments));
766 $transaction = $DB->start_delegated_transaction();
768 foreach ($params['assignments'] as $assignment) {
769 // Ensure correct context level with a instance id or contextid is passed.
770 $context = self::get_context_from_params($assignment);
772 // Ensure the current user is allowed to run this function in the enrolment context.
773 self::validate_context($context);
774 require_capability('moodle/role:assign', $context);
776 // throw an exception if user is not able to assign the role in this context
777 $roles = get_assignable_roles($context, ROLENAME_SHORT);
779 if (!array_key_exists($assignment['roleid'], $roles)) {
780 throw new invalid_parameter_exception('Can not assign roleid='.$assignment['roleid'].' in contextid='.$assignment['contextid']);
783 role_assign($assignment['roleid'], $assignment['userid'], $context->id);
786 $transaction->allow_commit();
790 * Returns description of method result value
792 * @return null
794 public static function assign_roles_returns() {
795 return null;
800 * Returns description of method parameters
802 * @return external_function_parameters
804 public static function unassign_roles_parameters() {
805 return new external_function_parameters(
806 array(
807 'unassignments' => new external_multiple_structure(
808 new external_single_structure(
809 array(
810 'roleid' => new external_value(PARAM_INT, 'Role to assign to the user'),
811 'userid' => new external_value(PARAM_INT, 'The user that is going to be assigned'),
812 'contextid' => new external_value(PARAM_INT, 'The context to unassign the user role from', VALUE_OPTIONAL),
813 'contextlevel' => new external_value(PARAM_ALPHA, 'The context level to unassign the user role in
814 + (block, course, coursecat, system, user, module)', VALUE_OPTIONAL),
815 'instanceid' => new external_value(PARAM_INT, 'The Instance id of item where the role needs to be unassigned', VALUE_OPTIONAL),
824 * Unassign roles from users
826 * @param array $unassignments An array of unassignment
828 public static function unassign_roles($unassignments) {
829 global $DB;
831 // Do basic automatic PARAM checks on incoming data, using params description
832 // If any problems are found then exceptions are thrown with helpful error messages
833 $params = self::validate_parameters(self::unassign_roles_parameters(), array('unassignments'=>$unassignments));
835 $transaction = $DB->start_delegated_transaction();
837 foreach ($params['unassignments'] as $unassignment) {
838 // Ensure the current user is allowed to run this function in the unassignment context
839 $context = self::get_context_from_params($unassignment);
840 self::validate_context($context);
841 require_capability('moodle/role:assign', $context);
843 // throw an exception if user is not able to unassign the role in this context
844 $roles = get_assignable_roles($context, ROLENAME_SHORT);
845 if (!array_key_exists($unassignment['roleid'], $roles)) {
846 throw new invalid_parameter_exception('Can not unassign roleid='.$unassignment['roleid'].' in contextid='.$unassignment['contextid']);
849 role_unassign($unassignment['roleid'], $unassignment['userid'], $context->id);
852 $transaction->allow_commit();
856 * Returns description of method result value
858 * @return null
860 public static function unassign_roles_returns() {
861 return null;