externallib.php 45.7 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

17

18
/**
19
 * External course participation api.
20
 *
21
22
23
 * This api is mostly read only, the actual enrol and unenrol
 * support is in each enrol plugin.
 *
24
25
26
 * @package    core_enrol
 * @category   external
 * @copyright  2010 Jerome Mouneyrac
27
28
29
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */

Petr Skoda's avatar
Petr Skoda committed
30
defined('MOODLE_INTERNAL') || die();
31

32
33
require_once("$CFG->libdir/externallib.php");

34
/**
35
36
37
38
39
40
41
 * Enrol external functions
 *
 * @package    core_enrol
 * @category   external
 * @copyright  2011 Jerome Mouneyrac
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @since Moodle 2.2
42
43
44
 */
class core_enrol_external extends external_api {

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
    /**
     * Returns description of method parameters
     *
     * @return external_function_parameters
     * @since Moodle 2.4
     */
    public static function get_enrolled_users_with_capability_parameters() {
        return new external_function_parameters(
            array (
                'coursecapabilities' => new external_multiple_structure(
                    new external_single_structure(
                        array (
                            'courseid' => new external_value(PARAM_INT, 'Course ID number in the Moodle course table'),
                            'capabilities' => new external_multiple_structure(
                                new external_value(PARAM_CAPABILITY, 'Capability name, such as mod/forum:viewdiscussion')),
                        )
                    )
                , 'course id and associated capability name'),
                 'options'  => new external_multiple_structure(
                    new external_single_structure(
                        array(
                            'name'  => new external_value(PARAM_ALPHANUMEXT, 'option name'),
                            'value' => new external_value(PARAM_RAW, 'option value')
                        )
                    ), 'Option names:
                            * groupid (integer) return only users in this group id. Requires \'moodle/site:accessallgroups\' .
                            * onlyactive (integer) only users with active enrolments. Requires \'moodle/course:enrolreview\' .
                            * userfields (\'string, string, ...\') return only the values of these user fields.
                            * limitfrom (integer) sql limit from.
                            * limitnumber (integer) max number of users per course and capability.', VALUE_DEFAULT, array())
            )
        );
    }

    /**
     * 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.
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
     *
     * @param array $coursecapabilities array of course ids and associated capability names {courseid, {capabilities}}
     * @return array An array of arrays describing users for each associated courseid and capability
     * @since  Moodle 2.4
     */
    public static function get_enrolled_users_with_capability($coursecapabilities, $options) {
        global $CFG, $DB;
        require_once($CFG->dirroot . "/user/lib.php");

        if (empty($coursecapabilities)) {
            throw new invalid_parameter_exception('Parameter can not be empty');
        }
        $params = self::validate_parameters(self::get_enrolled_users_with_capability_parameters(),
            array ('coursecapabilities' => $coursecapabilities,  'options'=>$options));
        $result = array();
        $userlist = array();
        $groupid        = 0;
        $onlyactive     = false;
        $userfields     = array();
        $limitfrom = 0;
        $limitnumber = 0;
        foreach ($params['options'] as $option) {
            switch ($option['name']) {
                case 'groupid':
                    $groupid = (int)$option['value'];
                    break;
                case 'onlyactive':
                    $onlyactive = !empty($option['value']);
                    break;
                case 'userfields':
                    $thefields = explode(',', $option['value']);
                    foreach ($thefields as $f) {
                        $userfields[] = clean_param($f, PARAM_ALPHANUMEXT);
                    }
                case 'limitfrom' :
                    $limitfrom = clean_param($option['value'], PARAM_INT);
                    break;
                case 'limitnumber' :
                    $limitnumber = clean_param($option['value'], PARAM_INT);
                    break;
            }
        }

        foreach ($params['coursecapabilities'] as $coursecapability) {
            $courseid = $coursecapability['courseid'];
            $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
            $coursecontext = context_course::instance($courseid);
            if (!$coursecontext) {
                throw new moodle_exception('cannotfindcourse', 'error', '', null,
                        'The course id ' . $courseid . ' doesn\'t exist.');
            }
            if ($courseid == SITEID) {
                $context = context_system::instance();
            } else {
                $context = $coursecontext;
            }
            try {
                self::validate_context($context);
            } catch (Exception $e) {
                $exceptionparam = new stdClass();
                $exceptionparam->message = $e->getMessage();
                $exceptionparam->courseid = $params['courseid'];
                throw new moodle_exception(get_string('errorcoursecontextnotvalid' , 'webservice', $exceptionparam));
            }

            if ($courseid == SITEID) {
                require_capability('moodle/site:viewparticipants', $context);
            } else {
                require_capability('moodle/course:viewparticipants', $context);
            }
            // The accessallgroups capability is needed to use this option.
            if (!empty($groupid) && groups_is_member($groupid)) {
                require_capability('moodle/site:accessallgroups', $coursecontext);
            }
            // The course:enrolereview capability is needed to use this option.
            if ($onlyactive) {
                require_capability('moodle/course:enrolreview', $coursecontext);
            }

            // To see the permissions of others role:review capability is required.
            require_capability('moodle/role:review', $coursecontext);
            foreach ($coursecapability['capabilities'] as $capability) {
                $courseusers['courseid'] = $courseid;
                $courseusers['capability'] = $capability;

                list($enrolledsql, $enrolledparams) = get_enrolled_sql($coursecontext, $capability, $groupid, $onlyactive);

                $sql = "SELECT u.* FROM {user} u WHERE u.id IN ($enrolledsql) ORDER BY u.id ASC";

                $enrolledusers = $DB->get_recordset_sql($sql, $enrolledparams, $limitfrom, $limitnumber);
                $users = array();
                foreach ($enrolledusers as $courseuser) {
                    if ($userdetails = user_get_user_details($courseuser, $course, $userfields)) {
                        $users[] = $userdetails;
                    }
                }
                $enrolledusers->close();
                $courseusers['users'] = $users;
                $result[] = $courseusers;
            }
        }
        return $result;
    }

    /**
     * Returns description of method result value
     *
     * @return external_multiple_structure
     * @since Moodle 2.4
     */
    public static function get_enrolled_users_with_capability_returns() {
        return  new external_multiple_structure( new external_single_structure (
                array (
                    'courseid' => new external_value(PARAM_INT, 'Course ID number in the Moodle course table'),
                    'capability' => new external_value(PARAM_CAPABILITY, 'Capability name'),
                    'users' => new external_multiple_structure(
                        new external_single_structure(
                array(
200
                    'id'    => new external_value(PARAM_INT, 'ID of the user'),
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
                    'username'    => new external_value(PARAM_RAW, 'Username', VALUE_OPTIONAL),
                    'firstname'   => new external_value(PARAM_NOTAGS, 'The first name(s) of the user', VALUE_OPTIONAL),
                    'lastname'    => new external_value(PARAM_NOTAGS, 'The family name of the user', VALUE_OPTIONAL),
                    'fullname'    => new external_value(PARAM_NOTAGS, 'The fullname of the user'),
                    'email'       => new external_value(PARAM_TEXT, 'Email address', VALUE_OPTIONAL),
                    'address'     => new external_value(PARAM_MULTILANG, 'Postal address', VALUE_OPTIONAL),
                    'phone1'      => new external_value(PARAM_NOTAGS, 'Phone 1', VALUE_OPTIONAL),
                    'phone2'      => new external_value(PARAM_NOTAGS, 'Phone 2', VALUE_OPTIONAL),
                    'icq'         => new external_value(PARAM_NOTAGS, 'icq number', VALUE_OPTIONAL),
                    'skype'       => new external_value(PARAM_NOTAGS, 'skype id', VALUE_OPTIONAL),
                    'yahoo'       => new external_value(PARAM_NOTAGS, 'yahoo id', VALUE_OPTIONAL),
                    'aim'         => new external_value(PARAM_NOTAGS, 'aim id', VALUE_OPTIONAL),
                    'msn'         => new external_value(PARAM_NOTAGS, 'msn number', VALUE_OPTIONAL),
                    'department'  => new external_value(PARAM_TEXT, 'department', VALUE_OPTIONAL),
                    'institution' => new external_value(PARAM_TEXT, 'institution', VALUE_OPTIONAL),
                    'interests'   => new external_value(PARAM_TEXT, 'user interests (separated by commas)', VALUE_OPTIONAL),
                    'firstaccess' => new external_value(PARAM_INT, 'first access to the site (0 if never)', VALUE_OPTIONAL),
                    'lastaccess'  => new external_value(PARAM_INT, 'last access to the site (0 if never)', VALUE_OPTIONAL),
                    'description' => new external_value(PARAM_RAW, 'User profile description', VALUE_OPTIONAL),
                    'descriptionformat' => new external_value(PARAM_INT, 'User profile description format', VALUE_OPTIONAL),
                    'city'        => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL),
                    'url'         => new external_value(PARAM_URL, 'URL of the user', VALUE_OPTIONAL),
                    'country'     => new external_value(PARAM_ALPHA, 'Country code of the user, such as AU or CZ', VALUE_OPTIONAL),
                    'profileimageurlsmall' => new external_value(PARAM_URL, 'User image profile URL - small', VALUE_OPTIONAL),
                    'profileimageurl' => new external_value(PARAM_URL, 'User image profile URL - big', VALUE_OPTIONAL),
                    'customfields' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'type'  => new external_value(PARAM_ALPHANUMEXT, 'The type of the custom field'),
                                'value' => new external_value(PARAM_RAW, 'The value of the custom field'),
                                'name' => new external_value(PARAM_RAW, 'The name of the custom field'),
                                'shortname' => new external_value(PARAM_RAW, 'The shortname of the custom field'),
                            )
                        ), 'User custom fields (also known as user profil fields)', VALUE_OPTIONAL),
                    'groups' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'id'  => new external_value(PARAM_INT, 'group id'),
                                'name' => new external_value(PARAM_RAW, 'group name'),
                                'description' => new external_value(PARAM_RAW, 'group description'),
                            )
                        ), 'user groups', VALUE_OPTIONAL),
                    'roles' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'roleid'       => new external_value(PARAM_INT, 'role id'),
                                'name'         => new external_value(PARAM_RAW, 'role name'),
                                'shortname'    => new external_value(PARAM_ALPHANUMEXT, 'role shortname'),
                                'sortorder'    => new external_value(PARAM_INT, 'role sortorder')
                            )
                        ), 'user roles', VALUE_OPTIONAL),
                    'preferences' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'name'  => new external_value(PARAM_ALPHANUMEXT, 'The name of the preferences'),
                                'value' => new external_value(PARAM_RAW, 'The value of the custom field'),
                            )
                    ), 'User preferences', VALUE_OPTIONAL),
                    'enrolledcourses' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'id'  => new external_value(PARAM_INT, 'Id of the course'),
                                'fullname' => new external_value(PARAM_RAW, 'Fullname of the course'),
                                'shortname' => new external_value(PARAM_RAW, 'Shortname of the course')
                            )
                    ), 'Courses where the user is enrolled - limited by which courses the user is able to see', VALUE_OPTIONAL)
                )
                        ), 'List of users that are enrolled in the course and have the specified capability'),
                    )
                )
            );
    }

