Fix a possible race condition in the PaintWeb DML code.
[moodle/mihaisucan.git] / user / index.php
blob04354cdf16c94dfdc35025530698376a1a664e92
1 <?PHP // $Id$
3 // Lists all the users within a given course
5 require_once('../config.php');
6 require_once($CFG->libdir.'/tablelib.php');
8 define('USER_SMALL_CLASS', 20); // Below this is considered small
9 define('USER_LARGE_CLASS', 200); // Above this is considered large
10 define('DEFAULT_PAGE_SIZE', 20);
11 define('SHOW_ALL_PAGE_SIZE', 5000);
13 $page = optional_param('page', 0, PARAM_INT); // which page to show
14 $perpage = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT); // how many per page
15 $mode = optional_param('mode', NULL); // '0' for less details, '1' for more
16 $accesssince = optional_param('accesssince',0,PARAM_INT); // filter by last access. -1 = never
17 $search = optional_param('search','',PARAM_CLEAN);
18 $roleid = optional_param('roleid', 0, PARAM_INT); // optional roleid, -1 means all site users on frontpage
20 $contextid = optional_param('contextid', 0, PARAM_INT); // one of this or
21 $courseid = optional_param('id', 0, PARAM_INT); // this are required
23 if ($contextid) {
24 if (! $context = get_context_instance_by_id($contextid)) {
25 error("Context ID is incorrect");
27 if (! $course = get_record('course', 'id', $context->instanceid)) {
28 error("Course ID is incorrect");
30 } else {
31 if (! $course = get_record('course', 'id', $courseid)) {
32 error("Course ID is incorrect");
34 if (! $context = get_context_instance(CONTEXT_COURSE, $course->id)) {
35 error("Context ID is incorrect");
38 // not needed anymore
39 unset($contextid);
40 unset($courseid);
42 require_login($course);
44 $sitecontext = get_context_instance(CONTEXT_SYSTEM);
45 $frontpagectx = get_context_instance(CONTEXT_COURSE, SITEID);
47 if ($context->id != $frontpagectx->id) {
48 require_capability('moodle/course:viewparticipants', $context);
49 } else {
50 require_capability('moodle/site:viewparticipants', $sitecontext);
51 // override the default on frontpage
52 $roleid = optional_param('roleid', -1, PARAM_INT);
55 /// front page course is different
56 $rolenames = array();
57 $avoidroles = array();
59 if ($roles = get_roles_used_in_context($context, true)) {
60 // We should ONLY allow roles with moodle/course:view because otherwise we get little niggly issues
61 // like MDL-8093
62 // We should further exclude "admin" users (those with "doanything" at site level) because
63 // Otherwise they appear in every participant list
65 $canviewroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
66 $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext);
68 if ($context->id == $frontpagectx->id) {
69 //we want admins listed on frontpage too
70 foreach ($doanythingroles as $dar) {
71 $canviewroles[$dar->id] = $dar;
73 $doanythingroles = array();
76 foreach ($roles as $role) {
77 if (!isset($canviewroles[$role->id])) { // Avoid this role (eg course creator)
78 $avoidroles[] = $role->id;
79 unset($roles[$role->id]);
80 continue;
82 if (isset($doanythingroles[$role->id])) { // Avoid this role (ie admin)
83 $avoidroles[] = $role->id;
84 unset($roles[$role->id]);
85 continue;
87 $rolenames[$role->id] = strip_tags(role_get_name($role, $context)); // Used in menus etc later on
91 if ($context->id == $frontpagectx->id and $CFG->defaultfrontpageroleid) {
92 // default frontpage role is assigned to all site users
93 unset($rolenames[$CFG->defaultfrontpageroleid]);
96 // no roles to display yet?
97 // frontpage course is an exception, on the front page course we should display all users
98 if (empty($rolenames) && $context->id != $frontpagectx->id) {
99 if (has_capability('moodle/role:assign', $context)) {
100 redirect($CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id);
101 } else {
102 error ('No participants found for this course');
106 add_to_log($course->id, 'user', 'view all', 'index.php?id='.$course->id, '');
108 $bulkoperations = has_capability('moodle/course:bulkmessaging', $context);
110 $countries = get_list_of_countries();
112 $strnever = get_string('never');
114 $datestring->year = get_string('year');
115 $datestring->years = get_string('years');
116 $datestring->day = get_string('day');
117 $datestring->days = get_string('days');
118 $datestring->hour = get_string('hour');
119 $datestring->hours = get_string('hours');
120 $datestring->min = get_string('min');
121 $datestring->mins = get_string('mins');
122 $datestring->sec = get_string('sec');
123 $datestring->secs = get_string('secs');
125 if ($mode !== NULL) {
126 $SESSION->userindexmode = $fullmode = ($mode == 1);
127 } else if (isset($SESSION->userindexmode)) {
128 $fullmode = $SESSION->userindexmode;
129 } else {
130 $fullmode = false;
133 /// Check to see if groups are being used in this course
134 /// and if so, set $currentgroup to reflect the current group
136 $groupmode = groups_get_course_groupmode($course); // Groups are being used
137 $currentgroup = groups_get_course_group($course, true);
139 if (!$currentgroup) { // To make some other functions work better later
140 $currentgroup = NULL;
143 $isseparategroups = ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context));
145 if ($isseparategroups and (!$currentgroup) ) {
146 $navlinks = array();
147 $navlinks[] = array('name' => get_string('participants'), 'link' => null, 'type' => 'misc');
148 $navigation = build_navigation($navlinks);
150 print_header("$course->shortname: ".get_string('participants'), $course->fullname, $navigation, "", "", true, "&nbsp;", navmenu($course));
151 print_heading(get_string("notingroup"));
152 print_footer($course);
153 exit;
156 // Should use this variable so that we don't break stuff every time a variable is added or changed.
157 $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);
159 /// Print headers
161 $navlinks = array();
162 $navlinks[] = array('name' => get_string('participants'), 'link' => null, 'type' => 'misc');
163 $navigation = build_navigation($navlinks);
165 print_header("$course->shortname: ".get_string('participants'), $course->fullname, $navigation, "", "", true, "&nbsp;", navmenu($course));
167 /// setting up tags
168 if ($course->id == SITEID) {
169 $filtertype = 'site';
170 } else if ($course->id && !$currentgroup) {
171 $filtertype = 'course';
172 $filterselect = $course->id;
173 } else {
174 $filtertype = 'group';
175 $filterselect = $currentgroup;
177 $currenttab = 'participants';
178 $user = $USER;
180 require_once($CFG->dirroot .'/user/tabs.php');
183 /// Get the hidden field list
184 if (has_capability('moodle/course:viewhiddenuserfields', $context)) {
185 $hiddenfields = array(); // teachers and admins are allowed to see everything
186 } else {
187 $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
190 if (isset($hiddenfields['lastaccess'])) {
191 // do not allow access since filtering
192 $accesssince = 0;
195 /// Print settings and things in a table across the top
197 echo '<table class="controls" cellspacing="0"><tr>';
199 /// Print my course menus
200 if ($mycourses = get_my_courses($USER->id)) {
201 echo '<td class="left">';
202 $courselist = array();
203 foreach ($mycourses as $mycourse) {
204 $courselist[$mycourse->id] = format_string($mycourse->shortname);
206 if (has_capability('moodle/site:viewparticipants', $sitecontext)) {
207 unset($courselist[SITEID]);
208 $courselist = array(SITEID => format_string($SITE->shortname)) + $courselist;
210 popup_form($CFG->wwwroot.'/user/index.php?roleid='.$roleid.'&amp;sifirst=&amp;silast=&amp;id=',
211 $courselist, 'courseform', $course->id, '', '', '', false, 'self', get_string('mycourses'));
212 echo '</td>';
215 echo '<td class="left">';
216 groups_print_course_menu($course, $baseurl);
217 echo '</td>';
219 if (!isset($hiddenfields['lastaccess'])) {
220 // get minimum lastaccess for this course and display a dropbox to filter by lastaccess going back this far.
221 // we need to make it diferently for normal courses and site course
222 if ($context->id != $frontpagectx->id) {
223 $minlastaccess = get_field_sql('SELECT min(timeaccess)
224 FROM '.$CFG->prefix.'user_lastaccess
225 WHERE courseid = '.$course->id.'
226 AND timeaccess != 0');
227 $lastaccess0exists = record_exists('user_lastaccess', 'courseid', $course->id, 'timeaccess', 0);
228 } else {
229 $minlastaccess = get_field_sql('SELECT min(lastaccess)
230 FROM '.$CFG->prefix.'user
231 WHERE lastaccess != 0');
232 $lastaccess0exists = record_exists('user','lastaccess',0);
235 $now = usergetmidnight(time());
236 $timeaccess = array();
238 // makes sense for this to go first.
239 $timeoptions[0] = get_string('selectperiod');
241 // days
242 for ($i = 1; $i < 7; $i++) {
243 if (strtotime('-'.$i.' days',$now) >= $minlastaccess) {
244 $timeoptions[strtotime('-'.$i.' days',$now)] = get_string('numdays','moodle',$i);
247 // weeks
248 for ($i = 1; $i < 10; $i++) {
249 if (strtotime('-'.$i.' weeks',$now) >= $minlastaccess) {
250 $timeoptions[strtotime('-'.$i.' weeks',$now)] = get_string('numweeks','moodle',$i);
253 // months
254 for ($i = 2; $i < 12; $i++) {
255 if (strtotime('-'.$i.' months',$now) >= $minlastaccess) {
256 $timeoptions[strtotime('-'.$i.' months',$now)] = get_string('nummonths','moodle',$i);
259 // try a year
260 if (strtotime('-1 year',$now) >= $minlastaccess) {
261 $timeoptions[strtotime('-1 year',$now)] = get_string('lastyear');
264 if (!empty($lastaccess0exists)) {
265 $timeoptions[-1] = get_string('never');
268 if (count($timeoptions) > 1) {
269 echo '<td class="left">';
270 $baseurl = preg_replace('/&amp;accesssince='.$accesssince.'/','',$baseurl);
271 popup_form($baseurl.'&amp;accesssince=',$timeoptions,'timeoptions',$accesssince, '', '', '', false, 'self', get_string('usersnoaccesssince'));
272 echo '</td>';
277 echo '<td class="right">';
278 $formatmenu = array( '0' => get_string('detailedless'),
279 '1' => get_string('detailedmore'));
280 popup_form($baseurl.'&amp;mode=', $formatmenu, 'formatmenu', $fullmode, '', '', '', false, 'self', get_string('userlist'));
281 echo '</td></tr></table>';
283 if ($currentgroup and (!$isseparategroups or has_capability('moodle/site:accessallgroups', $context))) { /// Display info about the group
284 if ($group = groups_get_group($currentgroup)) {
285 if (!empty($group->description) or (!empty($group->picture) and empty($group->hidepicture))) {
286 echo '<table class="groupinfobox"><tr><td class="left side picture">';
287 print_group_picture($group, $course->id, true, false, false);
288 echo '</td><td class="content">';
289 echo '<h3>'.$group->name;
290 if (has_capability('moodle/course:managegroups', $context)) {
291 echo '&nbsp;<a title="'.get_string('editgroupprofile').'" href="'.$CFG->wwwroot.'/group/group.php?id='.$group->id.'&amp;courseid='.$group->courseid.'">';
292 echo '<img src="'.$CFG->pixpath.'/t/edit.gif" alt="'.get_string('editgroupprofile').'" />';
293 echo '</a>';
295 echo '</h3>';
296 echo format_text($group->description);
297 echo '</td></tr></table>';
302 /// Define a table showing a list of users in the current role selection
304 $tablecolumns = array('userpic', 'fullname');
305 $tableheaders = array(get_string('userpic'), get_string('fullname'));
306 if (!isset($hiddenfields['city'])) {
307 $tablecolumns[] = 'city';
308 $tableheaders[] = get_string('city');
310 if (!isset($hiddenfields['country'])) {
311 $tablecolumns[] = 'country';
312 $tableheaders[] = get_string('country');
314 if (!isset($hiddenfields['lastaccess'])) {
315 $tablecolumns[] = 'lastaccess';
316 $tableheaders[] = get_string('lastaccess');
319 if ($course->enrolperiod) {
320 $tablecolumns[] = 'timeend';
321 $tableheaders[] = get_string('enrolmentend');
324 if ($bulkoperations) {
325 $tablecolumns[] = '';
326 $tableheaders[] = get_string('select');
329 $table = new flexible_table('user-index-participants-'.$course->id);
331 $table->define_columns($tablecolumns);
332 $table->define_headers($tableheaders);
333 $table->define_baseurl($baseurl);
335 if (!isset($hiddenfields['lastaccess'])) {
336 $table->sortable(true, 'lastaccess', SORT_DESC);
339 $table->set_attribute('cellspacing', '0');
340 $table->set_attribute('id', 'participants');
341 $table->set_attribute('class', 'generaltable generalbox');
343 $table->set_control_variables(array(
344 TABLE_VAR_SORT => 'ssort',
345 TABLE_VAR_HIDE => 'shide',
346 TABLE_VAR_SHOW => 'sshow',
347 TABLE_VAR_IFIRST => 'sifirst',
348 TABLE_VAR_ILAST => 'silast',
349 TABLE_VAR_PAGE => 'spage'
351 $table->setup();
354 // we are looking for all users with this role assigned in this context or higher
355 if ($usercontexts = get_parent_contexts($context)) {
356 $listofcontexts = '('.implode(',', $usercontexts).')';
357 } else {
358 $listofcontexts = '('.$sitecontext->id.')'; // must be site
360 if ($roleid > 0) {
361 $selectrole = " AND r.roleid = $roleid ";
362 } else {
363 $selectrole = " ";
366 if ($context->id != $frontpagectx->id) {
367 $select = 'SELECT DISTINCT u.id, u.username, u.firstname, u.lastname,
368 u.email, u.city, u.country, u.picture,
369 u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
370 COALESCE(ul.timeaccess, 0) AS lastaccess,
371 r.hidden,
372 ctx.id AS ctxid, ctx.path AS ctxpath,
373 ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel ';
374 $select .= $course->enrolperiod?', r.timeend ':'';
375 } else {
376 if ($roleid >= 0) {
377 $select = 'SELECT u.id, u.username, u.firstname, u.lastname,
378 u.email, u.city, u.country, u.picture,
379 u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
380 u.lastaccess, r.hidden,
381 ctx.id AS ctxid, ctx.path AS ctxpath,
382 ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel ';
383 } else {
384 $select = 'SELECT u.id, u.username, u.firstname, u.lastname,
385 u.email, u.city, u.country, u.picture,
386 u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
387 u.lastaccess,
388 ctx.id AS ctxid, ctx.path AS ctxpath,
389 ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel ';
393 if ($context->id != $frontpagectx->id or $roleid >= 0) {
394 $from = "FROM {$CFG->prefix}user u
395 LEFT OUTER JOIN {$CFG->prefix}context ctx
396 ON (u.id=ctx.instanceid AND ctx.contextlevel = ".CONTEXT_USER.")
397 JOIN {$CFG->prefix}role_assignments r
398 ON u.id=r.userid
399 LEFT OUTER JOIN {$CFG->prefix}user_lastaccess ul
400 ON (r.userid=ul.userid and ul.courseid = $course->id) ";
401 } else {
402 // on frontpage and we want all registered users
403 $from = "FROM {$CFG->prefix}user u
404 LEFT OUTER JOIN {$CFG->prefix}context ctx
405 ON (u.id=ctx.instanceid AND ctx.contextlevel = ".CONTEXT_USER.") ";
408 $hiddensql = has_capability('moodle/role:viewhiddenassigns', $context)? '':' AND r.hidden = 0 ';
410 // exclude users with roles we are avoiding
411 if ($avoidroles) {
412 $adminroles = 'AND r.roleid NOT IN (';
413 $adminroles .= implode(',', $avoidroles);
414 $adminroles .= ')';
415 } else {
416 $adminroles = '';
419 // join on 2 conditions
420 // otherwise we run into the problem of having records in ul table, but not relevant course
421 // and user record is not pulled out
423 if ($context->id != $frontpagectx->id) {
424 $where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
425 AND u.deleted = 0 $selectrole
426 AND (ul.courseid = $course->id OR ul.courseid IS NULL)
427 AND u.username != 'guest'
428 $adminroles
429 $hiddensql ";
430 $where .= get_course_lastaccess_sql($accesssince);
431 } else {
432 if ($roleid >= 0) {
433 $where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
434 AND u.deleted = 0 $selectrole
435 AND u.username != 'guest'";
436 $where .= get_user_lastaccess_sql($accesssince);
437 } else {
438 $where = "WHERE u.deleted = 0
439 AND u.username != 'guest'";
440 $where .= get_user_lastaccess_sql($accesssince);
443 $wheresearch = '';
445 if (!empty($search)) {
446 $LIKE = sql_ilike();
447 $fullname = sql_fullname('u.firstname','u.lastname');
448 $wheresearch .= ' AND ('. $fullname .' '. $LIKE .' \'%'. $search .'%\' OR email '. $LIKE .' \'%'. $search .'%\' OR idnumber '.$LIKE.' \'%'.$search.'%\') ';
452 if ($currentgroup) { // Displaying a group by choice
453 // FIX: TODO: This will not work if $currentgroup == 0, i.e. "those not in a group"
454 $from .= 'LEFT JOIN '.$CFG->prefix.'groups_members gm ON u.id = gm.userid ';
455 $where .= ' AND gm.groupid = '.$currentgroup;
458 $totalcount = count_records_sql('SELECT COUNT(distinct u.id) '.$from.$where); // Each user could have > 1 role
460 if ($table->get_sql_where()) {
461 $where .= ' AND '.$table->get_sql_where();
464 /// Always add r.hidden to sort in order to guarantee hiddens to "win"
465 /// in the resolution of duplicates later - MDL-13935
466 /// Only exception is frontpage that doesn't have such r.hidden info
467 /// because it retrieves ALL users (without role checking) - MDL-14034
468 if ($table->get_sql_sort()) {
469 $sort = ' ORDER BY '.$table->get_sql_sort();
470 if ($context->id != $frontpagectx->id or $roleid >= 0) {
471 $sort .= ', r.hidden DESC';
473 } else {
474 $sort = '';
475 if ($context->id != $frontpagectx->id or $roleid >= 0) {
476 $sort .= ' ORDER BY r.hidden DESC';
480 $matchcount = count_records_sql('SELECT COUNT(distinct u.id) '.$from.$where.$wheresearch);
482 $table->initialbars(true);
483 $table->pagesize($perpage, $matchcount);
485 $userlist = get_recordset_sql($select.$from.$where.$wheresearch.$sort,
486 $table->get_page_start(), $table->get_page_size());
488 if ($context->id == $frontpagectx->id) {
489 $strallsiteusers = get_string('allsiteusers', 'role');
490 if ($CFG->defaultfrontpageroleid) {
491 if ($fprole = get_record('role', 'id', $CFG->defaultfrontpageroleid)) {
492 $fprole = role_get_name($fprole, $frontpagectx);
493 $strallsiteusers = "$strallsiteusers ($fprole)";
496 $rolenames = array(-1 => $strallsiteusers) + $rolenames;
499 /// If there are multiple Roles in the course, then show a drop down menu for switching
500 if (count($rolenames) > 1) {
501 echo '<div class="rolesform">';
502 echo '<label for="rolesform_jump">'.get_string('currentrole', 'role').'&nbsp;</label>';
503 if ($context->id != $frontpagectx->id) {
504 $rolenames = array(0 => get_string('all')) + $rolenames;
505 } else {
506 if (!$CFG->defaultfrontpageroleid) {
507 // we do not want "All users with role" - we already have all users in defualt frontpage role option
508 $rolenames = array(0 => get_string('userswithrole', 'role')) + $rolenames;
511 popup_form("$CFG->wwwroot/user/index.php?contextid=$context->id&amp;sifirst=&amp;silast=&amp;roleid=", $rolenames,
512 'rolesform', $roleid, '');
513 echo '</div>';
515 } else if (count($rolenames) == 1) {
516 // when all users with the same role - print its name
517 echo '<div class="rolesform">';
518 echo get_string('role').': ';
519 $rolename = reset($rolenames);
520 echo $rolename;
521 echo '</div>';
524 if ($roleid > 0) {
525 if (!$currentrole = get_record('role','id',$roleid)) {
526 error('That role does not exist');
528 $a->number = $totalcount;
529 // MDL-12217, use course specific rolename
530 if (isset($rolenames[$currentrole->id])){
531 $a->role = $rolenames[$currentrole->id];
532 }else{
533 $a->role = $currentrole->name;//safety net
535 $heading = format_string(get_string('xuserswiththerole', 'role', $a));
537 if ($currentgroup and $group) {
538 $a->group = $group->name;
539 $heading .= ' ' . format_string(get_string('ingroup', 'role', $a));
542 if ($accesssince) {
543 $a->timeperiod = $timeoptions[$accesssince];
544 $heading .= ' ' . format_string(get_string('inactiveformorethan', 'role', $a));
547 $heading .= ": $a->number";
548 if (user_can_assign($context, $roleid)) {
549 $heading .= ' <a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?roleid='.$roleid.'&amp;contextid='.$context->id.'">';
550 $heading .= '<img src="'.$CFG->pixpath.'/i/edit.gif" class="icon" alt="" /></a>';
552 print_heading($heading, 'center', 3);
553 } else {
554 if ($course->id != SITEID && has_capability('moodle/role:assign', $context)) {
555 $editlink = ' <a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id.'">';
556 $editlink .= '<img src="'.$CFG->pixpath.'/i/edit.gif" class="icon" alt="" /></a>';
557 } else {
558 $editlink = '';
560 if ($course->id == SITEID and $roleid < 0) {
561 $strallparticipants = get_string('allsiteusers', 'role');
562 } else {
563 $strallparticipants = get_string('allparticipants');
565 if ($matchcount < $totalcount) {
566 print_heading($strallparticipants.': '.$matchcount.'/'.$totalcount . $editlink, '', 3);
567 } else {
568 print_heading($strallparticipants.': '.$matchcount . $editlink, '', 3);
573 if ($bulkoperations) {
574 echo '
575 <script type="text/javascript">
576 //<![CDATA[
577 function checksubmit(form) {
578 var destination = form.formaction.options[form.formaction.selectedIndex].value;
579 if (destination == "" || !checkchecked(form)) {
580 form.formaction.selectedIndex = 0;
581 return false;
582 } else {
583 return true;
587 function checkchecked(form) {
588 var inputs = document.getElementsByTagName(\'INPUT\');
589 var checked = false;
590 inputs = filterByParent(inputs, function() {return form;});
591 for(var i = 0; i < inputs.length; ++i) {
592 if (inputs[i].type == \'checkbox\' && inputs[i].checked) {
593 checked = true;
596 return checked;
598 //]]>
599 </script>
601 echo '<form action="action_redir.php" method="post" id="participantsform" onsubmit="return checksubmit(this);">';
602 echo '<div>';
603 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
604 echo '<input type="hidden" name="returnto" value="'.s(me()).'" />';
607 if ($CFG->longtimenosee > 0 && $CFG->longtimenosee < 1000 && $totalcount > 0) {
608 echo '<p id="longtimenosee">('.get_string('unusedaccounts', '', $CFG->longtimenosee).')</p>';
611 if ($fullmode) { // Print simple listing
612 if ($totalcount < 1) {
613 print_heading(get_string('nothingtodisplay'));
614 } else {
615 if ($totalcount > $perpage) {
617 $firstinitial = $table->get_initial_first();
618 $lastinitial = $table->get_initial_last();
619 $strall = get_string('all');
620 $alpha = explode(',', get_string('alphabet'));
622 // Bar of first initials
624 echo '<div class="initialbar firstinitial">'.get_string('firstname').' : ';
625 if(!empty($firstinitial)) {
626 echo '<a href="'.$baseurl.'&amp;sifirst=">'.$strall.'</a>';
627 } else {
628 echo '<strong>'.$strall.'</strong>';
630 foreach ($alpha as $letter) {
631 if ($letter == $firstinitial) {
632 echo ' <strong>'.$letter.'</strong>';
633 } else {
634 echo ' <a href="'.$baseurl.'&amp;sifirst='.$letter.'">'.$letter.'</a>';
637 echo '</div>';
639 // Bar of last initials
641 echo '<div class="initialbar lastinitial">'.get_string('lastname').' : ';
642 if(!empty($lastinitial)) {
643 echo '<a href="'.$baseurl.'&amp;silast=">'.$strall.'</a>';
644 } else {
645 echo '<strong>'.$strall.'</strong>';
647 foreach ($alpha as $letter) {
648 if ($letter == $lastinitial) {
649 echo ' <strong>'.$letter.'</strong>';
650 } else {
651 echo ' <a href="'.$baseurl.'&amp;silast='.$letter.'">'.$letter.'</a>';
654 echo '</div>';
656 print_paging_bar($matchcount, intval($table->get_page_start() / $perpage), $perpage, $baseurl.'&amp;', 'spage');
659 if ($matchcount > 0) {
660 $usersprinted = array();
661 while ($user = rs_fetch_next_record($userlist)) {
662 if (in_array($user->id, $usersprinted)) { /// Prevent duplicates by r.hidden - MDL-13935
663 continue;
665 $usersprinted[] = $user->id; /// Add new user to the array of users printed
667 $user = make_context_subobj($user);
668 print_user($user, $course, $bulkoperations);
671 } else {
672 print_heading(get_string('nothingtodisplay'));
676 } else {
677 $countrysort = (strpos($sort, 'country') !== false);
678 $timeformat = get_string('strftimedate');
681 if ($userlist) {
682 $usersprinted = array();
683 while ($user = rs_fetch_next_record($userlist)) {
684 if (in_array($user->id, $usersprinted)) { /// Prevent duplicates by r.hidden - MDL-13935
685 continue;
687 $usersprinted[] = $user->id; /// Add new user to the array of users printed
689 $user = make_context_subobj($user);
690 if ( !empty($user->hidden) ) {
691 // if the assignment is hidden, display icon
692 $hidden = " <img src=\"{$CFG->pixpath}/t/show.gif\" title=\"".get_string('userhashiddenassignments', 'role')."\" alt=\"".get_string('hiddenassign')."\" class=\"hide-show-image\"/>";
693 } else {
694 $hidden = '';
697 if ($user->lastaccess) {
698 $lastaccess = format_time(time() - $user->lastaccess, $datestring);
699 } else {
700 $lastaccess = $strnever;
703 if (empty($user->country)) {
704 $country = '';
706 } else {
707 if($countrysort) {
708 $country = '('.$user->country.') '.$countries[$user->country];
710 else {
711 $country = $countries[$user->country];
715 if (!isset($user->context)) {
716 $usercontext = get_context_instance(CONTEXT_USER, $user->id);
717 } else {
718 $usercontext = $user->context;
721 if ($piclink = ($USER->id == $user->id || has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext))) {
722 $profilelink = '<strong><a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&amp;course='.$course->id.'">'.fullname($user).'</a></strong>';
723 } else {
724 $profilelink = '<strong>'.fullname($user).'</strong>';
727 $data = array (
728 print_user_picture($user, $course->id, $user->picture, false, true, $piclink),
729 $profilelink . $hidden);
731 if (!isset($hiddenfields['city'])) {
732 $data[] = $user->city;
734 if (!isset($hiddenfields['country'])) {
735 $data[] = $country;
737 if (!isset($hiddenfields['lastaccess'])) {
738 $data[] = $lastaccess;
740 if ($course->enrolperiod) {
741 if ($user->timeend) {
742 $data[] = userdate($user->timeend, $timeformat);
743 } else {
744 $data[] = get_string('unlimited');
747 if ($bulkoperations) {
748 $data[] = '<input type="checkbox" name="user'.$user->id.'" />';
750 $table->add_data($data);
755 $table->print_html();
759 if ($bulkoperations) {
760 echo '<br /><div class="buttons">';
761 echo '<input type="button" onclick="checkall()" value="'.get_string('selectall').'" /> ';
762 echo '<input type="button" onclick="checknone()" value="'.get_string('deselectall').'" /> ';
763 $displaylist = array();
764 $displaylist['messageselect.php'] = get_string('messageselectadd');
765 if (!empty($CFG->enablenotes) && has_capability('moodle/notes:manage', $context) && $context->id != $frontpagectx->id) {
766 $displaylist['addnote.php'] = get_string('addnewnote', 'notes');
767 $displaylist['groupaddnote.php'] = get_string('groupaddnewnote', 'notes');
770 if ($context->id != $frontpagectx->id) {
771 $displaylist['extendenrol.php'] = get_string('extendenrol');
772 $displaylist['groupextendenrol.php'] = get_string('groupextendenrol');
775 helpbutton("participantswithselectedusers", get_string("withselectedusers"));
776 choose_from_menu ($displaylist, "formaction", "", get_string("withselectedusers"), "if(checksubmit(this.form))this.form.submit();", "");
777 echo '<input type="hidden" name="id" value="'.$course->id.'" />';
778 echo '<div id="noscriptparticipantsform" style="display: inline;">';
779 echo '<input type="submit" value="'.get_string('ok').'" /></div>';
780 echo '<script type="text/javascript">'.
781 "\n//<![CDATA[\n".
782 'document.getElementById("noscriptparticipantsform").style.display = "none";'.
783 "\n//]]>\n".'</script>';
784 echo '</div>';
785 echo '</div>';
786 echo '</form>';
790 if (has_capability('moodle/site:viewparticipants', $context) && $totalcount > ($perpage*3)) {
791 echo '<form action="index.php" class="searchform"><div><input type="hidden" name="id" value="'.$course->id.'" />'.get_string('search').':&nbsp;'."\n";
792 echo '<input type="text" name="search" value="'.s($search).'" />&nbsp;<input type="submit" value="'.get_string('search').'" /></div></form>'."\n";
795 $perpageurl = preg_replace('/&amp;perpage=\d*/','', $baseurl);
796 if ($perpage == SHOW_ALL_PAGE_SIZE) {
797 echo '<div id="showall"><a href="'.$perpageurl.'&amp;perpage='.DEFAULT_PAGE_SIZE.'">'.get_string('showperpage', '', DEFAULT_PAGE_SIZE).'</a></div>';
799 } else if ($matchcount > 0 && $perpage < $matchcount) {
800 echo '<div id="showall"><a href="'.$perpageurl.'&amp;perpage='.SHOW_ALL_PAGE_SIZE.'">'.get_string('showall', '', $matchcount).'</a></div>';
803 print_footer($course);
805 if ($userlist) {
806 rs_close($userlist);
810 function get_course_lastaccess_sql($accesssince='') {
811 if (empty($accesssince)) {
812 return '';
814 if ($accesssince == -1) { // never
815 return ' AND ul.timeaccess = 0';
816 } else {
817 return ' AND ul.timeaccess != 0 AND ul.timeaccess < '.$accesssince;
821 function get_user_lastaccess_sql($accesssince='') {
822 if (empty($accesssince)) {
823 return '';
825 if ($accesssince == -1) { // never
826 return ' AND u.lastaccess = 0';
827 } else {
828 return ' AND u.lastaccess != 0 AND u.lastaccess < '.$accesssince;