MDL-47740 question engine: let qs update variant later if appropriate
[moodle.git] / cohort / externallib.php
blob88defef95e40074b1cce2d83c40c39c09845eaf2
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),
54 'visible' => new external_value(PARAM_BOOL, 'cohort visible', VALUE_OPTIONAL, true),
62 /**
63 * Create one or more cohorts
65 * @param array $cohorts An array of cohorts to create.
66 * @return array An array of arrays
67 * @since Moodle 2.5
69 public static function create_cohorts($cohorts) {
70 global $CFG, $DB;
71 require_once("$CFG->dirroot/cohort/lib.php");
73 $params = self::validate_parameters(self::create_cohorts_parameters(), array('cohorts' => $cohorts));
75 $transaction = $DB->start_delegated_transaction();
77 $syscontext = context_system::instance();
78 $cohortids = array();
80 foreach ($params['cohorts'] as $cohort) {
81 $cohort = (object)$cohort;
83 // Category type (context id).
84 $categorytype = $cohort->categorytype;
85 if (!in_array($categorytype['type'], array('idnumber', 'id', 'system'))) {
86 throw new invalid_parameter_exception('category type must be id, idnumber or system:' . $categorytype['type']);
88 if ($categorytype['type'] === 'system') {
89 $cohort->contextid = $syscontext->id;
90 } else if ($catid = $DB->get_field('course_categories', 'id', array($categorytype['type'] => $categorytype['value']))) {
91 $catcontext = context_coursecat::instance($catid);
92 $cohort->contextid = $catcontext->id;
93 } else {
94 throw new invalid_parameter_exception('category not exists: category '
95 .$categorytype['type'].' = '.$categorytype['value']);
97 // Make sure that the idnumber doesn't already exist.
98 if ($DB->record_exists('cohort', array('idnumber' => $cohort->idnumber))) {
99 throw new invalid_parameter_exception('record already exists: idnumber='.$cohort->idnumber);
101 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
102 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
103 throw new invalid_parameter_exception('Invalid context');
105 self::validate_context($context);
106 require_capability('moodle/cohort:manage', $context);
108 // Validate format.
109 $cohort->descriptionformat = external_validate_format($cohort->descriptionformat);
110 $cohort->id = cohort_add_cohort($cohort);
112 list($cohort->description, $cohort->descriptionformat) =
113 external_format_text($cohort->description, $cohort->descriptionformat,
114 $context->id, 'cohort', 'description', $cohort->id);
115 $cohortids[] = (array)$cohort;
117 $transaction->allow_commit();
119 return $cohortids;
123 * Returns description of method result value
125 * @return external_description
126 * @since Moodle 2.5
128 public static function create_cohorts_returns() {
129 return new external_multiple_structure(
130 new external_single_structure(
131 array(
132 'id' => new external_value(PARAM_INT, 'cohort id'),
133 'name' => new external_value(PARAM_RAW, 'cohort name'),
134 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
135 'description' => new external_value(PARAM_RAW, 'cohort description'),
136 'descriptionformat' => new external_format_value('description'),
137 'visible' => new external_value(PARAM_BOOL, 'cohort visible'),
144 * Returns description of method parameters
146 * @return external_function_parameters
147 * @since Moodle 2.5
149 public static function delete_cohorts_parameters() {
150 return new external_function_parameters(
151 array(
152 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'cohort ID')),
158 * Delete cohorts
160 * @param array $cohortids
161 * @return null
162 * @since Moodle 2.5
164 public static function delete_cohorts($cohortids) {
165 global $CFG, $DB;
166 require_once("$CFG->dirroot/cohort/lib.php");
168 $params = self::validate_parameters(self::delete_cohorts_parameters(), array('cohortids' => $cohortids));
170 $transaction = $DB->start_delegated_transaction();
172 foreach ($params['cohortids'] as $cohortid) {
173 // Validate params.
174 $cohortid = validate_param($cohortid, PARAM_INT);
175 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
177 // Now security checks.
178 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
179 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
180 throw new invalid_parameter_exception('Invalid context');
182 self::validate_context($context);
183 require_capability('moodle/cohort:manage', $context);
184 cohort_delete_cohort($cohort);
186 $transaction->allow_commit();
188 return null;
192 * Returns description of method result value
194 * @return null
195 * @since Moodle 2.5
197 public static function delete_cohorts_returns() {
198 return null;
202 * Returns description of method parameters
204 * @return external_function_parameters
205 * @since Moodle 2.5
207 public static function get_cohorts_parameters() {
208 return new external_function_parameters(
209 array(
210 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'Cohort ID')
211 , 'List of cohort id. A cohort id is an integer.'),
217 * Get cohorts definition specified by ids
219 * @param array $cohortids array of cohort ids
220 * @return array of cohort objects (id, courseid, name)
221 * @since Moodle 2.5
223 public static function get_cohorts($cohortids) {
224 global $DB;
226 $params = self::validate_parameters(self::get_cohorts_parameters(), array('cohortids' => $cohortids));
228 $cohorts = array();
229 foreach ($params['cohortids'] as $cohortid) {
230 // Validate params.
231 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
233 // Now security checks.
234 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
235 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
236 throw new invalid_parameter_exception('Invalid context');
238 self::validate_context($context);
239 if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:view'), $context)) {
240 throw new required_capability_exception($context, 'moodle/cohort:view', 'nopermissions', '');
243 list($cohort->description, $cohort->descriptionformat) =
244 external_format_text($cohort->description, $cohort->descriptionformat,
245 $context->id, 'cohort', 'description', $cohort->id);
247 $cohorts[] = (array) $cohort;
250 return $cohorts;
254 * Returns description of method result value
256 * @return external_description
257 * @since Moodle 2.5
259 public static function get_cohorts_returns() {
260 return new external_multiple_structure(
261 new external_single_structure(
262 array(
263 'id' => new external_value(PARAM_INT, 'ID of the cohort'),
264 'name' => new external_value(PARAM_RAW, 'cohort name'),
265 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
266 'description' => new external_value(PARAM_RAW, 'cohort description'),
267 'descriptionformat' => new external_format_value('description'),
268 'visible' => new external_value(PARAM_BOOL, 'cohort visible'),
275 * Returns description of method parameters
277 * @return external_function_parameters
278 * @since Moodle 2.5
280 public static function update_cohorts_parameters() {
281 return new external_function_parameters(
282 array(
283 'cohorts' => new external_multiple_structure(
284 new external_single_structure(
285 array(
286 'id' => new external_value(PARAM_INT, 'ID of the cohort'),
287 'categorytype' => new external_single_structure(
288 array(
289 'type' => new external_value(PARAM_TEXT, 'the name of the field: id (numeric value
290 of course category id) or idnumber (alphanumeric value of idnumber course category)
291 or system (value ignored)'),
292 'value' => new external_value(PARAM_RAW, 'the value of the categorytype')
295 'name' => new external_value(PARAM_RAW, 'cohort name'),
296 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
297 'description' => new external_value(PARAM_RAW, 'cohort description', VALUE_OPTIONAL),
298 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
299 'visible' => new external_value(PARAM_BOOL, 'cohort visible', VALUE_OPTIONAL),
308 * Update cohorts
310 * @param array $cohorts
311 * @return null
312 * @since Moodle 2.5
314 public static function update_cohorts($cohorts) {
315 global $CFG, $DB;
316 require_once("$CFG->dirroot/cohort/lib.php");
318 $params = self::validate_parameters(self::update_cohorts_parameters(), array('cohorts' => $cohorts));
320 $transaction = $DB->start_delegated_transaction();
321 $syscontext = context_system::instance();
323 foreach ($params['cohorts'] as $cohort) {
324 $cohort = (object) $cohort;
326 if (trim($cohort->name) == '') {
327 throw new invalid_parameter_exception('Invalid cohort name');
330 $oldcohort = $DB->get_record('cohort', array('id' => $cohort->id), '*', MUST_EXIST);
331 $oldcontext = context::instance_by_id($oldcohort->contextid, MUST_EXIST);
332 require_capability('moodle/cohort:manage', $oldcontext);
334 // Category type (context id).
335 $categorytype = $cohort->categorytype;
336 if (!in_array($categorytype['type'], array('idnumber', 'id', 'system'))) {
337 throw new invalid_parameter_exception('category type must be id, idnumber or system:' . $categorytype['type']);
339 if ($categorytype['type'] === 'system') {
340 $cohort->contextid = $syscontext->id;
341 } else if ($catid = $DB->get_field('course_categories', 'id', array($categorytype['type'] => $categorytype['value']))) {
342 $cohort->contextid = $DB->get_field('context', 'id', array('instanceid' => $catid,
343 'contextlevel' => CONTEXT_COURSECAT));
344 } else {
345 throw new invalid_parameter_exception('category not exists: category='.$categorytype['value']);
348 if ($cohort->contextid != $oldcohort->contextid) {
349 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
350 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
351 throw new invalid_parameter_exception('Invalid context');
354 self::validate_context($context);
355 require_capability('moodle/cohort:manage', $context);
358 if (!empty($cohort->description)) {
359 $cohort->descriptionformat = external_validate_format($cohort->descriptionformat);
362 cohort_update_cohort($cohort);
365 $transaction->allow_commit();
367 return null;
371 * Returns description of method result value
373 * @return null
374 * @since Moodle 2.5
376 public static function update_cohorts_returns() {
377 return null;
381 * Returns description of method parameters
383 * @return external_function_parameters
384 * @since Moodle 2.5
386 public static function add_cohort_members_parameters() {
387 return new external_function_parameters (
388 array(
389 'members' => new external_multiple_structure (
390 new external_single_structure (
391 array (
392 'cohorttype' => new external_single_structure (
393 array(
394 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the field: id
395 (numeric value of cohortid) or idnumber (alphanumeric value of idnumber) '),
396 'value' => new external_value(PARAM_RAW, 'The value of the cohort')
399 'usertype' => new external_single_structure (
400 array(
401 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the field: id
402 (numeric value of id) or username (alphanumeric value of username) '),
403 'value' => new external_value(PARAM_RAW, 'The value of the cohort')
414 * Add cohort members
416 * @param array $members of arrays with keys userid, cohortid
417 * @since Moodle 2.5
419 public static function add_cohort_members($members) {
420 global $CFG, $DB;
421 require_once($CFG->dirroot."/cohort/lib.php");
423 $params = self::validate_parameters(self::add_cohort_members_parameters(), array('members' => $members));
425 $transaction = $DB->start_delegated_transaction();
426 $warnings = array();
427 foreach ($params['members'] as $member) {
428 // Cohort parameters.
429 $cohorttype = $member['cohorttype'];
430 $cohortparam = array($cohorttype['type'] => $cohorttype['value']);
431 // User parameters.
432 $usertype = $member['usertype'];
433 $userparam = array($usertype['type'] => $usertype['value']);
434 try {
435 // Check parameters.
436 if ($cohorttype['type'] != 'id' && $cohorttype['type'] != 'idnumber') {
437 $warning = array();
438 $warning['warningcode'] = '1';
439 $warning['message'] = 'invalid parameter: cohortype='.$cohorttype['type'];
440 $warnings[] = $warning;
441 continue;
443 if ($usertype['type'] != 'id' && $usertype['type'] != 'username') {
444 $warning = array();
445 $warning['warningcode'] = '1';
446 $warning['message'] = 'invalid parameter: usertype='.$usertype['type'];
447 $warnings[] = $warning;
448 continue;
450 // Extract parameters.
451 if (!$cohortid = $DB->get_field('cohort', 'id', $cohortparam)) {
452 $warning = array();
453 $warning['warningcode'] = '2';
454 $warning['message'] = 'cohort '.$cohorttype['type'].'='.$cohorttype['value'].' not exists';
455 $warnings[] = $warning;
456 continue;
458 if (!$userid = $DB->get_field('user', 'id', array_merge($userparam, array('deleted' => 0,
459 'mnethostid' => $CFG->mnet_localhost_id)))) {
460 $warning = array();
461 $warning['warningcode'] = '2';
462 $warning['message'] = 'user '.$usertype['type'].'='.$usertype['value'].' not exists';
463 $warnings[] = $warning;
464 continue;
466 if ($DB->record_exists('cohort_members', array('cohortid' => $cohortid, 'userid' => $userid))) {
467 $warning = array();
468 $warning['warningcode'] = '3';
469 $warning['message'] = 'record already exists: cohort('.$cohorttype['type'].'='.$cohorttype['value'].' '.
470 $usertype['type'].'='.$usertype['value'].')';
471 $warnings[] = $warning;
472 continue;
474 $cohort = $DB->get_record('cohort', array('id'=>$cohortid), '*', MUST_EXIST);
475 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
476 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
477 $warning = array();
478 $warning['warningcode'] = '1';
479 $warning['message'] = 'Invalid context: '.$context->contextlevel;
480 $warnings[] = $warning;
481 continue;
483 self::validate_context($context);
484 } catch (Exception $e) {
485 throw new moodle_exception('Error', 'cohort', '', $e->getMessage());
487 if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:assign'), $context)) {
488 throw new required_capability_exception($context, 'moodle/cohort:assign', 'nopermissions', '');
490 cohort_add_member($cohortid, $userid);
492 $transaction->allow_commit();
493 // Return.
494 $result = array();
495 $result['warnings'] = $warnings;
496 return $result;
500 * Returns description of method result value
502 * @return null
503 * @since Moodle 2.5
505 public static function add_cohort_members_returns() {
506 return new external_single_structure(
507 array(
508 'warnings' => new external_warnings()
514 * Returns description of method parameters
516 * @return external_function_parameters
517 * @since Moodle 2.5
519 public static function delete_cohort_members_parameters() {
520 return new external_function_parameters(
521 array(
522 'members' => new external_multiple_structure(
523 new external_single_structure(
524 array(
525 'cohortid' => new external_value(PARAM_INT, 'cohort record id'),
526 'userid' => new external_value(PARAM_INT, 'user id'),
535 * Delete cohort members
537 * @param array $members of arrays with keys userid, cohortid
538 * @since Moodle 2.5
540 public static function delete_cohort_members($members) {
541 global $CFG, $DB;
542 require_once("$CFG->dirroot/cohort/lib.php");
544 // Validate parameters.
545 $params = self::validate_parameters(self::delete_cohort_members_parameters(), array('members' => $members));
547 $transaction = $DB->start_delegated_transaction();
549 foreach ($params['members'] as $member) {
550 $cohortid = $member['cohortid'];
551 $userid = $member['userid'];
553 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
554 $user = $DB->get_record('user', array('id' => $userid, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id),
555 '*', MUST_EXIST);
557 // Now security checks.
558 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
559 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
560 throw new invalid_parameter_exception('Invalid context');
562 self::validate_context($context);
563 if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:assign'), $context)) {
564 throw new required_capability_exception($context, 'moodle/cohort:assign', 'nopermissions', '');
567 cohort_remove_member($cohort->id, $user->id);
569 $transaction->allow_commit();
573 * Returns description of method result value
575 * @return null
576 * @since Moodle 2.5
578 public static function delete_cohort_members_returns() {
579 return null;
583 * Returns description of method parameters
585 * @return external_function_parameters
586 * @since Moodle 2.5
588 public static function get_cohort_members_parameters() {
589 return new external_function_parameters(
590 array(
591 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'Cohort ID')),
597 * Return all members for a cohort
599 * @param array $cohortids array of cohort ids
600 * @return array with cohort id keys containing arrays of user ids
601 * @since Moodle 2.5
603 public static function get_cohort_members($cohortids) {
604 global $DB;
605 $params = self::validate_parameters(self::get_cohort_members_parameters(), array('cohortids' => $cohortids));
607 $members = array();
609 foreach ($params['cohortids'] as $cohortid) {
610 // Validate params.
611 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
612 // Now security checks.
613 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
614 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
615 throw new invalid_parameter_exception('Invalid context');
617 self::validate_context($context);
618 if (!has_any_capability(array('moodle/cohort:manage', 'moodle/cohort:view'), $context)) {
619 throw new required_capability_exception($context, 'moodle/cohort:view', 'nopermissions', '');
622 $cohortmembers = $DB->get_records_sql("SELECT u.id FROM {user} u, {cohort_members} cm
623 WHERE u.id = cm.userid AND cm.cohortid = ?
624 ORDER BY lastname ASC, firstname ASC", array($cohort->id));
625 $members[] = array('cohortid' => $cohortid, 'userids' => array_keys($cohortmembers));
627 return $members;
631 * Returns description of method result value
633 * @return external_description
634 * @since Moodle 2.5
636 public static function get_cohort_members_returns() {
637 return new external_multiple_structure(
638 new external_single_structure(
639 array(
640 'cohortid' => new external_value(PARAM_INT, 'cohort record id'),
641 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')),