274
275
    /**
     * Returns description of method parameters
276
     *
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
     * @return external_function_parameters
     */
    public static function get_users_courses_parameters() {
        return new external_function_parameters(
            array(
                'userid' => new external_value(PARAM_INT, 'user id'),
            )
        );
    }

    /**
     * Get list of courses user is enrolled in (only active enrolments are returned).
     * Please note the current user must be able to access the course, otherwise the course is not included.
     *
     * @param int $userid
     * @return array of courses
     */
    public static function get_users_courses($userid) {
295
        global $USER, $DB;
296
297
298
299
300
301
302
303
304

        // Do basic automatic PARAM checks on incoming data, using params description
        // If any problems are found then exceptions are thrown with helpful error messages
        $params = self::validate_parameters(self::get_users_courses_parameters(), array('userid'=>$userid));

        $courses = enrol_get_users_courses($params['userid'], true, 'id, shortname, fullname, idnumber, visible');
        $result = array();

        foreach ($courses as $course) {
305
            $context = context_course::instance($course->id, IGNORE_MISSING);
306
307
308
309
310
311
            try {
                self::validate_context($context);
            } catch (Exception $e) {
                // current user can not access this course, sorry we can not disclose who is enrolled in this course!
                continue;
            }
312

313
314
315
316
317
            if ($userid != $USER->id and !has_capability('moodle/course:viewparticipants', $context)) {
                // we need capability to view participants
                continue;
            }

318
            list($enrolledsqlselect, $enrolledparams) = get_enrolled_sql($context);
319
            $enrolledsql = "SELECT COUNT('x') FROM ($enrolledsqlselect) enrolleduserids";
320
321
322
            $enrolledusercount = $DB->count_records_sql($enrolledsql, $enrolledparams);

            $result[] = array('id'=>$course->id, 'shortname'=>$course->shortname, 'fullname'=>$course->fullname, 'idnumber'=>$course->idnumber,'visible'=>$course->visible, 'enrolledusercount'=>$enrolledusercount);
323
        }
324

325
326
327
328
329
        return $result;
    }

    /**
     * Returns description of method result value
330
     *
331
332
333
334
335
336
337
338
339
     * @return external_description
     */
    public static function get_users_courses_returns() {
        return new external_multiple_structure(
            new external_single_structure(
                array(
                    'id'        => new external_value(PARAM_INT, 'id of course'),
                    'shortname' => new external_value(PARAM_RAW, 'short name of course'),
                    'fullname'  => new external_value(PARAM_RAW, 'long name of course'),
340
                    'enrolledusercount' => new external_value(PARAM_INT, 'Number of enrolled users in this course'),
341
342
343
344
345
346
                    'idnumber'  => new external_value(PARAM_RAW, 'id number of course'),
                    'visible'   => new external_value(PARAM_INT, '1 means visible, 0 means hidden course'),
                )
            )
        );
    }
