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