forum: Portfolio save button was adding an additional '|' when no plugins
[moodle.git] / user / index.php
CommitLineData
f9903ed0 1<?PHP // $Id$
2
3// Lists all the users within a given course
4
cc038b47 5 require_once('../config.php');
68b38e8d 6 require_once($CFG->libdir.'/tablelib.php');
951b22a8 7
8 define('USER_SMALL_CLASS', 20); // Below this is considered small
9 define('USER_LARGE_CLASS', 200); // Above this is considered large
cc038b47 10 define('DEFAULT_PAGE_SIZE', 20);
36075e09 11 define('SHOW_ALL_PAGE_SIZE', 5000);
073af1a6 12 define('MODE_BRIEF', 0);
13 define('MODE_USERDETAILS', 1);
14 define('MODE_ENROLDETAILS', 2);
f9903ed0 15
cc038b47 16 $page = optional_param('page', 0, PARAM_INT); // which page to show
17 $perpage = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT); // how many per page
073af1a6 18 $mode = optional_param('mode', NULL); // use the MODE_ constants
5f9e296a 19 $accesssince = optional_param('accesssince',0,PARAM_INT); // filter by last access. -1 = never
ac17ef11 20 $search = optional_param('search','',PARAM_CLEAN);
5f9e296a 21 $roleid = optional_param('roleid', 0, PARAM_INT); // optional roleid, -1 means all site users on frontpage
e957cc26 22
5f9e296a 23 $contextid = optional_param('contextid', 0, PARAM_INT); // one of this or
24 $courseid = optional_param('id', 0, PARAM_INT); // this are required
f1e24e7a 25
e957cc26 26 if ($contextid) {
27 if (! $context = get_context_instance_by_id($contextid)) {
06e84d52 28 print_error('invalidcontext');
e957cc26 29 }
ce8c75ee 30 if (! $course = $DB->get_record('course', array('id'=>$context->instanceid))) {
06e84d52 31 print_error('invalidcourseid');
e957cc26 32 }
33 } else {
ce8c75ee 34 if (! $course = $DB->get_record('course', array('id'=>$courseid))) {
06e84d52 35 print_error('invalidcourseid');
e957cc26 36 }
37 if (! $context = get_context_instance(CONTEXT_COURSE, $course->id)) {
06e84d52 38 print_error('invalidcontext');
e957cc26 39 }
f9903ed0 40 }
87a13824 41 // not needed anymore
42 unset($contextid);
43 unset($courseid);
f9903ed0 44
224aa44a 45 require_login($course);
f9903ed0 46
1118434a 47 $systemcontext = get_context_instance(CONTEXT_SYSTEM);
165088f6 48 $frontpagectx = get_context_instance(CONTEXT_COURSE, SITEID);
224aa44a 49
165088f6 50 if ($context->id != $frontpagectx->id) {
b92adb86 51 require_capability('moodle/course:viewparticipants', $context);
165088f6 52 } else {
1118434a 53 require_capability('moodle/site:viewparticipants', $systemcontext);
5f9e296a 54 // override the default on frontpage
55 $roleid = optional_param('roleid', -1, PARAM_INT);
6d3c57f4 56 }
57
165088f6 58 /// front page course is different
6d3c57f4 59 $rolenames = array();
b373a751 60 $avoidroles = array();
6d3c57f4 61
62 if ($roles = get_roles_used_in_context($context, true)) {
0be6f678 63 // We should ONLY allow roles with moodle/course:view because otherwise we get little niggly issues
b373a751 64 // like MDL-8093
0be6f678 65 // We should further exclude "admin" users (those with "doanything" at site level) because
6d3c57f4 66 // Otherwise they appear in every participant list
67
b373a751 68 $canviewroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
1118434a 69 $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $systemcontext);
41d7209c 70
5f9e296a 71 if ($context->id == $frontpagectx->id) {
72 //we want admins listed on frontpage too
73 foreach ($doanythingroles as $dar) {
74 $canviewroles[$dar->id] = $dar;
75 }
76 $doanythingroles = array();
77 }
78
41d7209c 79 foreach ($roles as $role) {
b373a751 80 if (!isset($canviewroles[$role->id])) { // Avoid this role (eg course creator)
81 $avoidroles[] = $role->id;
82 unset($roles[$role->id]);
83 continue;
84 }
6d3c57f4 85 if (isset($doanythingroles[$role->id])) { // Avoid this role (ie admin)
b373a751 86 $avoidroles[] = $role->id;
6d3c57f4 87 unset($roles[$role->id]);
88 continue;
89 }
0150c561 90 $rolenames[$role->id] = strip_tags(role_get_name($role, $context)); // Used in menus etc later on
41d7209c 91 }
6d3c57f4 92 }
93
5f9e296a 94 if ($context->id == $frontpagectx->id and $CFG->defaultfrontpageroleid) {
95 // default frontpage role is assigned to all site users
96 unset($rolenames[$CFG->defaultfrontpageroleid]);
97 }
98
99 // no roles to display yet?
165088f6 100 // frontpage course is an exception, on the front page course we should display all users
101 if (empty($rolenames) && $context->id != $frontpagectx->id) {
294a176f 102 if (has_capability('moodle/role:assign', $context)) {
87a13824 103 redirect($CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id);
41d7209c 104 } else {
06e84d52 105 print_error('noparticipants');
41d7209c 106 }
107 }
108
cc038b47 109 add_to_log($course->id, 'user', 'view all', 'index.php?id='.$course->id, '');
f9903ed0 110
77c645df 111 $bulkoperations = has_capability('moodle/course:bulkmessaging', $context);
f1e24e7a 112
68b38e8d 113 $countries = get_list_of_countries();
114
cc038b47 115 $strnever = get_string('never');
68b38e8d 116
a59e5a1c 117 $datestring->year = get_string('year');
118 $datestring->years = get_string('years');
cc038b47 119 $datestring->day = get_string('day');
120 $datestring->days = get_string('days');
121 $datestring->hour = get_string('hour');
122 $datestring->hours = get_string('hours');
123 $datestring->min = get_string('min');
124 $datestring->mins = get_string('mins');
125 $datestring->sec = get_string('sec');
126 $datestring->secs = get_string('secs');
d578afc8 127
ff3caf30 128 if ($mode !== NULL) {
073af1a6 129 $mode = (int)$mode;
130 $SESSION->userindexmode = $mode;
ff3caf30 131 } else if (isset($SESSION->userindexmode)) {
073af1a6 132 $mode = (int)$SESSION->userindexmode;
ff3caf30 133 } else {
073af1a6 134 $mode = MODE_BRIEF;
ff3caf30 135 }
136
4cd0d3a0 137/// Check to see if groups are being used in this course
ff3caf30 138/// and if so, set $currentgroup to reflect the current group
139
ffc536af 140 $groupmode = groups_get_course_groupmode($course); // Groups are being used
141 $currentgroup = groups_get_course_group($course, true);
ff3caf30 142
cc038b47 143 if (!$currentgroup) { // To make some other functions work better later
144 $currentgroup = NULL;
145 }
ff3caf30 146
4bc162b7 147 $isseparategroups = ($course->groupmode == SEPARATEGROUPS and $course->groupmodeforce and
224aa44a 148 !has_capability('moodle/site:accessallgroups', $context));
2cb2ce61 149
0be6f678 150 if ($isseparategroups and (!$currentgroup) ) {
151 $navlinks = array();
152 $navlinks[] = array('name' => get_string('participants'), 'link' => null, 'type' => 'misc');
153 $navigation = build_navigation($navlinks);
154
155 print_header("$course->shortname: ".get_string('participants'), $course->fullname, $navigation, "", "", true, "&nbsp;", navmenu($course));
4cd0d3a0 156 print_heading(get_string("notingroup"));
ff3caf30 157 print_footer($course);
158 exit;
159 }
160
cc038b47 161 // Should use this variable so that we don't break stuff every time a variable is added or changed.
ffc536af 162 $baseurl = $CFG->wwwroot.'/user/index.php?contextid='.$context->id.'&amp;roleid='.$roleid.'&amp;id='.$course->id.'&amp;perpage='.$perpage.'&amp;accesssince='.$accesssince.'&amp;search='.s($search);
ff3caf30 163
164/// Print headers
2cb2ce61 165
0be6f678 166 $navlinks = array();
167 $navlinks[] = array('name' => get_string('participants'), 'link' => null, 'type' => 'misc');
168 $navigation = build_navigation($navlinks);
1242eb8f 169
0be6f678 170 print_header("$course->shortname: ".get_string('participants'), $course->fullname, $navigation, "", "", true, "&nbsp;", navmenu($course));
b373a751 171
224aa44a 172/// setting up tags
e957cc26 173 if ($course->id == SITEID) {
1242eb8f 174 $filtertype = 'site';
e957cc26 175 } else if ($course->id && !$currentgroup) {
1242eb8f 176 $filtertype = 'course';
e957cc26 177 $filterselect = $course->id;
1242eb8f 178 } else {
179 $filtertype = 'group';
180 $filterselect = $currentgroup;
181 }
182 $currenttab = 'participants';
183 $user = $USER;
1118434a 184 $userindexpage = true;
1242eb8f 185
186 require_once($CFG->dirroot .'/user/tabs.php');
187
188
3468d58a 189/// Get the hidden field list
224aa44a 190 if (has_capability('moodle/course:viewhiddenuserfields', $context)) {
3468d58a 191 $hiddenfields = array(); // teachers and admins are allowed to see everything
192 } else {
193 $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
194 }
195
bbbf2d40 196
ff3caf30 197/// Print settings and things in a table across the top
198
cc038b47 199 echo '<table class="controls" cellspacing="0"><tr>';
ff3caf30 200
a72784d3 201/// Print my course menus
7da0af9f 202 if ($mycourses = get_my_courses($USER->id)) {
203 echo '<td class="left">';
7da0af9f 204 $courselist = array();
205 foreach ($mycourses as $mycourse) {
364eef74 206 $courselist[$mycourse->id] = format_string($mycourse->shortname);
7da0af9f 207 }
1118434a 208 if (has_capability('moodle/site:viewparticipants', $systemcontext)) {
5f9e296a 209 unset($courselist[SITEID]);
210 $courselist = array(SITEID => format_string($SITE->shortname)) + $courselist;
211 }
87a13824 212 popup_form($CFG->wwwroot.'/user/index.php?roleid='.$roleid.'&amp;sifirst=&amp;silast=&amp;id=',
224aa44a 213 $courselist, 'courseform', $course->id, '', '', '', false, 'self', get_string('mycourses'));
7da0af9f 214 echo '</td>';
215 }
87a13824 216
9fffb691 217 echo '<td class="left">';
ffc536af 218 groups_print_course_menu($course, $baseurl);
9fffb691 219 echo '</td>';
ff3caf30 220
77c645df 221 // get minimum lastaccess for this course and display a dropbox to filter by lastaccess going back this far.
0749caef 222 // we need to make it diferently for normal courses and site course
223 if ($context->id != $frontpagectx->id) {
ce8c75ee 224 $minlastaccess = $DB->get_field_sql('SELECT min(timeaccess)
225 FROM {user_lastaccess}
226 WHERE courseid = ?
227 AND timeaccess != 0', array($course->id));
228 $lastaccess0exists = $DB->record_exists('user_lastaccess', array('courseid'=>$course->id, 'timeaccess'=>0));
0749caef 229 } else {
ce8c75ee 230 $minlastaccess = $DB->get_field_sql('SELECT min(lastaccess)
231 FROM {user}
232 WHERE lastaccess != 0');
233 $lastaccess0exists = $DB->record_exists('user', array('lastaccess'=>0));
0749caef 234 }
235
77c645df 236 $now = usergetmidnight(time());
237 $timeaccess = array();
87a13824 238
77c645df 239 // makes sense for this to go first.
240 $timeoptions[0] = get_string('selectperiod');
87a13824 241
77c645df 242 // days
243 for ($i = 1; $i < 7; $i++) {
244 if (strtotime('-'.$i.' days',$now) >= $minlastaccess) {
245 $timeoptions[strtotime('-'.$i.' days',$now)] = get_string('numdays','moodle',$i);
ca792680 246 }
77c645df 247 }
248 // weeks
249 for ($i = 1; $i < 10; $i++) {
250 if (strtotime('-'.$i.' weeks',$now) >= $minlastaccess) {
251 $timeoptions[strtotime('-'.$i.' weeks',$now)] = get_string('numweeks','moodle',$i);
ca792680 252 }
77c645df 253 }
87a13824 254 // months
77c645df 255 for ($i = 2; $i < 12; $i++) {
256 if (strtotime('-'.$i.' months',$now) >= $minlastaccess) {
257 $timeoptions[strtotime('-'.$i.' months',$now)] = get_string('nummonths','moodle',$i);
31b71336 258 }
31b71336 259 }
77c645df 260 // try a year
261 if (strtotime('-1 year',$now) >= $minlastaccess) {
262 $timeoptions[strtotime('-1 year',$now)] = get_string('lastyear');
263 }
87a13824 264
77c645df 265 if (!empty($lastaccess0exists)) {
266 $timeoptions[-1] = get_string('never');
87a13824 267 }
268
77c645df 269 if (count($timeoptions) > 1) {
270 echo '<td class="left">';
77c645df 271 $baseurl = preg_replace('/&amp;accesssince='.$accesssince.'/','',$baseurl);
224aa44a 272 popup_form($baseurl.'&amp;accesssince=',$timeoptions,'timeoptions',$accesssince, '', '', '', false, 'self', get_string('usersnoaccesssince'));
77c645df 273 echo '</td>';
274 }
87a13824 275
073af1a6 276 // Decide wheteher we will fetch extra enrolment/groups data.
277 //
278 // MODE_ENROLDETAILS is expensive, and only suitable where the listing is small
279 // (at or below DEFAULT_PAGE_SIZE) and $USER can enrol/unenrol
280 // (will take 1 extra DB query - 2 on Oracle)
281 //
06e84d52 282 if ($course->id != SITEID && $perpage <= DEFAULT_PAGE_SIZE
073af1a6 283 && has_capability('moodle/role:assign',$context)) {
284 $allowenroldetails=true;
285 } else {
286 $allowenroldetails=false;
287 }
288 if ($mode === MODE_ENROLDETAILS && !($allowenroldetails)) {
289 // conditions haven't been met - reset
290 $mode = MODE_BRIEF;
291 }
31b71336 292
cc038b47 293 echo '<td class="right">';
073af1a6 294 $formatmenu = array( '0' => get_string('brief'),
295 '1' => get_string('userdetails'));
296 if ($allowenroldetails) {
297 $formatmenu['2']= get_string('enroldetails');
298 }
299 popup_form($baseurl.'&amp;mode=', $formatmenu, 'formatmenu', $mode, '', '', '', false, 'self', get_string('userlist'));
ff3caf30 300 echo '</td></tr></table>';
301
224aa44a 302 if ($currentgroup and (!$isseparategroups or has_capability('moodle/site:accessallgroups', $context))) { /// Display info about the group
ffc536af 303 if ($group = groups_get_group($currentgroup)) {
87a13824 304 if (!empty($group->description) or (!empty($group->picture) and empty($group->hidepicture))) {
ff3caf30 305 echo '<table class="groupinfobox"><tr><td class="left side picture">';
306 print_group_picture($group, $course->id, true, false, false);
307 echo '</td><td class="content">';
308 echo '<h3>'.$group->name;
224aa44a 309 if (has_capability('moodle/course:managegroups', $context)) {
c4e953e6 310 echo '&nbsp;<a title="'.get_string('editgroupprofile').'" href="'.$CFG->wwwroot.'/group/group.php?id='.$group->id.'&amp;courseid='.$group->courseid.'">';
f3f7610c 311 echo '<img src="'.$CFG->pixpath.'/t/edit.gif" alt="'.get_string('editgroupprofile').'" />';
2c27cd19 312 echo '</a>';
313 }
ff3caf30 314 echo '</h3>';
315 echo format_text($group->description);
316 echo '</td></tr></table>';
317 }
318 }
319 }
320
77c645df 321 /// Define a table showing a list of users in the current role selection
322
1d40c70b 323 $tablecolumns = array('userpic', 'fullname');
d6cc2341 324 $tableheaders = array(get_string('userpic'), get_string('fullnameuser'));
073af1a6 325 if ($mode === MODE_BRIEF && !isset($hiddenfields['city'])) {
77c645df 326 $tablecolumns[] = 'city';
327 $tableheaders[] = get_string('city');
328 }
073af1a6 329 if ($mode === MODE_BRIEF && !isset($hiddenfields['country'])) {
77c645df 330 $tablecolumns[] = 'country';
331 $tableheaders[] = get_string('country');
332 }
333 if (!isset($hiddenfields['lastaccess'])) {
334 $tablecolumns[] = 'lastaccess';
335 $tableheaders[] = get_string('lastaccess');
336 }
337
338 if ($course->enrolperiod) {
339 $tablecolumns[] = 'timeend';
340 $tableheaders[] = get_string('enrolmentend');
341 }
342
073af1a6 343 if ($mode === MODE_ENROLDETAILS) {
664fe87f 344 $tablecolumns[] = 'roles';
345 $tableheaders[] = get_string('roles');
a32e05df 346 if ($groupmode != 0) {
347 $tablecolumns[] = 'groups';
348 $tableheaders[] = get_string('groups');
349 if (!empty($CFG->enablegroupings)) {
350 $tablecolumns[] = 'groupings';
351 $tableheaders[] = get_string('groupings', 'group');
352 }
664fe87f 353 }
354 }
355
77c645df 356 if ($bulkoperations) {
664fe87f 357 $tablecolumns[] = 'select';
77c645df 358 $tableheaders[] = get_string('select');
359 }
360
04186cd9 361 $table = new flexible_table('user-index-participants-'.$course->id);
77c645df 362
363 $table->define_columns($tablecolumns);
364 $table->define_headers($tableheaders);
365 $table->define_baseurl($baseurl);
0be6f678 366
77c645df 367 $table->sortable(true, 'lastaccess', SORT_DESC);
664fe87f 368 $table->no_sorting('roles');
369 $table->no_sorting('groups');
370 $table->no_sorting('groupings');
371 $table->no_sorting('select');
77c645df 372
373 $table->set_attribute('cellspacing', '0');
04186cd9 374 $table->set_attribute('id', 'participants');
77c645df 375 $table->set_attribute('class', 'generaltable generalbox');
376
377 $table->set_control_variables(array(
378 TABLE_VAR_SORT => 'ssort',
379 TABLE_VAR_HIDE => 'shide',
380 TABLE_VAR_SHOW => 'sshow',
381 TABLE_VAR_IFIRST => 'sifirst',
382 TABLE_VAR_ILAST => 'silast',
383 TABLE_VAR_PAGE => 'spage'
384 ));
385 $table->setup();
386
ce8c75ee 387 $params = array();
77c645df 388 // we are looking for all users with this role assigned in this context or higher
389 if ($usercontexts = get_parent_contexts($context)) {
390 $listofcontexts = '('.implode(',', $usercontexts).')';
391 } else {
1118434a 392 $listofcontexts = '('.$systemcontext->id.')'; // must be site
77c645df 393 }
5f9e296a 394 if ($roleid > 0) {
ce8c75ee 395 $selectrole = " AND r.roleid = :roleid ";
396 $params['roleid'] = $roleid;
77c645df 397 } else {
398 $selectrole = " ";
399 }
5f9e296a 400
165088f6 401 if ($context->id != $frontpagectx->id) {
5f2a203f 402 $select = 'SELECT DISTINCT u.id, u.username, u.firstname, u.lastname,
b6ac3623 403 u.email, u.city, u.country, u.picture,
404 u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
405 COALESCE(ul.timeaccess, 0) AS lastaccess,
406 r.hidden,
407 ctx.id AS ctxid, ctx.path AS ctxpath,
5f9e296a 408 ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel ';
165088f6 409 $select .= $course->enrolperiod?', r.timeend ':'';
410 } else {
5f9e296a 411 if ($roleid >= 0) {
412 $select = 'SELECT u.id, u.username, u.firstname, u.lastname,
413 u.email, u.city, u.country, u.picture,
414 u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
415 u.lastaccess, r.hidden,
416 ctx.id AS ctxid, ctx.path AS ctxpath,
417 ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel ';
418 } else {
419 $select = 'SELECT u.id, u.username, u.firstname, u.lastname,
420 u.email, u.city, u.country, u.picture,
421 u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
422 u.lastaccess,
423 ctx.id AS ctxid, ctx.path AS ctxpath,
424 ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel ';
425 }
165088f6 426 }
b6ac3623 427
5f9e296a 428 if ($context->id != $frontpagectx->id or $roleid >= 0) {
ce8c75ee 429 $from = "FROM {user} u
430 LEFT OUTER JOIN {context} ctx
431 ON (u.id=ctx.instanceid AND ctx.contextlevel = ".CONTEXT_USER.")
432 JOIN {role_assignments} r
433 ON u.id=r.userid
434 LEFT OUTER JOIN {user_lastaccess} ul
435 ON (r.userid=ul.userid and ul.courseid = :courseid) ";
436 $params['courseid'] = $course->id;
165088f6 437 } else {
5f9e296a 438 // on frontpage and we want all registered users
ce8c75ee 439 $from = "FROM {user} u
440 LEFT OUTER JOIN {context} ctx
441 ON (u.id=ctx.instanceid AND ctx.contextlevel = ".CONTEXT_USER.") ";
165088f6 442 }
5f9e296a 443
0be6f678 444 $hiddensql = has_capability('moodle/role:viewhiddenassigns', $context)? '':' AND r.hidden = 0 ';
c0527567 445
b373a751 446 // exclude users with roles we are avoiding
447 if ($avoidroles) {
789154a6 448 $adminroles = 'AND r.roleid NOT IN (';
b373a751 449 $adminroles .= implode(',', $avoidroles);
c0527567 450 $adminroles .= ')';
451 } else {
452 $adminroles = '';
453 }
0be6f678 454
1e248b44 455 // join on 2 conditions
456 // otherwise we run into the problem of having records in ul table, but not relevant course
457 // and user record is not pulled out
5f9e296a 458
165088f6 459 if ($context->id != $frontpagectx->id) {
460 $where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
ce8c75ee 461 AND u.deleted = 0 $selectrole
462 AND (ul.courseid = $course->id OR ul.courseid IS NULL)
463 AND u.username != 'guest'
464 $adminroles
465 $hiddensql ";
0749caef 466 $where .= get_course_lastaccess_sql($accesssince);
165088f6 467 } else {
5f9e296a 468 if ($roleid >= 0) {
469 $where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
ce8c75ee 470 AND u.deleted = 0 $selectrole
471 AND u.username != 'guest'";
472 $where .= get_user_lastaccess_sql($accesssince);
5f9e296a 473 } else {
474 $where = "WHERE u.deleted = 0
475 AND u.username != 'guest'";
476 $where .= get_user_lastaccess_sql($accesssince);
477 }
165088f6 478 }
77c645df 479 $wheresearch = '';
480
481 if (!empty($search)) {
ce8c75ee 482 $LIKE = $DB->sql_ilike();
483 $fullname = $DB->sql_fullname('u.firstname','u.lastname');
484 $wheresearch .= " AND ($fullname $LIKE :search1 OR email $LIKE :search2 OR idnumber $LIKE :search3) ";
485 $params['search1'] = "%$search%";
486 $params['search2'] = "%$search%";
487 $params['search3'] = "%$search%";
77c645df 488 }
489
490 if ($currentgroup) { // Displaying a group by choice
491 // FIX: TODO: This will not work if $currentgroup == 0, i.e. "those not in a group"
ce8c75ee 492 $from .= 'LEFT JOIN {groups_members} gm ON u.id = gm.userid ';
493 $where .= ' AND gm.groupid = :currentgroup';
d559bdc0 494 $params['currentgroup'] = $currentgroup;
77c645df 495 }
496
ce8c75ee 497 $totalcount = $DB->count_records_sql("SELECT COUNT(distinct u.id) $from $where", $params); // Each user could have > 1 role
77c645df 498
499 if ($table->get_sql_where()) {
500 $where .= ' AND '.$table->get_sql_where();
501 }
502
1f807bc4 503 /// Always add r.hidden to sort in order to guarantee hiddens to "win"
504 /// in the resolution of duplicates later - MDL-13935
4d93bc9e 505 /// Only exception is frontpage that doesn't have such r.hidden info
506 /// because it retrieves ALL users (without role checking) - MDL-14034
77c645df 507 if ($table->get_sql_sort()) {
4d93bc9e 508 $sort = ' ORDER BY '.$table->get_sql_sort();
5f9e296a 509 if ($context->id != $frontpagectx->id or $roleid >= 0) {
4d93bc9e 510 $sort .= ', r.hidden DESC';
511 }
77c645df 512 } else {
4d93bc9e 513 $sort = '';
5f9e296a 514 if ($context->id != $frontpagectx->id or $roleid >= 0) {
4d93bc9e 515 $sort .= ' ORDER BY r.hidden DESC';
516 }
77c645df 517 }
518
ce8c75ee 519 $matchcount = $DB->count_records_sql("SELECT COUNT(distinct u.id) $from $where $wheresearch", $params);
77c645df 520
281917e9 521 $table->initialbars(true);
77c645df 522 $table->pagesize($perpage, $matchcount);
523
ce8c75ee 524 $userlist = $DB->get_recordset_sql("$select $from $where $wheresearch $sort", $params,
77c645df 525 $table->get_page_start(), $table->get_page_size());
3e219038 526
664fe87f 527 //
528 // The SELECT behind get_participants_extra() is cheaper if we pass an array
529 // if IDs. We could pass the SELECT we did before (with the limit bits - tricky!)
530 // but this is much cheaper. And in any case, it is only doable with limited numbers
531 // of rows anyway. On a large course it will explode badly...
532 //
073af1a6 533 if ($mode===MODE_ENROLDETAILS) {
5f772e4a 534 if ($context->id != $frontpagectx->id) {
535 $userids = $DB->get_fieldset_sql("SELECT DISTINCT u.id $from $where $wheresearch", $params,
536 $table->get_page_start(), $table->get_page_size());
537 } else {
538 $userids = $DB->get_fieldset_sql("SELECT u.id $from $where $wheresearch", $params,
539 $table->get_page_start(), $table->get_page_size());
540 }
664fe87f 541 $userlist_extra = get_participants_extra($userids, $avoidroles, $course, $context);
664fe87f 542 }
543
5f9e296a 544 if ($context->id == $frontpagectx->id) {
545 $strallsiteusers = get_string('allsiteusers', 'role');
546 if ($CFG->defaultfrontpageroleid) {
ce8c75ee 547 if ($fprole = $DB->get_record('role', array('id'=>$CFG->defaultfrontpageroleid))) {
5f9e296a 548 $fprole = role_get_name($fprole, $frontpagectx);
549 $strallsiteusers = "$strallsiteusers ($fprole)";
550 }
551 }
552 $rolenames = array(-1 => $strallsiteusers) + $rolenames;
553 }
3e219038 554
5f9e296a 555 /// If there are multiple Roles in the course, then show a drop down menu for switching
6d3c57f4 556 if (count($rolenames) > 1) {
77c645df 557 echo '<div class="rolesform">';
5f9e296a 558 echo '<label for="rolesform_jump">'.get_string('currentrole', 'role').'&nbsp;</label>';
559 if ($context->id != $frontpagectx->id) {
560 $rolenames = array(0 => get_string('all')) + $rolenames;
561 } else {
562 if (!$CFG->defaultfrontpageroleid) {
563 // we do not want "All users with role" - we already have all users in defualt frontpage role option
564 $rolenames = array(0 => get_string('userswithrole', 'role')) + $rolenames;
565 }
566 }
6d3c57f4 567 popup_form("$CFG->wwwroot/user/index.php?contextid=$context->id&amp;sifirst=&amp;silast=&amp;roleid=", $rolenames,
77c645df 568 'rolesform', $roleid, '');
0f870a49 569 echo '</div>';
5f9e296a 570
571 } else if (count($rolenames) == 1) {
572 // when all users with the same role - print its name
573 echo '<div class="rolesform">';
574 echo get_string('role').': ';
575 $rolename = reset($rolenames);
576 echo $rolename;
577 echo '</div>';
77c645df 578 }
3e219038 579
5f9e296a 580 if ($roleid > 0) {
ce8c75ee 581 if (!$currentrole = $DB->get_record('role', array('id'=>$roleid))) {
06e84d52 582 print_error('invalidroleid');
e957cc26 583 }
b90e2f19 584 $a->number = $totalcount;
ed61510b 585 // MDL-12217, use course specific rolename
586 if (isset($rolenames[$currentrole->id])){
587 $a->role = $rolenames[$currentrole->id];
5f9e296a 588 }else{
ed61510b 589 $a->role = $currentrole->name;//safety net
590 }
5f9e296a 591 $heading = format_string(get_string('xuserswiththerole', 'role', $a));
f642a21a 592
593 if ($currentgroup and $group) {
594 $a->group = $group->name;
5f9e296a 595 $heading .= ' ' . format_string(get_string('ingroup', 'role', $a));
596 }
f642a21a 597
598 if ($accesssince) {
599 $a->timeperiod = $timeoptions[$accesssince];
5f9e296a 600 $heading .= ' ' . format_string(get_string('inactiveformorethan', 'role', $a));
f642a21a 601 }
602
603 $heading .= ": $a->number";
d02eeded 604 if (user_can_assign($context, $roleid)) {
3e219038 605 $heading .= ' <a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?roleid='.$roleid.'&amp;contextid='.$context->id.'">';
0d905d9f 606 $heading .= '<img src="'.$CFG->pixpath.'/i/edit.gif" class="icon" alt="" /></a>';
3e219038 607 }
608 print_heading($heading, 'center', 3);
3e219038 609 } else {
5f9e296a 610 if ($course->id != SITEID && has_capability('moodle/role:assign', $context)) {
15234a92 611 $editlink = ' <a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id.'">';
612 $editlink .= '<img src="'.$CFG->pixpath.'/i/edit.gif" class="icon" alt="" /></a>';
613 } else {
614 $editlink = '';
615 }
5f9e296a 616 if ($course->id == SITEID and $roleid < 0) {
617 $strallparticipants = get_string('allsiteusers', 'role');
618 } else {
619 $strallparticipants = get_string('allparticipants');
620 }
23f5ee25 621 if ($matchcount < $totalcount) {
5f9e296a 622 print_heading($strallparticipants.': '.$matchcount.'/'.$totalcount . $editlink, '', 3);
23f5ee25 623 } else {
5f9e296a 624 print_heading($strallparticipants.': '.$matchcount . $editlink, '', 3);
23f5ee25 625 }
3e219038 626 }
3e219038 627
77c645df 628
629 if ($bulkoperations) {
630 echo '
8430912a 631 <script type="text/javascript">
5f60ed9b 632 //<![CDATA[
77c645df 633 function checksubmit(form) {
634 var destination = form.formaction.options[form.formaction.selectedIndex].value;
635 if (destination == "" || !checkchecked(form)) {
636 form.formaction.selectedIndex = 0;
637 return false;
638 } else {
639 return true;
640 }
ee4a52c5 641 }
77c645df 642
643 function checkchecked(form) {
644 var inputs = document.getElementsByTagName(\'INPUT\');
645 var checked = false;
646 inputs = filterByParent(inputs, function() {return form;});
647 for(var i = 0; i < inputs.length; ++i) {
648 if (inputs[i].type == \'checkbox\' && inputs[i].checked) {
649 checked = true;
650 }
ee4a52c5 651 }
77c645df 652 return checked;
653 }
5f60ed9b 654 //]]>
77c645df 655 </script>
656 ';
c1138797 657 echo '<form action="action_redir.php" method="post" id="participantsform" onsubmit="return checksubmit(this);">';
658 echo '<div>';
77c645df 659 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
838c7d29 660 echo '<input type="hidden" name="returnto" value="'.s(me()).'" />';
77c645df 661 }
662
663 if ($CFG->longtimenosee > 0 && $CFG->longtimenosee < 1000 && $totalcount > 0) {
664 echo '<p id="longtimenosee">('.get_string('unusedaccounts', '', $CFG->longtimenosee).')</p>';
665 }
666
073af1a6 667 if ($mode===MODE_USERDETAILS) { // Print simple listing
77c645df 668 if ($totalcount < 1) {
04186cd9 669 print_heading(get_string('nothingtodisplay'));
77c645df 670 } else {
671 if ($totalcount > $perpage) {
672
673 $firstinitial = $table->get_initial_first();
674 $lastinitial = $table->get_initial_last();
675 $strall = get_string('all');
676 $alpha = explode(',', get_string('alphabet'));
677
678 // Bar of first initials
679
680 echo '<div class="initialbar firstinitial">'.get_string('firstname').' : ';
681 if(!empty($firstinitial)) {
682 echo '<a href="'.$baseurl.'&amp;sifirst=">'.$strall.'</a>';
683 } else {
684 echo '<strong>'.$strall.'</strong>';
685 }
686 foreach ($alpha as $letter) {
687 if ($letter == $firstinitial) {
688 echo ' <strong>'.$letter.'</strong>';
ee4a52c5 689 } else {
77c645df 690 echo ' <a href="'.$baseurl.'&amp;sifirst='.$letter.'">'.$letter.'</a>';
ee4a52c5 691 }
ee4a52c5 692 }
77c645df 693 echo '</div>';
694
695 // Bar of last initials
696
697 echo '<div class="initialbar lastinitial">'.get_string('lastname').' : ';
698 if(!empty($lastinitial)) {
699 echo '<a href="'.$baseurl.'&amp;silast=">'.$strall.'</a>';
700 } else {
701 echo '<strong>'.$strall.'</strong>';
702 }
703 foreach ($alpha as $letter) {
704 if ($letter == $lastinitial) {
705 echo ' <strong>'.$letter.'</strong>';
706 } else {
707 echo ' <a href="'.$baseurl.'&amp;silast='.$letter.'">'.$letter.'</a>';
ee4a52c5 708 }
709 }
77c645df 710 echo '</div>';
711
712 print_paging_bar($matchcount, intval($table->get_page_start() / $perpage), $perpage, $baseurl.'&amp;', 'spage');
713 }
714
715 if ($matchcount > 0) {
1f807bc4 716 $usersprinted = array();
ce8c75ee 717 foreach ($userlist as $user) {
1f807bc4 718 if (in_array($user->id, $usersprinted)) { /// Prevent duplicates by r.hidden - MDL-13935
719 continue;
720 }
721 $usersprinted[] = $user->id; /// Add new user to the array of users printed
722
b6ac3623 723 $user = make_context_subobj($user);
04186cd9 724 print_user($user, $course, $bulkoperations);
ee4a52c5 725 }
77c645df 726
727 } else {
728 print_heading(get_string('nothingtodisplay'));
ee4a52c5 729 }
730 }
77c645df 731
732 } else {
733 $countrysort = (strpos($sort, 'country') !== false);
734 $timeformat = get_string('strftimedate');
3997cb40 735
736
03cedd62 737 if ($userlist) {
664fe87f 738
739 // only show the plugin if multiple enrolment plugins
740 // are enabled...
741 if (strpos($CFG->enrol_plugins_enabled, ',')=== false) {
742 $showenrolplugin = true;
743 } else {
744 $showenrolplugin = false;
745 }
1f807bc4 746
747 $usersprinted = array();
ce8c75ee 748 foreach ($userlist as $user) {
1f807bc4 749 if (in_array($user->id, $usersprinted)) { /// Prevent duplicates by r.hidden - MDL-13935
750 continue;
751 }
752 $usersprinted[] = $user->id; /// Add new user to the array of users printed
753
b6ac3623 754 $user = make_context_subobj($user);
13d1f5a6 755 if ( !empty($user->hidden) ) {
3997cb40 756 // if the assignment is hidden, display icon
68c85775 757 $hidden = " <img src=\"{$CFG->pixpath}/t/show.gif\" title=\"".get_string('userhashiddenassignments', 'role')."\" alt=\"".get_string('hiddenassign')."\" class=\"hide-show-image\"/>";
3997cb40 758 } else {
0be6f678 759 $hidden = '';
3997cb40 760 }
0be6f678 761
04186cd9 762 if ($user->lastaccess) {
763 $lastaccess = format_time(time() - $user->lastaccess, $datestring);
77c645df 764 } else {
765 $lastaccess = $strnever;
766 }
767
04186cd9 768 if (empty($user->country)) {
77c645df 769 $country = '';
770
771 } else {
772 if($countrysort) {
04186cd9 773 $country = '('.$user->country.') '.$countries[$user->country];
ee4a52c5 774 }
775 else {
04186cd9 776 $country = $countries[$user->country];
ee4a52c5 777 }
77c645df 778 }
0be6f678 779
b6ac3623 780 if (!isset($user->context)) {
781 $usercontext = get_context_instance(CONTEXT_USER, $user->id);
782 } else {
783 $usercontext = $user->context;
784 }
0be6f678 785
b08261a1 786 if ($piclink = ($USER->id == $user->id || has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext))) {
22ae509e 787 $profilelink = '<strong><a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$course->id.'">'.fullname($user).'</a></strong>';
788 } else {
0be6f678 789 $profilelink = '<strong>'.fullname($user).'</strong>';
22ae509e 790 }
0be6f678 791
77c645df 792 $data = array (
a5d81e5e 793 print_user_picture($user, $course->id, $user->picture, false, true, $piclink),
13d1f5a6 794 $profilelink . $hidden);
22ae509e 795
073af1a6 796 if ($mode === MODE_BRIEF && !isset($hiddenfields['city'])) {
04186cd9 797 $data[] = $user->city;
77c645df 798 }
073af1a6 799 if ($mode === MODE_BRIEF && !isset($hiddenfields['country'])) {
77c645df 800 $data[] = $country;
801 }
802 if (!isset($hiddenfields['lastaccess'])) {
803 $data[] = $lastaccess;
804 }
805 if ($course->enrolperiod) {
04186cd9 806 if ($user->timeend) {
807 $data[] = userdate($user->timeend, $timeformat);
77c645df 808 } else {
809 $data[] = get_string('unlimited');
ee4a52c5 810 }
ee4a52c5 811 }
664fe87f 812
813 if (isset($userlist_extra) && isset($userlist_extra[$user->id])) {
814 $ras = $userlist_extra[$user->id]['ra'];
815 $rastring = '';
816 foreach ($ras AS $key=>$ra) {
817 $rolename = $rolenames [ $ra['roleid'] ] ;
818 if ($ra['ctxlevel'] == CONTEXT_COURSECAT) {
073af1a6 819 $rastring .= $rolename. ' @ ' . '<a href="'.$CFG->wwwroot.'/course/category.php?id='.$ra['ctxinstanceid'].'">'.s($ra['ccname']).'</a>';
664fe87f 820 } elseif ($ra['ctxlevel'] == CONTEXT_SYSTEM) {
073af1a6 821 $rastring .= $rolename. ' - ' . get_string('globalrole','role');
664fe87f 822 } else {
823 $rastring .= $rolename;
824 }
825 if ($showenrolplugin) {
826 $rastring .= '<br />';
827 } else {
828 $rastring .= ' ('. $ra['enrolplugin'] .')<br />';
829 }
830 }
06e84d52 831 $data[] = $rastring;
a32e05df 832 if ($groupmode != 0) {
664fe87f 833 // htmlescape with s() and implode the array
834 $data[] = implode(', ', array_map('s',$userlist_extra[$user->id]['group']));
a32e05df 835 if (!empty($CFG->enablegroupings)) {
836 $data[] = implode(', ', array_map('s', $userlist_extra[$user->id]['gping']));
837 }
664fe87f 838 }
664fe87f 839 }
840
77c645df 841 if ($bulkoperations) {
04186cd9 842 $data[] = '<input type="checkbox" name="user'.$user->id.'" />';
77c645df 843 }
844 $table->add_data($data);
ee4a52c5 845
ee4a52c5 846 }
ee4a52c5 847 }
b90e2f19 848
77c645df 849 $table->print_html();
850
851 }
852
853 if ($bulkoperations) {
c1138797 854 echo '<br /><div class="buttons">';
77c645df 855 echo '<input type="button" onclick="checkall()" value="'.get_string('selectall').'" /> ';
856 echo '<input type="button" onclick="checknone()" value="'.get_string('deselectall').'" /> ';
82d561ee 857 $displaylist = array();
576ad290 858 $displaylist['messageselect.php'] = get_string('messageselectadd');
90658eef 859 if (!empty($CFG->enablenotes) && has_capability('moodle/notes:manage', $context) && $context->id != $frontpagectx->id) {
eca3af25 860 $displaylist['addnote.php'] = get_string('addnewnote', 'notes');
861 $displaylist['groupaddnote.php'] = get_string('groupaddnewnote', 'notes');
862 }
576ad290 863
165088f6 864 if ($context->id != $frontpagectx->id) {
865 $displaylist['extendenrol.php'] = get_string('extendenrol');
866 $displaylist['groupextendenrol.php'] = get_string('groupextendenrol');
867 }
0be6f678 868
77c645df 869 helpbutton("participantswithselectedusers", get_string("withselectedusers"));
c1138797 870 choose_from_menu ($displaylist, "formaction", "", get_string("withselectedusers"), "if(checksubmit(this.form))this.form.submit();", "");
70ce923e 871 echo '<input type="hidden" name="id" value="'.$course->id.'" />';
cab6762b 872 echo '<div id="noscriptparticipantsform" style="display: inline;">';
873 echo '<input type="submit" value="'.get_string('ok').'" /></div>';
874 echo '<script type="text/javascript">'.
875 "\n//<![CDATA[\n".
876 'document.getElementById("noscriptparticipantsform").style.display = "none";'.
877 "\n//]]>\n".'</script>';
c1138797 878 echo '</div>';
879 echo '</div>';
880 echo '</form>';
d88c5043 881
77c645df 882 }
b90e2f19 883
77c645df 884 if ($bulkoperations && $totalcount > ($perpage*3)) {
4e7b349e 885 echo '<form action="index.php"><div><input type="hidden" name="id" value="'.$course->id.'" />'.get_string('search').':&nbsp;'."\n";
3593af19 886 echo '<input type="text" name="search" value="'.s($search).'" />&nbsp;<input type="submit" value="'.get_string('search').'" /></div></form>'."\n";
77c645df 887 }
b90e2f19 888
a2c4671e 889 $perpageurl = preg_replace('/&amp;perpage=\d*/','', $baseurl);
77c645df 890 if ($perpage == SHOW_ALL_PAGE_SIZE) {
a2c4671e 891 echo '<div id="showall"><a href="'.$perpageurl.'&amp;perpage='.DEFAULT_PAGE_SIZE.'">'.get_string('showperpage', '', DEFAULT_PAGE_SIZE).'</a></div>';
77c645df 892
893 } else if ($matchcount > 0 && $perpage < $matchcount) {
a2c4671e 894 echo '<div id="showall"><a href="'.$perpageurl.'&amp;perpage='.SHOW_ALL_PAGE_SIZE.'">'.get_string('showall', '', $matchcount).'</a></div>';
b90e2f19 895 }
77c645df 896
cc038b47 897 print_footer($course);
f9903ed0 898
03cedd62 899 if ($userlist) {
ce8c75ee 900 $userlist->close();
03cedd62 901 }
77c645df 902
903
0749caef 904function get_course_lastaccess_sql($accesssince='') {
31b71336 905 if (empty($accesssince)) {
906 return '';
907 }
908 if ($accesssince == -1) { // never
dfe60358 909 return ' AND ul.timeaccess = 0';
31b71336 910 } else {
0749caef 911 return ' AND ul.timeaccess != 0 AND ul.timeaccess < '.$accesssince;
912 }
913}
914
915function get_user_lastaccess_sql($accesssince='') {
916 if (empty($accesssince)) {
917 return '';
918 }
919 if ($accesssince == -1) { // never
920 return ' AND u.lastaccess = 0';
921 } else {
922 return ' AND u.lastaccess != 0 AND u.lastaccess < '.$accesssince;
31b71336 923 }
924}
925
664fe87f 926function get_participants_extra ($userids, $avoidroles, $course, $context) {
ce8c75ee 927 global $CFG, $DB;
664fe87f 928
929 if (count($userids) === 0 || count($avoidroles) === 0) {
930 return array();
931 }
932
ce8c75ee 933 $params = array();
934
664fe87f 935 $userids = implode(',', $userids);
936
937 // turn the path into a list of context ids
938 $contextids = substr($context->path, 1); // kill leading slash
939 $contextids = str_replace('/', ',', $contextids);;
940
941 if (count($avoidroles) > 0) {
942 $avoidroles = implode(',', $avoidroles);
943 $avoidrolescond = " AND ra.roleid NOT IN ($avoidroles) ";
944 } else {
945 $avoidrolescond = '';
946 }
947
948 if (!empty($CFG->enablegroupings)) {
ce8c75ee 949 $gpjoin = "LEFT OUTER JOIN {groupings_groups} gpg
950 ON gpg.groupid=g.id
951 LEFT OUTER JOIN {groupings} gp
952 ON (gp.courseid={$course->id} AND gp.id=gpg.groupingid)";
664fe87f 953 $gpselect = ',gp.id AS gpid, gp.name AS gpname ';
954 } else {
955 $gpjoin = '';
956 $gpselect = '';
957 }
958
959 // Note: this returns strange redundant rows, perhaps
960 // due to the multiple OUTER JOINs. If we can tweak the
961 // JOINs to avoid it ot
06e84d52 962 $sql = "SELECT DISTINCT ra.userid,
963 ctx.id AS ctxid, ctx.path AS ctxpath, ctx.depth AS ctxdepth,
664fe87f 964 ctx.contextlevel AS ctxlevel, ctx.instanceid AS ctxinstanceid,
06e84d52 965 cc.name AS ccname,
664fe87f 966 ra.roleid AS roleid,
967 ra.enrol AS enrolplugin,
968 g.id AS gid, g.name AS gname
969 $gpselect
ce8c75ee 970 FROM {role_assignments} ra
971 JOIN {context} ctx
972 ON (ra.contextid=ctx.id)
973 LEFT JOIN {course_categories} cc
974 ON (ctx.contextlevel=40 AND ctx.instanceid=cc.id)
664fe87f 975
976 /* only if groups active */
ce8c75ee 977 LEFT JOIN {groups_members} gm
978 ON (ra.userid=gm.userid)
979 LEFT JOIN {groups} g
980 ON (gm.groupid=g.id AND g.courseid={$course->id})
664fe87f 981 /* and if groupings is enabled... */
982 $gpjoin
983
06e84d52 984 WHERE ra.userid IN ( $userids )
985 AND ra.contextid in ( $contextids )
ce8c75ee 986 $avoidrolescond
664fe87f 987
ce8c75ee 988 ORDER BY ra.userid, ctx.depth DESC";
664fe87f 989
ce8c75ee 990 $rs = $DB->get_recordset_sql($sql, $params);
664fe87f 991 $extra = array();
992
993 // Data structure -
994 // $extra [ $userid ] [ 'group' ] [ $groupid => 'group name']
995 // [ 'gping' ] [ $gpingid => 'gping name']
996 // [ 'ra' ] [ [ "$ctxid:$roleid" => [ctxid => $ctxid
06e84d52 997 // ctxdepth => $ctxdepth,
664fe87f 998 // ctxpath => $ctxpath,
999 // ctxname => 'name' (categories only)
06e84d52 1000 // ctxinstid =>
664fe87f 1001 // roleid => $roleid
1002 // enrol => $pluginname
1003 //
1004 // Might be interesting to add to RA timestart, timeend, timemodified,
1005 // and modifierid (with an outer join to mdl_user!
1006 //
1007
ce8c75ee 1008 foreach ($rs as $rec) {
664fe87f 1009 $userid = $rec->userid;
1010
1011 // Prime an initial user rec...
1012 if (!isset($extra[$userid])) {
1013 $extra[$userid] = array( 'group' => array(),
1014 'gping' => array(),
1015 'ra' => array() );
1016 }
1017
1018 if (!empty($rec->gid)) {
1019 $extra[$userid]['group'][$rec->gid]= $rec->gname;
1020 }
1021 if (!empty($rec->gpid)) {
1022 $extra[$userid]['gping'][$rec->gpid]= $rec->gpname;
1023 }
1024 $rakey = $rec->ctxid . ':' . $rec->roleid;
1025 if (!isset($extra[$userid]['ra'][$rakey])) {
1026 $extra[$userid]['ra'][$rakey] = array('ctxid' => $rec->ctxid,
1027 'ctxlevel' => $rec->ctxlevel,
1028 'ctxinstanceid' => $rec->ctxinstanceid,
1029 'ccname' => $rec->ccname,
1030 'roleid' => $rec->roleid,
1031 'enrolplugin' => $rec->enrolplugin);
1032
1033 }
1034 }
ce8c75ee 1035 $rs->close();
664fe87f 1036 return $extra;
1037
1038}
1039
f9903ed0 1040?>