Sam Hemelryk's avatar
Sam Hemelryk committed
347

348
349
    /**
     * Returns description of method parameters
350
     *
351
352
353
354
355
356
357
358
359
360
361
362
     * @return external_function_parameters
     */
    public static function get_enrolled_users_parameters() {
        return new external_function_parameters(
            array(
                'courseid' => new external_value(PARAM_INT, 'course id'),
                'options'  => new external_multiple_structure(
                    new external_single_structure(
                        array(
                            'name'  => new external_value(PARAM_ALPHANUMEXT, 'option name'),
                            'value' => new external_value(PARAM_RAW, 'option value')
                        )
363
364
365
366
367
368
369
                    ), 'Option names:
                            * withcapability (string) return only users with this capability. This option requires \'moodle/role:review\' on the course context.
                            * groupid (integer) return only users in this group id. This option requires \'moodle/site:accessallgroups\' on the course context.
                            * onlyactive (integer) return only users with active enrolments and matching time restrictions. This option requires \'moodle/course:enrolreview\' on the course context.
                            * userfields (\'string, string, ...\') return only the values of these user fields.
                            * limitfrom (integer) sql limit from.
                            * limitnumber (integer) maximum number of returned users.', VALUE_DEFAULT, array()),
370
371
372
373
374
375
            )
        );
    }

    /**
     * Get course participants details
376
     *
377
378
     * @param int $courseid  course id
     * @param array $options options {
379
380
381
     *                                'name' => option name
     *                                'value' => option value
     *                               }
382
383
     * @return array An array of users
     */
384
    public static function get_enrolled_users($courseid, $options = array()) {
385
386
387
388
        global $CFG, $USER, $DB;
        require_once($CFG->dirroot . "/user/lib.php");

        $params = self::validate_parameters(
389
            self::get_enrolled_users_parameters(),
390
391
392
393
394
395
396
397
            array(
                'courseid'=>$courseid,
                'options'=>$options
            )
        );
        $withcapability = '';
        $groupid        = 0;
        $onlyactive     = false;
398
        $userfields     = array();
399
400
        $limitfrom = 0;
        $limitnumber = 0;
401
402
403
404
405
406
407
408
409
410
411
        foreach ($options as $option) {
            switch ($option['name']) {
            case 'withcapability':
                $withcapability = $option['value'];
                break;
            case 'groupid':
                $groupid = (int)$option['value'];
                break;
            case 'onlyactive':
                $onlyactive = !empty($option['value']);
                break;
412
413
414
415
416
            case 'userfields':
                $thefields = explode(',', $option['value']);
                foreach ($thefields as $f) {
                    $userfields[] = clean_param($f, PARAM_ALPHANUMEXT);
                }
417
418
419
420
421
            case 'limitfrom' :
                $limitfrom = clean_param($option['value'], PARAM_INT);
                break;
            case 'limitnumber' :
                $limitnumber = clean_param($option['value'], PARAM_INT);
422
                break;
423
424
425
            }
        }

426
        $course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
427
        $coursecontext = context_course::instance($courseid, IGNORE_MISSING);
428
        if ($courseid == SITEID) {
429
            $context = context_system::instance();
430
431
432
433
434
435
436
437
438
        } else {
            $context = $coursecontext;
        }
        try {
            self::validate_context($context);
        } catch (Exception $e) {
            $exceptionparam = new stdClass();
            $exceptionparam->message = $e->getMessage();
            $exceptionparam->courseid = $params['courseid'];
439
            throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
440
441
        }

442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
        if ($courseid == SITEID) {
            require_capability('moodle/site:viewparticipants', $context);
        } else {
            require_capability('moodle/course:viewparticipants', $context);
        }
        // to overwrite this parameter, you need role:review capability
        if ($withcapability) {
            require_capability('moodle/role:review', $coursecontext);
        }
        // need accessallgroups capability if you want to overwrite this option
        if (!empty($groupid) && groups_is_member($groupid)) {
            require_capability('moodle/site:accessallgroups', $coursecontext);
        }
        // to overwrite this option, you need course:enrolereview permission
        if ($onlyactive) {
            require_capability('moodle/course:enrolreview', $coursecontext);
        }

460
461
462
463
464
465
466
        list($enrolledsql, $enrolledparams) = get_enrolled_sql($coursecontext, $withcapability, $groupid, $onlyactive);
        list($ctxselect, $ctxjoin) = context_instance_preload_sql('u.id', CONTEXT_USER, 'ctx');
        $sqlparams['courseid'] = $courseid;
        $sql = "SELECT u.* $ctxselect
                  FROM {user} u $ctxjoin
                 WHERE u.id IN ($enrolledsql)
                 ORDER BY u.id ASC";
467
        $enrolledusers = $DB->get_recordset_sql($sql, $enrolledparams, $limitfrom, $limitnumber);
468
469
        $users = array();
        foreach ($enrolledusers as $user) {
470
            context_helper::preload_from_record($user);
471
            if ($userdetails = user_get_user_details($user, $course, $userfields)) {
472
473
474
475
476
477
478
                $users[] = $userdetails;
            }
        }
        $enrolledusers->close();

        return $users;
    }
Sam Hemelryk's avatar
Sam Hemelryk committed
479

480
481
    /**
     * Returns description of method result value
482
     *
483
484
485
486
487
488
     * @return external_description
     */
    public static function get_enrolled_users_returns() {
        return new external_multiple_structure(
            new external_single_structure(
                array(
489
                    'id'    => new external_value(PARAM_INT, 'ID of the user'),
490
491
492
493
494
                    'username'    => new external_value(PARAM_RAW, 'Username policy is defined in Moodle security config', VALUE_OPTIONAL),
                    'firstname'   => new external_value(PARAM_NOTAGS, 'The first name(s) of the user', VALUE_OPTIONAL),
                    'lastname'    => new external_value(PARAM_NOTAGS, 'The family name of the user', VALUE_OPTIONAL),
                    'fullname'    => new external_value(PARAM_NOTAGS, 'The fullname of the user'),
                    'email'       => new external_value(PARAM_TEXT, 'An email address - allow email as root@localhost', VALUE_OPTIONAL),
495
                    'address'     => new external_value(PARAM_TEXT, 'Postal address', VALUE_OPTIONAL),
496
497
498
499
500
501
502
503
504
                    'phone1'      => new external_value(PARAM_NOTAGS, 'Phone 1', VALUE_OPTIONAL),
                    'phone2'      => new external_value(PARAM_NOTAGS, 'Phone 2', VALUE_OPTIONAL),
                    'icq'         => new external_value(PARAM_NOTAGS, 'icq number', VALUE_OPTIONAL),
                    'skype'       => new external_value(PARAM_NOTAGS, 'skype id', VALUE_OPTIONAL),
                    'yahoo'       => new external_value(PARAM_NOTAGS, 'yahoo id', VALUE_OPTIONAL),
                    'aim'         => new external_value(PARAM_NOTAGS, 'aim id', VALUE_OPTIONAL),
                    'msn'         => new external_value(PARAM_NOTAGS, 'msn number', VALUE_OPTIONAL),
                    'department'  => new external_value(PARAM_TEXT, 'department', VALUE_OPTIONAL),
                    'institution' => new external_value(PARAM_TEXT, 'institution', VALUE_OPTIONAL),
505
                    'idnumber'    => new external_value(PARAM_RAW, 'An arbitrary ID code number perhaps from the institution', VALUE_OPTIONAL),
506
507
508
509
                    'interests'   => new external_value(PARAM_TEXT, 'user interests (separated by commas)', VALUE_OPTIONAL),
                    'firstaccess' => new external_value(PARAM_INT, 'first access to the site (0 if never)', VALUE_OPTIONAL),
                    'lastaccess'  => new external_value(PARAM_INT, 'last access to the site (0 if never)', VALUE_OPTIONAL),
                    'description' => new external_value(PARAM_RAW, 'User profile description', VALUE_OPTIONAL),
510
                    'descriptionformat' => new external_format_value('description', VALUE_OPTIONAL),
511
512
513
                    'city'        => new external_value(PARAM_NOTAGS, 'Home city of the user', VALUE_OPTIONAL),
                    'url'         => new external_value(PARAM_URL, 'URL of the user', VALUE_OPTIONAL),
                    'country'     => new external_value(PARAM_ALPHA, 'Home country code of the user, such as AU or CZ', VALUE_OPTIONAL),
514
515
                    'profileimageurlsmall' => new external_value(PARAM_URL, 'User image profile URL - small version', VALUE_OPTIONAL),
                    'profileimageurl' => new external_value(PARAM_URL, 'User image profile URL - big version', VALUE_OPTIONAL),
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
                    'customfields' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'type'  => new external_value(PARAM_ALPHANUMEXT, 'The type of the custom field - text field, checkbox...'),
                                'value' => new external_value(PARAM_RAW, 'The value of the custom field'),
                                'name' => new external_value(PARAM_RAW, 'The name of the custom field'),
                                'shortname' => new external_value(PARAM_RAW, 'The shortname of the custom field - to be able to build the field class in the code'),
                            )
                        ), 'User custom fields (also known as user profil fields)', VALUE_OPTIONAL),
                    'groups' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'id'  => new external_value(PARAM_INT, 'group id'),
                                'name' => new external_value(PARAM_RAW, 'group name'),
                                'description' => new external_value(PARAM_RAW, 'group description'),
531
                                'descriptionformat' => new external_format_value('description'),
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
                            )
                        ), 'user groups', VALUE_OPTIONAL),
                    'roles' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'roleid'       => new external_value(PARAM_INT, 'role id'),
                                'name'         => new external_value(PARAM_RAW, 'role name'),
                                'shortname'    => new external_value(PARAM_ALPHANUMEXT, 'role shortname'),
                                'sortorder'    => new external_value(PARAM_INT, 'role sortorder')
                            )
                        ), 'user roles', VALUE_OPTIONAL),
                    'preferences' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'name'  => new external_value(PARAM_ALPHANUMEXT, 'The name of the preferences'),
                                'value' => new external_value(PARAM_RAW, 'The value of the custom field'),
                            )
                    ), 'User preferences', VALUE_OPTIONAL),
                    'enrolledcourses' => new external_multiple_structure(
                        new external_single_structure(
                            array(
                                'id'  => new external_value(PARAM_INT, 'Id of the course'),
                                'fullname' => new external_value(PARAM_RAW, 'Fullname of the course'),
                                'shortname' => new external_value(PARAM_RAW, 'Shortname of the course')
                            )
                    ), 'Courses where the user is enrolled - limited by which courses the user is able to see', VALUE_OPTIONAL)
                )
            )
        );
    }

}

