Merge branch 'MDL-29472_m' of git://github.com/andreabix/moodle
[moodle.git] / cohort / externallib.php
CommitLineData
088645e2
AB
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/>.
16
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 */
25
26require_once("$CFG->libdir/externallib.php");
27
28class core_cohort_external extends external_api {
29
30 /**
31 * Returns description of method parameters
32 *
33 * @return external_function_parameters
34 * @since Moodle 2.4
35 */
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 'value' => new external_value(PARAM_RAW, 'the value of the categorytype')
47 )
48 ),
49 'name' => new external_value(PARAM_RAW, 'cohort name'),
50 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
51 'description' => new external_value(PARAM_RAW, 'cohort description', VALUE_OPTIONAL),
52 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
53 )
54 )
55 )
56 )
57 );
58 }
59
60 /**
61 * Create one or more cohorts
62 *
63 * @param array $cohorts An array of cohorts to create.
64 * @return array An array of arrays
65 * @since Moodle 2.4
66 */
67 public static function create_cohorts($cohorts) {
68 global $CFG, $DB;
69 require_once("$CFG->dirroot/cohort/lib.php");
70
71 $params = self::validate_parameters(self::create_cohorts_parameters(), array('cohorts' => $cohorts));
72
73 $transaction = $DB->start_delegated_transaction();
74
75 $cohortids = array();
76
77 foreach ($params['cohorts'] as $cohort) {
78 $cohort = (object)$cohort;
79
80 // Category type (context id).
81 $categorytype = $cohort->categorytype;
82 if ($catid = $DB->get_field('course_categories', 'id', array($categorytype['type'] => $categorytype['value']))) {
83 $cohort->contextid = $DB->get_field('context', 'id', array('instanceid' => $catid,
84 'contextlevel' => CONTEXT_COURSECAT));
85 } else {
86 throw new invalid_parameter_exception('category not exists: category '
87 .$categorytype['type'].' = '.$categorytype['value']);
88 }
89 // Make sure that the idnumber doesn't already exist.
90 if ($DB->record_exists('cohort', array('idnumber' => $cohort->idnumber))) {
91 throw new invalid_parameter_exception('record already exists: idnumber='.$cohort->idnumber);
92 }
93 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
94 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
95 throw new invalid_parameter_exception('Invalid context');
96 }
97 self::validate_context($context);
98 require_capability('moodle/cohort:manage', $context);
99
100 // Validate format.
101 $cohort->descriptionformat = external_validate_format($cohort->descriptionformat);
102 $cohort->id = cohort_add_cohort($cohort);
103
104 list($cohort->description, $cohort->descriptionformat) =
105 external_format_text($cohort->description, $cohort->descriptionformat,
106 $context->id, 'cohort', 'description', $cohort->id);
107 $cohortids[] = (array)$cohort;;
108 }
109 $transaction->allow_commit();
110
111 return $cohortids;
112 }
113
114 /**
115 * Returns description of method result value
116 *
117 * @return external_description
118 * @since Moodle 2.4
119 */
120 public static function create_cohorts_returns() {
121 return new external_multiple_structure(
122 new external_single_structure(
123 array(
124 'id' => new external_value(PARAM_INT, 'cohort id'),
125 'name' => new external_value(PARAM_RAW, 'cohort name'),
126 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
127 'description' => new external_value(PARAM_RAW, 'cohort description'),
128 'descriptionformat' => new external_format_value('description'),
129 )
130 )
131 );
132 }
133
134 /**
135 * Returns description of method parameters
136 *
137 * @return external_function_parameters
138 * @since Moodle 2.4
139 */
140 public static function delete_cohorts_parameters() {
141 return new external_function_parameters(
142 array(
143 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'cohort ID')),
144 )
145 );
146 }
147
148 /**
149 * Delete cohorts
150 *
151 * @param array $cohortids
152 * @return null
153 * @since Moodle 2.4
154 */
155 public static function delete_cohorts($cohortids) {
156 global $CFG, $DB;
157 require_once("$CFG->dirroot/cohort/lib.php");
158
159 $params = self::validate_parameters(self::delete_cohorts_parameters(), array('cohortids' => $cohortids));
160
161 $transaction = $DB->start_delegated_transaction();
162
163 foreach ($params['cohortids'] as $cohortid) {
164 // Validate params.
165 $cohortid = validate_param($cohortid, PARAM_INT);
166 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
167
168 // Now security checks.
169 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
170 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
171 throw new invalid_parameter_exception('Invalid context');
172 }
173 self::validate_context($context);
174 require_capability('moodle/cohort:manage', $context);
175 cohort_delete_cohort($cohort);
176 }
177 $transaction->allow_commit();
178
179 return null;
180 }
181
182 /**
183 * Returns description of method result value
184 *
185 * @return null
186 * @since Moodle 2.4
187 */
188 public static function delete_cohorts_returns() {
189 return null;
190 }
191
192 /**
193 * Returns description of method parameters
194 *
195 * @return external_function_parameters
196 * @since Moodle 2.4
197 */
198 public static function get_cohorts_parameters() {
199 return new external_function_parameters(
200 array(
201 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'Cohort ID')
202 , 'List of cohort id. A cohort id is an integer.'),
203 )
204 );
205 }
206
207 /**
208 * Get cohorts definition specified by ids
209 *
210 * @param array $cohortids array of cohort ids
211 * @return array of cohort objects (id, courseid, name)
212 * @since Moodle 2.4
213 */
214 public static function get_cohorts($cohortids) {
215 global $DB;
216
217 $params = self::validate_parameters(self::get_cohorts_parameters(), array('cohortids' => $cohortids));
218
219 $cohorts = array();
220 foreach ($params['cohortids'] as $cohortid) {
221 // Validate params.
222 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
223
224 // Now security checks.
225 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
226 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
227 throw new invalid_parameter_exception('Invalid context');
228 }
229 self::validate_context($context);
230 require_capability('moodle/cohort:view', $context);
231
232 list($cohort->description, $cohort->descriptionformat) =
233 external_format_text($cohort->description, $cohort->descriptionformat,
234 $context->id, 'cohort', 'description', $cohort->id);
235
236 $cohorts[] = (array) $cohort;
237 }
238
239 return $cohorts;
240 }
241
242 /**
243 * Returns description of method result value
244 *
245 * @return external_description
246 * @since Moodle 2.4
247 */
248 public static function get_cohorts_returns() {
249 return new external_multiple_structure(
250 new external_single_structure(
251 array(
252 'id' => new external_value(PARAM_NUMBER, 'ID of the cohort'),
253 'name' => new external_value(PARAM_RAW, 'cohort name'),
254 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
255 'description' => new external_value(PARAM_RAW, 'cohort description'),
256 'descriptionformat' => new external_format_value('description'),
257 )
258 )
259 );
260 }
261
262 /**
263 * Returns description of method parameters
264 *
265 * @return external_function_parameters
266 * @since Moodle 2.4
267 */
268 public static function update_cohorts_parameters() {
269 return new external_function_parameters(
270 array(
271 'cohorts' => new external_multiple_structure(
272 new external_single_structure(
273 array(
274 'id' => new external_value(PARAM_NUMBER, 'ID of the cohort'),
275 'categorytype' => new external_single_structure(
276 array(
277 'type' => new external_value(PARAM_TEXT, 'the name of the field: id (numeric value
278 of course category id) or idnumber (alphanumeric value of idnumber course category)'),
279 'value' => new external_value(PARAM_RAW, 'the value of the categorytype')
280 )
281 ),
282 'name' => new external_value(PARAM_RAW, 'cohort name'),
283 'idnumber' => new external_value(PARAM_RAW, 'cohort idnumber'),
284 'description' => new external_value(PARAM_RAW, 'cohort description', VALUE_OPTIONAL),
285 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
286 )
287 )
288 )
289 )
290 );
291 }
292
293 /**
294 * Update cohorts
295 *
296 * @param array $cohorts
297 * @return null
298 * @since Moodle 2.4
299 */
300 public static function update_cohorts($cohorts) {
301 global $CFG, $DB;
302 require_once("$CFG->dirroot/cohort/lib.php");
303
304 $params = self::validate_parameters(self::update_cohorts_parameters(), array('cohorts' => $cohorts));
305
306 $transaction = $DB->start_delegated_transaction();
307
308 foreach ($params['cohorts'] as $cohort) {
309 $cohort = (object) $cohort;
310
311 if (trim($cohort->name) == '') {
312 throw new invalid_parameter_exception('Invalid cohort name');
313 }
314
315 // Category type (context id).
316 $categorytype = $cohort->categorytype;
317 if ($catid = $DB->get_field('course_categories', 'id', array($categorytype['type'] => $categorytype['value']))) {
318 $cohort->contextid = $DB->get_field('context', 'id', array('instanceid' => $catid,
319 'contextlevel' => CONTEXT_COURSECAT));
320 } else {
321 throw new invalid_parameter_exception('category not exists: category='.$categorytype['value']);
322 }
323
324 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
325 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
326 throw new invalid_parameter_exception('Invalid context');
327 }
328 self::validate_context($context);
329 require_capability('moodle/cohort:manage', $context);
330
331 if (!empty($cohort->description)) {
332 $cohort->descriptionformat = external_validate_format($cohort->descriptionformat);
333 }
334
335 cohort_update_cohort($cohort);
336 }
337
338 $transaction->allow_commit();
339
340 return null;
341 }
342
343 /**
344 * Returns description of method result value
345 *
346 * @return null
347 * @since Moodle 2.4
348 */
349 public static function update_cohorts_returns() {
350 return null;
351 }
352
353 /**
354 * Returns description of method parameters
355 *
356 * @return external_function_parameters
357 * @since Moodle 2.4
358 */
359 public static function add_cohort_members_parameters() {
360 return new external_function_parameters (
361 array(
362 'members' => new external_multiple_structure (
363 new external_single_structure (
364 array (
365 'cohorttype' => new external_single_structure (
366 array(
367 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the field: id
368 (numeric value of cohortid) or idnumber (alphanumeric value of idnumber) '),
369 'value' => new external_value(PARAM_RAW, 'The value of the cohort')
370 )
371 ),
372 'usertype' => new external_single_structure (
373 array(
374 'type' => new external_value(PARAM_ALPHANUMEXT, 'The name of the field: id
375 (numeric value of id) or username (alphanumeric value of username) '),
376 'value' => new external_value(PARAM_RAW, 'The value of the cohort')
377 )
378 )
379 )
380 )
381 )
382 )
383 );
384 }
385
386 /**
387 * Add cohort members
388 *
389 * @param array $members of arrays with keys userid, cohortid
390 * @since Moodle 2.4
391 */
392 public static function add_cohort_members($members) {
393 global $CFG, $DB;
394 require_once($CFG->dirroot."/cohort/lib.php");
395
396 $params = self::validate_parameters(self::add_cohort_members_parameters(), array('members' => $members));
397
398 $transaction = $DB->start_delegated_transaction();
399 $warnings = array();
400 foreach ($params['members'] as $member) {
401 // Cohort parameters.
402 $cohorttype = $member['cohorttype'];
403 $cohortparam = array($cohorttype['type'] => $cohorttype['value']);
404 // User parameters.
405 $usertype = $member['usertype'];
406 $userparam = array($usertype['type'] => $usertype['value']);
407 try {
408 // Check parameters.
409 if ($cohorttype['type'] != 'id' && $cohorttype['type'] != 'idnumber') {
410 $warning = array();
411 $warning['warningcode'] = '1';
412 $warning['message'] = 'invalid parameter: cohortype='.$cohorttype['type'];
413 $warnings[] = $warning;
414 continue;
415 }
416 if ($usertype['type'] != 'id' && $usertype['type'] != 'username') {
417 $warning = array();
418 $warning['warningcode'] = '1';
419 $warning['message'] = 'invalid parameter: usertype='.$usertype['type'];
420 $warnings[] = $warning;
421 continue;
422 }
423 // Extract parameters.
424 if (!$cohortid = $DB->get_field('cohort', 'id', $cohortparam)) {
425 $warning = array();
426 $warning['warningcode'] = '2';
427 $warning['message'] = 'cohort '.$cohorttype['type'].'='.$cohorttype['value'].' not exists';
428 $warnings[] = $warning;
429 continue;
430 }
431 if (!$userid = $DB->get_field('user', 'id', array_merge($userparam, array('deleted' => 0,
432 'mnethostid' => $CFG->mnet_localhost_id)))) {
433 $warning = array();
434 $warning['warningcode'] = '2';
435 $warning['message'] = 'user '.$usertype['type'].'='.$usertype['value'].' not exists';
436 $warnings[] = $warning;
437 continue;
438 }
439 if ($DB->record_exists('cohort_members', array('cohortid' => $cohortid, 'userid' => $userid))) {
440 $warning = array();
441 $warning['warningcode'] = '3';
442 $warning['message'] = 'record already exists: cohort('.$cohorttype['type'].'='.$cohorttype['value'].' '.
443 $usertype['type'].'='.$usertype['value'].')';
444 $warnings[] = $warning;
445 continue;
446 }
447 $cohort = $DB->get_record('cohort', array('id'=>$cohortid), '*', MUST_EXIST);
448 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
449 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
450 $warning = array();
451 $warning['warningcode'] = '1';
452 $warning['message'] = 'Invalid context: '.$context->contextlevel;
453 $warnings[] = $warning;
454 continue;
455 }
456 self::validate_context($context);
457 } catch (Exception $e) {
458 throw new moodle_exception('Error', 'cohort', '', $e->getMessage());
459 }
460 require_capability('moodle/cohort:assign', $context);
461 cohort_add_member($cohortid, $userid);
462 }
463 $transaction->allow_commit();
464 // Return.
465 $result = array();
466 $result['warnings'] = $warnings;
467 return $result;
468 }
469
470 /**
471 * Returns description of method result value
472 *
473 * @return null
474 * @since Moodle 2.4
475 */
476 public static function add_cohort_members_returns() {
477 return new external_single_structure(
478 array(
479 'warnings' => new external_warnings()
480 )
481 );
482 }
483
484 /**
485 * Returns description of method parameters
486 *
487 * @return external_function_parameters
488 * @since Moodle 2.4
489 */
490 public static function delete_cohort_members_parameters() {
491 return new external_function_parameters(
492 array(
493 'members' => new external_multiple_structure(
494 new external_single_structure(
495 array(
496 'cohortid' => new external_value(PARAM_INT, 'cohort record id'),
497 'userid' => new external_value(PARAM_INT, 'user id'),
498 )
499 )
500 )
501 )
502 );
503 }
504
505 /**
506 * Delete cohort members
507 *
508 * @param array $members of arrays with keys userid, cohortid
509 * @since Moodle 2.4
510 */
511 public static function delete_cohort_members($members) {
512 global $CFG, $DB;
513 require_once("$CFG->dirroot/cohort/lib.php");
514
515 // Validate parameters.
516 $params = self::validate_parameters(self::delete_cohort_members_parameters(), array('members' => $members));
517
518 $transaction = $DB->start_delegated_transaction();
519
520 foreach ($params['members'] as $member) {
521 $cohortid = $member['cohortid'];
522 $userid = $member['userid'];
523
524 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
525 $user = $DB->get_record('user', array('id' => $userid, 'deleted' => 0, 'mnethostid' => $CFG->mnet_localhost_id),
526 '*', MUST_EXIST);
527
528 // Now security checks.
529 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
530 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
531 throw new invalid_parameter_exception('Invalid context');
532 }
533 self::validate_context($context);
534 require_capability('moodle/cohort:assign', $context);
535
536 cohort_remove_member($cohort->id, $user->id);
537 }
538 $transaction->allow_commit();
539 }
540
541 /**
542 * Returns description of method result value
543 *
544 * @return null
545 * @since Moodle 2.4
546 */
547 public static function delete_cohort_members_returns() {
548 return null;
549 }
550
551 /**
552 * Returns description of method parameters
553 *
554 * @return external_function_parameters
555 * @since Moodle 2.4
556 */
557 public static function get_cohort_members_parameters() {
558 return new external_function_parameters(
559 array(
560 'cohortids' => new external_multiple_structure(new external_value(PARAM_INT, 'Cohort ID')),
561 )
562 );
563 }
564
565 /**
566 * Return all members for a cohort
567 *
568 * @param array $cohortids array of cohort ids
569 * @return array with cohort id keys containing arrays of user ids
570 * @since Moodle 2.4
571 */
572 public static function get_cohort_members($cohortids) {
573 global $DB;
574 $params = self::validate_parameters(self::get_cohort_members_parameters(), array('cohortids' => $cohortids));
575
576 $members = array();
577
578 foreach ($params['cohortids'] as $cohortid) {
579 // Validate params.
580 $cohort = $DB->get_record('cohort', array('id' => $cohortid), '*', MUST_EXIST);
581 // Now security checks.
582 $context = context::instance_by_id($cohort->contextid, MUST_EXIST);
583 if ($context->contextlevel != CONTEXT_COURSECAT and $context->contextlevel != CONTEXT_SYSTEM) {
584 throw new invalid_parameter_exception('Invalid context');
585 }
586 self::validate_context($context);
587 require_capability('moodle/cohort:view', $context);
588
589 $cohortmembers = $DB->get_records_sql("SELECT u.id FROM {user} u, {cohort_members} cm
590 WHERE u.id = cm.userid AND cm.cohortid = ?
591 ORDER BY lastname ASC, firstname ASC", array($cohort->id));
592 $members[] = array('cohortid' => $cohortid, 'userids' => array_keys($cohortmembers));
593 }
594 return $members;
595 }
596
597 /**
598 * Returns description of method result value
599 *
600 * @return external_description
601 * @since Moodle 2.4
602 */
603 public static function get_cohort_members_returns() {
604 return new external_multiple_structure(
605 new external_single_structure(
606 array(
607 'cohortid' => new external_value(PARAM_INT, 'cohort record id'),
608 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')),
609 )
610 )
611 );
612 }
613}