MDL-18293 removing unused error strings (now replaced by exceptions)
[moodle.git] / group / lib.php
CommitLineData
f3f7610c
ML
1<?php
2/**
ddff2fa8 3 * Extra library for groups and groupings.
f3f7610c
ML
4 *
5 * @copyright &copy; 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 */
23function 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 */
61function 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 93function 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 */
124function 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 147function 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 */
176function 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 194function 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 231function 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 268function 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 */
307function 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 329function 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 366function 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 */
402function 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 445function 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 */
514function 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 */
533function 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 */
552function 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 576function 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 613function 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?>