/**
566
567
568
569
570
571
572
 * Role external functions
 *
 * @package    core_role
 * @category   external
 * @copyright  2011 Jerome Mouneyrac
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @since Moodle 2.2
573
574
575
576
577
 */
class core_role_external extends external_api {

    /**
     * Returns description of method parameters
578
     *
579
580
581
582
583
584
585
586
587
588
     * @return external_function_parameters
     */
    public static function assign_roles_parameters() {
        return new external_function_parameters(
            array(
                'assignments' => new external_multiple_structure(
                    new external_single_structure(
                        array(
                            'roleid'    => new external_value(PARAM_INT, 'Role to assign to the user'),
                            'userid'    => new external_value(PARAM_INT, 'The user that is going to be assigned'),
589
590
591
592
                            'contextid' => new external_value(PARAM_INT, 'The context to assign the user role in', VALUE_OPTIONAL),
                            'contextlevel' => new external_value(PARAM_ALPHA, 'The context level to assign the user role in
                                    (block, course, coursecat, system, user, module)', VALUE_OPTIONAL),
                            'instanceid' => new external_value(PARAM_INT, 'The Instance id of item where the role needs to be assigned', VALUE_OPTIONAL),
593
594
595
596
597
598
599
600
601
602
                        )
                    )
                )
            )
        );
    }

    /**
     * Manual role assignments to users
     *
603
     * @param array $assignments An array of manual role assignment
604
605
606
607
608
609
610
611
612
613
614
     */
    public static function assign_roles($assignments) {
        global $DB;

        // Do basic automatic PARAM checks on incoming data, using params description
        // If any problems are found then exceptions are thrown with helpful error messages
        $params = self::validate_parameters(self::assign_roles_parameters(), array('assignments'=>$assignments));

        $transaction = $DB->start_delegated_transaction();

        foreach ($params['assignments'] as $assignment) {
615
            // Ensure correct context level with a instance id or contextid is passed.
616
            $context = self::get_context_from_params($assignment);
617
618

            // Ensure the current user is allowed to run this function in the enrolment context.
619
620
621
622
623
624
            self::validate_context($context);
            require_capability('moodle/role:assign', $context);

            // throw an exception if user is not able to assign the role in this context
            $roles = get_assignable_roles($context, ROLENAME_SHORT);

625
            if (!array_key_exists($assignment['roleid'], $roles)) {
626
627
628
                throw new invalid_parameter_exception('Can not assign roleid='.$assignment['roleid'].' in contextid='.$assignment['contextid']);
            }

629
            role_assign($assignment['roleid'], $assignment['userid'], $context->id);
630
631
632
633
634
635
636
        }

        $transaction->allow_commit();
    }

    /**
     * Returns description of method result value
637
638
     *
     * @return null
639
640
641
642
643
644
645
646
     */
    public static function assign_roles_returns() {
        return null;
    }


    /**
     * Returns description of method parameters
647
     *
648
649
650
651
652
653
654
655
656
657
     * @return external_function_parameters
     */
    public static function unassign_roles_parameters() {
        return new external_function_parameters(
            array(
                'unassignments' => new external_multiple_structure(
                    new external_single_structure(
                        array(
                            'roleid'    => new external_value(PARAM_INT, 'Role to assign to the user'),
                            'userid'    => new external_value(PARAM_INT, 'The user that is going to be assigned'),
658
659
660
661
                            'contextid' => new external_value(PARAM_INT, 'The context to unassign the user role from', VALUE_OPTIONAL),
                            'contextlevel' => new external_value(PARAM_ALPHA, 'The context level to unassign the user role in
+                                    (block, course, coursecat, system, user, module)', VALUE_OPTIONAL),
                            'instanceid' => new external_value(PARAM_INT, 'The Instance id of item where the role needs to be unassigned', VALUE_OPTIONAL),
662
663
664
665
666
667
668
669
670
671
                        )
                    )
                )
            )
        );
    }

     /**
     * Unassign roles from users
     *
672
     * @param array $unassignments An array of unassignment
673
674
675
676
677
678
679
680
681
682
683
684
     */
    public static function unassign_roles($unassignments) {
         global $DB;

        // Do basic automatic PARAM checks on incoming data, using params description
        // If any problems are found then exceptions are thrown with helpful error messages
        $params = self::validate_parameters(self::unassign_roles_parameters(), array('unassignments'=>$unassignments));

        $transaction = $DB->start_delegated_transaction();

        foreach ($params['unassignments'] as $unassignment) {
            // Ensure the current user is allowed to run this function in the unassignment context
685
            $context = self::get_context_from_params($unassignment);
686
687
688
689
690
            self::validate_context($context);
            require_capability('moodle/role:assign', $context);

            // throw an exception if user is not able to unassign the role in this context
            $roles = get_assignable_roles($context, ROLENAME_SHORT);
691
            if (!array_key_exists($unassignment['roleid'], $roles)) {
692
693
694
                throw new invalid_parameter_exception('Can not unassign roleid='.$unassignment['roleid'].' in contextid='.$unassignment['contextid']);
            }

695
            role_unassign($unassignment['roleid'], $unassignment['userid'], $context->id);
696
697
698
699
700
701
702
        }

        $transaction->allow_commit();
    }

   /**
     * Returns description of method result value
703
     *
704
705
706
707
708
709
710
711
712
     * @return null
     */
    public static function unassign_roles_returns() {
        return null;
    }
}


/**
713
714
715
716
717
718
719
720
721
 * Deprecated enrol and role external functions
 *
 * @package    core_enrol
 * @copyright  2010 Jerome Mouneyrac
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 * @since Moodle 2.0
 * @deprecated Moodle 2.2 MDL-29106 - Please do not use this class any more.
 * @see core_enrol_external
 * @see core_role_external
722
 */
723
724
class moodle_enrol_external extends external_api {

725

726
727
    /**
     * Returns description of method parameters
728
     *
729
     * @return external_function_parameters
730
731
732
     * @since Moodle 2.0
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_enrol_external::get_enrolled_users_parameters()
733
     */
734
    public static function get_enrolled_users_parameters() {
735
736
737
        return new external_function_parameters(
            array(
                'courseid'       => new external_value(PARAM_INT, 'Course id'),
738
739
740
                'withcapability' => new external_value(PARAM_CAPABILITY, 'User should have this capability', VALUE_DEFAULT, null),
                'groupid'        => new external_value(PARAM_INT, 'Group id, null means all groups', VALUE_DEFAULT, null),
                'onlyactive'     => new external_value(PARAM_INT, 'True means only active, false means all participants', VALUE_DEFAULT, 0),
741
742
743
744
745
746
            )
        );
    }

    /**
     * Get list of course participants.
747
     *
748
749
750
751
752
     * @param int $courseid
     * @param text $withcapability
     * @param int $groupid
     * @param bool $onlyactive
     * @return array of course participants
753
754
755
     * @since Moodle 2.0
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_enrol_external::get_enrolled_users()
756
     */
757
758
    public static function get_enrolled_users($courseid, $withcapability = null, $groupid = null, $onlyactive = false) {
        global $DB, $CFG, $USER;
759
760
761

        // Do basic automatic PARAM checks on incoming data, using params description
        // If any problems are found then exceptions are thrown with helpful error messages
762
763
764
765
766
767
        $params = self::validate_parameters(self::get_enrolled_users_parameters(), array(
            'courseid'=>$courseid,
            'withcapability'=>$withcapability,
            'groupid'=>$groupid,
            'onlyactive'=>$onlyactive)
        );
768

769
        $coursecontext = context_course::instance($params['courseid'], IGNORE_MISSING);
770
        if ($courseid == SITEID) {
771
            $context = context_system::instance();
772
773
774
775
        } else {
            $context = $coursecontext;
        }

776
777
778
        try {
            self::validate_context($context);
        } catch (Exception $e) {
779
780
781
            $exceptionparam = new stdClass();
            $exceptionparam->message = $e->getMessage();
            $exceptionparam->courseid = $params['courseid'];
782
            throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
783
        }
784
785
786
787
788
789
790
791
792
793

        if ($courseid == SITEID) {
            require_capability('moodle/site:viewparticipants', $context);
        } else {
            require_capability('moodle/course:viewparticipants', $context);
        }

        if ($withcapability) {
            require_capability('moodle/role:review', $coursecontext);
        }
794
795
        if ($groupid && groups_is_member($groupid)) {
            require_capability('moodle/site:accessallgroups', $coursecontext);
796
        }
797
        if ($onlyactive) {
798
799
800
            require_capability('moodle/course:enrolreview', $coursecontext);
        }

801
802
        list($sqlparams, $params) =  get_enrolled_sql($coursecontext, $withcapability, $groupid, $onlyactive);
        $sql = "SELECT ue.userid, e.courseid, u.firstname, u.lastname, u.username, c.id as usercontextid
803
804
                  FROM {user_enrolments} ue
                  JOIN {enrol} e ON (e.id = ue.enrolid)
805
806
807
808
                  JOIN {user} u ON (ue.userid = u.id)
                  JOIN {context} c ON (u.id = c.instanceid AND contextlevel = " . CONTEXT_USER . ")
                  WHERE e.courseid = :courseid AND ue.userid IN ($sqlparams)
                  GROUP BY ue.userid, e.courseid, u.firstname, u.lastname, u.username, c.id";
809
        $params['courseid'] = $courseid;
810
811
        $enrolledusers = $DB->get_records_sql($sql, $params);
        $result = array();
812
813
        $isadmin = is_siteadmin($USER);
        $canviewfullnames = has_capability('moodle/site:viewfullnames', $context);
814
        foreach ($enrolledusers as $enrolleduser) {
815
816
            $profilimgurl = moodle_url::make_pluginfile_url($enrolleduser->usercontextid, 'user', 'icon', NULL, '/', 'f1');
            $profilimgurlsmall = moodle_url::make_pluginfile_url($enrolleduser->usercontextid, 'user', 'icon', NULL, '/', 'f2');
817
818
            $resultuser = array(
                'courseid' => $enrolleduser->courseid,
819
                'userid' => $enrolleduser->userid,
820
                'fullname' => fullname($enrolleduser),
821
                'profileimgurl' => $profilimgurl->out(false),
822
823
824
                'profileimgurlsmall' => $profilimgurlsmall->out(false)
            );
            // check if we can return username
825
826
827
            if ($isadmin) {
                $resultuser['username'] = $enrolleduser->username;
            }
828
829
            // check if we can return first and last name
            if ($isadmin or $canviewfullnames) {
830
831
832
833
                $resultuser['firstname'] = $enrolleduser->firstname;
                $resultuser['lastname'] = $enrolleduser->lastname;
            }
            $result[] = $resultuser;
834
835
836
        }

        return $result;
837
838
839
840
    }

    /**
     * Returns description of method result value
841
     *
842
     * @return external_description
843
844
845
     * @since Moodle 2.0
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_enrol_external::get_enrolled_users_returns()
846
847
     */
    public static function get_enrolled_users_returns() {
848
849
850
851
852
        return new external_multiple_structure(
            new external_single_structure(
                array(
                    'courseid' => new external_value(PARAM_INT, 'id of course'),
                    'userid' => new external_value(PARAM_INT, 'id of user'),
853
854
855
856
857
858
                    'firstname' => new external_value(PARAM_RAW, 'first name of user', VALUE_OPTIONAL),
                    'lastname' => new external_value(PARAM_RAW, 'last name of user', VALUE_OPTIONAL),
                    'fullname' => new external_value(PARAM_RAW, 'fullname of user'),
                    'username' => new external_value(PARAM_RAW, 'username of user', VALUE_OPTIONAL),
                    'profileimgurl' => new external_value(PARAM_URL, 'url of the profile image'),
                    'profileimgurlsmall' => new external_value(PARAM_URL, 'url of the profile image (small version)')
859
                )
860
861
862
863
            )
        );
    }

864
865
    /**
     * Returns description of method parameters
866
     *
867
     * @return external_function_parameters
868
869
870
     * @since Moodle 2.1
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_enrol_external::get_users_courses_parameters()
871
872
     */
    public static function get_users_courses_parameters() {
873
        return core_enrol_external::get_users_courses_parameters();
874
875
876
877
878
    }

    /**
     * Get list of courses user is enrolled in (only active enrolments are returned).
     * Please note the current user must be able to access the course, otherwise the course is not included.
879
     *
880
881
     * @param int $userid
     * @return array of courses
882
883
884
     * @since Moodle 2.1
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see use core_enrol_external::get_users_courses()
885
886
     */
    public static function get_users_courses($userid) {
887
        return core_enrol_external::get_users_courses($userid);
888
889
890
891
    }

    /**
     * Returns description of method result value
892
     *
893
     * @return external_description
894
895
896
     * @since Moodle 2.1
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_enrol_external::get_users_courses_returns()
897
898
     */
    public static function get_users_courses_returns() {
899
        return core_enrol_external::get_users_courses_returns();
900
901
902
    }


903
904
    /**
     * Returns description of method parameters
905
     *
906
     * @return external_function_parameters
907
908
909
     * @since Moodle 2.0
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_role_external::assign_roles_parameters()
910
911
     */
    public static function role_assign_parameters() {
912
        return core_role_external::assign_roles_parameters();
913
914
915
    }

    /**
916
     * Manual role assignments to users
917
918
919
920
921
     *
     * @param array $assignments An array of manual role assignment
     * @since Moodle 2.0
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_role_external::assign_roles()
922
     */
923
    public static function role_assign($assignments) {
924
        return core_role_external::assign_roles($assignments);
925
926
927
928
    }

    /**
     * Returns description of method result value
929
930
931
932
933
     *
     * @return null
     * @since Moodle 2.0
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_role_external::assign_roles_returns()
934
935
     */
    public static function role_assign_returns() {
936
        return core_role_external::assign_roles_returns();
937
938
939
940
941
    }


    /**
     * Returns description of method parameters
942
     *
943
     * @return external_function_parameters
944
945
946
     * @since Moodle 2.0
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_role_external::unassign_roles_parameters()
947
948
     */
    public static function role_unassign_parameters() {
949
        return core_role_external::unassign_roles_parameters();
950
951
952
    }

     /**
953
     * Unassign roles from users
954
955
956
957
958
     *
     * @param array $unassignments An array of unassignment
     * @since Moodle 2.0
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_role_external::unassign_roles()
959
     */
960
    public static function role_unassign($unassignments) {
961
         return core_role_external::unassign_roles($unassignments);
962
963
964
965
    }

   /**
     * Returns description of method result value
966
967
968
969
970
     *
     * @return null
     * @since Moodle 2.0
     * @deprecated Moodle 2.2 MDL-29106 - Please do not call this function any more.
     * @see core_role_external::unassign_roles_returns()
971
972
     */
    public static function role_unassign_returns() {
973
        return core_role_external::unassign_roles_returns();
974
975
    }
}