MDL-60637 group: remove useless id number validation on web services
[moodle.git] / group / externallib.php
CommitLineData
9a0df45a 1<?php
9a0df45a 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
4615817d 17
9a0df45a 18/**
19 * External groups API
20 *
4d8e2417 21 * @package core_group
4615817d
JM
22 * @category external
23 * @copyright 2009 Petr Skodak
9a0df45a 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
e71687ba
JL
27defined('MOODLE_INTERNAL') || die();
28
9a0df45a 29require_once("$CFG->libdir/externallib.php");
30
5d1017e1 31/**
4615817d 32 * Group external functions
4d8e2417
AG
33 *
34 * @package core_group
4615817d
JM
35 * @category external
36 * @copyright 2011 Jerome Mouneyrac
4d8e2417 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
4615817d 38 * @since Moodle 2.2
5d1017e1
JM
39 */
40class core_group_external extends external_api {
9a0df45a 41
0c96468c 42 /**
43 * Returns description of method parameters
4615817d 44 *
f5072177 45 * @return external_function_parameters
4615817d 46 * @since Moodle 2.2
0c96468c 47 */
48 public static function create_groups_parameters() {
f5072177 49 return new external_function_parameters(
50 array(
51 'groups' => new external_multiple_structure(
52 new external_single_structure(
53 array(
54 'courseid' => new external_value(PARAM_INT, 'id of course'),
55 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
56 'description' => new external_value(PARAM_RAW, 'group description text'),
93ce0e82 57 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
32435a69 58 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase', VALUE_OPTIONAL),
ed0fd1f6 59 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
f5072177 60 )
d4c6ef70 61 ), 'List of group object. A group has a courseid, a name, a description and an enrolment key.'
f5072177 62 )
63 )
64 );
0c96468c 65 }
66
67 /**
9a0df45a 68 * Create groups
4615817d 69 *
b4c1a34e 70 * @param array $groups array of group description arrays (with keys groupname and courseid)
f5072177 71 * @return array of newly created groups
4615817d 72 * @since Moodle 2.2
9a0df45a 73 */
b4c1a34e 74 public static function create_groups($groups) {
f5072177 75 global $CFG, $DB;
9a0df45a 76 require_once("$CFG->dirroot/group/lib.php");
77
c9c5cc81 78 $params = self::validate_parameters(self::create_groups_parameters(), array('groups'=>$groups));
0c96468c 79
d5a8d9aa
PS
80 $transaction = $DB->start_delegated_transaction();
81
82 $groups = array();
83
84 foreach ($params['groups'] as $group) {
85 $group = (object)$group;
86
87 if (trim($group->name) == '') {
88 throw new invalid_parameter_exception('Invalid group name');
89 }
90 if ($DB->get_record('groups', array('courseid'=>$group->courseid, 'name'=>$group->name))) {
91 throw new invalid_parameter_exception('Group with the same name already exists in the course');
ab9a01f2 92 }
d5a8d9aa
PS
93
94 // now security checks
0d4d49d1 95 $context = context_course::instance($group->courseid, IGNORE_MISSING);
41e962ff 96 try {
97 self::validate_context($context);
98 } catch (Exception $e) {
99 $exceptionparam = new stdClass();
100 $exceptionparam->message = $e->getMessage();
101 $exceptionparam->courseid = $group->courseid;
96d3b93b 102 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
41e962ff 103 }
d5a8d9aa
PS
104 require_capability('moodle/course:managegroups', $context);
105
93ce0e82
JM
106 // Validate format.
107 $group->descriptionformat = external_validate_format($group->descriptionformat);
108
d5a8d9aa
PS
109 // finally create the group
110 $group->id = groups_create_group($group, false);
e5f0e519
SH
111 if (!isset($group->enrolmentkey)) {
112 $group->enrolmentkey = '';
113 }
ed0fd1f6
DM
114 if (!isset($group->idnumber)) {
115 $group->idnumber = '';
116 }
117
d5a8d9aa 118 $groups[] = (array)$group;
9a0df45a 119 }
d5a8d9aa
PS
120
121 $transaction->allow_commit();
9a0df45a 122
2e13b916 123 return $groups;
9a0df45a 124 }
125
4d8e2417 126 /**
0c96468c 127 * Returns description of method result value
4615817d
JM
128 *
129 * @return external_description
130 * @since Moodle 2.2
0c96468c 131 */
132 public static function create_groups_returns() {
f5072177 133 return new external_multiple_structure(
134 new external_single_structure(
135 array(
136 'id' => new external_value(PARAM_INT, 'group record id'),
137 'courseid' => new external_value(PARAM_INT, 'id of course'),
138 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
139 'description' => new external_value(PARAM_RAW, 'group description text'),
93ce0e82 140 'descriptionformat' => new external_format_value('description'),
f5072177 141 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
ed0fd1f6 142 'idnumber' => new external_value(PARAM_RAW, 'id number')
f5072177 143 )
d4c6ef70 144 ), 'List of group object. A group has an id, a courseid, a name, a description and an enrolment key.'
f5072177 145 );
0c96468c 146 }
147
f5072177 148 /**
149 * Returns description of method parameters
4615817d 150 *
f5072177 151 * @return external_function_parameters
4615817d 152 * @since Moodle 2.2
f5072177 153 */
0c96468c 154 public static function get_groups_parameters() {
8c772ad7 155 return new external_function_parameters(
156 array(
d4c6ef70 157 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')
158 ,'List of group id. A group id is an integer.'),
8c772ad7 159 )
160 );
0c96468c 161 }
162
9a0df45a 163 /**
246f6da2 164 * Get groups definition specified by ids
4615817d 165 *
b4c1a34e 166 * @param array $groupids arrays of group ids
9a0df45a 167 * @return array of group objects (id, courseid, name, enrolmentkey)
4615817d 168 * @since Moodle 2.2
9a0df45a 169 */
b4c1a34e 170 public static function get_groups($groupids) {
c9c5cc81 171 $params = self::validate_parameters(self::get_groups_parameters(), array('groupids'=>$groupids));
0c96468c 172
246f6da2 173 $groups = array();
0c96468c 174 foreach ($params['groupids'] as $groupid) {
ab9a01f2 175 // validate params
ed0fd1f6 176 $group = groups_get_group($groupid, 'id, courseid, name, idnumber, description, descriptionformat, enrolmentkey', MUST_EXIST);
ab9a01f2 177
9a0df45a 178 // now security checks
0d4d49d1 179 $context = context_course::instance($group->courseid, IGNORE_MISSING);
41e962ff 180 try {
181 self::validate_context($context);
182 } catch (Exception $e) {
183 $exceptionparam = new stdClass();
184 $exceptionparam->message = $e->getMessage();
185 $exceptionparam->courseid = $group->courseid;
96d3b93b 186 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
41e962ff 187 }
9a0df45a 188 require_capability('moodle/course:managegroups', $context);
189
93ce0e82
JM
190 list($group->description, $group->descriptionformat) =
191 external_format_text($group->description, $group->descriptionformat,
192 $context->id, 'group', 'description', $group->id);
193
2e13b916 194 $groups[] = (array)$group;
9a0df45a 195 }
196
197 return $groups;
198 }
199
4d8e2417 200 /**
f5072177 201 * Returns description of method result value
4615817d
JM
202 *
203 * @return external_description
204 * @since Moodle 2.2
f5072177 205 */
0c96468c 206 public static function get_groups_returns() {
246f6da2 207 return new external_multiple_structure(
208 new external_single_structure(
209 array(
210 'id' => new external_value(PARAM_INT, 'group record id'),
211 'courseid' => new external_value(PARAM_INT, 'id of course'),
212 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
213 'description' => new external_value(PARAM_RAW, 'group description text'),
93ce0e82 214 'descriptionformat' => new external_format_value('description'),
246f6da2 215 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
ed0fd1f6 216 'idnumber' => new external_value(PARAM_RAW, 'id number')
246f6da2 217 )
218 )
219 );
220 }
221
222 /**
223 * Returns description of method parameters
4615817d 224 *
246f6da2 225 * @return external_function_parameters
4615817d 226 * @since Moodle 2.2
246f6da2 227 */
228 public static function get_course_groups_parameters() {
229 return new external_function_parameters(
230 array(
231 'courseid' => new external_value(PARAM_INT, 'id of course'),
232 )
233 );
234 }
235
236 /**
237 * Get all groups in the specified course
4615817d 238 *
246f6da2 239 * @param int $courseid id of course
240 * @return array of group objects (id, courseid, name, enrolmentkey)
4615817d 241 * @since Moodle 2.2
246f6da2 242 */
243 public static function get_course_groups($courseid) {
244 $params = self::validate_parameters(self::get_course_groups_parameters(), array('courseid'=>$courseid));
245
246 // now security checks
0d4d49d1 247 $context = context_course::instance($params['courseid'], IGNORE_MISSING);
41e962ff 248 try {
249 self::validate_context($context);
250 } catch (Exception $e) {
251 $exceptionparam = new stdClass();
252 $exceptionparam->message = $e->getMessage();
253 $exceptionparam->courseid = $params['courseid'];
96d3b93b 254 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
41e962ff 255 }
246f6da2 256 require_capability('moodle/course:managegroups', $context);
257
93ce0e82 258 $gs = groups_get_all_groups($params['courseid'], 0, 0,
ed0fd1f6 259 'g.id, g.courseid, g.name, g.idnumber, g.description, g.descriptionformat, g.enrolmentkey');
246f6da2 260
261 $groups = array();
262 foreach ($gs as $group) {
93ce0e82
JM
263 list($group->description, $group->descriptionformat) =
264 external_format_text($group->description, $group->descriptionformat,
265 $context->id, 'group', 'description', $group->id);
246f6da2 266 $groups[] = (array)$group;
267 }
268
269 return $groups;
270 }
271
4d8e2417 272 /**
246f6da2 273 * Returns description of method result value
4615817d
JM
274 *
275 * @return external_description
276 * @since Moodle 2.2
246f6da2 277 */
278 public static function get_course_groups_returns() {
8c772ad7 279 return new external_multiple_structure(
280 new external_single_structure(
281 array(
f5072177 282 'id' => new external_value(PARAM_INT, 'group record id'),
283 'courseid' => new external_value(PARAM_INT, 'id of course'),
04d212ce 284 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
f5072177 285 'description' => new external_value(PARAM_RAW, 'group description text'),
93ce0e82 286 'descriptionformat' => new external_format_value('description'),
f5072177 287 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
ed0fd1f6 288 'idnumber' => new external_value(PARAM_RAW, 'id number')
8c772ad7 289 )
290 )
291 );
0c96468c 292 }
293
0f4e72de
PS
294 /**
295 * Returns description of method parameters
4615817d 296 *
0f4e72de 297 * @return external_function_parameters
4615817d 298 * @since Moodle 2.2
0f4e72de 299 */
0c96468c 300 public static function delete_groups_parameters() {
0f4e72de
PS
301 return new external_function_parameters(
302 array(
303 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
304 )
305 );
0c96468c 306 }
307
9a0df45a 308 /**
309 * Delete groups
4615817d 310 *
b4c1a34e 311 * @param array $groupids array of group ids
4615817d 312 * @since Moodle 2.2
9a0df45a 313 */
b4c1a34e 314 public static function delete_groups($groupids) {
2cb1ee78 315 global $CFG, $DB;
9a0df45a 316 require_once("$CFG->dirroot/group/lib.php");
317
c9c5cc81 318 $params = self::validate_parameters(self::delete_groups_parameters(), array('groupids'=>$groupids));
0c96468c 319
d5a8d9aa
PS
320 $transaction = $DB->start_delegated_transaction();
321
d5a8d9aa
PS
322 foreach ($params['groupids'] as $groupid) {
323 // validate params
1e12c120 324 $groupid = validate_param($groupid, PARAM_INT);
cd5be9a5 325 if (!$group = groups_get_group($groupid, '*', IGNORE_MISSING)) {
d5a8d9aa
PS
326 // silently ignore attempts to delete nonexisting groups
327 continue;
0f4e72de 328 }
d5a8d9aa
PS
329
330 // now security checks
0d4d49d1 331 $context = context_course::instance($group->courseid, IGNORE_MISSING);
41e962ff 332 try {
333 self::validate_context($context);
334 } catch (Exception $e) {
335 $exceptionparam = new stdClass();
336 $exceptionparam->message = $e->getMessage();
337 $exceptionparam->courseid = $group->courseid;
96d3b93b 338 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
41e962ff 339 }
d5a8d9aa
PS
340 require_capability('moodle/course:managegroups', $context);
341
342 groups_delete_group($group);
9a0df45a 343 }
d5a8d9aa
PS
344
345 $transaction->allow_commit();
9a0df45a 346 }
347
4d8e2417 348 /**
0f4e72de 349 * Returns description of method result value
4615817d
JM
350 *
351 * @return null
352 * @since Moodle 2.2
0f4e72de 353 */
0c96468c 354 public static function delete_groups_returns() {
0f4e72de 355 return null;
0c96468c 356 }
357
358
0f4e72de
PS
359 /**
360 * Returns description of method parameters
4615817d 361 *
0f4e72de 362 * @return external_function_parameters
4615817d 363 * @since Moodle 2.2
0f4e72de 364 */
5d1017e1 365 public static function get_group_members_parameters() {
0f4e72de
PS
366 return new external_function_parameters(
367 array(
368 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
369 )
370 );
0c96468c 371 }
9a0df45a 372
373 /**
374 * Return all members for a group
4615817d 375 *
b4c1a34e 376 * @param array $groupids array of group ids
9a0df45a 377 * @return array with group id keys containing arrays of user ids
4615817d 378 * @since Moodle 2.2
9a0df45a 379 */
5d1017e1 380 public static function get_group_members($groupids) {
0f4e72de 381 $members = array();
9a0df45a 382
5d1017e1 383 $params = self::validate_parameters(self::get_group_members_parameters(), array('groupids'=>$groupids));
0c96468c 384
385 foreach ($params['groupids'] as $groupid) {
ab9a01f2 386 // validate params
9a0df45a 387 $group = groups_get_group($groupid, 'id, courseid, name, enrolmentkey', MUST_EXIST);
388 // now security checks
0d4d49d1 389 $context = context_course::instance($group->courseid, IGNORE_MISSING);
41e962ff 390 try {
391 self::validate_context($context);
392 } catch (Exception $e) {
393 $exceptionparam = new stdClass();
394 $exceptionparam->message = $e->getMessage();
395 $exceptionparam->courseid = $group->courseid;
96d3b93b 396 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
41e962ff 397 }
9a0df45a 398 require_capability('moodle/course:managegroups', $context);
399
400 $groupmembers = groups_get_members($group->id, 'u.id', 'lastname ASC, firstname ASC');
401
0f4e72de 402 $members[] = array('groupid'=>$groupid, 'userids'=>array_keys($groupmembers));
9a0df45a 403 }
404
0f4e72de 405 return $members;
9a0df45a 406 }
407
4d8e2417 408 /**
0f4e72de 409 * Returns description of method result value
4615817d 410 *
0f4e72de 411 * @return external_description
4615817d 412 * @since Moodle 2.2
0f4e72de 413 */
5d1017e1 414 public static function get_group_members_returns() {
0f4e72de
PS
415 return new external_multiple_structure(
416 new external_single_structure(
417 array(
418 'groupid' => new external_value(PARAM_INT, 'group record id'),
419 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')),
420 )
421 )
422 );
0c96468c 423 }
424
425
0f4e72de
PS
426 /**
427 * Returns description of method parameters
4615817d 428 *
0f4e72de 429 * @return external_function_parameters
4615817d 430 * @since Moodle 2.2
0f4e72de 431 */
5d1017e1 432 public static function add_group_members_parameters() {
4efa2483
PS
433 return new external_function_parameters(
434 array(
435 'members'=> new external_multiple_structure(
436 new external_single_structure(
437 array(
438 'groupid' => new external_value(PARAM_INT, 'group record id'),
439 'userid' => new external_value(PARAM_INT, 'user id'),
440 )
441 )
0f4e72de
PS
442 )
443 )
444 );
0c96468c 445 }
9a0df45a 446
447 /**
448 * Add group members
4615817d 449 *
b4c1a34e 450 * @param array $members of arrays with keys userid, groupid
4615817d 451 * @since Moodle 2.2
9a0df45a 452 */
5d1017e1 453 public static function add_group_members($members) {
2cb1ee78 454 global $CFG, $DB;
9a0df45a 455 require_once("$CFG->dirroot/group/lib.php");
456
5d1017e1 457 $params = self::validate_parameters(self::add_group_members_parameters(), array('members'=>$members));
9a0df45a 458
d5a8d9aa 459 $transaction = $DB->start_delegated_transaction();
d5a8d9aa
PS
460 foreach ($params['members'] as $member) {
461 // validate params
462 $groupid = $member['groupid'];
463 $userid = $member['userid'];
0c96468c 464
d5a8d9aa
PS
465 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
466 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
9a0df45a 467
d5a8d9aa 468 // now security checks
0d4d49d1 469 $context = context_course::instance($group->courseid, IGNORE_MISSING);
41e962ff 470 try {
471 self::validate_context($context);
472 } catch (Exception $e) {
473 $exceptionparam = new stdClass();
474 $exceptionparam->message = $e->getMessage();
475 $exceptionparam->courseid = $group->courseid;
96d3b93b 476 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
41e962ff 477 }
d5a8d9aa 478 require_capability('moodle/course:managegroups', $context);
9a0df45a 479
d5a8d9aa 480 // now make sure user is enrolled in course - this is mandatory requirement,
4f0c2d00
PS
481 // unfortunately this is slow
482 if (!is_enrolled($context, $userid)) {
483 throw new invalid_parameter_exception('Only enrolled users may be members of groups');
484 }
4efa2483 485
d5a8d9aa 486 groups_add_member($group, $user);
9a0df45a 487 }
d5a8d9aa
PS
488
489 $transaction->allow_commit();
9a0df45a 490 }
491
4d8e2417 492 /**
0f4e72de 493 * Returns description of method result value
4615817d 494 *
5d1017e1 495 * @return null
4615817d 496 * @since Moodle 2.2
0f4e72de 497 */
5d1017e1 498 public static function add_group_members_returns() {
0f4e72de 499 return null;
0c96468c 500 }
501
502
0f4e72de
PS
503 /**
504 * Returns description of method parameters
4615817d 505 *
0f4e72de 506 * @return external_function_parameters
4615817d 507 * @since Moodle 2.2
0f4e72de 508 */
5d1017e1 509 public static function delete_group_members_parameters() {
4efa2483
PS
510 return new external_function_parameters(
511 array(
512 'members'=> new external_multiple_structure(
513 new external_single_structure(
514 array(
515 'groupid' => new external_value(PARAM_INT, 'group record id'),
516 'userid' => new external_value(PARAM_INT, 'user id'),
517 )
518 )
0f4e72de
PS
519 )
520 )
521 );
0c96468c 522 }
9a0df45a 523
524 /**
525 * Delete group members
4615817d 526 *
b4c1a34e 527 * @param array $members of arrays with keys userid, groupid
4615817d 528 * @since Moodle 2.2
9a0df45a 529 */
5d1017e1 530 public static function delete_group_members($members) {
2cb1ee78 531 global $CFG, $DB;
9a0df45a 532 require_once("$CFG->dirroot/group/lib.php");
533
5d1017e1 534 $params = self::validate_parameters(self::delete_group_members_parameters(), array('members'=>$members));
9a0df45a 535
d5a8d9aa
PS
536 $transaction = $DB->start_delegated_transaction();
537
0c96468c 538 foreach ($params['members'] as $member) {
d5a8d9aa
PS
539 // validate params
540 $groupid = $member['groupid'];
541 $userid = $member['userid'];
0c96468c 542
d5a8d9aa
PS
543 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
544 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
9a0df45a 545
d5a8d9aa 546 // now security checks
0d4d49d1 547 $context = context_course::instance($group->courseid, IGNORE_MISSING);
41e962ff 548 try {
549 self::validate_context($context);
550 } catch (Exception $e) {
551 $exceptionparam = new stdClass();
552 $exceptionparam->message = $e->getMessage();
553 $exceptionparam->courseid = $group->courseid;
96d3b93b 554 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
41e962ff 555 }
d5a8d9aa 556 require_capability('moodle/course:managegroups', $context);
9a0df45a 557
1d1917ae 558 if (!groups_remove_member_allowed($group, $user)) {
559 throw new moodle_exception('errorremovenotpermitted', 'group', '', fullname($user));
560 }
d5a8d9aa 561 groups_remove_member($group, $user);
9a0df45a 562 }
d5a8d9aa
PS
563
564 $transaction->allow_commit();
9a0df45a 565 }
566
4d8e2417 567 /**
0f4e72de 568 * Returns description of method result value
4615817d 569 *
5d1017e1 570 * @return null
4615817d 571 * @since Moodle 2.2
0f4e72de 572 */
5d1017e1 573 public static function delete_group_members_returns() {
0f4e72de 574 return null;
0c96468c 575 }
576
882bac85
JL
577 /**
578 * Returns description of method parameters
67aa60f9 579 *
882bac85 580 * @return external_function_parameters
67aa60f9 581 * @since Moodle 2.3
882bac85
JL
582 */
583 public static function create_groupings_parameters() {
584 return new external_function_parameters(
585 array(
586 'groupings' => new external_multiple_structure(
587 new external_single_structure(
588 array(
589 'courseid' => new external_value(PARAM_INT, 'id of course'),
590 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
93ce0e82 591 'description' => new external_value(PARAM_RAW, 'grouping description text'),
ed0fd1f6
DM
592 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
593 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
882bac85
JL
594 )
595 ), 'List of grouping object. A grouping has a courseid, a name and a description.'
596 )
597 )
598 );
599 }
600
601 /**
602 * Create groupings
2c8ad38e 603 *
882bac85
JL
604 * @param array $groupings array of grouping description arrays (with keys groupname and courseid)
605 * @return array of newly created groupings
67aa60f9 606 * @since Moodle 2.3
882bac85
JL
607 */
608 public static function create_groupings($groupings) {
609 global $CFG, $DB;
610 require_once("$CFG->dirroot/group/lib.php");
611
612 $params = self::validate_parameters(self::create_groupings_parameters(), array('groupings'=>$groupings));
613
614 $transaction = $DB->start_delegated_transaction();
615
616 $groupings = array();
617
618 foreach ($params['groupings'] as $grouping) {
619 $grouping = (object)$grouping;
620
621 if (trim($grouping->name) == '') {
622 throw new invalid_parameter_exception('Invalid grouping name');
623 }
67aa60f9 624 if ($DB->count_records('groupings', array('courseid'=>$grouping->courseid, 'name'=>$grouping->name))) {
882bac85
JL
625 throw new invalid_parameter_exception('Grouping with the same name already exists in the course');
626 }
627
628 // Now security checks .
629 $context = context_course::instance($grouping->courseid);
630 try {
631 self::validate_context($context);
632 } catch (Exception $e) {
633 $exceptionparam = new stdClass();
634 $exceptionparam->message = $e->getMessage();
635 $exceptionparam->courseid = $grouping->courseid;
636 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
637 }
638 require_capability('moodle/course:managegroups', $context);
639
93ce0e82 640 $grouping->descriptionformat = external_validate_format($grouping->descriptionformat);
882bac85
JL
641
642 // Finally create the grouping.
643 $grouping->id = groups_create_grouping($grouping);
644 $groupings[] = (array)$grouping;
645 }
646
647 $transaction->allow_commit();
648
649 return $groupings;
650 }
651
652 /**
653 * Returns description of method result value
67aa60f9 654 *
882bac85 655 * @return external_description
67aa60f9 656 * @since Moodle 2.3
882bac85
JL
657 */
658 public static function create_groupings_returns() {
659 return new external_multiple_structure(
660 new external_single_structure(
661 array(
662 'id' => new external_value(PARAM_INT, 'grouping record id'),
663 'courseid' => new external_value(PARAM_INT, 'id of course'),
664 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
93ce0e82 665 'description' => new external_value(PARAM_RAW, 'grouping description text'),
ed0fd1f6
DM
666 'descriptionformat' => new external_format_value('description'),
667 'idnumber' => new external_value(PARAM_RAW, 'id number')
882bac85
JL
668 )
669 ), 'List of grouping object. A grouping has an id, a courseid, a name and a description.'
670 );
671 }
672
87e959f3
JL
673 /**
674 * Returns description of method parameters
67aa60f9 675 *
87e959f3 676 * @return external_function_parameters
67aa60f9 677 * @since Moodle 2.3
87e959f3
JL
678 */
679 public static function update_groupings_parameters() {
680 return new external_function_parameters(
681 array(
682 'groupings' => new external_multiple_structure(
683 new external_single_structure(
684 array(
685 'id' => new external_value(PARAM_INT, 'id of grouping'),
686 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
93ce0e82 687 'description' => new external_value(PARAM_RAW, 'grouping description text'),
ed0fd1f6
DM
688 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
689 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
87e959f3
JL
690 )
691 ), 'List of grouping object. A grouping has a courseid, a name and a description.'
692 )
693 )
694 );
695 }
696
697 /**
698 * Update groupings
67aa60f9 699 *
87e959f3
JL
700 * @param array $groupings array of grouping description arrays (with keys groupname and courseid)
701 * @return array of newly updated groupings
67aa60f9 702 * @since Moodle 2.3
87e959f3
JL
703 */
704 public static function update_groupings($groupings) {
705 global $CFG, $DB;
706 require_once("$CFG->dirroot/group/lib.php");
707
708 $params = self::validate_parameters(self::update_groupings_parameters(), array('groupings'=>$groupings));
709
710 $transaction = $DB->start_delegated_transaction();
711
87e959f3
JL
712 foreach ($params['groupings'] as $grouping) {
713 $grouping = (object)$grouping;
714
715 if (trim($grouping->name) == '') {
716 throw new invalid_parameter_exception('Invalid grouping name');
717 }
718
719 if (! $currentgrouping = $DB->get_record('groupings', array('id'=>$grouping->id))) {
720 throw new invalid_parameter_exception("Grouping $grouping->id does not exist in the course");
721 }
2c8ad38e
JL
722
723 // Check if the new modified grouping name already exists in the course.
724 if ($grouping->name != $currentgrouping->name and
725 $DB->count_records('groupings', array('courseid'=>$currentgrouping->courseid, 'name'=>$grouping->name))) {
726 throw new invalid_parameter_exception('A different grouping with the same name already exists in the course');
727 }
728
87e959f3
JL
729 $grouping->courseid = $currentgrouping->courseid;
730
731 // Now security checks.
732 $context = context_course::instance($grouping->courseid);
733 try {
734 self::validate_context($context);
735 } catch (Exception $e) {
736 $exceptionparam = new stdClass();
737 $exceptionparam->message = $e->getMessage();
738 $exceptionparam->courseid = $grouping->courseid;
739 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
740 }
741 require_capability('moodle/course:managegroups', $context);
742
743 // We must force allways FORMAT_HTML.
93ce0e82 744 $grouping->descriptionformat = external_validate_format($grouping->descriptionformat);
87e959f3
JL
745
746 // Finally update the grouping.
747 groups_update_grouping($grouping);
87e959f3
JL
748 }
749
750 $transaction->allow_commit();
751
67aa60f9 752 return null;
87e959f3
JL
753 }
754
67aa60f9 755 /**
87e959f3 756 * Returns description of method result value
67aa60f9 757 *
87e959f3 758 * @return external_description
67aa60f9 759 * @since Moodle 2.3
87e959f3
JL
760 */
761 public static function update_groupings_returns() {
67aa60f9 762 return null;
87e959f3
JL
763 }
764
ed849fba
JL
765 /**
766 * Returns description of method parameters
67aa60f9 767 *
ed849fba 768 * @return external_function_parameters
67aa60f9 769 * @since Moodle 2.3
ed849fba
JL
770 */
771 public static function get_groupings_parameters() {
772 return new external_function_parameters(
773 array(
774 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID')
67aa60f9 775 , 'List of grouping id. A grouping id is an integer.'),
45c0a7d0 776 'returngroups' => new external_value(PARAM_BOOL, 'return associated groups', VALUE_DEFAULT, 0)
ed849fba
JL
777 )
778 );
779 }
780
781 /**
782 * Get groupings definition specified by ids
67aa60f9 783 *
ed849fba 784 * @param array $groupingids arrays of grouping ids
45c0a7d0 785 * @param boolean $returngroups return the associated groups if true. The default is false.
ed849fba 786 * @return array of grouping objects (id, courseid, name)
67aa60f9 787 * @since Moodle 2.3
ed849fba 788 */
45c0a7d0
PC
789 public static function get_groupings($groupingids, $returngroups = false) {
790 global $CFG, $DB;
ed849fba 791 require_once("$CFG->dirroot/group/lib.php");
67aa60f9 792 require_once("$CFG->libdir/filelib.php");
ed849fba 793
45c0a7d0
PC
794 $params = self::validate_parameters(self::get_groupings_parameters(),
795 array('groupingids' => $groupingids,
796 'returngroups' => $returngroups));
ed849fba
JL
797
798 $groupings = array();
799 foreach ($params['groupingids'] as $groupingid) {
800 // Validate params.
801 $grouping = groups_get_grouping($groupingid, '*', MUST_EXIST);
802
803 // Now security checks.
804 $context = context_course::instance($grouping->courseid);
805 try {
806 self::validate_context($context);
807 } catch (Exception $e) {
808 $exceptionparam = new stdClass();
809 $exceptionparam->message = $e->getMessage();
810 $exceptionparam->courseid = $grouping->courseid;
811 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
812 }
813 require_capability('moodle/course:managegroups', $context);
814
93ce0e82
JM
815 list($grouping->description, $grouping->descriptionformat) =
816 external_format_text($grouping->description, $grouping->descriptionformat,
817 $context->id, 'grouping', 'description', $grouping->id);
ed849fba 818
45c0a7d0
PC
819 $groupingarray = (array)$grouping;
820
821 if ($params['returngroups']) {
822 $grouprecords = $DB->get_records_sql("SELECT * FROM {groups} g INNER JOIN {groupings_groups} gg ".
823 "ON g.id = gg.groupid WHERE gg.groupingid = ? ".
824 "ORDER BY groupid", array($groupingid));
825 if ($grouprecords) {
826 $groups = array();
827 foreach ($grouprecords as $grouprecord) {
828 list($grouprecord->description, $grouprecord->descriptionformat) =
829 external_format_text($grouprecord->description, $grouprecord->descriptionformat,
830 $context->id, 'group', 'description', $grouprecord->groupid);
831 $groups[] = array('id' => $grouprecord->groupid,
832 'name' => $grouprecord->name,
ed0fd1f6 833 'idnumber' => $grouprecord->idnumber,
45c0a7d0
PC
834 'description' => $grouprecord->description,
835 'descriptionformat' => $grouprecord->descriptionformat,
836 'enrolmentkey' => $grouprecord->enrolmentkey,
837 'courseid' => $grouprecord->courseid
838 );
839 }
840 $groupingarray['groups'] = $groups;
841 }
842 }
843 $groupings[] = $groupingarray;
ed849fba
JL
844 }
845
846 return $groupings;
847 }
848
67aa60f9 849 /**
ed849fba 850 * Returns description of method result value
67aa60f9 851 *
ed849fba 852 * @return external_description
67aa60f9 853 * @since Moodle 2.3
ed849fba
JL
854 */
855 public static function get_groupings_returns() {
856 return new external_multiple_structure(
857 new external_single_structure(
858 array(
859 'id' => new external_value(PARAM_INT, 'grouping record id'),
860 'courseid' => new external_value(PARAM_INT, 'id of course'),
861 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
93ce0e82 862 'description' => new external_value(PARAM_RAW, 'grouping description text'),
45c0a7d0 863 'descriptionformat' => new external_format_value('description'),
ed0fd1f6 864 'idnumber' => new external_value(PARAM_RAW, 'id number'),
45c0a7d0
PC
865 'groups' => new external_multiple_structure(
866 new external_single_structure(
867 array(
868 'id' => new external_value(PARAM_INT, 'group record id'),
869 'courseid' => new external_value(PARAM_INT, 'id of course'),
870 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
871 'description' => new external_value(PARAM_RAW, 'group description text'),
872 'descriptionformat' => new external_format_value('description'),
ed0fd1f6
DM
873 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
874 'idnumber' => new external_value(PARAM_RAW, 'id number')
45c0a7d0
PC
875 )
876 ),
877 'optional groups', VALUE_OPTIONAL)
ed849fba
JL
878 )
879 )
880 );
881 }
882
85e42d22
JL
883 /**
884 * Returns description of method parameters
67aa60f9 885 *
85e42d22 886 * @return external_function_parameters
67aa60f9 887 * @since Moodle 2.3
85e42d22
JL
888 */
889 public static function get_course_groupings_parameters() {
890 return new external_function_parameters(
891 array(
892 'courseid' => new external_value(PARAM_INT, 'id of course'),
893 )
894 );
895 }
896
897 /**
898 * Get all groupings in the specified course
67aa60f9 899 *
85e42d22
JL
900 * @param int $courseid id of course
901 * @return array of grouping objects (id, courseid, name, enrolmentkey)
67aa60f9 902 * @since Moodle 2.3
85e42d22
JL
903 */
904 public static function get_course_groupings($courseid) {
905 global $CFG;
906 require_once("$CFG->dirroot/group/lib.php");
67aa60f9 907 require_once("$CFG->libdir/filelib.php");
85e42d22
JL
908
909 $params = self::validate_parameters(self::get_course_groupings_parameters(), array('courseid'=>$courseid));
910
911 // Now security checks.
912 $context = context_course::instance($params['courseid']);
913
914 try {
915 self::validate_context($context);
916 } catch (Exception $e) {
917 $exceptionparam = new stdClass();
918 $exceptionparam->message = $e->getMessage();
919 $exceptionparam->courseid = $params['courseid'];
920 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
921 }
922 require_capability('moodle/course:managegroups', $context);
923
924 $gs = groups_get_all_groupings($params['courseid']);
925
926 $groupings = array();
927 foreach ($gs as $grouping) {
93ce0e82
JM
928 list($grouping->description, $grouping->descriptionformat) =
929 external_format_text($grouping->description, $grouping->descriptionformat,
930 $context->id, 'grouping', 'description', $grouping->id);
85e42d22
JL
931 $groupings[] = (array)$grouping;
932 }
933
934 return $groupings;
935 }
936
67aa60f9 937 /**
85e42d22 938 * Returns description of method result value
67aa60f9 939 *
85e42d22 940 * @return external_description
67aa60f9 941 * @since Moodle 2.3
85e42d22
JL
942 */
943 public static function get_course_groupings_returns() {
944 return new external_multiple_structure(
945 new external_single_structure(
946 array(
947 'id' => new external_value(PARAM_INT, 'grouping record id'),
948 'courseid' => new external_value(PARAM_INT, 'id of course'),
949 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
93ce0e82 950 'description' => new external_value(PARAM_RAW, 'grouping description text'),
ed0fd1f6
DM
951 'descriptionformat' => new external_format_value('description'),
952 'idnumber' => new external_value(PARAM_RAW, 'id number')
85e42d22
JL
953 )
954 )
955 );
956 }
957
a531136e
JL
958 /**
959 * Returns description of method parameters
67aa60f9 960 *
a531136e 961 * @return external_function_parameters
67aa60f9 962 * @since Moodle 2.3
a531136e
JL
963 */
964 public static function delete_groupings_parameters() {
965 return new external_function_parameters(
966 array(
967 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID')),
968 )
969 );
970 }
971
972 /**
973 * Delete groupings
67aa60f9 974 *
a531136e
JL
975 * @param array $groupingids array of grouping ids
976 * @return void
67aa60f9 977 * @since Moodle 2.3
a531136e
JL
978 */
979 public static function delete_groupings($groupingids) {
980 global $CFG, $DB;
981 require_once("$CFG->dirroot/group/lib.php");
982
983 $params = self::validate_parameters(self::delete_groupings_parameters(), array('groupingids'=>$groupingids));
984
985 $transaction = $DB->start_delegated_transaction();
986
987 foreach ($params['groupingids'] as $groupingid) {
67aa60f9 988
a531136e
JL
989 if (!$grouping = groups_get_grouping($groupingid, 'id, courseid', IGNORE_MISSING)) {
990 // Silently ignore attempts to delete nonexisting groupings.
991 continue;
992 }
993
994 // Now security checks.
995 $context = context_course::instance($grouping->courseid);
996 try {
997 self::validate_context($context);
998 } catch (Exception $e) {
999 $exceptionparam = new stdClass();
1000 $exceptionparam->message = $e->getMessage();
1001 $exceptionparam->courseid = $grouping->courseid;
1002 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
1003 }
1004 require_capability('moodle/course:managegroups', $context);
1005
1006 groups_delete_grouping($grouping);
1007 }
1008
1009 $transaction->allow_commit();
1010 }
1011
67aa60f9 1012 /**
a531136e 1013 * Returns description of method result value
67aa60f9 1014 *
a531136e 1015 * @return external_description
67aa60f9 1016 * @since Moodle 2.3
a531136e
JL
1017 */
1018 public static function delete_groupings_returns() {
1019 return null;
1020 }
1021
20053b8c
JL
1022 /**
1023 * Returns description of method parameters
67aa60f9 1024 *
20053b8c 1025 * @return external_function_parameters
67aa60f9 1026 * @since Moodle 2.3
20053b8c
JL
1027 */
1028 public static function assign_grouping_parameters() {
1029 return new external_function_parameters(
1030 array(
1031 'assignments'=> new external_multiple_structure(
1032 new external_single_structure(
1033 array(
1034 'groupingid' => new external_value(PARAM_INT, 'grouping record id'),
1035 'groupid' => new external_value(PARAM_INT, 'group record id'),
1036 )
1037 )
1038 )
1039 )
1040 );
1041 }
1042
1043 /**
1044 * Assign a group to a grouping
67aa60f9 1045 *
20053b8c
JL
1046 * @param array $assignments of arrays with keys groupid, groupingid
1047 * @return void
67aa60f9 1048 * @since Moodle 2.3
20053b8c
JL
1049 */
1050 public static function assign_grouping($assignments) {
1051 global $CFG, $DB;
1052 require_once("$CFG->dirroot/group/lib.php");
1053
1054 $params = self::validate_parameters(self::assign_grouping_parameters(), array('assignments'=>$assignments));
1055
1056 $transaction = $DB->start_delegated_transaction();
1057 foreach ($params['assignments'] as $assignment) {
1058 // Validate params.
1059 $groupingid = $assignment['groupingid'];
1060 $groupid = $assignment['groupid'];
1061
1062 $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST);
1063 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
1064
1065 if ($DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
1066 // Continue silently if the group is yet assigned to the grouping.
1067 continue;
1068 }
1069
67aa60f9 1070 // Now security checks.
20053b8c
JL
1071 $context = context_course::instance($grouping->courseid);
1072 try {
1073 self::validate_context($context);
1074 } catch (Exception $e) {
1075 $exceptionparam = new stdClass();
1076 $exceptionparam->message = $e->getMessage();
1077 $exceptionparam->courseid = $group->courseid;
1078 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
1079 }
1080 require_capability('moodle/course:managegroups', $context);
1081
1082 groups_assign_grouping($groupingid, $groupid);
1083 }
1084
1085 $transaction->allow_commit();
1086 }
1087
67aa60f9 1088 /**
20053b8c 1089 * Returns description of method result value
67aa60f9 1090 *
20053b8c 1091 * @return null
67aa60f9 1092 * @since Moodle 2.3
20053b8c
JL
1093 */
1094 public static function assign_grouping_returns() {
1095 return null;
1096 }
1097
fb3f5d31
JL
1098 /**
1099 * Returns description of method parameters
67aa60f9 1100 *
fb3f5d31 1101 * @return external_function_parameters
67aa60f9 1102 * @since Moodle 2.3
fb3f5d31
JL
1103 */
1104 public static function unassign_grouping_parameters() {
1105 return new external_function_parameters(
1106 array(
1107 'unassignments'=> new external_multiple_structure(
1108 new external_single_structure(
1109 array(
1110 'groupingid' => new external_value(PARAM_INT, 'grouping record id'),
1111 'groupid' => new external_value(PARAM_INT, 'group record id'),
1112 )
1113 )
1114 )
1115 )
1116 );
1117 }
1118
1119 /**
1120 * Unassign a group from a grouping
67aa60f9 1121 *
fb3f5d31
JL
1122 * @param array $unassignments of arrays with keys groupid, groupingid
1123 * @return void
67aa60f9 1124 * @since Moodle 2.3
fb3f5d31
JL
1125 */
1126 public static function unassign_grouping($unassignments) {
1127 global $CFG, $DB;
1128 require_once("$CFG->dirroot/group/lib.php");
1129
1130 $params = self::validate_parameters(self::unassign_grouping_parameters(), array('unassignments'=>$unassignments));
1131
1132 $transaction = $DB->start_delegated_transaction();
1133 foreach ($params['unassignments'] as $unassignment) {
1134 // Validate params.
1135 $groupingid = $unassignment['groupingid'];
1136 $groupid = $unassignment['groupid'];
1137
1138 $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST);
1139 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
1140
1141 if (!$DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
1142 // Continue silently if the group is not assigned to the grouping.
1143 continue;
1144 }
1145
67aa60f9 1146 // Now security checks.
fb3f5d31
JL
1147 $context = context_course::instance($grouping->courseid);
1148 try {
1149 self::validate_context($context);
1150 } catch (Exception $e) {
1151 $exceptionparam = new stdClass();
1152 $exceptionparam->message = $e->getMessage();
1153 $exceptionparam->courseid = $group->courseid;
1154 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
1155 }
1156 require_capability('moodle/course:managegroups', $context);
1157
1158 groups_unassign_grouping($groupingid, $groupid);
1159 }
1160
1161 $transaction->allow_commit();
1162 }
1163
67aa60f9 1164 /**
fb3f5d31 1165 * Returns description of method result value
67aa60f9 1166 *
fb3f5d31 1167 * @return null
67aa60f9 1168 * @since Moodle 2.3
fb3f5d31
JL
1169 */
1170 public static function unassign_grouping_returns() {
1171 return null;
1172 }
1173
5d62e813
JL
1174 /**
1175 * Returns description of method parameters
1176 *
1177 * @return external_function_parameters
1178 * @since Moodle 2.9
1179 */
1180 public static function get_course_user_groups_parameters() {
1181 return new external_function_parameters(
1182 array(
1183 'courseid' => new external_value(PARAM_INT, 'id of course'),
1184 'userid' => new external_value(PARAM_INT, 'id of user'),
1185 'groupingid' => new external_value(PARAM_INT, 'returns only groups in the specified grouping', VALUE_DEFAULT, 0)
1186 )
1187 );
1188 }
1189
1190 /**
1191 * Get all groups in the specified course for the specified user.
1192 *
1193 * @throws moodle_exception
1194 * @param int $courseid id of course.
1195 * @param int $userid id of user.
1196 * @param int $groupingid optional returns only groups in the specified grouping.
1197 * @return array of group objects (id, name, description, format) and possible warnings.
1198 * @since Moodle 2.9
1199 */
1200 public static function get_course_user_groups($courseid, $userid, $groupingid = 0) {
1201 global $USER;
1202
1203 // Warnings array, it can be empty at the end but is mandatory.
1204 $warnings = array();
1205
1206 $params = array(
1207 'courseid' => $courseid,
1208 'userid' => $userid,
1209 'groupingid' => $groupingid
1210 );
1211 $params = self::validate_parameters(self::get_course_user_groups_parameters(), $params);
1212 $courseid = $params['courseid'];
1213 $userid = $params['userid'];
1214 $groupingid = $params['groupingid'];
1215
1216 // Validate course and user. get_course throws an exception if the course does not exists.
1217 $course = get_course($courseid);
4485f7c5
JL
1218 $user = core_user::get_user($userid, '*', MUST_EXIST);
1219 core_user::require_active_user($user);
5d62e813
JL
1220
1221 // Security checks.
1222 $context = context_course::instance($course->id);
1223 self::validate_context($context);
1224
1225 // Check if we have permissions for retrieve the information.
1226 if ($user->id != $USER->id) {
1227 if (!has_capability('moodle/course:managegroups', $context)) {
1228 throw new moodle_exception('accessdenied', 'admin');
1229 }
1230 // Validate if the user is enrolled in the course.
1231 if (!is_enrolled($context, $user->id)) {
1232 // We return a warning because the function does not fail for not enrolled users.
1233 $warning['item'] = 'course';
1234 $warning['itemid'] = $course->id;
1235 $warning['warningcode'] = '1';
1236 $warning['message'] = "User $user->id is not enrolled in course $course->id";
1237 $warnings[] = $warning;
1238 }
1239 }
1240
1241 $usergroups = array();
1242 if (empty($warnings)) {
ed0fd1f6 1243 $groups = groups_get_all_groups($course->id, $user->id, 0, 'g.id, g.name, g.description, g.descriptionformat, g.idnumber');
5d62e813
JL
1244
1245 foreach ($groups as $group) {
1246 list($group->description, $group->descriptionformat) =
1247 external_format_text($group->description, $group->descriptionformat,
1248 $context->id, 'group', 'description', $group->id);
7107c2f0
JL
1249 $group->courseid = $course->id;
1250 $usergroups[] = $group;
5d62e813
JL
1251 }
1252 }
1253
1254 $results = array(
1255 'groups' => $usergroups,
1256 'warnings' => $warnings
1257 );
1258 return $results;
1259 }
1260
1261 /**
1262 * Returns description of method result value.
1263 *
1264 * @return external_description A single structure containing groups and possible warnings.
1265 * @since Moodle 2.9
1266 */
1267 public static function get_course_user_groups_returns() {
1268 return new external_single_structure(
1269 array(
7107c2f0
JL
1270 'groups' => new external_multiple_structure(self::group_description()),
1271 'warnings' => new external_warnings(),
1272 )
1273 );
1274 }
1275
1276 /**
1277 * Create group return value description.
1278 *
1279 * @return external_single_structure The group description
1280 */
1281 public static function group_description() {
1282 return new external_single_structure(
1283 array(
1284 'id' => new external_value(PARAM_INT, 'group record id'),
1285 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
1286 'description' => new external_value(PARAM_RAW, 'group description text'),
1287 'descriptionformat' => new external_format_value('description'),
1288 'idnumber' => new external_value(PARAM_RAW, 'id number'),
1289 'courseid' => new external_value(PARAM_INT, 'course id', VALUE_OPTIONAL),
1290 )
1291 );
1292 }
1293
1294 /**
1295 * Returns description of method parameters
1296 *
1297 * @return external_function_parameters
1298 * @since Moodle 3.0
1299 */
1300 public static function get_activity_allowed_groups_parameters() {
1301 return new external_function_parameters(
1302 array(
1303 'cmid' => new external_value(PARAM_INT, 'course module id'),
4d9edf1b 1304 'userid' => new external_value(PARAM_INT, 'id of user, empty for current user', VALUE_DEFAULT, 0)
7107c2f0
JL
1305 )
1306 );
1307 }
1308
1309 /**
1310 * Gets a list of groups that the user is allowed to access within the specified activity.
1311 *
1312 * @throws moodle_exception
1313 * @param int $cmid course module id
1314 * @param int $userid id of user.
1315 * @return array of group objects (id, name, description, format) and possible warnings.
1316 * @since Moodle 3.0
1317 */
1318 public static function get_activity_allowed_groups($cmid, $userid = 0) {
1319 global $USER;
1320
1321 // Warnings array, it can be empty at the end but is mandatory.
1322 $warnings = array();
1323
1324 $params = array(
1325 'cmid' => $cmid,
1326 'userid' => $userid
1327 );
1328 $params = self::validate_parameters(self::get_activity_allowed_groups_parameters(), $params);
1329 $cmid = $params['cmid'];
1330 $userid = $params['userid'];
1331
1332 $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
1333
1334 // Security checks.
1335 $context = context_module::instance($cm->id);
1336 $coursecontext = context_course::instance($cm->course);
1337 self::validate_context($context);
1338
1339 if (empty($userid)) {
1340 $userid = $USER->id;
1341 }
1342
4485f7c5
JL
1343 $user = core_user::get_user($userid, '*', MUST_EXIST);
1344 core_user::require_active_user($user);
7107c2f0
JL
1345
1346 // Check if we have permissions for retrieve the information.
1347 if ($user->id != $USER->id) {
1348 if (!has_capability('moodle/course:managegroups', $context)) {
1349 throw new moodle_exception('accessdenied', 'admin');
1350 }
1351
1352 // Validate if the user is enrolled in the course.
48a90a21
JL
1353 $course = get_course($cm->course);
1354 if (!can_access_course($course, $user, '', true)) {
7107c2f0
JL
1355 // We return a warning because the function does not fail for not enrolled users.
1356 $warning = array();
1357 $warning['item'] = 'course';
1358 $warning['itemid'] = $cm->course;
1359 $warning['warningcode'] = '1';
48a90a21 1360 $warning['message'] = "User $user->id cannot access course $cm->course";
7107c2f0
JL
1361 $warnings[] = $warning;
1362 }
1363 }
1364
1365 $usergroups = array();
1366 if (empty($warnings)) {
1367 $groups = groups_get_activity_allowed_groups($cm, $user->id);
1368
1369 foreach ($groups as $group) {
1370 list($group->description, $group->descriptionformat) =
1371 external_format_text($group->description, $group->descriptionformat,
1372 $coursecontext->id, 'group', 'description', $group->id);
1373 $group->courseid = $cm->course;
1374 $usergroups[] = $group;
1375 }
1376 }
1377
1378 $results = array(
1379 'groups' => $usergroups,
0f398b50 1380 'canaccessallgroups' => has_capability('moodle/site:accessallgroups', $context, $user),
7107c2f0
JL
1381 'warnings' => $warnings
1382 );
1383 return $results;
1384 }
1385
1386 /**
1387 * Returns description of method result value.
1388 *
1389 * @return external_description A single structure containing groups and possible warnings.
1390 * @since Moodle 3.0
1391 */
1392 public static function get_activity_allowed_groups_returns() {
1393 return new external_single_structure(
1394 array(
1395 'groups' => new external_multiple_structure(self::group_description()),
0f398b50
JL
1396 'canaccessallgroups' => new external_value(PARAM_BOOL,
1397 'Whether the user will be able to access all the activity groups.', VALUE_OPTIONAL),
5d62e813
JL
1398 'warnings' => new external_warnings(),
1399 )
1400 );
1401 }
1402
c0ef63eb
JL
1403 /**
1404 * Returns description of method parameters
1405 *
1406 * @return external_function_parameters
1407 * @since Moodle 3.0
1408 */
1409 public static function get_activity_groupmode_parameters() {
1410 return new external_function_parameters(
1411 array(
1412 'cmid' => new external_value(PARAM_INT, 'course module id')
1413 )
1414 );
1415 }
1416
1417 /**
1418 * Returns effective groupmode used in a given activity.
1419 *
1420 * @throws moodle_exception
1421 * @param int $cmid course module id.
1422 * @return array containing the group mode and possible warnings.
1423 * @since Moodle 3.0
1424 * @throws moodle_exception
1425 */
1426 public static function get_activity_groupmode($cmid) {
1427 global $USER;
1428
1429 // Warnings array, it can be empty at the end but is mandatory.
1430 $warnings = array();
1431
1432 $params = array(
1433 'cmid' => $cmid
1434 );
1435 $params = self::validate_parameters(self::get_activity_groupmode_parameters(), $params);
1436 $cmid = $params['cmid'];
1437
1438 $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
1439
1440 // Security checks.
1441 $context = context_module::instance($cm->id);
1442 self::validate_context($context);
1443
1444 $groupmode = groups_get_activity_groupmode($cm);
1445
1446 $results = array(
1447 'groupmode' => $groupmode,
1448 'warnings' => $warnings
1449 );
1450 return $results;
1451 }
1452
1453 /**
1454 * Returns description of method result value.
1455 *
1456 * @return external_description
1457 * @since Moodle 3.0
1458 */
1459 public static function get_activity_groupmode_returns() {
1460 return new external_single_structure(
1461 array(
1462 'groupmode' => new external_value(PARAM_INT, 'group mode:
1463 0 for no groups, 1 for separate groups, 2 for visible groups'),
1464 'warnings' => new external_warnings(),
1465 )
1466 );
1467 }
1468
4ca6cfbf 1469}