Commit | Line | Data |
---|---|---|
f3f7610c ML |
1 | <?php |
2 | /** | |
ddff2fa8 | 3 | * Extra library for groups and groupings. |
f3f7610c ML |
4 | * |
5 | * @copyright © 2006 The Open University | |
2942a5cd | 6 | * @author J.White AT open.ac.uk, Petr Skoda (skodak) |
f3f7610c ML |
7 | * @license http://www.gnu.org/copyleft/gpl.html GNU Public License |
8 | * @package groups | |
9 | */ | |
10 | ||
ddff2fa8 | 11 | /* |
12 | * INTERNAL FUNCTIONS - to be used by moodle core only | |
13 | * require_once $CFG->dirroot.'/group/lib.php' must be used | |
14 | */ | |
15 | ||
778918fd | 16 | /** |
17 | * Adds a specified user to a group | |
18 | * @param int $userid The user id | |
19 | * @param int $groupid The group id | |
f16fa0a3 | 20 | * @return boolean True if user added successfully or the user is already a |
21 | * member of the group, false otherwise. | |
778918fd | 22 | */ |
23 | function groups_add_member($groupid, $userid) { | |
dfdaabd6 | 24 | global $DB; |
25 | ||
778918fd | 26 | if (!groups_group_exists($groupid)) { |
27 | return false; | |
28 | } | |
29 | ||
30 | if (groups_is_member($groupid, $userid)) { | |
31 | return true; | |
32 | } | |
33 | ||
34 | $member = new object(); | |
35 | $member->groupid = $groupid; | |
36 | $member->userid = $userid; | |
37 | $member->timeadded = time(); | |
38 | ||
dfdaabd6 | 39 | if (!$DB->insert_record('groups_members', $member)) { |
778918fd | 40 | return false; |
41 | } | |
42 | ||
43 | //update group info | |
dfdaabd6 | 44 | $DB->set_field('groups', 'timemodified', $member->timeadded, array('id'=>$groupid)); |
778918fd | 45 | |
2942a5cd | 46 | //trigger groups events |
778918fd | 47 | $eventdata = new object(); |
48 | $eventdata->groupid = $groupid; | |
2942a5cd | 49 | $eventdata->userid = $userid; |
50 | events_trigger('groups_member_added', $eventdata); | |
778918fd | 51 | |
52 | return true; | |
53 | } | |
54 | ||
55 | /** | |
56 | * Deletes the link between the specified user and group. | |
57 | * @param int $groupid The group to delete the user from | |
58 | * @param int $userid The user to delete | |
59 | * @return boolean True if deletion was successful, false otherwise | |
60 | */ | |
61 | function groups_remove_member($groupid, $userid) { | |
dfdaabd6 | 62 | global $DB; |
63 | ||
778918fd | 64 | if (!groups_group_exists($groupid)) { |
65 | return false; | |
66 | } | |
67 | ||
68 | if (!groups_is_member($groupid, $userid)) { | |
69 | return true; | |
70 | } | |
71 | ||
dfdaabd6 | 72 | if (!$DB->delete_records('groups_members', array('groupid'=>$groupid, 'userid'=>$userid))) { |
778918fd | 73 | return false; |
f16fa0a3 | 74 | } |
778918fd | 75 | //update group info |
dfdaabd6 | 76 | $DB->set_field('groups', 'timemodified', time(), array('id'=>$groupid)); |
778918fd | 77 | |
2942a5cd | 78 | //trigger groups events |
79 | $eventdata = new object(); | |
80 | $eventdata->groupid = $groupid; | |
81 | $eventdata->userid = $userid; | |
82 | events_trigger('groups_member_removed', $eventdata); | |
83 | ||
778918fd | 84 | return true; |
85 | } | |
86 | ||
ddff2fa8 | 87 | /** |
88 | * Add a new group | |
f16fa0a3 | 89 | * @param object $data group properties (with magic quotes) |
ddff2fa8 | 90 | * @param object $um upload manager with group picture |
91 | * @return id of group or false if error | |
92 | */ | |
172dd12c | 93 | function groups_create_group($data, $editform=false) { |
dfdaabd6 | 94 | global $CFG, $DB; |
ddff2fa8 | 95 | require_once("$CFG->libdir/gdlib.php"); |
96 | ||
dfdaabd6 | 97 | $data->timecreated = time(); |
ddff2fa8 | 98 | $data->timemodified = $data->timecreated; |
dfdaabd6 | 99 | $data->name = trim($data->name); |
100 | $id = $DB->insert_record('groups', $data); | |
ddff2fa8 | 101 | |
2942a5cd | 102 | if ($id) { |
103 | $data->id = $id; | |
172dd12c | 104 | if ($editform) { |
2942a5cd | 105 | //update image |
172dd12c | 106 | if (save_profile_image($id, $editform, 'groups')) { |
2942a5cd | 107 | $DB->set_field('groups', 'picture', 1, array('id'=>$id)); |
108 | } | |
109 | $data->picture = 1; | |
ddff2fa8 | 110 | } |
2942a5cd | 111 | |
112 | //trigger groups events | |
113 | events_trigger('groups_group_created', $data); | |
ddff2fa8 | 114 | } |
115 | ||
116 | return $id; | |
117 | } | |
118 | ||
119 | /** | |
f16fa0a3 | 120 | * Add a new grouping |
121 | * @param object $data grouping properties (with magic quotes) | |
122 | * @return id of grouping or false if error | |
123 | */ | |
124 | function groups_create_grouping($data) { | |
dfdaabd6 | 125 | global $DB; |
f16fa0a3 | 126 | |
dfdaabd6 | 127 | $data->timecreated = time(); |
f16fa0a3 | 128 | $data->timemodified = $data->timecreated; |
dfdaabd6 | 129 | $data->name = trim($data->name); |
2942a5cd | 130 | $id = $DB->insert_record('groupings', $data); |
131 | ||
132 | if ($id) { | |
133 | //trigger groups events | |
134 | $data->id = $id; | |
135 | events_trigger('groups_grouping_created', $data); | |
136 | } | |
137 | ||
138 | return $id; | |
f16fa0a3 | 139 | } |
140 | ||
141 | /** | |
142 | * Update group | |
143 | * @param object $data group properties (with magic quotes) | |
ddff2fa8 | 144 | * @param object $um upload manager with group picture |
145 | * @return boolean success | |
146 | */ | |
172dd12c | 147 | function groups_update_group($data, $editform=false) { |
dfdaabd6 | 148 | global $CFG, $DB; |
ddff2fa8 | 149 | require_once("$CFG->libdir/gdlib.php"); |
150 | ||
151 | $data->timemodified = time(); | |
dfdaabd6 | 152 | $data->name = trim($data->name); |
153 | $result = $DB->update_record('groups', $data); | |
ddff2fa8 | 154 | |
2942a5cd | 155 | if ($result) { |
172dd12c | 156 | if ($editform) { |
2942a5cd | 157 | //update image |
172dd12c | 158 | if (save_profile_image($data->id, $editform, 'groups')) { |
dfdaabd6 | 159 | $DB->set_field('groups', 'picture', 1, array('id'=>$data->id)); |
2942a5cd | 160 | $data->picture = 1; |
161 | } | |
ddff2fa8 | 162 | } |
2942a5cd | 163 | |
164 | //trigger groups events | |
165 | events_trigger('groups_group_updated', $data); | |
ddff2fa8 | 166 | } |
167 | ||
168 | return $result; | |
169 | } | |
170 | ||
f16fa0a3 | 171 | /** |
172 | * Update grouping | |
173 | * @param object $data grouping properties (with magic quotes) | |
174 | * @return boolean success | |
175 | */ | |
176 | function groups_update_grouping($data) { | |
dfdaabd6 | 177 | global $DB; |
f16fa0a3 | 178 | $data->timemodified = time(); |
dfdaabd6 | 179 | $data->name = trim($data->name); |
2942a5cd | 180 | $result = $DB->update_record('groupings', $data); |
181 | if ($result) { | |
182 | //trigger groups events | |
183 | events_trigger('groups_grouping_updated', $data); | |
184 | } | |
185 | return $result; | |
f16fa0a3 | 186 | } |
187 | ||
ddff2fa8 | 188 | /** |
189 | * Delete a group best effort, first removing members and links with courses and groupings. | |
190 | * Removes group avatar too. | |
2942a5cd | 191 | * @param mixed $grouporid The id of group to delete or full group object |
ddff2fa8 | 192 | * @return boolean True if deletion was successful, false otherwise |
193 | */ | |
2942a5cd | 194 | function groups_delete_group($grouporid) { |
dfdaabd6 | 195 | global $CFG, $DB; |
ddff2fa8 | 196 | require_once($CFG->libdir.'/gdlib.php'); |
197 | ||
2942a5cd | 198 | if (is_object($grouporid)) { |
199 | $groupid = $grouporid->id; | |
200 | $group = $grouporid; | |
201 | } else { | |
202 | $groupid = $grouporid; | |
203 | if (!$group = $DB->get_record('groups', array('id'=>$groupid))) { | |
204 | return false; | |
205 | } | |
ddff2fa8 | 206 | } |
207 | ||
0b5a80a1 | 208 | // delete group calendar events |
dfdaabd6 | 209 | $DB->delete_records('event', array('groupid'=>$groupid)); |
ddff2fa8 | 210 | //first delete usage in groupings_groups |
dfdaabd6 | 211 | $DB->delete_records('groupings_groups', array('groupid'=>$groupid)); |
ddff2fa8 | 212 | //delete members |
dfdaabd6 | 213 | $DB->delete_records('groups_members', array('groupid'=>$groupid)); |
ddff2fa8 | 214 | //then imge |
215 | delete_profile_image($groupid, 'groups'); | |
216 | //group itself last | |
2942a5cd | 217 | $result = $DB->delete_records('groups', array('id'=>$groupid)); |
218 | if ($result) { | |
219 | //trigger groups events | |
220 | events_trigger('groups_group_deleted', $group); | |
221 | } | |
222 | ||
223 | return $result; | |
ddff2fa8 | 224 | } |
225 | ||
f16fa0a3 | 226 | /** |
227 | * Delete grouping | |
228 | * @param int $groupingid | |
229 | * @return bool success | |
230 | */ | |
2942a5cd | 231 | function groups_delete_grouping($groupingorid) { |
dfdaabd6 | 232 | global $DB; |
233 | ||
2942a5cd | 234 | if (is_object($groupingorid)) { |
235 | $groupingid = $groupingorid->id; | |
236 | $grouping = $groupingorid; | |
237 | } else { | |
238 | $groupingid = $groupingorid; | |
239 | if (!$grouping = $DB->get_record('groupings', array('id'=>$groupingorid))) { | |
240 | return false; | |
241 | } | |
ddff2fa8 | 242 | } |
243 | ||
244 | //first delete usage in groupings_groups | |
dfdaabd6 | 245 | $DB->delete_records('groupings_groups', array('groupingid'=>$groupingid)); |
ddff2fa8 | 246 | // remove the default groupingid from course |
dfdaabd6 | 247 | $DB->set_field('course', 'defaultgroupingid', 0, array('defaultgroupingid'=>$groupingid)); |
ddff2fa8 | 248 | // remove the groupingid from all course modules |
dfdaabd6 | 249 | $DB->set_field('course_modules', 'groupingid', 0, array('groupingid'=>$groupingid)); |
ddff2fa8 | 250 | //group itself last |
2942a5cd | 251 | $result = $DB->delete_records('groupings', array('id'=>$groupingid)); |
252 | ||
253 | if ($result) { | |
254 | //trigger groups events | |
255 | events_trigger('groups_grouping_deleted', $grouping); | |
256 | } | |
257 | ||
258 | return $result; | |
ddff2fa8 | 259 | } |
260 | ||
f16fa0a3 | 261 | /** |
ffc670d9 | 262 | * Remove all users (or one user) from all groups in course |
f16fa0a3 | 263 | * @param int $courseid |
ffc670d9 | 264 | * @param int $userid 0 means all users |
f16fa0a3 | 265 | * @param bool $showfeedback |
266 | * @return bool success | |
267 | */ | |
ffc670d9 | 268 | function groups_delete_group_members($courseid, $userid=0, $showfeedback=false) { |
dfdaabd6 | 269 | global $DB; |
ddff2fa8 | 270 | |
ffc670d9 | 271 | if (is_bool($userid)) { |
272 | debugging('Incorrect userid function parameter'); | |
273 | return false; | |
274 | } | |
275 | ||
276 | $params = array('courseid'=>$courseid); | |
277 | ||
278 | if ($userid) { | |
279 | $usersql = "AND userid = :userid"; | |
280 | $params['userid'] = $userid; | |
281 | } else { | |
282 | $usersql = ""; | |
283 | } | |
284 | ||
285 | $groupssql = "SELECT id FROM {groups} g WHERE g.courseid = :courseid"; | |
286 | $DB->delete_records_select('groups_members', "groupid IN ($groupssql) $usersql", $params); | |
ddff2fa8 | 287 | |
2942a5cd | 288 | //trigger groups events |
ffc670d9 | 289 | $eventdata = new object(); |
290 | $eventdata->courseid = $courseid; | |
291 | $eventdata->userid = $userid; | |
292 | events_trigger('groups_members_removed', $eventdata); | |
2942a5cd | 293 | |
ddff2fa8 | 294 | if ($showfeedback) { |
295 | notify(get_string('deleted').' groups_members'); | |
296 | } | |
297 | ||
298 | return true; | |
299 | } | |
300 | ||
0b5a80a1 | 301 | /** |
302 | * Remove all groups from all groupings in course | |
303 | * @param int $courseid | |
304 | * @param bool $showfeedback | |
305 | * @return bool success | |
306 | */ | |
307 | function groups_delete_groupings_groups($courseid, $showfeedback=false) { | |
dfdaabd6 | 308 | global $DB; |
0b5a80a1 | 309 | |
dfdaabd6 | 310 | $groupssql = "SELECT id FROM {groups} g WHERE g.courseid = ?"; |
311 | $DB->delete_records_select('groupings_groups', "groupid IN ($groupssql)", array($courseid)); | |
0b5a80a1 | 312 | |
2942a5cd | 313 | //trigger groups events |
314 | events_trigger('groups_groupings_groups_removed', $courseid); | |
315 | ||
0b5a80a1 | 316 | if ($showfeedback) { |
317 | notify(get_string('deleted').' groupings_groups'); | |
318 | } | |
319 | ||
320 | return true; | |
321 | } | |
322 | ||
f16fa0a3 | 323 | /** |
324 | * Delete all groups from course | |
325 | * @param int $courseid | |
326 | * @param bool $showfeedback | |
327 | * @return bool success | |
328 | */ | |
ddff2fa8 | 329 | function groups_delete_groups($courseid, $showfeedback=false) { |
dfdaabd6 | 330 | global $CFG, $DB; |
ddff2fa8 | 331 | require_once($CFG->libdir.'/gdlib.php'); |
332 | ||
0b5a80a1 | 333 | // delete any uses of groups |
334 | groups_delete_groupings_groups($courseid, $showfeedback); | |
ffc670d9 | 335 | groups_delete_group_members($courseid, 0, $showfeedback); |
ddff2fa8 | 336 | |
337 | // delete group pictures | |
dfdaabd6 | 338 | if ($groups = $DB->get_records('groups', array('courseid'=>$courseid))) { |
ddff2fa8 | 339 | foreach($groups as $group) { |
340 | delete_profile_image($group->id, 'groups'); | |
341 | } | |
342 | } | |
343 | ||
0b5a80a1 | 344 | // delete group calendar events |
dfdaabd6 | 345 | $groupssql = "SELECT id FROM {groups} g WHERE g.courseid = ?"; |
346 | $DB->delete_records_select('event', "groupid IN ($groupssql)", array($courseid)); | |
0b5a80a1 | 347 | |
dfdaabd6 | 348 | $DB->delete_records('groups', array('courseid'=>$courseid)); |
2942a5cd | 349 | |
350 | //trigger groups events | |
351 | events_trigger('groups_groups_deleted', $courseid); | |
352 | ||
ddff2fa8 | 353 | if ($showfeedback) { |
354 | notify(get_string('deleted').' groups'); | |
355 | } | |
356 | ||
357 | return true; | |
358 | } | |
359 | ||
f16fa0a3 | 360 | /** |
361 | * Delete all groupings from course | |
362 | * @param int $courseid | |
363 | * @param bool $showfeedback | |
364 | * @return bool success | |
365 | */ | |
ddff2fa8 | 366 | function groups_delete_groupings($courseid, $showfeedback=false) { |
dfdaabd6 | 367 | global $DB; |
ddff2fa8 | 368 | |
369 | // delete any uses of groupings | |
dfdaabd6 | 370 | $sql = "DELETE FROM {groupings_groups} |
371 | WHERE groupingid in (SELECT id FROM {groupings} g WHERE g.courseid = ?)"; | |
372 | $DB->execute($sql, array($courseid)); | |
ddff2fa8 | 373 | |
374 | // remove the default groupingid from course | |
dfdaabd6 | 375 | $DB->set_field('course', 'defaultgroupingid', 0, array('id'=>$courseid)); |
ddff2fa8 | 376 | // remove the groupingid from all course modules |
dfdaabd6 | 377 | $DB->set_field('course_modules', 'groupingid', 0, array('course'=>$courseid)); |
ddff2fa8 | 378 | |
dfdaabd6 | 379 | $DB->delete_records('groupings', array('courseid'=>$courseid)); |
2942a5cd | 380 | |
381 | //trigger groups events | |
382 | events_trigger('groups_groupings_deleted', $courseid); | |
383 | ||
ddff2fa8 | 384 | if ($showfeedback) { |
385 | notify(get_string('deleted').' groupings'); | |
386 | } | |
387 | ||
388 | return true; | |
389 | } | |
390 | ||
391 | /* =================================== */ | |
392 | /* various functions used by groups UI */ | |
393 | /* =================================== */ | |
394 | ||
e254aa34 | 395 | /** |
396 | * Obtains a list of the possible roles that group members might come from, | |
397 | * on a course. Generally this includes all the roles who would have | |
398 | * course:view on that course, except the doanything roles. | |
399 | * @param object $context Context of course | |
400 | * @return Array of role ID integers, or false if error/none. | |
401 | */ | |
402 | function groups_get_possible_roles($context) { | |
ddff2fa8 | 403 | $capability = 'moodle/course:view'; |
404 | $doanything = false; | |
f3f7610c | 405 | |
ddff2fa8 | 406 | // find all possible "student" roles |
407 | if ($possibleroles = get_roles_with_capability($capability, CAP_ALLOW, $context)) { | |
408 | if (!$doanything) { | |
409 | if (!$sitecontext = get_context_instance(CONTEXT_SYSTEM)) { | |
410 | return false; // Something is seriously wrong | |
411 | } | |
412 | $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext); | |
413 | } | |
f3f7610c | 414 | |
ddff2fa8 | 415 | $validroleids = array(); |
416 | foreach ($possibleroles as $possiblerole) { | |
417 | if (!$doanything) { | |
418 | if (isset($doanythingroles[$possiblerole->id])) { // We don't want these included | |
419 | continue; | |
420 | } | |
421 | } | |
422 | if ($caps = role_context_capabilities($possiblerole->id, $context, $capability)) { // resolved list | |
423 | if (isset($caps[$capability]) && $caps[$capability] > 0) { // resolved capability > 0 | |
424 | $validroleids[] = $possiblerole->id; | |
425 | } | |
426 | } | |
427 | } | |
428 | if (empty($validroleids)) { | |
429 | return false; | |
430 | } | |
e254aa34 | 431 | return $validroleids; |
ddff2fa8 | 432 | } else { |
433 | return false; // No need to continue, since no roles have this capability set | |
e254aa34 | 434 | } |
acf000b0 | 435 | } |
436 | ||
437 | ||
438 | /** | |
439 | * Gets potential group members for grouping | |
440 | * @param int $courseid The id of the course | |
441 | * @param int $roleid The role to select users from | |
442 | * @param string $orderby The colum to sort users by | |
443 | * @return array An array of the users | |
444 | */ | |
f16fa0a3 | 445 | function groups_get_potential_members($courseid, $roleid = null, $orderby = 'lastname,firstname') { |
dfdaabd6 | 446 | global $DB; |
f16fa0a3 | 447 | |
acf000b0 | 448 | $context = get_context_instance(CONTEXT_COURSE, $courseid); |
449 | $sitecontext = get_context_instance(CONTEXT_SYSTEM); | |
450 | $rolenames = array(); | |
451 | $avoidroles = array(); | |
452 | ||
453 | if ($roles = get_roles_used_in_context($context, true)) { | |
454 | ||
455 | $canviewroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context); | |
456 | $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext); | |
457 | ||
458 | foreach ($roles as $role) { | |
459 | if (!isset($canviewroles[$role->id])) { // Avoid this role (eg course creator) | |
460 | $avoidroles[] = $role->id; | |
461 | unset($roles[$role->id]); | |
462 | continue; | |
463 | } | |
464 | if (isset($doanythingroles[$role->id])) { // Avoid this role (ie admin) | |
465 | $avoidroles[] = $role->id; | |
466 | unset($roles[$role->id]); | |
467 | continue; | |
468 | } | |
469 | $rolenames[$role->id] = strip_tags(role_get_name($role, $context)); // Used in menus etc later on | |
470 | } | |
471 | } | |
f16fa0a3 | 472 | |
acf000b0 | 473 | if ($avoidroles) { |
dfdaabd6 | 474 | list($adminroles, $params) = $DB->get_in_or_equal($avoidroles, SQL_PARAMS_NAMED, 'ar0', false); |
475 | $adminroles = "AND r.roleid $adminroles"; | |
acf000b0 | 476 | } else { |
dfdaabd6 | 477 | $adminroles = ""; |
478 | $params = array(); | |
acf000b0 | 479 | } |
480 | ||
481 | // we are looking for all users with this role assigned in this context or higher | |
482 | if ($usercontexts = get_parent_contexts($context)) { | |
dfdaabd6 | 483 | $listofcontexts = 'IN ('.implode(',', $usercontexts).')'; |
acf000b0 | 484 | } else { |
dfdaabd6 | 485 | $listofcontexts = '='.$sitecontext->id.')'; // must be site |
acf000b0 | 486 | } |
f16fa0a3 | 487 | |
acf000b0 | 488 | if ($roleid) { |
dfdaabd6 | 489 | $selectrole = "AND r.roleid = :roleid"; |
490 | $params['roleid'] = $roleid; | |
acf000b0 | 491 | } else { |
dfdaabd6 | 492 | $selectrole = ""; |
acf000b0 | 493 | } |
f16fa0a3 | 494 | |
dfdaabd6 | 495 | $sql = "SELECT u.id, u.username, u.firstname, u.lastname, u.idnumber |
496 | FROM {user} u | |
497 | JOIN {role_assignments} r on u.id=r.userid | |
498 | WHERE (r.contextid = :contextid OR r.contextid $listofcontexts) | |
499 | AND u.deleted = 0 AND u.username != 'guest' | |
500 | $selectrole $adminroles | |
501 | ORDER BY $orderby"; | |
502 | $params['contextid'] = $context->id; | |
f16fa0a3 | 503 | |
dfdaabd6 | 504 | return $DB->get_records_sql($sql, $params); |
f16fa0a3 | 505 | |
acf000b0 | 506 | } |
f3f7610c | 507 | |
acf000b0 | 508 | /** |
509 | * Parse a group name for characters to replace | |
510 | * @param string $format The format a group name will follow | |
511 | * @param int $groupnumber The number of the group to be used in the parsed format string | |
512 | * @return string the parsed format string | |
513 | */ | |
514 | function groups_parse_name($format, $groupnumber) { | |
acf000b0 | 515 | if (strstr($format, '@') !== false) { // Convert $groupnumber to a character series |
f16fa0a3 | 516 | $letter = 'A'; |
517 | for($i=0; $i<$groupnumber; $i++) { | |
518 | $letter++; | |
acf000b0 | 519 | } |
f16fa0a3 | 520 | $str = str_replace('@', $letter, $format); |
acf000b0 | 521 | } else { |
f16fa0a3 | 522 | $str = str_replace('#', $groupnumber+1, $format); |
acf000b0 | 523 | } |
524 | return($str); | |
ddff2fa8 | 525 | } |
f3f7610c | 526 | |
f16fa0a3 | 527 | /** |
528 | * Assigns group into grouping | |
529 | * @param int groupingid | |
530 | * @param int groupid | |
531 | * @return bool success | |
532 | */ | |
533 | function groups_assign_grouping($groupingid, $groupid) { | |
dfdaabd6 | 534 | global $DB; |
535 | ||
536 | if ($DB->record_exists('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid))) { | |
f16fa0a3 | 537 | return true; |
538 | } | |
539 | $assign = new object(); | |
540 | $assign->groupingid = $groupingid; | |
dfdaabd6 | 541 | $assign->groupid = $groupid; |
542 | $assign->timeadded = time(); | |
543 | return (bool)$DB->insert_record('groupings_groups', $assign); | |
f16fa0a3 | 544 | } |
545 | ||
546 | /** | |
547 | * Unassigns group grom grouping | |
548 | * @param int groupingid | |
549 | * @param int groupid | |
550 | * @return bool success | |
551 | */ | |
552 | function groups_unassign_grouping($groupingid, $groupid) { | |
dfdaabd6 | 553 | global $DB; |
554 | ||
555 | return $DB->delete_records('groupings_groups', array('groupingid'=>$groupingid, 'groupid'=>$groupid)); | |
f16fa0a3 | 556 | } |
557 | ||
e254aa34 | 558 | /** |
559 | * Lists users in a group based on their role on the course. | |
560 | * Returns false if there's an error or there are no users in the group. | |
561 | * Otherwise returns an array of role ID => role data, where role data includes: | |
562 | * (role) $id, $shortname, $name | |
563 | * $users: array of objects for each user which include the specified fields | |
564 | * Users who do not have a role are stored in the returned array with key '-' | |
565 | * and pseudo-role details (including a name, 'No role'). Users with multiple | |
566 | * roles, same deal with key '*' and name 'Multiple roles'. You can find out | |
567 | * which roles each has by looking in the $roles array of the user object. | |
568 | * @param int $groupid | |
569 | * @param int $courseid Course ID (should match the group's course) | |
570 | * @param string $fields List of fields from user table prefixed with u, default 'u.*' | |
571 | * @param string $sort SQL ORDER BY clause, default 'u.lastname ASC' | |
97873016 | 572 | * @param string $extrawheretest extra SQL conditions ANDed with the existing where clause. |
573 | * @param array $whereparams any parameters required by $extrawheretest. | |
e254aa34 | 574 | * @return array Complex array as described above |
575 | */ | |
97873016 | 576 | function groups_get_members_by_role($groupid, $courseid, $fields='u.*', |
577 | $sort='u.lastname ASC', $extrawheretest='', $whereparams=array()) { | |
dfdaabd6 | 578 | global $CFG, $DB; |
e254aa34 | 579 | |
580 | // Retrieve information about all users and their roles on the course or | |
581 | // parent ('related') contexts | |
dfdaabd6 | 582 | $context = get_context_instance(CONTEXT_COURSE, $courseid); |
583 | ||
97873016 | 584 | if ($extrawheretest) { |
585 | $extrawheretest = ' AND ' . $extrawheretest; | |
586 | } | |
587 | ||
dfdaabd6 | 588 | $sql = "SELECT r.id AS roleid, r.shortname AS roleshortname, r.name AS rolename, |
589 | u.id AS userid, $fields | |
590 | FROM {groups_members} gm | |
591 | JOIN {user} u ON u.id = gm.userid | |
592 | JOIN {role_assignments} ra ON ra.userid = u.id | |
593 | JOIN {role} r ON r.id = ra.roleid | |
594 | WHERE gm.groupid=? | |
97873016 | 595 | AND ra.contextid ".get_related_contexts_string($context). |
596 | $extrawheretest." | |
dfdaabd6 | 597 | ORDER BY r.sortorder, $sort"; |
97873016 | 598 | array_unshift($whereparams, $groupid); |
599 | $rs = $DB->get_recordset_sql($sql, $whereparams); | |
dfdaabd6 | 600 | |
601 | return groups_calculate_role_people($rs, $context); | |
e254aa34 | 602 | } |
603 | ||
604 | /** | |
605 | * Internal function used by groups_get_members_by_role to handle the | |
606 | * results of a database query that includes a list of users and possible | |
607 | * roles on a course. | |
608 | * | |
609 | * @param object $rs The record set (may be false) | |
3540f2b3 | 610 | * @param int $contextid ID of course context |
e254aa34 | 611 | * @return array As described in groups_get_members_by_role |
612 | */ | |
dfdaabd6 | 613 | function groups_calculate_role_people($rs, $context) { |
614 | global $CFG, $DB; | |
615 | ||
616 | if (!$rs) { | |
617 | return array(); | |
3540f2b3 | 618 | } |
e254aa34 | 619 | |
dfdaabd6 | 620 | $roles = $DB->get_records_menu('role', null, 'name', 'id, name'); |
621 | $aliasnames = role_fix_names($roles, $context); | |
622 | ||
e254aa34 | 623 | // Array of all involved roles |
dfdaabd6 | 624 | $roles = array(); |
e254aa34 | 625 | // Array of all retrieved users |
dfdaabd6 | 626 | $users = array(); |
e254aa34 | 627 | // Fill arrays |
dfdaabd6 | 628 | foreach ($rs as $rec) { |
e254aa34 | 629 | // Create information about user if this is a new one |
dfdaabd6 | 630 | if (!array_key_exists($rec->userid, $users)) { |
e254aa34 | 631 | // User data includes all the optional fields, but not any of the |
632 | // stuff we added to get the role details | |
633 | $userdata=clone($rec); | |
634 | unset($userdata->roleid); | |
635 | unset($userdata->roleshortname); | |
636 | unset($userdata->rolename); | |
637 | unset($userdata->userid); | |
dfdaabd6 | 638 | $userdata->id = $rec->userid; |
e254aa34 | 639 | |
640 | // Make an array to hold the list of roles for this user | |
dfdaabd6 | 641 | $userdata->roles = array(); |
642 | $users[$rec->userid] = $userdata; | |
e254aa34 | 643 | } |
644 | // If user has a role... | |
dfdaabd6 | 645 | if (!is_null($rec->roleid)) { |
e254aa34 | 646 | // Create information about role if this is a new one |
dfdaabd6 | 647 | if (!array_key_exists($rec->roleid,$roles)) { |
648 | $roledata = new object(); | |
649 | $roledata->id = $rec->roleid; | |
650 | $roledata->shortname = $rec->roleshortname; | |
651 | if (array_key_exists($rec->roleid, $aliasnames)) { | |
652 | $roledata->name = $aliasnames[$rec->roleid]; | |
3540f2b3 | 653 | } else { |
dfdaabd6 | 654 | $roledata->name = $rec->rolename; |
3540f2b3 | 655 | } |
dfdaabd6 | 656 | $roledata->users = array(); |
657 | $roles[$roledata->id] = $roledata; | |
e254aa34 | 658 | } |
659 | // Record that user has role | |
660 | $users[$rec->userid]->roles[] = $roles[$rec->roleid]; | |
661 | } | |
662 | } | |
dfdaabd6 | 663 | $rs->close(); |
e254aa34 | 664 | |
665 | // Return false if there weren't any users | |
dfdaabd6 | 666 | if (count($users)==0) { |
e254aa34 | 667 | return false; |
668 | } | |
669 | ||
670 | // Add pseudo-role for multiple roles | |
dfdaabd6 | 671 | $roledata = new object(); |
672 | $roledata->name = get_string('multipleroles','role'); | |
673 | $roledata->users = array(); | |
674 | $roles['*'] = $roledata; | |
e254aa34 | 675 | |
676 | // Now we rearrange the data to store users by role | |
dfdaabd6 | 677 | foreach ($users as $userid=>$userdata) { |
678 | $rolecount = count($userdata->roles); | |
679 | if ($rolecount==0) { | |
e254aa34 | 680 | debugging("Unexpected: user $userid is missing roles"); |
681 | } else if($rolecount>1) { | |
dfdaabd6 | 682 | $roleid = '*'; |
e254aa34 | 683 | } else { |
dfdaabd6 | 684 | $roleid = $userdata->roles[0]->id; |
e254aa34 | 685 | } |
dfdaabd6 | 686 | $roles[$roleid]->users[$userid] = $userdata; |
e254aa34 | 687 | } |
688 | ||
689 | // Delete roles not used | |
dfdaabd6 | 690 | foreach ($roles as $key=>$roledata) { |
691 | if (count($roledata->users)===0) { | |
e254aa34 | 692 | unset($roles[$key]); |
693 | } | |
694 | } | |
695 | ||
696 | // Return list of roles containing their users | |
697 | return $roles; | |
698 | } | |
699 | ||
47d1ec41 | 700 | ?> |