MDL-12886 more external groups api
[moodle.git] / group / externallib.php
CommitLineData
9a0df45a 1<?php
2
3// This file is part of Moodle - http://moodle.org/
4//
5// Moodle is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// Moodle is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17
18/**
19 * External groups API
20 *
21 * @package moodlecore
22 * @subpackage webservice
551f4420 23 * @copyright 2009 Moodle Pty Ltd (http://moodle.com)
9a0df45a 24 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25 */
26
27require_once("$CFG->libdir/externallib.php");
28
29class moodle_group_external extends external_api {
30
0c96468c 31 /**
32 * Returns description of method parameters
f5072177 33 * @return external_function_parameters
0c96468c 34 */
35 public static function create_groups_parameters() {
f5072177 36 return new external_function_parameters(
37 array(
38 'groups' => new external_multiple_structure(
39 new external_single_structure(
40 array(
41 'courseid' => new external_value(PARAM_INT, 'id of course'),
42 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
43 'description' => new external_value(PARAM_RAW, 'group description text'),
44 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
45 )
46 )
47 )
48 )
49 );
0c96468c 50 }
51
52 /**
9a0df45a 53 * Create groups
b4c1a34e 54 * @param array $groups array of group description arrays (with keys groupname and courseid)
f5072177 55 * @return array of newly created groups
9a0df45a 56 */
b4c1a34e 57 public static function create_groups($groups) {
f5072177 58 global $CFG, $DB;
9a0df45a 59 require_once("$CFG->dirroot/group/lib.php");
60
c9c5cc81 61 $params = self::validate_parameters(self::create_groups_parameters(), array('groups'=>$groups));
0c96468c 62
f5072177 63 // ideally create all groups or none at all, unfortunately myisam engine does not support transactions :-(
64 $DB->begin_sql();
65 try {
0f4e72de 66//TODO: there is a potential problem with events propagating actions to external systems :-(
f5072177 67 $groups = array();
68
69 foreach ($params['groups'] as $group) {
70 $group = (object)$group;
71
72 if (trim($group->name) == '') {
73 throw new invalid_parameter_exception('Invalid group name');
74 }
75 if ($DB->get_record('groups', array('courseid'=>$group->courseid, 'name'=>$group->name))) {
76 throw new invalid_parameter_exception('Group with the same name already exists in the course');
77 }
78
79 // now security checks
80 $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
81 self::validate_context($context);
82 require_capability('moodle/course:managegroups', $context);
83
84 // finally create the group
85 $group->id = groups_create_group($group, false);
86 $groups[] = (array)$group;
ab9a01f2 87 }
f5072177 88 } catch (Exception $ex) {
89 $DB->rollback_sql();
90 throw $ex;
9a0df45a 91 }
f5072177 92 $DB->commit_sql();
9a0df45a 93
2e13b916 94 return $groups;
9a0df45a 95 }
96
0c96468c 97 /**
98 * Returns description of method result value
f5072177 99 * @return external_description
0c96468c 100 */
101 public static function create_groups_returns() {
f5072177 102 return new external_multiple_structure(
103 new external_single_structure(
104 array(
105 'id' => new external_value(PARAM_INT, 'group record id'),
106 'courseid' => new external_value(PARAM_INT, 'id of course'),
107 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
108 'description' => new external_value(PARAM_RAW, 'group description text'),
109 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
110 )
111 )
112 );
0c96468c 113 }
114
f5072177 115 /**
116 * Returns description of method parameters
117 * @return external_function_parameters
118 */
0c96468c 119 public static function get_groups_parameters() {
8c772ad7 120 return new external_function_parameters(
121 array(
f5072177 122 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
8c772ad7 123 )
124 );
0c96468c 125 }
126
9a0df45a 127 /**
246f6da2 128 * Get groups definition specified by ids
b4c1a34e 129 * @param array $groupids arrays of group ids
9a0df45a 130 * @return array of group objects (id, courseid, name, enrolmentkey)
131 */
b4c1a34e 132 public static function get_groups($groupids) {
c9c5cc81 133 $params = self::validate_parameters(self::get_groups_parameters(), array('groupids'=>$groupids));
0c96468c 134
246f6da2 135 $groups = array();
0c96468c 136 foreach ($params['groupids'] as $groupid) {
ab9a01f2 137 // validate params
ab9a01f2 138 $group = groups_get_group($groupid, 'id, courseid, name, description, enrolmentkey', MUST_EXIST);
139
9a0df45a 140 // now security checks
141 $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
142 self::validate_context($context);
143 require_capability('moodle/course:managegroups', $context);
144
2e13b916 145 $groups[] = (array)$group;
9a0df45a 146 }
147
148 return $groups;
149 }
150
f5072177 151 /**
152 * Returns description of method result value
153 * @return external_description
154 */
0c96468c 155 public static function get_groups_returns() {
246f6da2 156 return new external_multiple_structure(
157 new external_single_structure(
158 array(
159 'id' => new external_value(PARAM_INT, 'group record id'),
160 'courseid' => new external_value(PARAM_INT, 'id of course'),
161 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
162 'description' => new external_value(PARAM_RAW, 'group description text'),
163 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
164 )
165 )
166 );
167 }
168
169 /**
170 * Returns description of method parameters
171 * @return external_function_parameters
172 */
173 public static function get_course_groups_parameters() {
174 return new external_function_parameters(
175 array(
176 'courseid' => new external_value(PARAM_INT, 'id of course'),
177 )
178 );
179 }
180
181 /**
182 * Get all groups in the specified course
183 * @param int $courseid id of course
184 * @return array of group objects (id, courseid, name, enrolmentkey)
185 */
186 public static function get_course_groups($courseid) {
187 $params = self::validate_parameters(self::get_course_groups_parameters(), array('courseid'=>$courseid));
188
189 // now security checks
190 $context = get_context_instance(CONTEXT_COURSE, $params['courseid']);
191 self::validate_context($context);
192 require_capability('moodle/course:managegroups', $context);
193
194 $gs = groups_get_all_groups($params['courseid'], 0, 0, 'g.id, g.courseid, g.name, g.description, g.enrolmentkey');
195
196 $groups = array();
197 foreach ($gs as $group) {
198 $groups[] = (array)$group;
199 }
200
201 return $groups;
202 }
203
204 /**
205 * Returns description of method result value
206 * @return external_description
207 */
208 public static function get_course_groups_returns() {
8c772ad7 209 return new external_multiple_structure(
210 new external_single_structure(
211 array(
f5072177 212 'id' => new external_value(PARAM_INT, 'group record id'),
213 'courseid' => new external_value(PARAM_INT, 'id of course'),
04d212ce 214 'name' => new external_value(PARAM_TEXT, 'multilang compatible name, course unique'),
f5072177 215 'description' => new external_value(PARAM_RAW, 'group description text'),
216 'enrolmentkey' => new external_value(PARAM_RAW, 'group enrol secret phrase'),
8c772ad7 217 )
218 )
219 );
0c96468c 220 }
221
0f4e72de
PS
222 /**
223 * Returns description of method parameters
224 * @return external_function_parameters
225 */
0c96468c 226 public static function delete_groups_parameters() {
0f4e72de
PS
227 return new external_function_parameters(
228 array(
229 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
230 )
231 );
0c96468c 232 }
233
9a0df45a 234 /**
235 * Delete groups
b4c1a34e 236 * @param array $groupids array of group ids
9a0df45a 237 * @return void
238 */
b4c1a34e 239 public static function delete_groups($groupids) {
2cb1ee78 240 global $CFG, $DB;
9a0df45a 241 require_once("$CFG->dirroot/group/lib.php");
242
c9c5cc81 243 $params = self::validate_parameters(self::delete_groups_parameters(), array('groupids'=>$groupids));
0c96468c 244
0f4e72de
PS
245 $DB->begin_sql();
246 try {
247// TODO: this is problematic because the DB rollback does not handle deleting of images!!
248// there is also potential problem with events propagating action to external systems :-(
249 foreach ($params['groupids'] as $groupid) {
250 // validate params
251 $groupid = validate_param($groupid, PARAM_INTEGER);
252 if (!$group = groups_get_group($groupid, 'id, courseid', IGNORE_MISSING)) {
253 // silently ignore attempts to delete nonexisting groups
254 continue;
255 }
ab9a01f2 256
0f4e72de
PS
257 // now security checks
258 $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
259 self::validate_context($context);
260 require_capability('moodle/course:managegroups', $context);
9a0df45a 261
0f4e72de
PS
262 groups_delete_group($group);
263 }
264 } catch (Exception $ex) {
265 $DB->rollback_sql();
266 throw $ex;
9a0df45a 267 }
0f4e72de 268 $DB->commit_sql();
9a0df45a 269 }
270
0f4e72de
PS
271 /**
272 * Returns description of method result value
273 * @return external_description
274 */
0c96468c 275 public static function delete_groups_returns() {
0f4e72de 276 return null;
0c96468c 277 }
278
279
0f4e72de
PS
280 /**
281 * Returns description of method parameters
282 * @return external_function_parameters
283 */
0c96468c 284 public static function get_groupmembers_parameters() {
0f4e72de
PS
285 return new external_function_parameters(
286 array(
287 'groupids' => new external_multiple_structure(new external_value(PARAM_INT, 'Group ID')),
288 )
289 );
0c96468c 290 }
9a0df45a 291
292 /**
293 * Return all members for a group
b4c1a34e 294 * @param array $groupids array of group ids
9a0df45a 295 * @return array with group id keys containing arrays of user ids
296 */
b4c1a34e 297 public static function get_groupmembers($groupids) {
0f4e72de 298 $members = array();
9a0df45a 299
c9c5cc81 300 $params = self::validate_parameters(self::get_groupmembers_parameters(), array('groupids'=>$groupids));
0c96468c 301
302 foreach ($params['groupids'] as $groupid) {
ab9a01f2 303 // validate params
9a0df45a 304 $group = groups_get_group($groupid, 'id, courseid, name, enrolmentkey', MUST_EXIST);
305 // now security checks
306 $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
307 self::validate_context($context);
308 require_capability('moodle/course:managegroups', $context);
309
310 $groupmembers = groups_get_members($group->id, 'u.id', 'lastname ASC, firstname ASC');
311
0f4e72de 312 $members[] = array('groupid'=>$groupid, 'userids'=>array_keys($groupmembers));
9a0df45a 313 }
314
0f4e72de 315 return $members;
9a0df45a 316 }
317
0f4e72de
PS
318 /**
319 * Returns description of method result value
320 * @return external_description
321 */
0c96468c 322 public static function get_groupmembers_returns() {
0f4e72de
PS
323 return new external_multiple_structure(
324 new external_single_structure(
325 array(
326 'groupid' => new external_value(PARAM_INT, 'group record id'),
327 'userids' => new external_multiple_structure(new external_value(PARAM_INT, 'user id')),
328 )
329 )
330 );
0c96468c 331 }
332
333
0f4e72de
PS
334 /**
335 * Returns description of method parameters
336 * @return external_function_parameters
337 */
0c96468c 338 public static function add_groupmembers_parameters() {
0f4e72de
PS
339 return new external_multiple_structure(
340 new external_single_structure(
341 array(
342 'groupid' => new external_value(PARAM_INT, 'group record id'),
343 'userid' => new external_value(PARAM_INT, 'user id'),
344 )
345 )
346 );
0c96468c 347 }
9a0df45a 348
349 /**
350 * Add group members
b4c1a34e 351 * @param array $members of arrays with keys userid, groupid
9a0df45a 352 * @return void
353 */
b4c1a34e 354 public static function add_groupmembers($members) {
2cb1ee78 355 global $CFG, $DB;
9a0df45a 356 require_once("$CFG->dirroot/group/lib.php");
357
c9c5cc81 358 $params = self::validate_parameters(self::add_groupmembers_parameters(), array('members'=>$members));
9a0df45a 359
0f4e72de
PS
360 $DB->begin_sql();
361 try {
362// TODO: there is a potential problem with events propagating action to external systems :-(
363 foreach ($params['members'] as $member) {
364 // validate params
365 $groupid = $member['groupid'];
366 $userid = $member['userid'];
0c96468c 367
0f4e72de
PS
368 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
369 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
9a0df45a 370
0f4e72de
PS
371 // now security checks
372 $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
373 self::validate_context($context);
374 require_capability('moodle/course:managegroups', $context);
9a0df45a 375
0f4e72de
PS
376 groups_add_member($group, $user);
377 }
378 } catch (Exception $ex) {
379 $DB->rollback_sql();
380 throw $ex;
9a0df45a 381 }
0f4e72de 382 $DB->commit_sql();
9a0df45a 383 }
384
0f4e72de
PS
385 /**
386 * Returns description of method result value
387 * @return external_description
388 */
0c96468c 389 public static function add_groupmembers_returns() {
0f4e72de 390 return null;
0c96468c 391 }
392
393
0f4e72de
PS
394 /**
395 * Returns description of method parameters
396 * @return external_function_parameters
397 */
0c96468c 398 public static function delete_groupmembers_parameters() {
0f4e72de
PS
399 return new external_multiple_structure(
400 new external_single_structure(
401 array(
402 'groupid' => new external_value(PARAM_INT, 'group record id'),
403 'userid' => new external_value(PARAM_INT, 'user id'),
404 )
405 )
406 );
0c96468c 407 }
9a0df45a 408
409 /**
410 * Delete group members
b4c1a34e 411 * @param array $members of arrays with keys userid, groupid
9a0df45a 412 * @return void
413 */
b4c1a34e 414 public static function delete_groupmembers($members) {
2cb1ee78 415 global $CFG, $DB;
9a0df45a 416 require_once("$CFG->dirroot/group/lib.php");
417
c9c5cc81 418 $params = self::validate_parameters(self::delete_groupmembers_parameters(), array($members=>'members'));
9a0df45a 419
0f4e72de
PS
420 $DB->begin_sql();
421 try {
422// TODO: there is a potential problem with events propagating action to external systems :-(
0c96468c 423 foreach ($params['members'] as $member) {
0f4e72de
PS
424 // validate params
425 $groupid = $member['groupid'];
426 $userid = $member['userid'];
0c96468c 427
0f4e72de
PS
428 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
429 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
9a0df45a 430
0f4e72de
PS
431 // now security checks
432 $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
433 self::validate_context($context);
434 require_capability('moodle/course:managegroups', $context);
9a0df45a 435
0f4e72de
PS
436 groups_remove_member($group, $user);
437 }
438 } catch (Exception $ex) {
439 $DB->rollback_sql();
440 throw $ex;
9a0df45a 441 }
0f4e72de 442 $DB->commit_sql();
9a0df45a 443 }
444
0f4e72de
PS
445 /**
446 * Returns description of method result value
447 * @return external_description
448 */
0c96468c 449 public static function delete_groupmembers_returns() {
0f4e72de 450 return null;
0c96468c 451 }
452
4ca6cfbf 453}