MDL-64506 phpunit: Update unit tests to use classic
[moodle.git] / cohort / externallib.php
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/>.
17 /**
18  * External cohort API
19  *
20  * @package    core_cohort
21  * @category   external
22  * @copyright  MediaTouch 2000 srl
23  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24  */
26 defined('MOODLE_INTERNAL') || die();
28 require_once("$CFG->libdir/externallib.php");
30 class core_cohort_external extends external_api {
32     /**
33      * Returns description of method parameters
34      *
35      * @return external_function_parameters
36      * @since Moodle 2.5
37      */
38     public static function create_cohorts_parameters() {
39         return new external_function_parameters(
40             array(
41                 'cohorts' => new external_multiple_structure(
42                     new external_single_structure(
43                         array(
44                             'categorytype' => new external_single_structure(
45                                 array(
46                                     'type' => new external_value(PARAM_TEXT, 'the name of the field: id (numeric value
47                                         of course category id) or idnumber (alphanumeric value of idnumber course category)
48                                         or system (value ignored)'),
49                                     'value' => new external_value(PARAM_RAW, 'the value of the categorytype')
50                                 )
51                             ),
52                             'name' => new external_value(PARAM_RAW, 'cohort name'),
53                             'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
54                             'description' => new external_value(PARAM_RAW, 'cohort description', VALUE_OPTIONAL),
55                             'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
56                             'visible' => new external_value(PARAM_BOOL, 'cohort visible', VALUE_OPTIONAL, true),
57                             'theme' => new external_value(PARAM_THEME,
58                                 'the cohort theme. The allowcohortthemes setting must be enabled on Moodle',
59                                 VALUE_OPTIONAL
60                             ),
61                         )
62                     )
63                 )
64             )
65         );
66     }
68     /**
69      * Create one or more cohorts
70      *
71      * @param array $cohorts An array of cohorts to create.
72      * @return array An array of arrays
73      * @since Moodle 2.5
74      */
75     public static function create_cohorts($cohorts) {
76         global $CFG, $DB;
77         require_once("$CFG->dirroot/cohort/lib.php");
79         $params = self::validate_parameters(self::create_cohorts_parameters(), array('cohorts' => $cohorts));
81         $availablethemes = cohort_get_list_of_themes();
83         $transaction = $DB->start_delegated_transaction();
85         $syscontext = context_system::instance();
86         $cohortids = array();
88         foreach ($params['cohorts'] as $cohort) {
89             $cohort = (object)$cohort;
91             // Category type (context id).
92             $categorytype = $cohort->categorytype;
93             if (!in_array($categorytype['type'], array('idnumber', 'id', 'system'))) {
94                 throw new invalid_parameter_exception('category type must be id, idnumber or system:' . $categorytype['type']);
95             }
96             if ($categorytype['type'] === 'system') {
97                 $cohort->contextid = $syscontext->id;
98             } else if ($catid = $DB->get_field('course_categories', 'id', array($categorytype['type'] => $categorytype['value']))) {
99                 $catcontext = context_coursecat::instance($catid);
100                 $cohort->contextid = $catcontext->id;
101             } else {
102                 throw new invalid_parameter_exception('category not exists: category '
103                     .$categorytype['type'].' = '.$categorytype['value']);
104             }
105             // Make sure that the idnumber doesn't already exist.
106             if ($DB->record_exists('cohort', array('idnumber' => $cohort->idnumber))) {
107                 throw new invalid_parameter_exception('record already exists: idnumber='.$cohort->idnumber);
108             }
109             $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
110             if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
111                 throw new invalid_parameter_exception('Invalid context');
112             }
113             self::validate_context($context);
114             require_capability('moodle/cohort:manage', $context);
116             // Make sure theme is valid.
117             if (isset($cohort->theme)) {
118                 if (!empty($CFG->allowcohortthemes)) {
119                     if (empty($availablethemes[$cohort->theme])) {
120                         throw new moodle_exception('errorinvalidparam', 'webservice', '', 'theme');
121                     }
122                 }
123             }
125             // Validate format.
126             $cohort->descriptionformat = external_validate_format($cohort->descriptionformat);
127             $cohort->id = cohort_add_cohort($cohort);
129             list($cohort->description, $cohort->descriptionformat) =
130                 external_format_text($cohort->description, $cohort->descriptionformat,
131                         $context->id, 'cohort', 'description', $cohort->id);
132             $cohortids[] = (array)$cohort;
133         }
134         $transaction->allow_commit();
136         return $cohortids;
137     }
139     /**
140      * Returns description of method result value
141      *
142      * @return external_description
143      * @since Moodle 2.5
144      */
145     public static function create_cohorts_returns() {
146         return new external_multiple_structure(
147             new external_single_structure(
148                 array(
149                     'id' => new external_value(PARAM_INT, 'cohort id'),
150                     'name' => new external_value(PARAM_RAW, 'cohort name'),
151                     'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
152                     'description' => new external_value(PARAM_RAW, 'cohort description'),
153                     'descriptionformat' => new external_format_value('description'),
154                     'visible' => new external_value(PARAM_BOOL, 'cohort visible'),
155                     'theme' => new external_value(PARAM_THEME, 'cohort theme', VALUE_OPTIONAL),
156                 )
157             )
158         );
159     }
161     /**
162      * Returns description of method parameters
163      *
164      * @return external_function_parameters
165      * @since Moodle 2.5
166      */
167     public static function delete_cohorts_parameters() {
168         return new external_function_parameters(
169             array(
170                 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'cohort ID')),
171             )
172         );
173     }
175     /**
176      * Delete cohorts
177      *
178      * @param array $cohortids
179      * @return null
180      * @since Moodle 2.5
181      */
182     public static function delete_cohorts($cohortids) {
183         global $CFG, $DB;
184         require_once("$CFG->dirroot/cohort/lib.php");
186         $params = self::validate_parameters(self::delete_cohorts_parameters(), array('cohortids' => $cohortids));
188         $transaction = $DB->start_delegated_transaction();
190         foreach ($params['cohortids'] as $cohortid) {
191             // Validate params.
192             $cohortid = validate_param($cohortid, PARAM_INT);
193             $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
195             // Now security checks.
196             $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
197             if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
198                 throw new invalid_parameter_exception('Invalid context');
199             }
200             self::validate_context($context);
201             require_capability('moodle/cohort:manage', $context);
202             cohort_delete_cohort($cohort);
203         }
204         $transaction->allow_commit();
206         return null;
207     }
209     /**
210      * Returns description of method result value
211      *
212      * @return null
213      * @since Moodle 2.5
214      */
215     public static function delete_cohorts_returns() {
216         return null;
217     }
219     /**
220      * Returns description of method parameters
221      *
222      * @return external_function_parameters
223      * @since Moodle 2.5
224      */
225     public static function get_cohorts_parameters() {
226         return new external_function_parameters(
227             array(
228                 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'Cohort ID')
229                     , 'List of cohort id. A cohort id is an integer.', VALUE_DEFAULT, array()),
230             )
231         );
232     }
234     /**
235      * Get cohorts definition specified by ids
236      *
237      * @param array $cohortids array of cohort ids
238      * @return array of cohort objects (id, courseid, name)
239      * @since Moodle 2.5
240      */
241     public static function get_cohorts($cohortids = array()) {
242         global $DB, $CFG;
244         $params = self::validate_parameters(self::get_cohorts_parameters(), array('cohortids' => $cohortids));
246         if (empty($cohortids)) {
247             $cohorts = $DB->get_records('cohort');
248         } else {
249             $cohorts = $DB->get_records_list('cohort', 'id', $params['cohortids']);
250         }
252         $cohortsinfo = array();
253         foreach ($cohorts as $cohort) {
254             // Now security checks.
255             $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
256             if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
257                 throw new invalid_parameter_exception('Invalid context');
258             }
259             self::validate_context($context);
260             if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:view'), $context)) {
261                 throw new required_capability_exception($context, 'moodle/cohort:view', 'nopermissions', '');
262             }
264             // Only return theme when $CFG->allowcohortthemes is enabled.
265             if (!empty($cohort->theme) && empty($CFG->allowcohortthemes)) {
266                 $cohort->theme = null;
267             }
269             list($cohort->description, $cohort->descriptionformat) =
270                 external_format_text($cohort->description, $cohort->descriptionformat,
271                         $context->id, 'cohort', 'description', $cohort->id);
273             $cohortsinfo[] = (array) $cohort;
274         }
275         return $cohortsinfo;
276     }
279     /**
280      * Returns description of method result value
281      *
282      * @return external_description
283      * @since Moodle 2.5
284      */
285     public static function get_cohorts_returns() {
286         return new external_multiple_structure(
287             new external_single_structure(
288                 array(
289                     'id' => new external_value(PARAM_INT, 'ID of the cohort'),
290                     'name' => new external_value(PARAM_RAW, 'cohort name'),
291                     'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
292                     'description' => new external_value(PARAM_RAW, 'cohort description'),
293                     'descriptionformat' => new external_format_value('description'),
294                     'visible' => new external_value(PARAM_BOOL, 'cohort visible'),
295                     'theme' => new external_value(PARAM_THEME, 'cohort theme', VALUE_OPTIONAL),
296                 )
297             )
298         );
299     }
301     /**
302      * Returns the description of external function parameters.
303      *
304      * @return external_function_parameters
305      */
306     public static function search_cohorts_parameters() {
307         $query = new external_value(
308             PARAM_RAW,
309             'Query string'
310         );
311         $includes = new external_value(
312             PARAM_ALPHA,
313             'What other contexts to fetch the frameworks from. (all, parents, self)',
314             VALUE_DEFAULT,
315             'parents'
316         );
317         $limitfrom = new external_value(
318             PARAM_INT,
319             'limitfrom we are fetching the records from',
320             VALUE_DEFAULT,
321             0
322         );
323         $limitnum = new external_value(
324             PARAM_INT,
325             'Number of records to fetch',
326             VALUE_DEFAULT,
327             25
328         );
329         return new external_function_parameters(array(
330             'query' => $query,
331             'context' => self::get_context_parameters(),
332             'includes' => $includes,
333             'limitfrom' => $limitfrom,
334             'limitnum' => $limitnum
335         ));
336     }
338     /**
339      * Search cohorts.
340      *
341      * @param string $query
342      * @param array $context
343      * @param string $includes
344      * @param int $limitfrom
345      * @param int $limitnum
346      * @return array
347      */
348     public static function search_cohorts($query, $context, $includes = 'parents', $limitfrom = 0, $limitnum = 25) {
349         global $CFG;
350         require_once($CFG->dirroot . '/cohort/lib.php');
352         $params = self::validate_parameters(self::search_cohorts_parameters(), array(
353             'query' => $query,
354             'context' => $context,
355             'includes' => $includes,
356             'limitfrom' => $limitfrom,
357             'limitnum' => $limitnum,
358         ));
359         $query = $params['query'];
360         $includes = $params['includes'];
361         $context = self::get_context_from_params($params['context']);
362         $limitfrom = $params['limitfrom'];
363         $limitnum = $params['limitnum'];
365         self::validate_context($context);
367         $manager = has_capability('moodle/cohort:manage', $context);
368         if (!$manager) {
369             require_capability('moodle/cohort:view', $context);
370         }
372         // TODO Make this more efficient.
373         if ($includes == 'self') {
374             $results = cohort_get_cohorts($context->id, $limitfrom, $limitnum, $query);
375             $results = $results['cohorts'];
376         } else if ($includes == 'parents') {
377             $results = cohort_get_cohorts($context->id, $limitfrom, $limitnum, $query);
378             $results = $results['cohorts'];
379             if (!$context instanceof context_system) {
380                 $results = array_merge($results, cohort_get_available_cohorts($context, COHORT_ALL, $limitfrom, $limitnum, $query));
381             }
382         } else if ($includes == 'all') {
383             $results = cohort_get_all_cohorts($limitfrom, $limitnum, $query);
384             $results = $results['cohorts'];
385         } else {
386             throw new coding_exception('Invalid parameter value for \'includes\'.');
387         }
389         $cohorts = array();
390         foreach ($results as $key => $cohort) {
391             $cohortcontext = context::instance_by_id($cohort->contextid);
393             // Only return theme when $CFG->allowcohortthemes is enabled.
394             if (!empty($cohort->theme) && empty($CFG->allowcohortthemes)) {
395                 $cohort->theme = null;
396             }
398             if (!isset($cohort->description)) {
399                 $cohort->description = '';
400             }
401             if (!isset($cohort->descriptionformat)) {
402                 $cohort->descriptionformat = FORMAT_PLAIN;
403             }
405             list($cohort->description, $cohort->descriptionformat) =
406                 external_format_text($cohort->description, $cohort->descriptionformat,
407                         $cohortcontext->id, 'cohort', 'description', $cohort->id);
409             $cohorts[$key] = $cohort;
410         }
412         return array('cohorts' => $cohorts);
413     }
415     /**
416      * Returns description of external function result value.
417      *
418      * @return external_description
419      */
420     public static function search_cohorts_returns() {
421         return new external_single_structure(array(
422             'cohorts' => new external_multiple_structure(
423                 new external_single_structure(array(
424                     'id' => new external_value(PARAM_INT, 'ID of the cohort'),
425                     'name' => new external_value(PARAM_RAW, 'cohort name'),
426                     'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
427                     'description' => new external_value(PARAM_RAW, 'cohort description'),
428                     'descriptionformat' => new external_format_value('description'),
429                     'visible' => new external_value(PARAM_BOOL, 'cohort visible'),
430                     'theme' => new external_value(PARAM_THEME, 'cohort theme', VALUE_OPTIONAL),
431                 ))
432             )
433         ));
434     }
438     /**
439      * Returns description of method parameters
440      *
441      * @return external_function_parameters
442      * @since Moodle 2.5
443      */
444     public static function update_cohorts_parameters() {
445         return new external_function_parameters(
446             array(
447                 'cohorts' => new external_multiple_structure(
448                     new external_single_structure(
449                         array(
450                             'id' => new external_value(PARAM_INT, 'ID of the cohort'),
451                             'categorytype' => new external_single_structure(
452                                 array(
453                                     'type' => new external_value(PARAM_TEXT, 'the name of the field: id (numeric value
454                                         of course category id) or idnumber (alphanumeric value of idnumber course category)
455                                         or system (value ignored)'),
456                                     'value' => new external_value(PARAM_RAW, 'the value of the categorytype')
457                                 )
458                             ),
459                             'name' => new external_value(PARAM_RAW, 'cohort name'),
460                             'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
461                             'description' => new external_value(PARAM_RAW, 'cohort description', VALUE_OPTIONAL),
462                             'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
463                             'visible' => new external_value(PARAM_BOOL, 'cohort visible', VALUE_OPTIONAL),
464                             'theme' => new external_value(PARAM_THEME,
465                                 'the cohort theme. The allowcohortthemes setting must be enabled on Moodle',
466                                 VALUE_OPTIONAL
467                             ),
468                         )
469                     )
470                 )
471             )
472         );
473     }
475     /**
476      * Update cohorts
477      *
478      * @param array $cohorts
479      * @return null
480      * @since Moodle 2.5
481      */
482     public static function update_cohorts($cohorts) {
483         global $CFG, $DB;
484         require_once("$CFG->dirroot/cohort/lib.php");
486         $params = self::validate_parameters(self::update_cohorts_parameters(), array('cohorts' => $cohorts));
488         $availablethemes = cohort_get_list_of_themes();
490         $transaction = $DB->start_delegated_transaction();
491         $syscontext = context_system::instance();
493         foreach ($params['cohorts'] as $cohort) {
494             $cohort = (object) $cohort;
496             if (trim($cohort->name) == '') {
497                 throw new invalid_parameter_exception('Invalid cohort name');
498             }
500             $oldcohort = $DB->get_record('cohort', array('id' => $cohort->id), '*', MUST_EXIST);
501             $oldcontext = context::instance_by_id($oldcohort->contextid, MUST_EXIST);
502             require_capability('moodle/cohort:manage', $oldcontext);
504             // Category type (context id).
505             $categorytype = $cohort->categorytype;
506             if (!in_array($categorytype['type'], array('idnumber', 'id', 'system'))) {
507                 throw new invalid_parameter_exception('category type must be id, idnumber or system:' . $categorytype['type']);
508             }
509             if ($categorytype['type'] === 'system') {
510                 $cohort->contextid = $syscontext->id;
511             } else if ($catid = $DB->get_field('course_categories', 'id', array($categorytype['type'] => $categorytype['value']))) {
512                 $cohort->contextid = $DB->get_field('context', 'id', array('instanceid' => $catid,
513                     'contextlevel' => CONTEXT_COURSECAT));
514             } else {
515                 throw new invalid_parameter_exception('category not exists: category='.$categorytype['value']);
516             }
518             if ($cohort->contextid != $oldcohort->contextid) {
519                 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
520                 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
521                     throw new invalid_parameter_exception('Invalid context');
522                 }
524                 self::validate_context($context);
525                 require_capability('moodle/cohort:manage', $context);
526             }
528             // Make sure theme is valid.
529             if (!empty($cohort->theme) && !empty($CFG->allowcohortthemes)) {
530                 if (empty($availablethemes[$cohort->theme])) {
531                     $debuginfo = 'The following cohort theme is not installed on this site: '.$cohort->theme;
532                     throw new moodle_exception('errorinvalidparam', 'webservice', '', 'theme', $debuginfo);
533                 }
534             }
536             if (!empty($cohort->description)) {
537                 $cohort->descriptionformat = external_validate_format($cohort->descriptionformat);
538             }
540             cohort_update_cohort($cohort);
541         }
543         $transaction->allow_commit();
545         return null;
546     }
548     /**
549      * Returns description of method result value
550      *
551      * @return null
552      * @since Moodle 2.5
553      */
554     public static function update_cohorts_returns() {
555         return null;
556     }
558     /**
559      * Returns description of method parameters
560      *
561      * @return external_function_parameters
562      * @since Moodle 2.5
563      */
564     public static function add_cohort_members_parameters() {
565         return new external_function_parameters (
566             array(
567                 'members' => new external_multiple_structure (
568                     new external_single_structure (
569                         array (
570                             'cohorttype' => new external_single_structure (
571                                 array(
572                                     'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the field: id
573                                         (numeric value of cohortid) or idnumber (alphanumeric value of idnumber) '),
574                                     'value' => new external_value(PARAM_RAW, 'The value of the cohort')
575                                 )
576                             ),
577                             'usertype' => new external_single_structure (
578                                 array(
579                                     'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the field: id
580                                         (numeric value of id) or username (alphanumeric value of username) '),
581                                     'value' => new external_value(PARAM_RAW, 'The value of the cohort')
582                                 )
583                             )
584                         )
585                     )
586                 )
587             )
588         );
589     }
591     /**
592      * Add cohort members
593      *
594      * @param array $members of arrays with keys userid, cohortid
595      * @since Moodle 2.5
596      */
597     public static function add_cohort_members($members) {
598         global $CFG, $DB;
599         require_once($CFG->dirroot."/cohort/lib.php");
601         $params = self::validate_parameters(self::add_cohort_members_parameters(), array('members' => $members));
603         $transaction = $DB->start_delegated_transaction();
604         $warnings = array();
605         foreach ($params['members'] as $member) {
606             // Cohort parameters.
607             $cohorttype = $member['cohorttype'];
608             $cohortparam = array($cohorttype['type'] => $cohorttype['value']);
609             // User parameters.
610             $usertype = $member['usertype'];
611             $userparam = array($usertype['type'] => $usertype['value']);
612             try {
613                 // Check parameters.
614                 if ($cohorttype['type'] != 'id' && $cohorttype['type'] != 'idnumber') {
615                     $warning = array();
616                     $warning['warningcode'] = '1';
617                     $warning['message'] = 'invalid parameter: cohortype='.$cohorttype['type'];
618                     $warnings[] = $warning;
619                     continue;
620                 }
621                 if ($usertype['type'] != 'id' && $usertype['type'] != 'username') {
622                     $warning = array();
623                     $warning['warningcode'] = '1';
624                     $warning['message'] = 'invalid parameter: usertype='.$usertype['type'];
625                     $warnings[] = $warning;
626                     continue;
627                 }
628                 // Extract parameters.
629                 if (!$cohortid = $DB->get_field('cohort', 'id', $cohortparam)) {
630                     $warning = array();
631                     $warning['warningcode'] = '2';
632                     $warning['message'] = 'cohort '.$cohorttype['type'].'='.$cohorttype['value'].' not exists';
633                     $warnings[] = $warning;
634                     continue;
635                 }
636                 if (!$userid = $DB->get_field('user', 'id', array_merge($userparam, array('deleted' => 0,
637                     'mnethostid' => $CFG->mnet_localhost_id)))) {
638                     $warning = array();
639                     $warning['warningcode'] = '2';
640                     $warning['message'] = 'user '.$usertype['type'].'='.$usertype['value'].' not exists';
641                     $warnings[] = $warning;
642                     continue;
643                 }
644                 if ($DB->record_exists('cohort_members', array('cohortid' => $cohortid, 'userid' => $userid))) {
645                     $warning = array();
646                     $warning['warningcode'] = '3';
647                     $warning['message'] = 'record already exists: cohort('.$cohorttype['type'].'='.$cohorttype['value'].' '.
648                         $usertype['type'].'='.$usertype['value'].')';
649                     $warnings[] = $warning;
650                     continue;
651                 }
652                 $cohort = $DB->get_record('cohort', array('id'=>$cohortid), '*', MUST_EXIST);
653                 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
654                 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
655                     $warning = array();
656                     $warning['warningcode'] = '1';
657                     $warning['message'] = 'Invalid context: '.$context->contextlevel;
658                     $warnings[] = $warning;
659                     continue;
660                 }
661                 self::validate_context($context);
662             } catch (Exception $e) {
663                 throw new moodle_exception('Error', 'cohort', '', $e->getMessage());
664             }
665             if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:assign'), $context)) {
666                 throw new required_capability_exception($context, 'moodle/cohort:assign', 'nopermissions', '');
667             }
668             cohort_add_member($cohortid, $userid);
669         }
670         $transaction->allow_commit();
671         // Return.
672         $result = array();
673         $result['warnings'] = $warnings;
674         return $result;
675     }
677     /**
678      * Returns description of method result value
679      *
680      * @return null
681      * @since Moodle 2.5
682      */
683     public static function add_cohort_members_returns() {
684         return new external_single_structure(
685             array(
686                 'warnings' => new external_warnings()
687             )
688         );
689     }
691     /**
692      * Returns description of method parameters
693      *
694      * @return external_function_parameters
695      * @since Moodle 2.5
696      */
697     public static function delete_cohort_members_parameters() {
698         return new external_function_parameters(
699             array(
700                 'members' => new external_multiple_structure(
701                     new external_single_structure(
702                         array(
703                             'cohortid' => new external_value(PARAM_INT, 'cohort record id'),
704                             'userid' => new external_value(PARAM_INT, 'user id'),
705                         )
706                     )
707                 )
708             )
709         );
710     }
712     /**
713      * Delete cohort members
714      *
715      * @param array $members of arrays with keys userid, cohortid
716      * @since Moodle 2.5
717      */
718     public static function delete_cohort_members($members) {
719         global $CFG, $DB;
720         require_once("$CFG->dirroot/cohort/lib.php");
722         // Validate parameters.
723         $params = self::validate_parameters(self::delete_cohort_members_parameters(), array('members' => $members));
725         $transaction = $DB->start_delegated_transaction();
727         foreach ($params['members'] as $member) {
728             $cohortid = $member['cohortid'];
729             $userid = $member['userid'];
731             $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
732             $user = $DB->get_record('user', array('id' => $userid, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id),
733                 '*', MUST_EXIST);
735             // Now security checks.
736             $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
737             if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
738                 throw new invalid_parameter_exception('Invalid context');
739             }
740             self::validate_context($context);
741             if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:assign'), $context)) {
742                 throw new required_capability_exception($context, 'moodle/cohort:assign', 'nopermissions', '');
743             }
745             cohort_remove_member($cohort->id, $user->id);
746         }
747         $transaction->allow_commit();
748     }
750     /**
751      * Returns description of method result value
752      *
753      * @return null
754      * @since Moodle 2.5
755      */
756     public static function delete_cohort_members_returns() {
757         return null;
758     }
760     /**
761      * Returns description of method parameters
762      *
763      * @return external_function_parameters
764      * @since Moodle 2.5
765      */
766     public static function get_cohort_members_parameters() {
767         return new external_function_parameters(
768             array(
769                 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'Cohort ID')),
770             )
771         );
772     }
774     /**
775      * Return all members for a cohort
776      *
777      * @param array $cohortids array of cohort ids
778      * @return array with cohort id keys containing arrays of user ids
779      * @since Moodle 2.5
780      */
781     public static function get_cohort_members($cohortids) {
782         global $DB;
783         $params = self::validate_parameters(self::get_cohort_members_parameters(), array('cohortids' => $cohortids));
785         $members = array();
787         foreach ($params['cohortids'] as $cohortid) {
788             // Validate params.
789             $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
790             // Now security checks.
791             $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
792             if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
793                 throw new invalid_parameter_exception('Invalid context');
794             }
795             self::validate_context($context);
796             if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:view'), $context)) {
797                 throw new required_capability_exception($context, 'moodle/cohort:view', 'nopermissions', '');
798             }
800             $cohortmembers = $DB->get_records_sql("SELECT u.id FROM {user} u, {cohort_members} cm
801                 WHERE u.id = cm.userid AND cm.cohortid = ?
802                 ORDER BY lastname ASC, firstname ASC", array($cohort->id));
803             $members[] = array('cohortid' => $cohortid, 'userids' => array_keys($cohortmembers));
804         }
805         return $members;
806     }
808     /**
809      * Returns description of method result value
810      *
811      * @return external_description
812      * @since Moodle 2.5
813      */
814     public static function get_cohort_members_returns() {
815         return new external_multiple_structure(
816             new external_single_structure(
817                 array(
818                     'cohortid' => new external_value(PARAM_INT, 'cohort record id'),
819                     'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')),
820                 )
821             )
822         );
823     }