Merge branch 'm25_MDL-40200_Notices_When_Viewing_Profile_Invalid_UserId' of https...
[moodle.git] / cohort / externallib.php
blob682145960eed069d439a76be891a760b58ab8ce9
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/>.
17 /**
18 * External cohort API
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
26 require_once("$CFG->libdir/externallib.php");
28 class core_cohort_external extends external_api {
30 /**
31 * Returns description of method parameters
33 * @return external_function_parameters
34 * @since Moodle 2.5
36 public static function create_cohorts_parameters() {
37 return new external_function_parameters(
38 array(
39 'cohorts' => new external_multiple_structure(
40 new external_single_structure(
41 array(
42 'categorytype' => new external_single_structure(
43 array(
44 'type' => new external_value(PARAM_TEXT, 'the name of the field: id (numeric value
45 of course category id) or idnumber (alphanumeric value of idnumber course category)
46 or system (value ignored)'),
47 'value' => new external_value(PARAM_RAW, 'the value of the categorytype')
50 'name' => new external_value(PARAM_RAW, 'cohort name'),
51 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
52 'description' => new external_value(PARAM_RAW, 'cohort description', VALUE_OPTIONAL),
53 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
61 /**
62 * Create one or more cohorts
64 * @param array $cohorts An array of cohorts to create.
65 * @return array An array of arrays
66 * @since Moodle 2.5
68 public static function create_cohorts($cohorts) {
69 global $CFG, $DB;
70 require_once("$CFG->dirroot/cohort/lib.php");
72 $params = self::validate_parameters(self::create_cohorts_parameters(), array('cohorts' => $cohorts));
74 $transaction = $DB->start_delegated_transaction();
76 $syscontext = context_system::instance();
77 $cohortids = array();
79 foreach ($params['cohorts'] as $cohort) {
80 $cohort = (object)$cohort;
82 // Category type (context id).
83 $categorytype = $cohort->categorytype;
84 if (!in_array($categorytype['type'], array('idnumber', 'id', 'system'))) {
85 throw new invalid_parameter_exception('category type must be id, idnumber or system:' . $categorytype['type']);
87 if ($categorytype['type'] === 'system') {
88 $cohort->contextid = $syscontext->id;
89 } else if ($catid = $DB->get_field('course_categories', 'id', array($categorytype['type'] => $categorytype['value']))) {
90 $catcontext = context_coursecat::instance($catid);
91 $cohort->contextid = $catcontext->id;
92 } else {
93 throw new invalid_parameter_exception('category not exists: category '
94 .$categorytype['type'].' = '.$categorytype['value']);
96 // Make sure that the idnumber doesn't already exist.
97 if ($DB->record_exists('cohort', array('idnumber' => $cohort->idnumber))) {
98 throw new invalid_parameter_exception('record already exists: idnumber='.$cohort->idnumber);
100 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
101 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
102 throw new invalid_parameter_exception('Invalid context');
104 self::validate_context($context);
105 require_capability('moodle/cohort:manage', $context);
107 // Validate format.
108 $cohort->descriptionformat = external_validate_format($cohort->descriptionformat);
109 $cohort->id = cohort_add_cohort($cohort);
111 list($cohort->description, $cohort->descriptionformat) =
112 external_format_text($cohort->description, $cohort->descriptionformat,
113 $context->id, 'cohort', 'description', $cohort->id);
114 $cohortids[] = (array)$cohort;
116 $transaction->allow_commit();
118 return $cohortids;
122 * Returns description of method result value
124 * @return external_description
125 * @since Moodle 2.5
127 public static function create_cohorts_returns() {
128 return new external_multiple_structure(
129 new external_single_structure(
130 array(
131 'id' => new external_value(PARAM_INT, 'cohort id'),
132 'name' => new external_value(PARAM_RAW, 'cohort name'),
133 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
134 'description' => new external_value(PARAM_RAW, 'cohort description'),
135 'descriptionformat' => new external_format_value('description'),
142 * Returns description of method parameters
144 * @return external_function_parameters
145 * @since Moodle 2.5
147 public static function delete_cohorts_parameters() {
148 return new external_function_parameters(
149 array(
150 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'cohort ID')),
156 * Delete cohorts
158 * @param array $cohortids
159 * @return null
160 * @since Moodle 2.5
162 public static function delete_cohorts($cohortids) {
163 global $CFG, $DB;
164 require_once("$CFG->dirroot/cohort/lib.php");
166 $params = self::validate_parameters(self::delete_cohorts_parameters(), array('cohortids' => $cohortids));
168 $transaction = $DB->start_delegated_transaction();
170 foreach ($params['cohortids'] as $cohortid) {
171 // Validate params.
172 $cohortid = validate_param($cohortid, PARAM_INT);
173 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
175 // Now security checks.
176 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
177 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
178 throw new invalid_parameter_exception('Invalid context');
180 self::validate_context($context);
181 require_capability('moodle/cohort:manage', $context);
182 cohort_delete_cohort($cohort);
184 $transaction->allow_commit();
186 return null;
190 * Returns description of method result value
192 * @return null
193 * @since Moodle 2.5
195 public static function delete_cohorts_returns() {
196 return null;
200 * Returns description of method parameters
202 * @return external_function_parameters
203 * @since Moodle 2.5
205 public static function get_cohorts_parameters() {
206 return new external_function_parameters(
207 array(
208 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'Cohort ID')
209 , 'List of cohort id. A cohort id is an integer.'),
215 * Get cohorts definition specified by ids
217 * @param array $cohortids array of cohort ids
218 * @return array of cohort objects (id, courseid, name)
219 * @since Moodle 2.5
221 public static function get_cohorts($cohortids) {
222 global $DB;
224 $params = self::validate_parameters(self::get_cohorts_parameters(), array('cohortids' => $cohortids));
226 $cohorts = array();
227 foreach ($params['cohortids'] as $cohortid) {
228 // Validate params.
229 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
231 // Now security checks.
232 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
233 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
234 throw new invalid_parameter_exception('Invalid context');
236 self::validate_context($context);
237 if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:view'), $context)) {
238 throw new required_capability_exception($context, 'moodle/cohort:view', 'nopermissions', '');
241 list($cohort->description, $cohort->descriptionformat) =
242 external_format_text($cohort->description, $cohort->descriptionformat,
243 $context->id, 'cohort', 'description', $cohort->id);
245 $cohorts[] = (array) $cohort;
248 return $cohorts;
252 * Returns description of method result value
254 * @return external_description
255 * @since Moodle 2.5
257 public static function get_cohorts_returns() {
258 return new external_multiple_structure(
259 new external_single_structure(
260 array(
261 'id' => new external_value(PARAM_NUMBER, 'ID of the cohort'),
262 'name' => new external_value(PARAM_RAW, 'cohort name'),
263 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
264 'description' => new external_value(PARAM_RAW, 'cohort description'),
265 'descriptionformat' => new external_format_value('description'),
272 * Returns description of method parameters
274 * @return external_function_parameters
275 * @since Moodle 2.5
277 public static function update_cohorts_parameters() {
278 return new external_function_parameters(
279 array(
280 'cohorts' => new external_multiple_structure(
281 new external_single_structure(
282 array(
283 'id' => new external_value(PARAM_NUMBER, 'ID of the cohort'),
284 'categorytype' => new external_single_structure(
285 array(
286 'type' => new external_value(PARAM_TEXT, 'the name of the field: id (numeric value
287 of course category id) or idnumber (alphanumeric value of idnumber course category)
288 or system (value ignored)'),
289 'value' => new external_value(PARAM_RAW, 'the value of the categorytype')
292 'name' => new external_value(PARAM_RAW, 'cohort name'),
293 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
294 'description' => new external_value(PARAM_RAW, 'cohort description', VALUE_OPTIONAL),
295 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
304 * Update cohorts
306 * @param array $cohorts
307 * @return null
308 * @since Moodle 2.5
310 public static function update_cohorts($cohorts) {
311 global $CFG, $DB;
312 require_once("$CFG->dirroot/cohort/lib.php");
314 $params = self::validate_parameters(self::update_cohorts_parameters(), array('cohorts' => $cohorts));
316 $transaction = $DB->start_delegated_transaction();
317 $syscontext = context_system::instance();
319 foreach ($params['cohorts'] as $cohort) {
320 $cohort = (object) $cohort;
322 if (trim($cohort->name) == '') {
323 throw new invalid_parameter_exception('Invalid cohort name');
326 $oldcohort = $DB->get_record('cohort', array('id' => $cohort->id), '*', MUST_EXIST);
327 $oldcontext = context::instance_by_id($oldcohort->contextid, MUST_EXIST);
328 require_capability('moodle/cohort:manage', $oldcontext);
330 // Category type (context id).
331 $categorytype = $cohort->categorytype;
332 if (!in_array($categorytype['type'], array('idnumber', 'id', 'system'))) {
333 throw new invalid_parameter_exception('category type must be id, idnumber or system:' . $categorytype['type']);
335 if ($categorytype['type'] === 'system') {
336 $cohort->contextid = $syscontext->id;
337 } else if ($catid = $DB->get_field('course_categories', 'id', array($categorytype['type'] => $categorytype['value']))) {
338 $cohort->contextid = $DB->get_field('context', 'id', array('instanceid' => $catid,
339 'contextlevel' => CONTEXT_COURSECAT));
340 } else {
341 throw new invalid_parameter_exception('category not exists: category='.$categorytype['value']);
344 if ($cohort->contextid != $oldcohort->contextid) {
345 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
346 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
347 throw new invalid_parameter_exception('Invalid context');
350 self::validate_context($context);
351 require_capability('moodle/cohort:manage', $context);
354 if (!empty($cohort->description)) {
355 $cohort->descriptionformat = external_validate_format($cohort->descriptionformat);
358 cohort_update_cohort($cohort);
361 $transaction->allow_commit();
363 return null;
367 * Returns description of method result value
369 * @return null
370 * @since Moodle 2.5
372 public static function update_cohorts_returns() {
373 return null;
377 * Returns description of method parameters
379 * @return external_function_parameters
380 * @since Moodle 2.5
382 public static function add_cohort_members_parameters() {
383 return new external_function_parameters (
384 array(
385 'members' => new external_multiple_structure (
386 new external_single_structure (
387 array (
388 'cohorttype' => new external_single_structure (
389 array(
390 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the field: id
391 (numeric value of cohortid) or idnumber (alphanumeric value of idnumber) '),
392 'value' => new external_value(PARAM_RAW, 'The value of the cohort')
395 'usertype' => new external_single_structure (
396 array(
397 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the field: id
398 (numeric value of id) or username (alphanumeric value of username) '),
399 'value' => new external_value(PARAM_RAW, 'The value of the cohort')
410 * Add cohort members
412 * @param array $members of arrays with keys userid, cohortid
413 * @since Moodle 2.5
415 public static function add_cohort_members($members) {
416 global $CFG, $DB;
417 require_once($CFG->dirroot."/cohort/lib.php");
419 $params = self::validate_parameters(self::add_cohort_members_parameters(), array('members' => $members));
421 $transaction = $DB->start_delegated_transaction();
422 $warnings = array();
423 foreach ($params['members'] as $member) {
424 // Cohort parameters.
425 $cohorttype = $member['cohorttype'];
426 $cohortparam = array($cohorttype['type'] => $cohorttype['value']);
427 // User parameters.
428 $usertype = $member['usertype'];
429 $userparam = array($usertype['type'] => $usertype['value']);
430 try {
431 // Check parameters.
432 if ($cohorttype['type'] != 'id' && $cohorttype['type'] != 'idnumber') {
433 $warning = array();
434 $warning['warningcode'] = '1';
435 $warning['message'] = 'invalid parameter: cohortype='.$cohorttype['type'];
436 $warnings[] = $warning;
437 continue;
439 if ($usertype['type'] != 'id' && $usertype['type'] != 'username') {
440 $warning = array();
441 $warning['warningcode'] = '1';
442 $warning['message'] = 'invalid parameter: usertype='.$usertype['type'];
443 $warnings[] = $warning;
444 continue;
446 // Extract parameters.
447 if (!$cohortid = $DB->get_field('cohort', 'id', $cohortparam)) {
448 $warning = array();
449 $warning['warningcode'] = '2';
450 $warning['message'] = 'cohort '.$cohorttype['type'].'='.$cohorttype['value'].' not exists';
451 $warnings[] = $warning;
452 continue;
454 if (!$userid = $DB->get_field('user', 'id', array_merge($userparam, array('deleted' => 0,
455 'mnethostid' => $CFG->mnet_localhost_id)))) {
456 $warning = array();
457 $warning['warningcode'] = '2';
458 $warning['message'] = 'user '.$usertype['type'].'='.$usertype['value'].' not exists';
459 $warnings[] = $warning;
460 continue;
462 if ($DB->record_exists('cohort_members', array('cohortid' => $cohortid, 'userid' => $userid))) {
463 $warning = array();
464 $warning['warningcode'] = '3';
465 $warning['message'] = 'record already exists: cohort('.$cohorttype['type'].'='.$cohorttype['value'].' '.
466 $usertype['type'].'='.$usertype['value'].')';
467 $warnings[] = $warning;
468 continue;
470 $cohort = $DB->get_record('cohort', array('id'=>$cohortid), '*', MUST_EXIST);
471 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
472 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
473 $warning = array();
474 $warning['warningcode'] = '1';
475 $warning['message'] = 'Invalid context: '.$context->contextlevel;
476 $warnings[] = $warning;
477 continue;
479 self::validate_context($context);
480 } catch (Exception $e) {
481 throw new moodle_exception('Error', 'cohort', '', $e->getMessage());
483 if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:assign'), $context)) {
484 throw new required_capability_exception($context, 'moodle/cohort:assign', 'nopermissions', '');
486 cohort_add_member($cohortid, $userid);
488 $transaction->allow_commit();
489 // Return.
490 $result = array();
491 $result['warnings'] = $warnings;
492 return $result;
496 * Returns description of method result value
498 * @return null
499 * @since Moodle 2.5
501 public static function add_cohort_members_returns() {
502 return new external_single_structure(
503 array(
504 'warnings' => new external_warnings()
510 * Returns description of method parameters
512 * @return external_function_parameters
513 * @since Moodle 2.5
515 public static function delete_cohort_members_parameters() {
516 return new external_function_parameters(
517 array(
518 'members' => new external_multiple_structure(
519 new external_single_structure(
520 array(
521 'cohortid' => new external_value(PARAM_INT, 'cohort record id'),
522 'userid' => new external_value(PARAM_INT, 'user id'),
531 * Delete cohort members
533 * @param array $members of arrays with keys userid, cohortid
534 * @since Moodle 2.5
536 public static function delete_cohort_members($members) {
537 global $CFG, $DB;
538 require_once("$CFG->dirroot/cohort/lib.php");
540 // Validate parameters.
541 $params = self::validate_parameters(self::delete_cohort_members_parameters(), array('members' => $members));
543 $transaction = $DB->start_delegated_transaction();
545 foreach ($params['members'] as $member) {
546 $cohortid = $member['cohortid'];
547 $userid = $member['userid'];
549 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
550 $user = $DB->get_record('user', array('id' => $userid, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id),
551 '*', MUST_EXIST);
553 // Now security checks.
554 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
555 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
556 throw new invalid_parameter_exception('Invalid context');
558 self::validate_context($context);
559 if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:assign'), $context)) {
560 throw new required_capability_exception($context, 'moodle/cohort:assign', 'nopermissions', '');
563 cohort_remove_member($cohort->id, $user->id);
565 $transaction->allow_commit();
569 * Returns description of method result value
571 * @return null
572 * @since Moodle 2.5
574 public static function delete_cohort_members_returns() {
575 return null;
579 * Returns description of method parameters
581 * @return external_function_parameters
582 * @since Moodle 2.5
584 public static function get_cohort_members_parameters() {
585 return new external_function_parameters(
586 array(
587 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'Cohort ID')),
593 * Return all members for a cohort
595 * @param array $cohortids array of cohort ids
596 * @return array with cohort id keys containing arrays of user ids
597 * @since Moodle 2.5
599 public static function get_cohort_members($cohortids) {
600 global $DB;
601 $params = self::validate_parameters(self::get_cohort_members_parameters(), array('cohortids' => $cohortids));
603 $members = array();
605 foreach ($params['cohortids'] as $cohortid) {
606 // Validate params.
607 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
608 // Now security checks.
609 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
610 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
611 throw new invalid_parameter_exception('Invalid context');
613 self::validate_context($context);
614 if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:view'), $context)) {
615 throw new required_capability_exception($context, 'moodle/cohort:view', 'nopermissions', '');
618 $cohortmembers = $DB->get_records_sql("SELECT u.id FROM {user} u, {cohort_members} cm
619 WHERE u.id = cm.userid AND cm.cohortid = ?
620 ORDER BY lastname ASC, firstname ASC", array($cohort->id));
621 $members[] = array('cohortid' => $cohortid, 'userids' => array_keys($cohortmembers));
623 return $members;
627 * Returns description of method result value
629 * @return external_description
630 * @since Moodle 2.5
632 public static function get_cohort_members_returns() {
633 return new external_multiple_structure(
634 new external_single_structure(
635 array(
636 'cohortid' => new external_value(PARAM_INT, 'cohort record id'),
637 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')),