Moodle release 4.2beta
[moodle.git] / group / externallib.php
blob9d258195392d1f3a3f3a5357f13f33d9413968e5
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 use core_external\external_api;
18 use core_external\external_format_value;
19 use core_external\external_function_parameters;
20 use core_external\external_multiple_structure;
21 use core_external\external_single_structure;
22 use core_external\external_value;
23 use core_external\external_warnings;
24 use core_external\util;
25 use core_group\visibility;
27 /**
28 * Group external functions
30 * @package core_group
31 * @category external
32 * @copyright 2011 Jerome Mouneyrac
33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34 * @since Moodle 2.2
36 class core_group_external extends external_api {
39 /**
40 * Validate visibility.
42 * @param int $visibility Visibility string, must one of the visibility class constants.
43 * @throws invalid_parameter_exception if visibility is not an allowed value.
45 protected static function validate_visibility(int $visibility): void {
46 $allowed = [
47 GROUPS_VISIBILITY_ALL,
48 GROUPS_VISIBILITY_MEMBERS,
49 GROUPS_VISIBILITY_OWN,
50 GROUPS_VISIBILITY_NONE,
52 if (!array_key_exists($visibility, $allowed)) {
53 throw new invalid_parameter_exception('Invalid group visibility provided. Must be one of '
54 . join(',', $allowed));
58 /**
59 * Returns description of method parameters
61 * @return external_function_parameters
62 * @since Moodle 2.2
64 public static function create_groups_parameters() {
65 return new external_function_parameters(
66 array(
67 'groups' => new external_multiple_structure(
68 new external_single_structure(
69 array(
70 'courseid' => new external_value(PARAM_INT, 'id of course'),
71 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
72 'description' => new external_value(PARAM_RAW, 'group description text'),
73 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
74 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase', VALUE_OPTIONAL),
75 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL),
76 'visibility' => new external_value(PARAM_INT,
77 'group visibility mode. 0 = Visible to all. 1 = Visible to members. '
78 . '2 = See own membership. 3 = Membership is hidden. default: 0',
79 VALUE_DEFAULT, 0),
80 'participation' => new external_value(PARAM_BOOL,
81 'activity participation enabled? Only for "all" and "members" visibility. Default true.',
82 VALUE_DEFAULT, true),
84 ), 'List of group object. A group has a courseid, a name, a description and an enrolment key.'
90 /**
91 * Create groups
93 * @param array $groups array of group description arrays (with keys groupname and courseid)
94 * @return array of newly created groups
95 * @since Moodle 2.2
97 public static function create_groups($groups) {
98 global $CFG, $DB;
99 require_once("$CFG->dirroot/group/lib.php");
101 $params = self::validate_parameters(self::create_groups_parameters(), array('groups'=>$groups));
103 $transaction = $DB->start_delegated_transaction();
105 $groups = array();
107 foreach ($params['groups'] as $group) {
108 $group = (object)$group;
110 if (trim($group->name) == '') {
111 throw new invalid_parameter_exception('Invalid group name');
113 if ($DB->get_record('groups', array('courseid'=>$group->courseid, 'name'=>$group->name))) {
114 throw new invalid_parameter_exception('Group with the same name already exists in the course');
117 // now security checks
118 $context = context_course::instance($group->courseid, IGNORE_MISSING);
119 try {
120 self::validate_context($context);
121 } catch (Exception $e) {
122 $exceptionparam = new stdClass();
123 $exceptionparam->message = $e->getMessage();
124 $exceptionparam->courseid = $group->courseid;
125 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
127 require_capability('moodle/course:managegroups', $context);
129 // Validate format.
130 $group->descriptionformat = util::validate_format($group->descriptionformat);
132 // Validate visibility.
133 self::validate_visibility($group->visibility);
135 // finally create the group
136 $group->id = groups_create_group($group, false);
137 if (!isset($group->enrolmentkey)) {
138 $group->enrolmentkey = '';
140 if (!isset($group->idnumber)) {
141 $group->idnumber = '';
144 $groups[] = (array)$group;
147 $transaction->allow_commit();
149 return $groups;
153 * Returns description of method result value
155 * @return \core_external\external_description
156 * @since Moodle 2.2
158 public static function create_groups_returns() {
159 return new external_multiple_structure(
160 new external_single_structure(
161 array(
162 'id' => new external_value(PARAM_INT, 'group record id'),
163 'courseid' => new external_value(PARAM_INT, 'id of course'),
164 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
165 'description' => new external_value(PARAM_RAW, 'group description text'),
166 'descriptionformat' => new external_format_value('description'),
167 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
168 'idnumber' => new external_value(PARAM_RAW, 'id number'),
169 'visibility' => new external_value(PARAM_INT,
170 'group visibility mode. 0 = Visible to all. 1 = Visible to members. 2 = See own membership. '
171 . '3 = Membership is hidden.'),
172 'participation' => new external_value(PARAM_BOOL, 'participation mode'),
174 ), 'List of group object. A group has an id, a courseid, a name, a description and an enrolment key.'
179 * Returns description of method parameters
181 * @return external_function_parameters
182 * @since Moodle 2.2
184 public static function get_groups_parameters() {
185 return new external_function_parameters(
186 array(
187 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')
188 ,'List of group id. A group id is an integer.'),
194 * Get groups definition specified by ids
196 * @param array $groupids arrays of group ids
197 * @return array of group objects (id, courseid, name, enrolmentkey)
198 * @since Moodle 2.2
200 public static function get_groups($groupids) {
201 $params = self::validate_parameters(self::get_groups_parameters(), array('groupids'=>$groupids));
203 $groups = array();
204 foreach ($params['groupids'] as $groupid) {
205 // validate params
206 $group = groups_get_group($groupid, 'id, courseid, name, idnumber, description, descriptionformat, enrolmentkey, '
207 . 'visibility, participation', MUST_EXIST);
209 // now security checks
210 $context = context_course::instance($group->courseid, IGNORE_MISSING);
211 try {
212 self::validate_context($context);
213 } catch (Exception $e) {
214 $exceptionparam = new stdClass();
215 $exceptionparam->message = $e->getMessage();
216 $exceptionparam->courseid = $group->courseid;
217 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
219 require_capability('moodle/course:managegroups', $context);
221 list($group->description, $group->descriptionformat) =
222 \core_external\util::format_text($group->description, $group->descriptionformat,
223 $context, 'group', 'description', $group->id);
225 $groups[] = (array)$group;
228 return $groups;
232 * Returns description of method result value
234 * @return \core_external\external_description
235 * @since Moodle 2.2
237 public static function get_groups_returns() {
238 return new external_multiple_structure(
239 new external_single_structure(
240 array(
241 'id' => new external_value(PARAM_INT, 'group record id'),
242 'courseid' => new external_value(PARAM_INT, 'id of course'),
243 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
244 'description' => new external_value(PARAM_RAW, 'group description text'),
245 'descriptionformat' => new external_format_value('description'),
246 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
247 'idnumber' => new external_value(PARAM_RAW, 'id number'),
248 'visibility' => new external_value(PARAM_INT,
249 'group visibility mode. 0 = Visible to all. 1 = Visible to members. 2 = See own membership. '
250 . '3 = Membership is hidden.'),
251 'participation' => new external_value(PARAM_BOOL, 'participation mode'),
258 * Returns description of method parameters
260 * @return external_function_parameters
261 * @since Moodle 2.2
263 public static function get_course_groups_parameters() {
264 return new external_function_parameters(
265 array(
266 'courseid' => new external_value(PARAM_INT, 'id of course'),
272 * Get all groups in the specified course
274 * @param int $courseid id of course
275 * @return array of group objects (id, courseid, name, enrolmentkey)
276 * @since Moodle 2.2
278 public static function get_course_groups($courseid) {
279 $params = self::validate_parameters(self::get_course_groups_parameters(), array('courseid'=>$courseid));
281 // now security checks
282 $context = context_course::instance($params['courseid'], IGNORE_MISSING);
283 try {
284 self::validate_context($context);
285 } catch (Exception $e) {
286 $exceptionparam = new stdClass();
287 $exceptionparam->message = $e->getMessage();
288 $exceptionparam->courseid = $params['courseid'];
289 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
291 require_capability('moodle/course:managegroups', $context);
293 $gs = groups_get_all_groups($params['courseid'], 0, 0,
294 'g.id, g.courseid, g.name, g.idnumber, g.description, g.descriptionformat, g.enrolmentkey, '
295 . 'g.visibility, g.participation');
297 $groups = array();
298 foreach ($gs as $group) {
299 list($group->description, $group->descriptionformat) =
300 \core_external\util::format_text($group->description, $group->descriptionformat,
301 $context, 'group', 'description', $group->id);
302 $groups[] = (array)$group;
305 return $groups;
309 * Returns description of method result value
311 * @return \core_external\external_description
312 * @since Moodle 2.2
314 public static function get_course_groups_returns() {
315 return new external_multiple_structure(
316 new external_single_structure(
317 array(
318 'id' => new external_value(PARAM_INT, 'group record id'),
319 'courseid' => new external_value(PARAM_INT, 'id of course'),
320 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
321 'description' => new external_value(PARAM_RAW, 'group description text'),
322 'descriptionformat' => new external_format_value('description'),
323 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
324 'idnumber' => new external_value(PARAM_RAW, 'id number'),
325 'visibility' => new external_value(PARAM_INT,
326 'group visibility mode. 0 = Visible to all. 1 = Visible to members. 2 = See own membership. '
327 . '3 = Membership is hidden.'),
328 'participation' => new external_value(PARAM_BOOL, 'participation mode'),
335 * Returns description of method parameters
337 * @return external_function_parameters
338 * @since Moodle 2.2
340 public static function delete_groups_parameters() {
341 return new external_function_parameters(
342 array(
343 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
349 * Delete groups
351 * @param array $groupids array of group ids
352 * @since Moodle 2.2
354 public static function delete_groups($groupids) {
355 global $CFG, $DB;
356 require_once("$CFG->dirroot/group/lib.php");
358 $params = self::validate_parameters(self::delete_groups_parameters(), array('groupids'=>$groupids));
360 $transaction = $DB->start_delegated_transaction();
362 foreach ($params['groupids'] as $groupid) {
363 // validate params
364 $groupid = validate_param($groupid, PARAM_INT);
365 if (!$group = groups_get_group($groupid, '*', IGNORE_MISSING)) {
366 // silently ignore attempts to delete nonexisting groups
367 continue;
370 // now security checks
371 $context = context_course::instance($group->courseid, IGNORE_MISSING);
372 try {
373 self::validate_context($context);
374 } catch (Exception $e) {
375 $exceptionparam = new stdClass();
376 $exceptionparam->message = $e->getMessage();
377 $exceptionparam->courseid = $group->courseid;
378 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
380 require_capability('moodle/course:managegroups', $context);
382 groups_delete_group($group);
385 $transaction->allow_commit();
389 * Returns description of method result value
391 * @return null
392 * @since Moodle 2.2
394 public static function delete_groups_returns() {
395 return null;
400 * Returns description of method parameters
402 * @return external_function_parameters
403 * @since Moodle 2.2
405 public static function get_group_members_parameters() {
406 return new external_function_parameters(
407 array(
408 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
414 * Return all members for a group
416 * @param array $groupids array of group ids
417 * @return array with group id keys containing arrays of user ids
418 * @since Moodle 2.2
420 public static function get_group_members($groupids) {
421 $members = array();
423 $params = self::validate_parameters(self::get_group_members_parameters(), array('groupids'=>$groupids));
425 foreach ($params['groupids'] as $groupid) {
426 // validate params
427 $group = groups_get_group($groupid, 'id, courseid, name, enrolmentkey', MUST_EXIST);
428 // now security checks
429 $context = context_course::instance($group->courseid, IGNORE_MISSING);
430 try {
431 self::validate_context($context);
432 } catch (Exception $e) {
433 $exceptionparam = new stdClass();
434 $exceptionparam->message = $e->getMessage();
435 $exceptionparam->courseid = $group->courseid;
436 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
438 require_capability('moodle/course:managegroups', $context);
440 $groupmembers = groups_get_members($group->id, 'u.id', 'lastname ASC, firstname ASC');
442 $members[] = array('groupid'=>$groupid, 'userids'=>array_keys($groupmembers));
445 return $members;
449 * Returns description of method result value
451 * @return \core_external\external_description
452 * @since Moodle 2.2
454 public static function get_group_members_returns() {
455 return new external_multiple_structure(
456 new external_single_structure(
457 array(
458 'groupid' => new external_value(PARAM_INT, 'group record id'),
459 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')),
467 * Returns description of method parameters
469 * @return external_function_parameters
470 * @since Moodle 2.2
472 public static function add_group_members_parameters() {
473 return new external_function_parameters(
474 array(
475 'members'=> new external_multiple_structure(
476 new external_single_structure(
477 array(
478 'groupid' => new external_value(PARAM_INT, 'group record id'),
479 'userid' => new external_value(PARAM_INT, 'user id'),
488 * Add group members
490 * @param array $members of arrays with keys userid, groupid
491 * @since Moodle 2.2
493 public static function add_group_members($members) {
494 global $CFG, $DB;
495 require_once("$CFG->dirroot/group/lib.php");
497 $params = self::validate_parameters(self::add_group_members_parameters(), array('members'=>$members));
499 $transaction = $DB->start_delegated_transaction();
500 foreach ($params['members'] as $member) {
501 // validate params
502 $groupid = $member['groupid'];
503 $userid = $member['userid'];
505 $group = groups_get_group($groupid, '*', MUST_EXIST);
506 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
508 // now security checks
509 $context = context_course::instance($group->courseid, IGNORE_MISSING);
510 try {
511 self::validate_context($context);
512 } catch (Exception $e) {
513 $exceptionparam = new stdClass();
514 $exceptionparam->message = $e->getMessage();
515 $exceptionparam->courseid = $group->courseid;
516 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
518 require_capability('moodle/course:managegroups', $context);
520 // now make sure user is enrolled in course - this is mandatory requirement,
521 // unfortunately this is slow
522 if (!is_enrolled($context, $userid)) {
523 throw new invalid_parameter_exception('Only enrolled users may be members of groups');
526 groups_add_member($group, $user);
529 $transaction->allow_commit();
533 * Returns description of method result value
535 * @return null
536 * @since Moodle 2.2
538 public static function add_group_members_returns() {
539 return null;
544 * Returns description of method parameters
546 * @return external_function_parameters
547 * @since Moodle 2.2
549 public static function delete_group_members_parameters() {
550 return new external_function_parameters(
551 array(
552 'members'=> new external_multiple_structure(
553 new external_single_structure(
554 array(
555 'groupid' => new external_value(PARAM_INT, 'group record id'),
556 'userid' => new external_value(PARAM_INT, 'user id'),
565 * Delete group members
567 * @param array $members of arrays with keys userid, groupid
568 * @since Moodle 2.2
570 public static function delete_group_members($members) {
571 global $CFG, $DB;
572 require_once("$CFG->dirroot/group/lib.php");
574 $params = self::validate_parameters(self::delete_group_members_parameters(), array('members'=>$members));
576 $transaction = $DB->start_delegated_transaction();
578 foreach ($params['members'] as $member) {
579 // validate params
580 $groupid = $member['groupid'];
581 $userid = $member['userid'];
583 $group = groups_get_group($groupid, '*', MUST_EXIST);
584 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
586 // now security checks
587 $context = context_course::instance($group->courseid, IGNORE_MISSING);
588 try {
589 self::validate_context($context);
590 } catch (Exception $e) {
591 $exceptionparam = new stdClass();
592 $exceptionparam->message = $e->getMessage();
593 $exceptionparam->courseid = $group->courseid;
594 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
596 require_capability('moodle/course:managegroups', $context);
598 if (!groups_remove_member_allowed($group, $user)) {
599 $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
600 throw new moodle_exception('errorremovenotpermitted', 'group', '', $fullname);
602 groups_remove_member($group, $user);
605 $transaction->allow_commit();
609 * Returns description of method result value
611 * @return null
612 * @since Moodle 2.2
614 public static function delete_group_members_returns() {
615 return null;
619 * Returns description of method parameters
621 * @return external_function_parameters
622 * @since Moodle 2.3
624 public static function create_groupings_parameters() {
625 return new external_function_parameters(
626 array(
627 'groupings' => new external_multiple_structure(
628 new external_single_structure(
629 array(
630 'courseid' => new external_value(PARAM_INT, 'id of course'),
631 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
632 'description' => new external_value(PARAM_RAW, 'grouping description text'),
633 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
634 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
636 ), 'List of grouping object. A grouping has a courseid, a name and a description.'
643 * Create groupings
645 * @param array $groupings array of grouping description arrays (with keys groupname and courseid)
646 * @return array of newly created groupings
647 * @since Moodle 2.3
649 public static function create_groupings($groupings) {
650 global $CFG, $DB;
651 require_once("$CFG->dirroot/group/lib.php");
653 $params = self::validate_parameters(self::create_groupings_parameters(), array('groupings'=>$groupings));
655 $transaction = $DB->start_delegated_transaction();
657 $groupings = array();
659 foreach ($params['groupings'] as $grouping) {
660 $grouping = (object)$grouping;
662 if (trim($grouping->name) == '') {
663 throw new invalid_parameter_exception('Invalid grouping name');
665 if ($DB->count_records('groupings', array('courseid'=>$grouping->courseid, 'name'=>$grouping->name))) {
666 throw new invalid_parameter_exception('Grouping with the same name already exists in the course');
669 // Now security checks .
670 $context = context_course::instance($grouping->courseid);
671 try {
672 self::validate_context($context);
673 } catch (Exception $e) {
674 $exceptionparam = new stdClass();
675 $exceptionparam->message = $e->getMessage();
676 $exceptionparam->courseid = $grouping->courseid;
677 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
679 require_capability('moodle/course:managegroups', $context);
681 $grouping->descriptionformat = util::validate_format($grouping->descriptionformat);
683 // Finally create the grouping.
684 $grouping->id = groups_create_grouping($grouping);
685 $groupings[] = (array)$grouping;
688 $transaction->allow_commit();
690 return $groupings;
694 * Returns description of method result value
696 * @return \core_external\external_description
697 * @since Moodle 2.3
699 public static function create_groupings_returns() {
700 return new external_multiple_structure(
701 new external_single_structure(
702 array(
703 'id' => new external_value(PARAM_INT, 'grouping record id'),
704 'courseid' => new external_value(PARAM_INT, 'id of course'),
705 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
706 'description' => new external_value(PARAM_RAW, 'grouping description text'),
707 'descriptionformat' => new external_format_value('description'),
708 'idnumber' => new external_value(PARAM_RAW, 'id number')
710 ), 'List of grouping object. A grouping has an id, a courseid, a name and a description.'
715 * Returns description of method parameters
717 * @return external_function_parameters
718 * @since Moodle 2.3
720 public static function update_groupings_parameters() {
721 return new external_function_parameters(
722 array(
723 'groupings' => new external_multiple_structure(
724 new external_single_structure(
725 array(
726 'id' => new external_value(PARAM_INT, 'id of grouping'),
727 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
728 'description' => new external_value(PARAM_RAW, 'grouping description text'),
729 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
730 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
732 ), 'List of grouping object. A grouping has a courseid, a name and a description.'
739 * Update groupings
741 * @param array $groupings array of grouping description arrays (with keys groupname and courseid)
742 * @return array of newly updated groupings
743 * @since Moodle 2.3
745 public static function update_groupings($groupings) {
746 global $CFG, $DB;
747 require_once("$CFG->dirroot/group/lib.php");
749 $params = self::validate_parameters(self::update_groupings_parameters(), array('groupings'=>$groupings));
751 $transaction = $DB->start_delegated_transaction();
753 foreach ($params['groupings'] as $grouping) {
754 $grouping = (object)$grouping;
756 if (trim($grouping->name) == '') {
757 throw new invalid_parameter_exception('Invalid grouping name');
760 if (! $currentgrouping = $DB->get_record('groupings', array('id'=>$grouping->id))) {
761 throw new invalid_parameter_exception("Grouping $grouping->id does not exist in the course");
764 // Check if the new modified grouping name already exists in the course.
765 if ($grouping->name != $currentgrouping->name and
766 $DB->count_records('groupings', array('courseid'=>$currentgrouping->courseid, 'name'=>$grouping->name))) {
767 throw new invalid_parameter_exception('A different grouping with the same name already exists in the course');
770 $grouping->courseid = $currentgrouping->courseid;
772 // Now security checks.
773 $context = context_course::instance($grouping->courseid);
774 try {
775 self::validate_context($context);
776 } catch (Exception $e) {
777 $exceptionparam = new stdClass();
778 $exceptionparam->message = $e->getMessage();
779 $exceptionparam->courseid = $grouping->courseid;
780 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
782 require_capability('moodle/course:managegroups', $context);
784 // We must force allways FORMAT_HTML.
785 $grouping->descriptionformat = util::validate_format($grouping->descriptionformat);
787 // Finally update the grouping.
788 groups_update_grouping($grouping);
791 $transaction->allow_commit();
793 return null;
797 * Returns description of method result value
799 * @return \core_external\external_description
800 * @since Moodle 2.3
802 public static function update_groupings_returns() {
803 return null;
807 * Returns description of method parameters
809 * @return external_function_parameters
810 * @since Moodle 2.3
812 public static function get_groupings_parameters() {
813 return new external_function_parameters(
814 array(
815 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID')
816 , 'List of grouping id. A grouping id is an integer.'),
817 'returngroups' => new external_value(PARAM_BOOL, 'return associated groups', VALUE_DEFAULT, 0)
823 * Get groupings definition specified by ids
825 * @param array $groupingids arrays of grouping ids
826 * @param boolean $returngroups return the associated groups if true. The default is false.
827 * @return array of grouping objects (id, courseid, name)
828 * @since Moodle 2.3
830 public static function get_groupings($groupingids, $returngroups = false) {
831 global $CFG, $DB;
832 require_once("$CFG->dirroot/group/lib.php");
833 require_once("$CFG->libdir/filelib.php");
835 $params = self::validate_parameters(self::get_groupings_parameters(),
836 array('groupingids' => $groupingids,
837 'returngroups' => $returngroups));
839 $groupings = array();
840 foreach ($params['groupingids'] as $groupingid) {
841 // Validate params.
842 $grouping = groups_get_grouping($groupingid, '*', MUST_EXIST);
844 // Now security checks.
845 $context = context_course::instance($grouping->courseid);
846 try {
847 self::validate_context($context);
848 } catch (Exception $e) {
849 $exceptionparam = new stdClass();
850 $exceptionparam->message = $e->getMessage();
851 $exceptionparam->courseid = $grouping->courseid;
852 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
854 require_capability('moodle/course:managegroups', $context);
856 list($grouping->description, $grouping->descriptionformat) =
857 \core_external\util::format_text($grouping->description, $grouping->descriptionformat,
858 $context, 'grouping', 'description', $grouping->id);
860 $groupingarray = (array)$grouping;
862 if ($params['returngroups']) {
863 $grouprecords = $DB->get_records_sql("SELECT * FROM {groups} g INNER JOIN {groupings_groups} gg ".
864 "ON g.id = gg.groupid WHERE gg.groupingid = ? ".
865 "ORDER BY groupid", array($groupingid));
866 if ($grouprecords) {
867 $groups = array();
868 foreach ($grouprecords as $grouprecord) {
869 list($grouprecord->description, $grouprecord->descriptionformat) =
870 \core_external\util::format_text($grouprecord->description, $grouprecord->descriptionformat,
871 $context, 'group', 'description', $grouprecord->groupid);
872 $groups[] = array('id' => $grouprecord->groupid,
873 'name' => $grouprecord->name,
874 'idnumber' => $grouprecord->idnumber,
875 'description' => $grouprecord->description,
876 'descriptionformat' => $grouprecord->descriptionformat,
877 'enrolmentkey' => $grouprecord->enrolmentkey,
878 'courseid' => $grouprecord->courseid
881 $groupingarray['groups'] = $groups;
884 $groupings[] = $groupingarray;
887 return $groupings;
891 * Returns description of method result value
893 * @return \core_external\external_description
894 * @since Moodle 2.3
896 public static function get_groupings_returns() {
897 return new external_multiple_structure(
898 new external_single_structure(
899 array(
900 'id' => new external_value(PARAM_INT, 'grouping record id'),
901 'courseid' => new external_value(PARAM_INT, 'id of course'),
902 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
903 'description' => new external_value(PARAM_RAW, 'grouping description text'),
904 'descriptionformat' => new external_format_value('description'),
905 'idnumber' => new external_value(PARAM_RAW, 'id number'),
906 'groups' => new external_multiple_structure(
907 new external_single_structure(
908 array(
909 'id' => new external_value(PARAM_INT, 'group record id'),
910 'courseid' => new external_value(PARAM_INT, 'id of course'),
911 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
912 'description' => new external_value(PARAM_RAW, 'group description text'),
913 'descriptionformat' => new external_format_value('description'),
914 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
915 'idnumber' => new external_value(PARAM_RAW, 'id number')
918 'optional groups', VALUE_OPTIONAL)
925 * Returns description of method parameters
927 * @return external_function_parameters
928 * @since Moodle 2.3
930 public static function get_course_groupings_parameters() {
931 return new external_function_parameters(
932 array(
933 'courseid' => new external_value(PARAM_INT, 'id of course'),
939 * Get all groupings in the specified course
941 * @param int $courseid id of course
942 * @return array of grouping objects (id, courseid, name, enrolmentkey)
943 * @since Moodle 2.3
945 public static function get_course_groupings($courseid) {
946 global $CFG;
947 require_once("$CFG->dirroot/group/lib.php");
948 require_once("$CFG->libdir/filelib.php");
950 $params = self::validate_parameters(self::get_course_groupings_parameters(), array('courseid'=>$courseid));
952 // Now security checks.
953 $context = context_course::instance($params['courseid']);
955 try {
956 self::validate_context($context);
957 } catch (Exception $e) {
958 $exceptionparam = new stdClass();
959 $exceptionparam->message = $e->getMessage();
960 $exceptionparam->courseid = $params['courseid'];
961 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
963 require_capability('moodle/course:managegroups', $context);
965 $gs = groups_get_all_groupings($params['courseid']);
967 $groupings = array();
968 foreach ($gs as $grouping) {
969 list($grouping->description, $grouping->descriptionformat) =
970 \core_external\util::format_text($grouping->description, $grouping->descriptionformat,
971 $context, 'grouping', 'description', $grouping->id);
972 $groupings[] = (array)$grouping;
975 return $groupings;
979 * Returns description of method result value
981 * @return \core_external\external_description
982 * @since Moodle 2.3
984 public static function get_course_groupings_returns() {
985 return new external_multiple_structure(
986 new external_single_structure(
987 array(
988 'id' => new external_value(PARAM_INT, 'grouping record id'),
989 'courseid' => new external_value(PARAM_INT, 'id of course'),
990 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
991 'description' => new external_value(PARAM_RAW, 'grouping description text'),
992 'descriptionformat' => new external_format_value('description'),
993 'idnumber' => new external_value(PARAM_RAW, 'id number')
1000 * Returns description of method parameters
1002 * @return external_function_parameters
1003 * @since Moodle 2.3
1005 public static function delete_groupings_parameters() {
1006 return new external_function_parameters(
1007 array(
1008 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID')),
1014 * Delete groupings
1016 * @param array $groupingids array of grouping ids
1017 * @return void
1018 * @since Moodle 2.3
1020 public static function delete_groupings($groupingids) {
1021 global $CFG, $DB;
1022 require_once("$CFG->dirroot/group/lib.php");
1024 $params = self::validate_parameters(self::delete_groupings_parameters(), array('groupingids'=>$groupingids));
1026 $transaction = $DB->start_delegated_transaction();
1028 foreach ($params['groupingids'] as $groupingid) {
1030 if (!$grouping = groups_get_grouping($groupingid)) {
1031 // Silently ignore attempts to delete nonexisting groupings.
1032 continue;
1035 // Now security checks.
1036 $context = context_course::instance($grouping->courseid);
1037 try {
1038 self::validate_context($context);
1039 } catch (Exception $e) {
1040 $exceptionparam = new stdClass();
1041 $exceptionparam->message = $e->getMessage();
1042 $exceptionparam->courseid = $grouping->courseid;
1043 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
1045 require_capability('moodle/course:managegroups', $context);
1047 groups_delete_grouping($grouping);
1050 $transaction->allow_commit();
1054 * Returns description of method result value
1056 * @return \core_external\external_description
1057 * @since Moodle 2.3
1059 public static function delete_groupings_returns() {
1060 return null;
1064 * Returns description of method parameters
1066 * @return external_function_parameters
1067 * @since Moodle 2.3
1069 public static function assign_grouping_parameters() {
1070 return new external_function_parameters(
1071 array(
1072 'assignments'=> new external_multiple_structure(
1073 new external_single_structure(
1074 array(
1075 'groupingid' => new external_value(PARAM_INT, 'grouping record id'),
1076 'groupid' => new external_value(PARAM_INT, 'group record id'),
1085 * Assign a group to a grouping
1087 * @param array $assignments of arrays with keys groupid, groupingid
1088 * @return void
1089 * @since Moodle 2.3
1091 public static function assign_grouping($assignments) {
1092 global $CFG, $DB;
1093 require_once("$CFG->dirroot/group/lib.php");
1095 $params = self::validate_parameters(self::assign_grouping_parameters(), array('assignments'=>$assignments));
1097 $transaction = $DB->start_delegated_transaction();
1098 foreach ($params['assignments'] as $assignment) {
1099 // Validate params.
1100 $groupingid = $assignment['groupingid'];
1101 $groupid = $assignment['groupid'];
1103 $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST);
1104 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
1106 if ($DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
1107 // Continue silently if the group is yet assigned to the grouping.
1108 continue;
1111 // Now security checks.
1112 $context = context_course::instance($grouping->courseid);
1113 try {
1114 self::validate_context($context);
1115 } catch (Exception $e) {
1116 $exceptionparam = new stdClass();
1117 $exceptionparam->message = $e->getMessage();
1118 $exceptionparam->courseid = $group->courseid;
1119 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
1121 require_capability('moodle/course:managegroups', $context);
1123 groups_assign_grouping($groupingid, $groupid);
1126 $transaction->allow_commit();
1130 * Returns description of method result value
1132 * @return null
1133 * @since Moodle 2.3
1135 public static function assign_grouping_returns() {
1136 return null;
1140 * Returns description of method parameters
1142 * @return external_function_parameters
1143 * @since Moodle 2.3
1145 public static function unassign_grouping_parameters() {
1146 return new external_function_parameters(
1147 array(
1148 'unassignments'=> new external_multiple_structure(
1149 new external_single_structure(
1150 array(
1151 'groupingid' => new external_value(PARAM_INT, 'grouping record id'),
1152 'groupid' => new external_value(PARAM_INT, 'group record id'),
1161 * Unassign a group from a grouping
1163 * @param array $unassignments of arrays with keys groupid, groupingid
1164 * @return void
1165 * @since Moodle 2.3
1167 public static function unassign_grouping($unassignments) {
1168 global $CFG, $DB;
1169 require_once("$CFG->dirroot/group/lib.php");
1171 $params = self::validate_parameters(self::unassign_grouping_parameters(), array('unassignments'=>$unassignments));
1173 $transaction = $DB->start_delegated_transaction();
1174 foreach ($params['unassignments'] as $unassignment) {
1175 // Validate params.
1176 $groupingid = $unassignment['groupingid'];
1177 $groupid = $unassignment['groupid'];
1179 $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST);
1180 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
1182 if (!$DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
1183 // Continue silently if the group is not assigned to the grouping.
1184 continue;
1187 // Now security checks.
1188 $context = context_course::instance($grouping->courseid);
1189 try {
1190 self::validate_context($context);
1191 } catch (Exception $e) {
1192 $exceptionparam = new stdClass();
1193 $exceptionparam->message = $e->getMessage();
1194 $exceptionparam->courseid = $group->courseid;
1195 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
1197 require_capability('moodle/course:managegroups', $context);
1199 groups_unassign_grouping($groupingid, $groupid);
1202 $transaction->allow_commit();
1206 * Returns description of method result value
1208 * @return null
1209 * @since Moodle 2.3
1211 public static function unassign_grouping_returns() {
1212 return null;
1216 * Returns description of method parameters
1218 * @return external_function_parameters
1219 * @since Moodle 2.9
1221 public static function get_course_user_groups_parameters() {
1222 return new external_function_parameters(
1223 array(
1224 'courseid' => new external_value(PARAM_INT,
1225 'Id of course (empty or 0 for all the courses where the user is enrolled).', VALUE_DEFAULT, 0),
1226 'userid' => new external_value(PARAM_INT, 'Id of user (empty or 0 for current user).', VALUE_DEFAULT, 0),
1227 'groupingid' => new external_value(PARAM_INT, 'returns only groups in the specified grouping', VALUE_DEFAULT, 0)
1233 * Get all groups in the specified course for the specified user.
1235 * @throws moodle_exception
1236 * @param int $courseid id of course.
1237 * @param int $userid id of user.
1238 * @param int $groupingid optional returns only groups in the specified grouping.
1239 * @return array of group objects (id, name, description, format) and possible warnings.
1240 * @since Moodle 2.9
1242 public static function get_course_user_groups($courseid = 0, $userid = 0, $groupingid = 0) {
1243 global $USER;
1245 // Warnings array, it can be empty at the end but is mandatory.
1246 $warnings = array();
1248 $params = array(
1249 'courseid' => $courseid,
1250 'userid' => $userid,
1251 'groupingid' => $groupingid
1253 $params = self::validate_parameters(self::get_course_user_groups_parameters(), $params);
1255 $courseid = $params['courseid'];
1256 $userid = $params['userid'];
1257 $groupingid = $params['groupingid'];
1259 // Validate user.
1260 if (empty($userid)) {
1261 $userid = $USER->id;
1262 } else {
1263 $user = core_user::get_user($userid, '*', MUST_EXIST);
1264 core_user::require_active_user($user);
1267 // Get courses.
1268 if (empty($courseid)) {
1269 $courses = enrol_get_users_courses($userid, true);
1270 $checkenrolments = false; // No need to check enrolments here since they are my courses.
1271 } else {
1272 $courses = array($courseid => get_course($courseid));
1273 $checkenrolments = true;
1276 // Security checks.
1277 list($courses, $warnings) = util::validate_courses(array_keys($courses), $courses, true);
1279 $usergroups = array();
1280 foreach ($courses as $course) {
1281 // Check if we have permissions for retrieve the information.
1282 if ($userid != $USER->id && !has_capability('moodle/course:managegroups', $course->context)) {
1283 $warnings[] = array(
1284 'item' => 'course',
1285 'itemid' => $course->id,
1286 'warningcode' => 'cannotmanagegroups',
1287 'message' => "User $USER->id cannot manage groups in course $course->id",
1289 continue;
1292 // Check if the user being check is enrolled in the given course.
1293 if ($checkenrolments && !is_enrolled($course->context, $userid)) {
1294 // We return a warning because the function does not fail for not enrolled users.
1295 $warnings[] = array(
1296 'item' => 'course',
1297 'itemid' => $course->id,
1298 'warningcode' => 'notenrolled',
1299 'message' => "User $userid is not enrolled in course $course->id",
1303 $groups = groups_get_all_groups($course->id, $userid, $groupingid,
1304 'g.id, g.name, g.description, g.descriptionformat, g.idnumber');
1306 foreach ($groups as $group) {
1307 list($group->description, $group->descriptionformat) =
1308 \core_external\util::format_text($group->description, $group->descriptionformat,
1309 $course->context, 'group', 'description', $group->id);
1310 $group->courseid = $course->id;
1311 $usergroups[] = $group;
1315 $results = array(
1316 'groups' => $usergroups,
1317 'warnings' => $warnings
1319 return $results;
1323 * Returns description of method result value.
1325 * @return \core_external\external_description A single structure containing groups and possible warnings.
1326 * @since Moodle 2.9
1328 public static function get_course_user_groups_returns() {
1329 return new external_single_structure(
1330 array(
1331 'groups' => new external_multiple_structure(self::group_description()),
1332 'warnings' => new external_warnings(),
1338 * Create group return value description.
1340 * @return external_single_structure The group description
1342 public static function group_description() {
1343 return new external_single_structure(
1344 array(
1345 'id' => new external_value(PARAM_INT, 'group record id'),
1346 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
1347 'description' => new external_value(PARAM_RAW, 'group description text'),
1348 'descriptionformat' => new external_format_value('description'),
1349 'idnumber' => new external_value(PARAM_RAW, 'id number'),
1350 'courseid' => new external_value(PARAM_INT, 'course id', VALUE_OPTIONAL),
1356 * Returns description of method parameters
1358 * @return external_function_parameters
1359 * @since Moodle 3.0
1361 public static function get_activity_allowed_groups_parameters() {
1362 return new external_function_parameters(
1363 array(
1364 'cmid' => new external_value(PARAM_INT, 'course module id'),
1365 'userid' => new external_value(PARAM_INT, 'id of user, empty for current user', VALUE_DEFAULT, 0)
1371 * Gets a list of groups that the user is allowed to access within the specified activity.
1373 * @throws moodle_exception
1374 * @param int $cmid course module id
1375 * @param int $userid id of user.
1376 * @return array of group objects (id, name, description, format) and possible warnings.
1377 * @since Moodle 3.0
1379 public static function get_activity_allowed_groups($cmid, $userid = 0) {
1380 global $USER;
1382 // Warnings array, it can be empty at the end but is mandatory.
1383 $warnings = array();
1385 $params = array(
1386 'cmid' => $cmid,
1387 'userid' => $userid
1389 $params = self::validate_parameters(self::get_activity_allowed_groups_parameters(), $params);
1390 $cmid = $params['cmid'];
1391 $userid = $params['userid'];
1393 $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
1395 // Security checks.
1396 $context = context_module::instance($cm->id);
1397 $coursecontext = context_course::instance($cm->course);
1398 self::validate_context($context);
1400 if (empty($userid)) {
1401 $userid = $USER->id;
1404 $user = core_user::get_user($userid, '*', MUST_EXIST);
1405 core_user::require_active_user($user);
1407 // Check if we have permissions for retrieve the information.
1408 if ($user->id != $USER->id) {
1409 if (!has_capability('moodle/course:managegroups', $context)) {
1410 throw new moodle_exception('accessdenied', 'admin');
1413 // Validate if the user is enrolled in the course.
1414 $course = get_course($cm->course);
1415 if (!can_access_course($course, $user, '', true)) {
1416 // We return a warning because the function does not fail for not enrolled users.
1417 $warning = array();
1418 $warning['item'] = 'course';
1419 $warning['itemid'] = $cm->course;
1420 $warning['warningcode'] = '1';
1421 $warning['message'] = "User $user->id cannot access course $cm->course";
1422 $warnings[] = $warning;
1426 $usergroups = array();
1427 if (empty($warnings)) {
1428 $groups = groups_get_activity_allowed_groups($cm, $user->id);
1430 foreach ($groups as $group) {
1431 list($group->description, $group->descriptionformat) =
1432 \core_external\util::format_text($group->description, $group->descriptionformat,
1433 $coursecontext, 'group', 'description', $group->id);
1434 $group->courseid = $cm->course;
1435 $usergroups[] = $group;
1439 $results = array(
1440 'groups' => $usergroups,
1441 'canaccessallgroups' => has_capability('moodle/site:accessallgroups', $context, $user),
1442 'warnings' => $warnings
1444 return $results;
1448 * Returns description of method result value.
1450 * @return \core_external\external_description A single structure containing groups and possible warnings.
1451 * @since Moodle 3.0
1453 public static function get_activity_allowed_groups_returns() {
1454 return new external_single_structure(
1455 array(
1456 'groups' => new external_multiple_structure(self::group_description()),
1457 'canaccessallgroups' => new external_value(PARAM_BOOL,
1458 'Whether the user will be able to access all the activity groups.', VALUE_OPTIONAL),
1459 'warnings' => new external_warnings(),
1465 * Returns description of method parameters
1467 * @return external_function_parameters
1468 * @since Moodle 3.0
1470 public static function get_activity_groupmode_parameters() {
1471 return new external_function_parameters(
1472 array(
1473 'cmid' => new external_value(PARAM_INT, 'course module id')
1479 * Returns effective groupmode used in a given activity.
1481 * @throws moodle_exception
1482 * @param int $cmid course module id.
1483 * @return array containing the group mode and possible warnings.
1484 * @since Moodle 3.0
1485 * @throws moodle_exception
1487 public static function get_activity_groupmode($cmid) {
1488 global $USER;
1490 // Warnings array, it can be empty at the end but is mandatory.
1491 $warnings = array();
1493 $params = array(
1494 'cmid' => $cmid
1496 $params = self::validate_parameters(self::get_activity_groupmode_parameters(), $params);
1497 $cmid = $params['cmid'];
1499 $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
1501 // Security checks.
1502 $context = context_module::instance($cm->id);
1503 self::validate_context($context);
1505 $groupmode = groups_get_activity_groupmode($cm);
1507 $results = array(
1508 'groupmode' => $groupmode,
1509 'warnings' => $warnings
1511 return $results;
1515 * Returns description of method result value.
1517 * @return \core_external\external_description
1518 * @since Moodle 3.0
1520 public static function get_activity_groupmode_returns() {
1521 return new external_single_structure(
1522 array(
1523 'groupmode' => new external_value(PARAM_INT, 'group mode:
1524 0 for no groups, 1 for separate groups, 2 for visible groups'),
1525 'warnings' => new external_warnings(),
1531 * Returns description of method parameters
1533 * @return external_function_parameters
1534 * @since Moodle 3.6
1536 public static function update_groups_parameters() {
1537 return new external_function_parameters(
1538 array(
1539 'groups' => new external_multiple_structure(
1540 new external_single_structure(
1541 array(
1542 'id' => new external_value(PARAM_INT, 'ID of the group'),
1543 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
1544 'description' => new external_value(PARAM_RAW, 'group description text', VALUE_OPTIONAL),
1545 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
1546 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase', VALUE_OPTIONAL),
1547 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL),
1548 'visibility' => new external_value(PARAM_TEXT,
1549 'group visibility mode. 0 = Visible to all. 1 = Visible to members. '
1550 . '2 = See own membership. 3 = Membership is hidden.', VALUE_OPTIONAL),
1551 'participation' => new external_value(PARAM_BOOL,
1552 'activity participation enabled? Only for "all" and "members" visibility', VALUE_OPTIONAL),
1554 ), 'List of group objects. A group is found by the id, then all other details provided will be updated.'
1561 * Update groups
1563 * @param array $groups
1564 * @return null
1565 * @since Moodle 3.6
1567 public static function update_groups($groups) {
1568 global $CFG, $DB;
1569 require_once("$CFG->dirroot/group/lib.php");
1571 $params = self::validate_parameters(self::update_groups_parameters(), array('groups' => $groups));
1573 $transaction = $DB->start_delegated_transaction();
1575 foreach ($params['groups'] as $group) {
1576 $group = (object) $group;
1578 if (trim($group->name) == '') {
1579 throw new invalid_parameter_exception('Invalid group name');
1582 if (!$currentgroup = $DB->get_record('groups', array('id' => $group->id))) {
1583 throw new invalid_parameter_exception("Group $group->id does not exist");
1586 // Check if the modified group name already exists in the course.
1587 if ($group->name != $currentgroup->name and
1588 $DB->get_record('groups', array('courseid' => $currentgroup->courseid, 'name' => $group->name))) {
1589 throw new invalid_parameter_exception('A different group with the same name already exists in the course');
1592 if (isset($group->visibility) || isset($group->participation)) {
1593 $hasmembers = $DB->record_exists('groups_members', ['groupid' => $group->id]);
1594 if (isset($group->visibility)) {
1595 // Validate visibility.
1596 self::validate_visibility($group->visibility);
1597 if ($hasmembers && $group->visibility != $currentgroup->visibility) {
1598 throw new invalid_parameter_exception(
1599 'The visibility of this group cannot be changed as it currently has members.');
1601 } else {
1602 $group->visibility = $currentgroup->visibility;
1604 if (isset($group->participation) && $hasmembers && $group->participation != $currentgroup->participation) {
1605 throw new invalid_parameter_exception(
1606 'The participation mode of this group cannot be changed as it currently has members.');
1610 $group->courseid = $currentgroup->courseid;
1612 // Now security checks.
1613 $context = context_course::instance($group->courseid);
1614 try {
1615 self::validate_context($context);
1616 } catch (Exception $e) {
1617 $exceptionparam = new stdClass();
1618 $exceptionparam->message = $e->getMessage();
1619 $exceptionparam->courseid = $group->courseid;
1620 throw new moodle_exception('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam);
1622 require_capability('moodle/course:managegroups', $context);
1624 if (!empty($group->description)) {
1625 $group->descriptionformat = util::validate_format($group->descriptionformat);
1628 groups_update_group($group);
1631 $transaction->allow_commit();
1633 return null;
1637 * Returns description of method result value
1639 * @return null
1640 * @since Moodle 3.6
1642 public static function update_groups_returns() {
1643 return null;