Merge branch 'MDL-78684-402' of https://github.com/andelacruz/moodle into MOODLE_402_...
[moodle.git] / group / externallib.php
blobf94a8f30699cf0af773712fd5a0cab703332b004
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 $group->name = \core_external\util::format_string($group->name, $context);
222 [$group->description, $group->descriptionformat] =
223 \core_external\util::format_text($group->description, $group->descriptionformat,
224 $context, 'group', 'description', $group->id);
226 $groups[] = (array)$group;
229 return $groups;
233 * Returns description of method result value
235 * @return \core_external\external_description
236 * @since Moodle 2.2
238 public static function get_groups_returns() {
239 return new external_multiple_structure(
240 new external_single_structure(
241 array(
242 'id' => new external_value(PARAM_INT, 'group record id'),
243 'courseid' => new external_value(PARAM_INT, 'id of course'),
244 'name' => new external_value(PARAM_TEXT, 'group name'),
245 'description' => new external_value(PARAM_RAW, 'group description text'),
246 'descriptionformat' => new external_format_value('description'),
247 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
248 'idnumber' => new external_value(PARAM_RAW, 'id number'),
249 'visibility' => new external_value(PARAM_INT,
250 'group visibility mode. 0 = Visible to all. 1 = Visible to members. 2 = See own membership. '
251 . '3 = Membership is hidden.'),
252 'participation' => new external_value(PARAM_BOOL, 'participation mode'),
259 * Returns description of method parameters
261 * @return external_function_parameters
262 * @since Moodle 2.2
264 public static function get_course_groups_parameters() {
265 return new external_function_parameters(
266 array(
267 'courseid' => new external_value(PARAM_INT, 'id of course'),
273 * Get all groups in the specified course
275 * @param int $courseid id of course
276 * @return array of group objects (id, courseid, name, enrolmentkey)
277 * @since Moodle 2.2
279 public static function get_course_groups($courseid) {
280 $params = self::validate_parameters(self::get_course_groups_parameters(), array('courseid'=>$courseid));
282 // now security checks
283 $context = context_course::instance($params['courseid'], IGNORE_MISSING);
284 try {
285 self::validate_context($context);
286 } catch (Exception $e) {
287 $exceptionparam = new stdClass();
288 $exceptionparam->message = $e->getMessage();
289 $exceptionparam->courseid = $params['courseid'];
290 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
292 require_capability('moodle/course:managegroups', $context);
294 $gs = groups_get_all_groups($params['courseid'], 0, 0,
295 'g.id, g.courseid, g.name, g.idnumber, g.description, g.descriptionformat, g.enrolmentkey, '
296 . 'g.visibility, g.participation');
298 $groups = array();
299 foreach ($gs as $group) {
300 $group->name = \core_external\util::format_string($group->name, $context);
301 [$group->description, $group->descriptionformat] =
302 \core_external\util::format_text($group->description, $group->descriptionformat,
303 $context, 'group', 'description', $group->id);
304 $groups[] = (array)$group;
307 return $groups;
311 * Returns description of method result value
313 * @return \core_external\external_description
314 * @since Moodle 2.2
316 public static function get_course_groups_returns() {
317 return new external_multiple_structure(
318 new external_single_structure(
319 array(
320 'id' => new external_value(PARAM_INT, 'group record id'),
321 'courseid' => new external_value(PARAM_INT, 'id of course'),
322 'name' => new external_value(PARAM_TEXT, 'group name'),
323 'description' => new external_value(PARAM_RAW, 'group description text'),
324 'descriptionformat' => new external_format_value('description'),
325 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
326 'idnumber' => new external_value(PARAM_RAW, 'id number'),
327 'visibility' => new external_value(PARAM_INT,
328 'group visibility mode. 0 = Visible to all. 1 = Visible to members. 2 = See own membership. '
329 . '3 = Membership is hidden.'),
330 'participation' => new external_value(PARAM_BOOL, 'participation mode'),
337 * Returns description of method parameters
339 * @return external_function_parameters
340 * @since Moodle 2.2
342 public static function delete_groups_parameters() {
343 return new external_function_parameters(
344 array(
345 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
351 * Delete groups
353 * @param array $groupids array of group ids
354 * @since Moodle 2.2
356 public static function delete_groups($groupids) {
357 global $CFG, $DB;
358 require_once("$CFG->dirroot/group/lib.php");
360 $params = self::validate_parameters(self::delete_groups_parameters(), array('groupids'=>$groupids));
362 $transaction = $DB->start_delegated_transaction();
364 foreach ($params['groupids'] as $groupid) {
365 // validate params
366 $groupid = validate_param($groupid, PARAM_INT);
367 if (!$group = groups_get_group($groupid, '*', IGNORE_MISSING)) {
368 // silently ignore attempts to delete nonexisting groups
369 continue;
372 // now security checks
373 $context = context_course::instance($group->courseid, IGNORE_MISSING);
374 try {
375 self::validate_context($context);
376 } catch (Exception $e) {
377 $exceptionparam = new stdClass();
378 $exceptionparam->message = $e->getMessage();
379 $exceptionparam->courseid = $group->courseid;
380 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
382 require_capability('moodle/course:managegroups', $context);
384 groups_delete_group($group);
387 $transaction->allow_commit();
391 * Returns description of method result value
393 * @return null
394 * @since Moodle 2.2
396 public static function delete_groups_returns() {
397 return null;
402 * Returns description of method parameters
404 * @return external_function_parameters
405 * @since Moodle 2.2
407 public static function get_group_members_parameters() {
408 return new external_function_parameters(
409 array(
410 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
416 * Return all members for a group
418 * @param array $groupids array of group ids
419 * @return array with group id keys containing arrays of user ids
420 * @since Moodle 2.2
422 public static function get_group_members($groupids) {
423 $members = array();
425 $params = self::validate_parameters(self::get_group_members_parameters(), array('groupids'=>$groupids));
427 foreach ($params['groupids'] as $groupid) {
428 // validate params
429 $group = groups_get_group($groupid, 'id, courseid, name, enrolmentkey', MUST_EXIST);
430 // now security checks
431 $context = context_course::instance($group->courseid, IGNORE_MISSING);
432 try {
433 self::validate_context($context);
434 } catch (Exception $e) {
435 $exceptionparam = new stdClass();
436 $exceptionparam->message = $e->getMessage();
437 $exceptionparam->courseid = $group->courseid;
438 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
440 require_capability('moodle/course:managegroups', $context);
442 $groupmembers = groups_get_members($group->id, 'u.id', 'lastname ASC, firstname ASC');
444 $members[] = array('groupid'=>$groupid, 'userids'=>array_keys($groupmembers));
447 return $members;
451 * Returns description of method result value
453 * @return \core_external\external_description
454 * @since Moodle 2.2
456 public static function get_group_members_returns() {
457 return new external_multiple_structure(
458 new external_single_structure(
459 array(
460 'groupid' => new external_value(PARAM_INT, 'group record id'),
461 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')),
469 * Returns description of method parameters
471 * @return external_function_parameters
472 * @since Moodle 2.2
474 public static function add_group_members_parameters() {
475 return new external_function_parameters(
476 array(
477 'members'=> new external_multiple_structure(
478 new external_single_structure(
479 array(
480 'groupid' => new external_value(PARAM_INT, 'group record id'),
481 'userid' => new external_value(PARAM_INT, 'user id'),
490 * Add group members
492 * @param array $members of arrays with keys userid, groupid
493 * @since Moodle 2.2
495 public static function add_group_members($members) {
496 global $CFG, $DB;
497 require_once("$CFG->dirroot/group/lib.php");
499 $params = self::validate_parameters(self::add_group_members_parameters(), array('members'=>$members));
501 $transaction = $DB->start_delegated_transaction();
502 foreach ($params['members'] as $member) {
503 // validate params
504 $groupid = $member['groupid'];
505 $userid = $member['userid'];
507 $group = groups_get_group($groupid, '*', MUST_EXIST);
508 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
510 // now security checks
511 $context = context_course::instance($group->courseid, IGNORE_MISSING);
512 try {
513 self::validate_context($context);
514 } catch (Exception $e) {
515 $exceptionparam = new stdClass();
516 $exceptionparam->message = $e->getMessage();
517 $exceptionparam->courseid = $group->courseid;
518 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
520 require_capability('moodle/course:managegroups', $context);
522 // now make sure user is enrolled in course - this is mandatory requirement,
523 // unfortunately this is slow
524 if (!is_enrolled($context, $userid)) {
525 throw new invalid_parameter_exception('Only enrolled users may be members of groups');
528 groups_add_member($group, $user);
531 $transaction->allow_commit();
535 * Returns description of method result value
537 * @return null
538 * @since Moodle 2.2
540 public static function add_group_members_returns() {
541 return null;
546 * Returns description of method parameters
548 * @return external_function_parameters
549 * @since Moodle 2.2
551 public static function delete_group_members_parameters() {
552 return new external_function_parameters(
553 array(
554 'members'=> new external_multiple_structure(
555 new external_single_structure(
556 array(
557 'groupid' => new external_value(PARAM_INT, 'group record id'),
558 'userid' => new external_value(PARAM_INT, 'user id'),
567 * Delete group members
569 * @param array $members of arrays with keys userid, groupid
570 * @since Moodle 2.2
572 public static function delete_group_members($members) {
573 global $CFG, $DB;
574 require_once("$CFG->dirroot/group/lib.php");
576 $params = self::validate_parameters(self::delete_group_members_parameters(), array('members'=>$members));
578 $transaction = $DB->start_delegated_transaction();
580 foreach ($params['members'] as $member) {
581 // validate params
582 $groupid = $member['groupid'];
583 $userid = $member['userid'];
585 $group = groups_get_group($groupid, '*', MUST_EXIST);
586 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
588 // now security checks
589 $context = context_course::instance($group->courseid, IGNORE_MISSING);
590 try {
591 self::validate_context($context);
592 } catch (Exception $e) {
593 $exceptionparam = new stdClass();
594 $exceptionparam->message = $e->getMessage();
595 $exceptionparam->courseid = $group->courseid;
596 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
598 require_capability('moodle/course:managegroups', $context);
600 if (!groups_remove_member_allowed($group, $user)) {
601 $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
602 throw new moodle_exception('errorremovenotpermitted', 'group', '', $fullname);
604 groups_remove_member($group, $user);
607 $transaction->allow_commit();
611 * Returns description of method result value
613 * @return null
614 * @since Moodle 2.2
616 public static function delete_group_members_returns() {
617 return null;
621 * Returns description of method parameters
623 * @return external_function_parameters
624 * @since Moodle 2.3
626 public static function create_groupings_parameters() {
627 return new external_function_parameters(
628 array(
629 'groupings' => new external_multiple_structure(
630 new external_single_structure(
631 array(
632 'courseid' => new external_value(PARAM_INT, 'id of course'),
633 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
634 'description' => new external_value(PARAM_RAW, 'grouping description text'),
635 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
636 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
638 ), 'List of grouping object. A grouping has a courseid, a name and a description.'
645 * Create groupings
647 * @param array $groupings array of grouping description arrays (with keys groupname and courseid)
648 * @return array of newly created groupings
649 * @since Moodle 2.3
651 public static function create_groupings($groupings) {
652 global $CFG, $DB;
653 require_once("$CFG->dirroot/group/lib.php");
655 $params = self::validate_parameters(self::create_groupings_parameters(), array('groupings'=>$groupings));
657 $transaction = $DB->start_delegated_transaction();
659 $groupings = array();
661 foreach ($params['groupings'] as $grouping) {
662 $grouping = (object)$grouping;
664 if (trim($grouping->name) == '') {
665 throw new invalid_parameter_exception('Invalid grouping name');
667 if ($DB->count_records('groupings', array('courseid'=>$grouping->courseid, 'name'=>$grouping->name))) {
668 throw new invalid_parameter_exception('Grouping with the same name already exists in the course');
671 // Now security checks .
672 $context = context_course::instance($grouping->courseid);
673 try {
674 self::validate_context($context);
675 } catch (Exception $e) {
676 $exceptionparam = new stdClass();
677 $exceptionparam->message = $e->getMessage();
678 $exceptionparam->courseid = $grouping->courseid;
679 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
681 require_capability('moodle/course:managegroups', $context);
683 $grouping->descriptionformat = util::validate_format($grouping->descriptionformat);
685 // Finally create the grouping.
686 $grouping->id = groups_create_grouping($grouping);
687 $groupings[] = (array)$grouping;
690 $transaction->allow_commit();
692 return $groupings;
696 * Returns description of method result value
698 * @return \core_external\external_description
699 * @since Moodle 2.3
701 public static function create_groupings_returns() {
702 return new external_multiple_structure(
703 new external_single_structure(
704 array(
705 'id' => new external_value(PARAM_INT, 'grouping record id'),
706 'courseid' => new external_value(PARAM_INT, 'id of course'),
707 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
708 'description' => new external_value(PARAM_RAW, 'grouping description text'),
709 'descriptionformat' => new external_format_value('description'),
710 'idnumber' => new external_value(PARAM_RAW, 'id number')
712 ), 'List of grouping object. A grouping has an id, a courseid, a name and a description.'
717 * Returns description of method parameters
719 * @return external_function_parameters
720 * @since Moodle 2.3
722 public static function update_groupings_parameters() {
723 return new external_function_parameters(
724 array(
725 'groupings' => new external_multiple_structure(
726 new external_single_structure(
727 array(
728 'id' => new external_value(PARAM_INT, 'id of grouping'),
729 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
730 'description' => new external_value(PARAM_RAW, 'grouping description text'),
731 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
732 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL)
734 ), 'List of grouping object. A grouping has a courseid, a name and a description.'
741 * Update groupings
743 * @param array $groupings array of grouping description arrays (with keys groupname and courseid)
744 * @return array of newly updated groupings
745 * @since Moodle 2.3
747 public static function update_groupings($groupings) {
748 global $CFG, $DB;
749 require_once("$CFG->dirroot/group/lib.php");
751 $params = self::validate_parameters(self::update_groupings_parameters(), array('groupings'=>$groupings));
753 $transaction = $DB->start_delegated_transaction();
755 foreach ($params['groupings'] as $grouping) {
756 $grouping = (object)$grouping;
758 if (trim($grouping->name) == '') {
759 throw new invalid_parameter_exception('Invalid grouping name');
762 if (! $currentgrouping = $DB->get_record('groupings', array('id'=>$grouping->id))) {
763 throw new invalid_parameter_exception("Grouping $grouping->id does not exist in the course");
766 // Check if the new modified grouping name already exists in the course.
767 if ($grouping->name != $currentgrouping->name and
768 $DB->count_records('groupings', array('courseid'=>$currentgrouping->courseid, 'name'=>$grouping->name))) {
769 throw new invalid_parameter_exception('A different grouping with the same name already exists in the course');
772 $grouping->courseid = $currentgrouping->courseid;
774 // Now security checks.
775 $context = context_course::instance($grouping->courseid);
776 try {
777 self::validate_context($context);
778 } catch (Exception $e) {
779 $exceptionparam = new stdClass();
780 $exceptionparam->message = $e->getMessage();
781 $exceptionparam->courseid = $grouping->courseid;
782 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
784 require_capability('moodle/course:managegroups', $context);
786 // We must force allways FORMAT_HTML.
787 $grouping->descriptionformat = util::validate_format($grouping->descriptionformat);
789 // Finally update the grouping.
790 groups_update_grouping($grouping);
793 $transaction->allow_commit();
795 return null;
799 * Returns description of method result value
801 * @return \core_external\external_description
802 * @since Moodle 2.3
804 public static function update_groupings_returns() {
805 return null;
809 * Returns description of method parameters
811 * @return external_function_parameters
812 * @since Moodle 2.3
814 public static function get_groupings_parameters() {
815 return new external_function_parameters(
816 array(
817 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID')
818 , 'List of grouping id. A grouping id is an integer.'),
819 'returngroups' => new external_value(PARAM_BOOL, 'return associated groups', VALUE_DEFAULT, 0)
825 * Get groupings definition specified by ids
827 * @param array $groupingids arrays of grouping ids
828 * @param boolean $returngroups return the associated groups if true. The default is false.
829 * @return array of grouping objects (id, courseid, name)
830 * @since Moodle 2.3
832 public static function get_groupings($groupingids, $returngroups = false) {
833 global $CFG, $DB;
834 require_once("$CFG->dirroot/group/lib.php");
835 require_once("$CFG->libdir/filelib.php");
837 $params = self::validate_parameters(self::get_groupings_parameters(),
838 array('groupingids' => $groupingids,
839 'returngroups' => $returngroups));
841 $groupings = array();
842 foreach ($params['groupingids'] as $groupingid) {
843 // Validate params.
844 $grouping = groups_get_grouping($groupingid, '*', MUST_EXIST);
846 // Now security checks.
847 $context = context_course::instance($grouping->courseid);
848 try {
849 self::validate_context($context);
850 } catch (Exception $e) {
851 $exceptionparam = new stdClass();
852 $exceptionparam->message = $e->getMessage();
853 $exceptionparam->courseid = $grouping->courseid;
854 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
856 require_capability('moodle/course:managegroups', $context);
858 list($grouping->description, $grouping->descriptionformat) =
859 \core_external\util::format_text($grouping->description, $grouping->descriptionformat,
860 $context, 'grouping', 'description', $grouping->id);
862 $groupingarray = (array)$grouping;
864 if ($params['returngroups']) {
865 $grouprecords = $DB->get_records_sql("SELECT * FROM {groups} g INNER JOIN {groupings_groups} gg ".
866 "ON g.id = gg.groupid WHERE gg.groupingid = ? ".
867 "ORDER BY groupid", array($groupingid));
868 if ($grouprecords) {
869 $groups = array();
870 foreach ($grouprecords as $grouprecord) {
871 list($grouprecord->description, $grouprecord->descriptionformat) =
872 \core_external\util::format_text($grouprecord->description, $grouprecord->descriptionformat,
873 $context, 'group', 'description', $grouprecord->groupid);
874 $groups[] = array('id' => $grouprecord->groupid,
875 'name' => $grouprecord->name,
876 'idnumber' => $grouprecord->idnumber,
877 'description' => $grouprecord->description,
878 'descriptionformat' => $grouprecord->descriptionformat,
879 'enrolmentkey' => $grouprecord->enrolmentkey,
880 'courseid' => $grouprecord->courseid
883 $groupingarray['groups'] = $groups;
886 $groupings[] = $groupingarray;
889 return $groupings;
893 * Returns description of method result value
895 * @return \core_external\external_description
896 * @since Moodle 2.3
898 public static function get_groupings_returns() {
899 return new external_multiple_structure(
900 new external_single_structure(
901 array(
902 'id' => new external_value(PARAM_INT, 'grouping record id'),
903 'courseid' => new external_value(PARAM_INT, 'id of course'),
904 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
905 'description' => new external_value(PARAM_RAW, 'grouping description text'),
906 'descriptionformat' => new external_format_value('description'),
907 'idnumber' => new external_value(PARAM_RAW, 'id number'),
908 'groups' => new external_multiple_structure(
909 new external_single_structure(
910 array(
911 'id' => new external_value(PARAM_INT, 'group record id'),
912 'courseid' => new external_value(PARAM_INT, 'id of course'),
913 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
914 'description' => new external_value(PARAM_RAW, 'group description text'),
915 'descriptionformat' => new external_format_value('description'),
916 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
917 'idnumber' => new external_value(PARAM_RAW, 'id number')
920 'optional groups', VALUE_OPTIONAL)
927 * Returns description of method parameters
929 * @return external_function_parameters
930 * @since Moodle 2.3
932 public static function get_course_groupings_parameters() {
933 return new external_function_parameters(
934 array(
935 'courseid' => new external_value(PARAM_INT, 'id of course'),
941 * Get all groupings in the specified course
943 * @param int $courseid id of course
944 * @return array of grouping objects (id, courseid, name, enrolmentkey)
945 * @since Moodle 2.3
947 public static function get_course_groupings($courseid) {
948 global $CFG;
949 require_once("$CFG->dirroot/group/lib.php");
950 require_once("$CFG->libdir/filelib.php");
952 $params = self::validate_parameters(self::get_course_groupings_parameters(), array('courseid'=>$courseid));
954 // Now security checks.
955 $context = context_course::instance($params['courseid']);
957 try {
958 self::validate_context($context);
959 } catch (Exception $e) {
960 $exceptionparam = new stdClass();
961 $exceptionparam->message = $e->getMessage();
962 $exceptionparam->courseid = $params['courseid'];
963 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
965 require_capability('moodle/course:managegroups', $context);
967 $gs = groups_get_all_groupings($params['courseid']);
969 $groupings = array();
970 foreach ($gs as $grouping) {
971 list($grouping->description, $grouping->descriptionformat) =
972 \core_external\util::format_text($grouping->description, $grouping->descriptionformat,
973 $context, 'grouping', 'description', $grouping->id);
974 $groupings[] = (array)$grouping;
977 return $groupings;
981 * Returns description of method result value
983 * @return \core_external\external_description
984 * @since Moodle 2.3
986 public static function get_course_groupings_returns() {
987 return new external_multiple_structure(
988 new external_single_structure(
989 array(
990 'id' => new external_value(PARAM_INT, 'grouping record id'),
991 'courseid' => new external_value(PARAM_INT, 'id of course'),
992 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
993 'description' => new external_value(PARAM_RAW, 'grouping description text'),
994 'descriptionformat' => new external_format_value('description'),
995 'idnumber' => new external_value(PARAM_RAW, 'id number')
1002 * Returns description of method parameters
1004 * @return external_function_parameters
1005 * @since Moodle 2.3
1007 public static function delete_groupings_parameters() {
1008 return new external_function_parameters(
1009 array(
1010 'groupingids' => new external_multiple_structure(new external_value(PARAM_INT, 'grouping ID')),
1016 * Delete groupings
1018 * @param array $groupingids array of grouping ids
1019 * @return void
1020 * @since Moodle 2.3
1022 public static function delete_groupings($groupingids) {
1023 global $CFG, $DB;
1024 require_once("$CFG->dirroot/group/lib.php");
1026 $params = self::validate_parameters(self::delete_groupings_parameters(), array('groupingids'=>$groupingids));
1028 $transaction = $DB->start_delegated_transaction();
1030 foreach ($params['groupingids'] as $groupingid) {
1032 if (!$grouping = groups_get_grouping($groupingid)) {
1033 // Silently ignore attempts to delete nonexisting groupings.
1034 continue;
1037 // Now security checks.
1038 $context = context_course::instance($grouping->courseid);
1039 try {
1040 self::validate_context($context);
1041 } catch (Exception $e) {
1042 $exceptionparam = new stdClass();
1043 $exceptionparam->message = $e->getMessage();
1044 $exceptionparam->courseid = $grouping->courseid;
1045 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
1047 require_capability('moodle/course:managegroups', $context);
1049 groups_delete_grouping($grouping);
1052 $transaction->allow_commit();
1056 * Returns description of method result value
1058 * @return \core_external\external_description
1059 * @since Moodle 2.3
1061 public static function delete_groupings_returns() {
1062 return null;
1066 * Returns description of method parameters
1068 * @return external_function_parameters
1069 * @since Moodle 2.3
1071 public static function assign_grouping_parameters() {
1072 return new external_function_parameters(
1073 array(
1074 'assignments'=> new external_multiple_structure(
1075 new external_single_structure(
1076 array(
1077 'groupingid' => new external_value(PARAM_INT, 'grouping record id'),
1078 'groupid' => new external_value(PARAM_INT, 'group record id'),
1087 * Assign a group to a grouping
1089 * @param array $assignments of arrays with keys groupid, groupingid
1090 * @return void
1091 * @since Moodle 2.3
1093 public static function assign_grouping($assignments) {
1094 global $CFG, $DB;
1095 require_once("$CFG->dirroot/group/lib.php");
1097 $params = self::validate_parameters(self::assign_grouping_parameters(), array('assignments'=>$assignments));
1099 $transaction = $DB->start_delegated_transaction();
1100 foreach ($params['assignments'] as $assignment) {
1101 // Validate params.
1102 $groupingid = $assignment['groupingid'];
1103 $groupid = $assignment['groupid'];
1105 $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST);
1106 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
1108 if ($DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
1109 // Continue silently if the group is yet assigned to the grouping.
1110 continue;
1113 // Now security checks.
1114 $context = context_course::instance($grouping->courseid);
1115 try {
1116 self::validate_context($context);
1117 } catch (Exception $e) {
1118 $exceptionparam = new stdClass();
1119 $exceptionparam->message = $e->getMessage();
1120 $exceptionparam->courseid = $group->courseid;
1121 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
1123 require_capability('moodle/course:managegroups', $context);
1125 groups_assign_grouping($groupingid, $groupid);
1128 $transaction->allow_commit();
1132 * Returns description of method result value
1134 * @return null
1135 * @since Moodle 2.3
1137 public static function assign_grouping_returns() {
1138 return null;
1142 * Returns description of method parameters
1144 * @return external_function_parameters
1145 * @since Moodle 2.3
1147 public static function unassign_grouping_parameters() {
1148 return new external_function_parameters(
1149 array(
1150 'unassignments'=> new external_multiple_structure(
1151 new external_single_structure(
1152 array(
1153 'groupingid' => new external_value(PARAM_INT, 'grouping record id'),
1154 'groupid' => new external_value(PARAM_INT, 'group record id'),
1163 * Unassign a group from a grouping
1165 * @param array $unassignments of arrays with keys groupid, groupingid
1166 * @return void
1167 * @since Moodle 2.3
1169 public static function unassign_grouping($unassignments) {
1170 global $CFG, $DB;
1171 require_once("$CFG->dirroot/group/lib.php");
1173 $params = self::validate_parameters(self::unassign_grouping_parameters(), array('unassignments'=>$unassignments));
1175 $transaction = $DB->start_delegated_transaction();
1176 foreach ($params['unassignments'] as $unassignment) {
1177 // Validate params.
1178 $groupingid = $unassignment['groupingid'];
1179 $groupid = $unassignment['groupid'];
1181 $grouping = groups_get_grouping($groupingid, 'id, courseid', MUST_EXIST);
1182 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
1184 if (!$DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) {
1185 // Continue silently if the group is not assigned to the grouping.
1186 continue;
1189 // Now security checks.
1190 $context = context_course::instance($grouping->courseid);
1191 try {
1192 self::validate_context($context);
1193 } catch (Exception $e) {
1194 $exceptionparam = new stdClass();
1195 $exceptionparam->message = $e->getMessage();
1196 $exceptionparam->courseid = $group->courseid;
1197 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam);
1199 require_capability('moodle/course:managegroups', $context);
1201 groups_unassign_grouping($groupingid, $groupid);
1204 $transaction->allow_commit();
1208 * Returns description of method result value
1210 * @return null
1211 * @since Moodle 2.3
1213 public static function unassign_grouping_returns() {
1214 return null;
1218 * Returns description of method parameters
1220 * @return external_function_parameters
1221 * @since Moodle 2.9
1223 public static function get_course_user_groups_parameters() {
1224 return new external_function_parameters(
1225 array(
1226 'courseid' => new external_value(PARAM_INT,
1227 'Id of course (empty or 0 for all the courses where the user is enrolled).', VALUE_DEFAULT, 0),
1228 'userid' => new external_value(PARAM_INT, 'Id of user (empty or 0 for current user).', VALUE_DEFAULT, 0),
1229 'groupingid' => new external_value(PARAM_INT, 'returns only groups in the specified grouping', VALUE_DEFAULT, 0)
1235 * Get all groups in the specified course for the specified user.
1237 * @throws moodle_exception
1238 * @param int $courseid id of course.
1239 * @param int $userid id of user.
1240 * @param int $groupingid optional returns only groups in the specified grouping.
1241 * @return array of group objects (id, name, description, format) and possible warnings.
1242 * @since Moodle 2.9
1244 public static function get_course_user_groups($courseid = 0, $userid = 0, $groupingid = 0) {
1245 global $USER;
1247 // Warnings array, it can be empty at the end but is mandatory.
1248 $warnings = array();
1250 $params = array(
1251 'courseid' => $courseid,
1252 'userid' => $userid,
1253 'groupingid' => $groupingid
1255 $params = self::validate_parameters(self::get_course_user_groups_parameters(), $params);
1257 $courseid = $params['courseid'];
1258 $userid = $params['userid'];
1259 $groupingid = $params['groupingid'];
1261 // Validate user.
1262 if (empty($userid)) {
1263 $userid = $USER->id;
1264 } else {
1265 $user = core_user::get_user($userid, '*', MUST_EXIST);
1266 core_user::require_active_user($user);
1269 // Get courses.
1270 if (empty($courseid)) {
1271 $courses = enrol_get_users_courses($userid, true);
1272 $checkenrolments = false; // No need to check enrolments here since they are my courses.
1273 } else {
1274 $courses = array($courseid => get_course($courseid));
1275 $checkenrolments = true;
1278 // Security checks.
1279 list($courses, $warnings) = util::validate_courses(array_keys($courses), $courses, true);
1281 $usergroups = array();
1282 foreach ($courses as $course) {
1283 // Check if we have permissions for retrieve the information.
1284 if ($userid != $USER->id && !has_capability('moodle/course:managegroups', $course->context)) {
1285 $warnings[] = array(
1286 'item' => 'course',
1287 'itemid' => $course->id,
1288 'warningcode' => 'cannotmanagegroups',
1289 'message' => "User $USER->id cannot manage groups in course $course->id",
1291 continue;
1294 // Check if the user being check is enrolled in the given course.
1295 if ($checkenrolments && !is_enrolled($course->context, $userid)) {
1296 // We return a warning because the function does not fail for not enrolled users.
1297 $warnings[] = array(
1298 'item' => 'course',
1299 'itemid' => $course->id,
1300 'warningcode' => 'notenrolled',
1301 'message' => "User $userid is not enrolled in course $course->id",
1305 $groups = groups_get_all_groups($course->id, $userid, $groupingid,
1306 'g.id, g.name, g.description, g.descriptionformat, g.idnumber');
1308 foreach ($groups as $group) {
1309 $group->name = \core_external\util::format_string($group->name, $course->context);
1310 [$group->description, $group->descriptionformat] =
1311 \core_external\util::format_text($group->description, $group->descriptionformat,
1312 $course->context, 'group', 'description', $group->id);
1313 $group->courseid = $course->id;
1314 $usergroups[] = $group;
1318 $results = array(
1319 'groups' => $usergroups,
1320 'warnings' => $warnings
1322 return $results;
1326 * Returns description of method result value.
1328 * @return \core_external\external_description A single structure containing groups and possible warnings.
1329 * @since Moodle 2.9
1331 public static function get_course_user_groups_returns() {
1332 return new external_single_structure(
1333 array(
1334 'groups' => new external_multiple_structure(self::group_description()),
1335 'warnings' => new external_warnings(),
1341 * Create group return value description.
1343 * @return external_single_structure The group description
1345 public static function group_description() {
1346 return new external_single_structure(
1347 array(
1348 'id' => new external_value(PARAM_INT, 'group record id'),
1349 'name' => new external_value(PARAM_TEXT, 'group name'),
1350 'description' => new external_value(PARAM_RAW, 'group description text'),
1351 'descriptionformat' => new external_format_value('description'),
1352 'idnumber' => new external_value(PARAM_RAW, 'id number'),
1353 'courseid' => new external_value(PARAM_INT, 'course id', VALUE_OPTIONAL),
1359 * Returns description of method parameters
1361 * @return external_function_parameters
1362 * @since Moodle 3.0
1364 public static function get_activity_allowed_groups_parameters() {
1365 return new external_function_parameters(
1366 array(
1367 'cmid' => new external_value(PARAM_INT, 'course module id'),
1368 'userid' => new external_value(PARAM_INT, 'id of user, empty for current user', VALUE_DEFAULT, 0)
1374 * Gets a list of groups that the user is allowed to access within the specified activity.
1376 * @throws moodle_exception
1377 * @param int $cmid course module id
1378 * @param int $userid id of user.
1379 * @return array of group objects (id, name, description, format) and possible warnings.
1380 * @since Moodle 3.0
1382 public static function get_activity_allowed_groups($cmid, $userid = 0) {
1383 global $USER;
1385 // Warnings array, it can be empty at the end but is mandatory.
1386 $warnings = array();
1388 $params = array(
1389 'cmid' => $cmid,
1390 'userid' => $userid
1392 $params = self::validate_parameters(self::get_activity_allowed_groups_parameters(), $params);
1393 $cmid = $params['cmid'];
1394 $userid = $params['userid'];
1396 $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
1398 // Security checks.
1399 $context = context_module::instance($cm->id);
1400 $coursecontext = context_course::instance($cm->course);
1401 self::validate_context($context);
1403 if (empty($userid)) {
1404 $userid = $USER->id;
1407 $user = core_user::get_user($userid, '*', MUST_EXIST);
1408 core_user::require_active_user($user);
1410 // Check if we have permissions for retrieve the information.
1411 if ($user->id != $USER->id) {
1412 if (!has_capability('moodle/course:managegroups', $context)) {
1413 throw new moodle_exception('accessdenied', 'admin');
1416 // Validate if the user is enrolled in the course.
1417 $course = get_course($cm->course);
1418 if (!can_access_course($course, $user, '', true)) {
1419 // We return a warning because the function does not fail for not enrolled users.
1420 $warning = array();
1421 $warning['item'] = 'course';
1422 $warning['itemid'] = $cm->course;
1423 $warning['warningcode'] = '1';
1424 $warning['message'] = "User $user->id cannot access course $cm->course";
1425 $warnings[] = $warning;
1429 $usergroups = array();
1430 if (empty($warnings)) {
1431 $groups = groups_get_activity_allowed_groups($cm, $user->id);
1433 foreach ($groups as $group) {
1434 $group->name = \core_external\util::format_string($group->name, $coursecontext);
1435 [$group->description, $group->descriptionformat] =
1436 \core_external\util::format_text($group->description, $group->descriptionformat,
1437 $coursecontext, 'group', 'description', $group->id);
1438 $group->courseid = $cm->course;
1439 $usergroups[] = $group;
1443 $results = array(
1444 'groups' => $usergroups,
1445 'canaccessallgroups' => has_capability('moodle/site:accessallgroups', $context, $user),
1446 'warnings' => $warnings
1448 return $results;
1452 * Returns description of method result value.
1454 * @return \core_external\external_description A single structure containing groups and possible warnings.
1455 * @since Moodle 3.0
1457 public static function get_activity_allowed_groups_returns() {
1458 return new external_single_structure(
1459 array(
1460 'groups' => new external_multiple_structure(self::group_description()),
1461 'canaccessallgroups' => new external_value(PARAM_BOOL,
1462 'Whether the user will be able to access all the activity groups.', VALUE_OPTIONAL),
1463 'warnings' => new external_warnings(),
1469 * Returns description of method parameters
1471 * @return external_function_parameters
1472 * @since Moodle 3.0
1474 public static function get_activity_groupmode_parameters() {
1475 return new external_function_parameters(
1476 array(
1477 'cmid' => new external_value(PARAM_INT, 'course module id')
1483 * Returns effective groupmode used in a given activity.
1485 * @throws moodle_exception
1486 * @param int $cmid course module id.
1487 * @return array containing the group mode and possible warnings.
1488 * @since Moodle 3.0
1489 * @throws moodle_exception
1491 public static function get_activity_groupmode($cmid) {
1492 global $USER;
1494 // Warnings array, it can be empty at the end but is mandatory.
1495 $warnings = array();
1497 $params = array(
1498 'cmid' => $cmid
1500 $params = self::validate_parameters(self::get_activity_groupmode_parameters(), $params);
1501 $cmid = $params['cmid'];
1503 $cm = get_coursemodule_from_id(null, $cmid, 0, false, MUST_EXIST);
1505 // Security checks.
1506 $context = context_module::instance($cm->id);
1507 self::validate_context($context);
1509 $groupmode = groups_get_activity_groupmode($cm);
1511 $results = array(
1512 'groupmode' => $groupmode,
1513 'warnings' => $warnings
1515 return $results;
1519 * Returns description of method result value.
1521 * @return \core_external\external_description
1522 * @since Moodle 3.0
1524 public static function get_activity_groupmode_returns() {
1525 return new external_single_structure(
1526 array(
1527 'groupmode' => new external_value(PARAM_INT, 'group mode:
1528 0 for no groups, 1 for separate groups, 2 for visible groups'),
1529 'warnings' => new external_warnings(),
1535 * Returns description of method parameters
1537 * @return external_function_parameters
1538 * @since Moodle 3.6
1540 public static function update_groups_parameters() {
1541 return new external_function_parameters(
1542 array(
1543 'groups' => new external_multiple_structure(
1544 new external_single_structure(
1545 array(
1546 'id' => new external_value(PARAM_INT, 'ID of the group'),
1547 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
1548 'description' => new external_value(PARAM_RAW, 'group description text', VALUE_OPTIONAL),
1549 'descriptionformat' => new external_format_value('description', VALUE_DEFAULT),
1550 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase', VALUE_OPTIONAL),
1551 'idnumber' => new external_value(PARAM_RAW, 'id number', VALUE_OPTIONAL),
1552 'visibility' => new external_value(PARAM_TEXT,
1553 'group visibility mode. 0 = Visible to all. 1 = Visible to members. '
1554 . '2 = See own membership. 3 = Membership is hidden.', VALUE_OPTIONAL),
1555 'participation' => new external_value(PARAM_BOOL,
1556 'activity participation enabled? Only for "all" and "members" visibility', VALUE_OPTIONAL),
1558 ), 'List of group objects. A group is found by the id, then all other details provided will be updated.'
1565 * Update groups
1567 * @param array $groups
1568 * @return null
1569 * @since Moodle 3.6
1571 public static function update_groups($groups) {
1572 global $CFG, $DB;
1573 require_once("$CFG->dirroot/group/lib.php");
1575 $params = self::validate_parameters(self::update_groups_parameters(), array('groups' => $groups));
1577 $transaction = $DB->start_delegated_transaction();
1579 foreach ($params['groups'] as $group) {
1580 $group = (object) $group;
1582 if (trim($group->name) == '') {
1583 throw new invalid_parameter_exception('Invalid group name');
1586 if (!$currentgroup = $DB->get_record('groups', array('id' => $group->id))) {
1587 throw new invalid_parameter_exception("Group $group->id does not exist");
1590 // Check if the modified group name already exists in the course.
1591 if ($group->name != $currentgroup->name and
1592 $DB->get_record('groups', array('courseid' => $currentgroup->courseid, 'name' => $group->name))) {
1593 throw new invalid_parameter_exception('A different group with the same name already exists in the course');
1596 if (isset($group->visibility) || isset($group->participation)) {
1597 $hasmembers = $DB->record_exists('groups_members', ['groupid' => $group->id]);
1598 if (isset($group->visibility)) {
1599 // Validate visibility.
1600 self::validate_visibility($group->visibility);
1601 if ($hasmembers && $group->visibility != $currentgroup->visibility) {
1602 throw new invalid_parameter_exception(
1603 'The visibility of this group cannot be changed as it currently has members.');
1605 } else {
1606 $group->visibility = $currentgroup->visibility;
1608 if (isset($group->participation) && $hasmembers && $group->participation != $currentgroup->participation) {
1609 throw new invalid_parameter_exception(
1610 'The participation mode of this group cannot be changed as it currently has members.');
1614 $group->courseid = $currentgroup->courseid;
1616 // Now security checks.
1617 $context = context_course::instance($group->courseid);
1618 try {
1619 self::validate_context($context);
1620 } catch (Exception $e) {
1621 $exceptionparam = new stdClass();
1622 $exceptionparam->message = $e->getMessage();
1623 $exceptionparam->courseid = $group->courseid;
1624 throw new moodle_exception('errorcoursecontextnotvalid', 'webservice', '', $exceptionparam);
1626 require_capability('moodle/course:managegroups', $context);
1628 if (!empty($group->description)) {
1629 $group->descriptionformat = util::validate_format($group->descriptionformat);
1632 groups_update_group($group);
1635 $transaction->allow_commit();
1637 return null;
1641 * Returns description of method result value
1643 * @return null
1644 * @since Moodle 3.6
1646 public static function update_groups_returns() {
1647 return null;