Updated the HEAD build version to 20091107
[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() {
4efa2483
PS
339 return new external_function_parameters(
340 array(
341 'members'=> new external_multiple_structure(
342 new external_single_structure(
343 array(
344 'groupid' => new external_value(PARAM_INT, 'group record id'),
345 'userid' => new external_value(PARAM_INT, 'user id'),
346 )
347 )
0f4e72de
PS
348 )
349 )
350 );
0c96468c 351 }
9a0df45a 352
353 /**
354 * Add group members
b4c1a34e 355 * @param array $members of arrays with keys userid, groupid
9a0df45a 356 * @return void
357 */
b4c1a34e 358 public static function add_groupmembers($members) {
2cb1ee78 359 global $CFG, $DB;
9a0df45a 360 require_once("$CFG->dirroot/group/lib.php");
361
c9c5cc81 362 $params = self::validate_parameters(self::add_groupmembers_parameters(), array('members'=>$members));
9a0df45a 363
0f4e72de
PS
364 $DB->begin_sql();
365 try {
366// TODO: there is a potential problem with events propagating action to external systems :-(
367 foreach ($params['members'] as $member) {
368 // validate params
369 $groupid = $member['groupid'];
370 $userid = $member['userid'];
0c96468c 371
0f4e72de
PS
372 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
373 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
9a0df45a 374
0f4e72de
PS
375 // now security checks
376 $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
377 self::validate_context($context);
378 require_capability('moodle/course:managegroups', $context);
9a0df45a 379
4efa2483
PS
380 // now make sure user is enrolled in course - this is mandatory requirement,
381 // unfortunately this is extermely slow
382 require_capability('moodle/course:view', $context, $userid, false);
383
0f4e72de
PS
384 groups_add_member($group, $user);
385 }
386 } catch (Exception $ex) {
387 $DB->rollback_sql();
388 throw $ex;
9a0df45a 389 }
0f4e72de 390 $DB->commit_sql();
9a0df45a 391 }
392
0f4e72de
PS
393 /**
394 * Returns description of method result value
395 * @return external_description
396 */
0c96468c 397 public static function add_groupmembers_returns() {
0f4e72de 398 return null;
0c96468c 399 }
400
401
0f4e72de
PS
402 /**
403 * Returns description of method parameters
404 * @return external_function_parameters
405 */
0c96468c 406 public static function delete_groupmembers_parameters() {
4efa2483
PS
407 return new external_function_parameters(
408 array(
409 'members'=> new external_multiple_structure(
410 new external_single_structure(
411 array(
412 'groupid' => new external_value(PARAM_INT, 'group record id'),
413 'userid' => new external_value(PARAM_INT, 'user id'),
414 )
415 )
0f4e72de
PS
416 )
417 )
418 );
0c96468c 419 }
9a0df45a 420
421 /**
422 * Delete group members
b4c1a34e 423 * @param array $members of arrays with keys userid, groupid
9a0df45a 424 * @return void
425 */
b4c1a34e 426 public static function delete_groupmembers($members) {
2cb1ee78 427 global $CFG, $DB;
9a0df45a 428 require_once("$CFG->dirroot/group/lib.php");
429
443364ab 430 $params = self::validate_parameters(self::delete_groupmembers_parameters(), array('members'=>$members));
9a0df45a 431
0f4e72de
PS
432 $DB->begin_sql();
433 try {
434// TODO: there is a potential problem with events propagating action to external systems :-(
0c96468c 435 foreach ($params['members'] as $member) {
0f4e72de
PS
436 // validate params
437 $groupid = $member['groupid'];
438 $userid = $member['userid'];
0c96468c 439
0f4e72de
PS
440 $group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
441 $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
9a0df45a 442
0f4e72de
PS
443 // now security checks
444 $context = get_context_instance(CONTEXT_COURSE, $group->courseid);
445 self::validate_context($context);
446 require_capability('moodle/course:managegroups', $context);
9a0df45a 447
0f4e72de
PS
448 groups_remove_member($group, $user);
449 }
450 } catch (Exception $ex) {
451 $DB->rollback_sql();
452 throw $ex;
9a0df45a 453 }
0f4e72de 454 $DB->commit_sql();
9a0df45a 455 }
456
0f4e72de
PS
457 /**
458 * Returns description of method result value
459 * @return external_description
460 */
0c96468c 461 public static function delete_groupmembers_returns() {
0f4e72de 462 return null;
0c96468c 463 }
464
4ca6cfbf 465}