Commit | Line | Data |
---|---|---|
aa6c1ced | 1 | <?php |
a2ed6e69 SH |
2 | // This file is part of Moodle - http://moodle.org/ |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | /** | |
18 | * Lists all the users within a given course. | |
19 | * | |
20 | * @copyright 1999 Martin Dougiamas http://dougiamas.com | |
21 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
22 | * @package core_user | |
23 | */ | |
24 | ||
25 | require_once('../config.php'); | |
0ff203b6 | 26 | require_once($CFG->dirroot.'/user/lib.php'); |
a2ed6e69 SH |
27 | require_once($CFG->libdir.'/tablelib.php'); |
28 | require_once($CFG->libdir.'/filelib.php'); | |
29 | ||
30 | define('USER_SMALL_CLASS', 20); // Below this is considered small. | |
31 | define('USER_LARGE_CLASS', 200); // Above this is considered large. | |
32 | define('DEFAULT_PAGE_SIZE', 20); | |
33 | define('SHOW_ALL_PAGE_SIZE', 5000); | |
34 | define('MODE_BRIEF', 0); | |
35 | define('MODE_USERDETAILS', 1); | |
36 | ||
37 | $page = optional_param('page', 0, PARAM_INT); // Which page to show. | |
38 | $perpage = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT); // How many per page. | |
39 | $mode = optional_param('mode', null, PARAM_INT); // Use the MODE_ constants. | |
40 | $accesssince = optional_param('accesssince', 0, PARAM_INT); // Filter by last access. -1 = never. | |
41 | $search = optional_param('search', '', PARAM_RAW); // Make sure it is processed with p() or s() when sending to output! | |
42 | $roleid = optional_param('roleid', 0, PARAM_INT); // Optional roleid, 0 means all enrolled users (or all on the frontpage). | |
43 | $contextid = optional_param('contextid', 0, PARAM_INT); // One of this or. | |
44 | $courseid = optional_param('id', 0, PARAM_INT); // This are required. | |
45 | ||
46 | $PAGE->set_url('/user/index.php', array( | |
47 | 'page' => $page, | |
48 | 'perpage' => $perpage, | |
49 | 'mode' => $mode, | |
50 | 'accesssince' => $accesssince, | |
51 | 'search' => $search, | |
52 | 'roleid' => $roleid, | |
53 | 'contextid' => $contextid, | |
54 | 'id' => $courseid)); | |
55 | ||
56 | if ($contextid) { | |
57 | $context = context::instance_by_id($contextid, MUST_EXIST); | |
58 | if ($context->contextlevel != CONTEXT_COURSE) { | |
59 | print_error('invalidcontext'); | |
60 | } | |
61 | $course = $DB->get_record('course', array('id' => $context->instanceid), '*', MUST_EXIST); | |
62 | } else { | |
63 | $course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST); | |
64 | $context = context_course::instance($course->id, MUST_EXIST); | |
65 | } | |
66 | // Not needed anymore. | |
67 | unset($contextid); | |
68 | unset($courseid); | |
f9903ed0 | 69 | |
a2ed6e69 | 70 | require_login($course); |
f9903ed0 | 71 | |
a2ed6e69 SH |
72 | $systemcontext = context_system::instance(); |
73 | $isfrontpage = ($course->id == SITEID); | |
f9903ed0 | 74 | |
a2ed6e69 | 75 | $frontpagectx = context_course::instance(SITEID); |
4f0c2d00 | 76 | |
a2ed6e69 SH |
77 | if ($isfrontpage) { |
78 | $PAGE->set_pagelayout('admin'); | |
79 | require_capability('moodle/site:viewparticipants', $systemcontext); | |
80 | } else { | |
81 | $PAGE->set_pagelayout('incourse'); | |
82 | require_capability('moodle/course:viewparticipants', $context); | |
83 | } | |
224aa44a | 84 | |
a2ed6e69 | 85 | $rolenamesurl = new moodle_url("$CFG->wwwroot/user/index.php?contextid=$context->id&sifirst=&silast="); |
6d3c57f4 | 86 | |
a2ed6e69 SH |
87 | $rolenames = role_fix_names(get_profile_roles($context), $context, ROLENAME_ALIAS, true); |
88 | if ($isfrontpage) { | |
89 | $rolenames[0] = get_string('allsiteusers', 'role'); | |
90 | } else { | |
91 | $rolenames[0] = get_string('allparticipants'); | |
92 | } | |
d7270311 | 93 | |
a2ed6e69 SH |
94 | // Make sure other roles may not be selected by any means. |
95 | if (empty($rolenames[$roleid])) { | |
96 | print_error('noparticipants'); | |
97 | } | |
5f9e296a | 98 | |
a2ed6e69 SH |
99 | // No roles to display yet? |
100 | // frontpage course is an exception, on the front page course we should display all users. | |
101 | if (empty($rolenames) && !$isfrontpage) { | |
102 | if (has_capability('moodle/role:assign', $context)) { | |
103 | redirect($CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id); | |
104 | } else { | |
4f0c2d00 | 105 | print_error('noparticipants'); |
5f9e296a | 106 | } |
a2ed6e69 | 107 | } |
5f9e296a | 108 | |
0ff203b6 JL |
109 | // Trigger events. |
110 | user_list_view($course, $context); | |
a2ed6e69 SH |
111 | |
112 | $bulkoperations = has_capability('moodle/course:bulkmessaging', $context); | |
113 | ||
114 | $countries = get_string_manager()->get_list_of_countries(); | |
115 | ||
116 | $strnever = get_string('never'); | |
117 | ||
118 | $datestring = new stdClass(); | |
119 | $datestring->year = get_string('year'); | |
120 | $datestring->years = get_string('years'); | |
121 | $datestring->day = get_string('day'); | |
122 | $datestring->days = get_string('days'); | |
123 | $datestring->hour = get_string('hour'); | |
124 | $datestring->hours = get_string('hours'); | |
125 | $datestring->min = get_string('min'); | |
126 | $datestring->mins = get_string('mins'); | |
127 | $datestring->sec = get_string('sec'); | |
128 | $datestring->secs = get_string('secs'); | |
129 | ||
130 | if ($mode !== null) { | |
131 | $mode = (int)$mode; | |
132 | $SESSION->userindexmode = $mode; | |
133 | } else if (isset($SESSION->userindexmode)) { | |
134 | $mode = (int)$SESSION->userindexmode; | |
135 | } else { | |
136 | $mode = MODE_BRIEF; | |
137 | } | |
41d7209c | 138 | |
a2ed6e69 SH |
139 | // Check to see if groups are being used in this course |
140 | // and if so, set $currentgroup to reflect the current group. | |
ff3caf30 | 141 | |
a2ed6e69 SH |
142 | $groupmode = groups_get_course_groupmode($course); // Groups are being used. |
143 | $currentgroup = groups_get_course_group($course, true); | |
ff3caf30 | 144 | |
a2ed6e69 SH |
145 | if (!$currentgroup) { // To make some other functions work better later. |
146 | $currentgroup = null; | |
147 | } | |
ff3caf30 | 148 | |
a2ed6e69 | 149 | $isseparategroups = ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)); |
ff3caf30 | 150 | |
a2ed6e69 SH |
151 | $PAGE->set_title("$course->shortname: ".get_string('participants')); |
152 | $PAGE->set_heading($course->fullname); | |
153 | $PAGE->set_pagetype('course-view-' . $course->format); | |
154 | $PAGE->add_body_class('path-user'); // So we can style it independently. | |
155 | $PAGE->set_other_editing_capability('moodle/course:manageactivities'); | |
2cb2ce61 | 156 | |
a2ed6e69 | 157 | echo $OUTPUT->header(); |
4e1f6047 | 158 | echo $OUTPUT->heading(get_string('participants')); |
caa8363f | 159 | |
a2ed6e69 | 160 | echo '<div class="userlist">'; |
0be6f678 | 161 | |
a2ed6e69 SH |
162 | if ($isseparategroups and (!$currentgroup) ) { |
163 | // The user is not in the group so show message and exit. | |
164 | echo $OUTPUT->heading(get_string("notingroup")); | |
165 | echo $OUTPUT->footer(); | |
166 | exit; | |
167 | } | |
99cca847 | 168 | |
ff3caf30 | 169 | |
a2ed6e69 SH |
170 | // Should use this variable so that we don't break stuff every time a variable is added or changed. |
171 | $baseurl = new moodle_url('/user/index.php', array( | |
172 | 'contextid' => $context->id, | |
173 | 'roleid' => $roleid, | |
174 | 'id' => $course->id, | |
175 | 'perpage' => $perpage, | |
176 | 'accesssince' => $accesssince, | |
177 | 'search' => s($search))); | |
178 | ||
179 | // Setting up tags. | |
180 | if ($course->id == SITEID) { | |
181 | $filtertype = 'site'; | |
182 | } else if ($course->id && !$currentgroup) { | |
183 | $filtertype = 'course'; | |
184 | $filterselect = $course->id; | |
185 | } else { | |
186 | $filtertype = 'group'; | |
187 | $filterselect = $currentgroup; | |
188 | } | |
03d9401e | 189 | |
1242eb8f | 190 | |
03d9401e | 191 | |
a2ed6e69 SH |
192 | // Get the hidden field list. |
193 | if (has_capability('moodle/course:viewhiddenuserfields', $context)) { | |
194 | $hiddenfields = array(); // Teachers and admins are allowed to see everything. | |
195 | } else { | |
c6b44cb4 | 196 | $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields)); |
a2ed6e69 | 197 | } |
1242eb8f | 198 | |
a2ed6e69 SH |
199 | if (isset($hiddenfields['lastaccess'])) { |
200 | // Do not allow access since filtering. | |
201 | $accesssince = 0; | |
202 | } | |
3468d58a | 203 | |
a2ed6e69 SH |
204 | // Print settings and things in a table across the top. |
205 | $controlstable = new html_table(); | |
206 | $controlstable->attributes['class'] = 'controls'; | |
207 | $controlstable->cellspacing = 0; | |
208 | $controlstable->data[] = new html_table_row(); | |
209 | ||
210 | // Print my course menus. | |
211 | if ($mycourses = enrol_get_my_courses()) { | |
212 | $courselist = array(); | |
213 | $popupurl = new moodle_url('/user/index.php?roleid='.$roleid.'&sifirst=&silast='); | |
214 | foreach ($mycourses as $mycourse) { | |
215 | $coursecontext = context_course::instance($mycourse->id); | |
216 | $courselist[$mycourse->id] = format_string($mycourse->shortname, true, array('context' => $coursecontext)); | |
217 | } | |
218 | if (has_capability('moodle/site:viewparticipants', $systemcontext)) { | |
219 | unset($courselist[SITEID]); | |
220 | $courselist = array(SITEID => format_string($SITE->shortname, true, array('context' => $systemcontext))) + $courselist; | |
221 | } | |
222 | $select = new single_select($popupurl, 'id', $courselist, $course->id, null, 'courseform'); | |
223 | $select->set_label(get_string('mycourses')); | |
224 | $controlstable->data[0]->cells[] = $OUTPUT->render($select); | |
225 | } | |
bbbf2d40 | 226 | |
24c3db91 DP |
227 | if ($groupmenu = groups_print_course_menu($course, $baseurl->out(), true)) { |
228 | $controlstable->data[0]->cells[] = $groupmenu; | |
229 | } | |
a2ed6e69 SH |
230 | |
231 | if (!isset($hiddenfields['lastaccess'])) { | |
232 | // Get minimum lastaccess for this course and display a dropbox to filter by lastaccess going back this far. | |
233 | // We need to make it diferently for normal courses and site course. | |
234 | if (!$isfrontpage) { | |
235 | $minlastaccess = $DB->get_field_sql('SELECT min(timeaccess) | |
236 | FROM {user_lastaccess} | |
237 | WHERE courseid = ? | |
238 | AND timeaccess != 0', array($course->id)); | |
239 | $lastaccess0exists = $DB->record_exists('user_lastaccess', array('courseid' => $course->id, 'timeaccess' => 0)); | |
240 | } else { | |
241 | $minlastaccess = $DB->get_field_sql('SELECT min(lastaccess) | |
242 | FROM {user} | |
243 | WHERE lastaccess != 0'); | |
244 | $lastaccess0exists = $DB->record_exists('user', array('lastaccess' => 0)); | |
7da0af9f | 245 | } |
87a13824 | 246 | |
a2ed6e69 SH |
247 | $now = usergetmidnight(time()); |
248 | $timeaccess = array(); | |
249 | $baseurl->remove_params('accesssince'); | |
87a13824 | 250 | |
a2ed6e69 SH |
251 | // Makes sense for this to go first. |
252 | $timeoptions[0] = get_string('selectperiod'); | |
87a13824 | 253 | |
a2ed6e69 SH |
254 | // Days. |
255 | for ($i = 1; $i < 7; $i++) { | |
256 | if (strtotime('-'.$i.' days', $now) >= $minlastaccess) { | |
257 | $timeoptions[strtotime('-'.$i.' days', $now)] = get_string('numdays', 'moodle', $i); | |
ca792680 | 258 | } |
a2ed6e69 SH |
259 | } |
260 | // Weeks. | |
261 | for ($i = 1; $i < 10; $i++) { | |
262 | if (strtotime('-'.$i.' weeks', $now) >= $minlastaccess) { | |
263 | $timeoptions[strtotime('-'.$i.' weeks', $now)] = get_string('numweeks', 'moodle', $i); | |
5ff311f0 | 264 | } |
a2ed6e69 SH |
265 | } |
266 | // Months. | |
267 | for ($i = 2; $i < 12; $i++) { | |
268 | if (strtotime('-'.$i.' months', $now) >= $minlastaccess) { | |
269 | $timeoptions[strtotime('-'.$i.' months', $now)] = get_string('nummonths', 'moodle', $i); | |
31b71336 | 270 | } |
a2ed6e69 SH |
271 | } |
272 | // Try a year. | |
273 | if (strtotime('-1 year', $now) >= $minlastaccess) { | |
274 | $timeoptions[strtotime('-1 year', $now)] = get_string('lastyear'); | |
275 | } | |
87a13824 | 276 | |
a2ed6e69 SH |
277 | if (!empty($lastaccess0exists)) { |
278 | $timeoptions[-1] = get_string('never'); | |
279 | } | |
87a13824 | 280 | |
a2ed6e69 SH |
281 | if (count($timeoptions) > 1) { |
282 | $select = new single_select($baseurl, 'accesssince', $timeoptions, $accesssince, null, 'timeoptions'); | |
283 | $select->set_label(get_string('usersnoaccesssince')); | |
284 | $controlstable->data[0]->cells[] = $OUTPUT->render($select); | |
77c645df | 285 | } |
a2ed6e69 | 286 | } |
87a13824 | 287 | |
a2ed6e69 SH |
288 | $formatmenu = array( '0' => get_string('brief'), |
289 | '1' => get_string('userdetails')); | |
290 | $select = new single_select($baseurl, 'mode', $formatmenu, $mode, null, 'formatmenu'); | |
291 | $select->set_label(get_string('userlist')); | |
292 | $userlistcell = new html_table_cell(); | |
293 | $userlistcell->attributes['class'] = 'right'; | |
294 | $userlistcell->text = $OUTPUT->render($select); | |
295 | $controlstable->data[0]->cells[] = $userlistcell; | |
296 | ||
297 | echo html_writer::table($controlstable); | |
298 | ||
299 | if ($currentgroup and (!$isseparategroups or has_capability('moodle/site:accessallgroups', $context))) { | |
300 | // Display info about the group. | |
301 | if ($group = groups_get_group($currentgroup)) { | |
302 | if (!empty($group->description) or (!empty($group->picture) and empty($group->hidepicture))) { | |
303 | $groupinfotable = new html_table(); | |
304 | $groupinfotable->attributes['class'] = 'groupinfobox'; | |
305 | $picturecell = new html_table_cell(); | |
306 | $picturecell->attributes['class'] = 'left side picture'; | |
307 | $picturecell->text = print_group_picture($group, $course->id, true, true, false); | |
308 | ||
309 | $contentcell = new html_table_cell(); | |
310 | $contentcell->attributes['class'] = 'content'; | |
311 | ||
312 | $contentheading = $group->name; | |
313 | if (has_capability('moodle/course:managegroups', $context)) { | |
314 | $aurl = new moodle_url('/group/group.php', array('id' => $group->id, 'courseid' => $group->courseid)); | |
315 | $contentheading .= ' ' . $OUTPUT->action_icon($aurl, new pix_icon('t/edit', get_string('editgroupprofile'))); | |
316 | } | |
8bdc9cac | 317 | |
a2ed6e69 SH |
318 | $group->description = file_rewrite_pluginfile_urls($group->description, 'pluginfile.php', $context->id, 'group', |
319 | 'description', $group->id); | |
320 | if (!isset($group->descriptionformat)) { | |
321 | $group->descriptionformat = FORMAT_MOODLE; | |
ff3caf30 | 322 | } |
a2ed6e69 SH |
323 | $options = array('overflowdiv' => true); |
324 | $formatteddesc = format_text($group->description, $group->descriptionformat, $options); | |
325 | $contentcell->text = $OUTPUT->heading($contentheading, 3) . $formatteddesc; | |
326 | $groupinfotable->data[] = new html_table_row(array($picturecell, $contentcell)); | |
327 | echo html_writer::table($groupinfotable); | |
ff3caf30 | 328 | } |
329 | } | |
a2ed6e69 | 330 | } |
ff3caf30 | 331 | |
a2ed6e69 SH |
332 | // Define a table showing a list of users in the current role selection. |
333 | $tablecolumns = array(); | |
334 | $tableheaders = array(); | |
335 | if ($bulkoperations && $mode === MODE_BRIEF) { | |
336 | $tablecolumns[] = 'select'; | |
337 | $tableheaders[] = get_string('select'); | |
338 | } | |
339 | $tablecolumns[] = 'userpic'; | |
340 | $tablecolumns[] = 'fullname'; | |
c238e1e2 | 341 | |
a2ed6e69 SH |
342 | $extrafields = get_extra_user_fields($context); |
343 | $tableheaders[] = get_string('userpic'); | |
344 | $tableheaders[] = get_string('fullnameuser'); | |
77c645df | 345 | |
a2ed6e69 SH |
346 | if ($mode === MODE_BRIEF) { |
347 | foreach ($extrafields as $field) { | |
348 | $tablecolumns[] = $field; | |
349 | $tableheaders[] = get_user_field_name($field); | |
77c645df | 350 | } |
a2ed6e69 SH |
351 | } |
352 | if ($mode === MODE_BRIEF && !isset($hiddenfields['city'])) { | |
353 | $tablecolumns[] = 'city'; | |
354 | $tableheaders[] = get_string('city'); | |
355 | } | |
356 | if ($mode === MODE_BRIEF && !isset($hiddenfields['country'])) { | |
357 | $tablecolumns[] = 'country'; | |
358 | $tableheaders[] = get_string('country'); | |
359 | } | |
360 | if (!isset($hiddenfields['lastaccess'])) { | |
361 | $tablecolumns[] = 'lastaccess'; | |
e89682d8 DC |
362 | if ($course->id == SITEID) { |
363 | // Exception case for viewing participants on site home. | |
364 | $tableheaders[] = get_string('lastsiteaccess'); | |
365 | } else { | |
366 | $tableheaders[] = get_string('lastcourseaccess'); | |
367 | } | |
a2ed6e69 | 368 | } |
77c645df | 369 | |
a2ed6e69 SH |
370 | if ($bulkoperations && $mode === MODE_USERDETAILS) { |
371 | $tablecolumns[] = 'select'; | |
372 | $tableheaders[] = get_string('select'); | |
373 | } | |
0be6f678 | 374 | |
a2ed6e69 SH |
375 | $table = new flexible_table('user-index-participants-'.$course->id); |
376 | $table->define_columns($tablecolumns); | |
377 | $table->define_headers($tableheaders); | |
378 | $table->define_baseurl($baseurl->out()); | |
5ff311f0 | 379 | |
28d27e85 | 380 | if (!isset($hiddenfields['lastaccess'])) { |
381 | $table->sortable(true, 'lastaccess', SORT_DESC); | |
a2ed6e69 SH |
382 | } else { |
383 | $table->sortable(true, 'firstname', SORT_ASC); | |
384 | } | |
4f0c2d00 | 385 | |
a2ed6e69 SH |
386 | $table->no_sorting('roles'); |
387 | $table->no_sorting('groups'); | |
388 | $table->no_sorting('groupings'); | |
389 | $table->no_sorting('select'); | |
390 | ||
391 | $table->set_attribute('cellspacing', '0'); | |
392 | $table->set_attribute('id', 'participants'); | |
393 | $table->set_attribute('class', 'generaltable generalbox'); | |
394 | ||
395 | $table->set_control_variables(array( | |
396 | TABLE_VAR_SORT => 'ssort', | |
397 | TABLE_VAR_HIDE => 'shide', | |
398 | TABLE_VAR_SHOW => 'sshow', | |
399 | TABLE_VAR_IFIRST => 'sifirst', | |
400 | TABLE_VAR_ILAST => 'silast', | |
401 | TABLE_VAR_PAGE => 'spage' | |
402 | )); | |
403 | $table->setup(); | |
404 | ||
405 | list($esql, $params) = get_enrolled_sql($context, null, $currentgroup, true); | |
406 | $joins = array("FROM {user} u"); | |
407 | $wheres = array(); | |
408 | ||
368f0bf8 DC |
409 | $userfields = array('username', 'email', 'city', 'country', 'lang', 'timezone', 'maildisplay'); |
410 | $mainuserfields = user_picture::fields('u', $userfields); | |
411 | $extrasql = get_extra_user_fields_sql($context, 'u', '', $userfields); | |
a2ed6e69 SH |
412 | |
413 | if ($isfrontpage) { | |
414 | $select = "SELECT $mainuserfields, u.lastaccess$extrasql"; | |
415 | $joins[] = "JOIN ($esql) e ON e.id = u.id"; // Everybody on the frontpage usually. | |
416 | if ($accesssince) { | |
417 | $wheres[] = get_user_lastaccess_sql($accesssince); | |
418 | } | |
419 | ||
420 | } else { | |
421 | $select = "SELECT $mainuserfields, COALESCE(ul.timeaccess, 0) AS lastaccess$extrasql"; | |
422 | $joins[] = "JOIN ($esql) e ON e.id = u.id"; // Course enrolled users only. | |
423 | $joins[] = "LEFT JOIN {user_lastaccess} ul ON (ul.userid = u.id AND ul.courseid = :courseid)"; // Not everybody accessed course yet. | |
424 | $params['courseid'] = $course->id; | |
425 | if ($accesssince) { | |
426 | $wheres[] = get_course_lastaccess_sql($accesssince); | |
165088f6 | 427 | } |
a2ed6e69 | 428 | } |
5f9e296a | 429 | |
a2ed6e69 SH |
430 | // Performance hacks - we preload user contexts together with accounts. |
431 | $ccselect = ', ' . context_helper::get_preload_record_columns_sql('ctx'); | |
432 | $ccjoin = "LEFT JOIN {context} ctx ON (ctx.instanceid = u.id AND ctx.contextlevel = :contextlevel)"; | |
433 | $params['contextlevel'] = CONTEXT_USER; | |
434 | $select .= $ccselect; | |
435 | $joins[] = $ccjoin; | |
c0527567 | 436 | |
4f0c2d00 | 437 | |
a2ed6e69 SH |
438 | // Limit list to users with some role only. |
439 | if ($roleid) { | |
419d1abd DW |
440 | // We want to query both the current context and parent contexts. |
441 | list($relatedctxsql, $relatedctxparams) = $DB->get_in_or_equal($context->get_parent_context_ids(true), SQL_PARAMS_NAMED, 'relatedctx'); | |
442 | ||
a2ed6e69 | 443 | $wheres[] = "u.id IN (SELECT userid FROM {role_assignments} WHERE roleid = :roleid AND contextid $relatedctxsql)"; |
419d1abd | 444 | $params = array_merge($params, array('roleid' => $roleid), $relatedctxparams); |
a2ed6e69 | 445 | } |
0be6f678 | 446 | |
a2ed6e69 SH |
447 | $from = implode("\n", $joins); |
448 | if ($wheres) { | |
449 | $where = "WHERE " . implode(" AND ", $wheres); | |
450 | } else { | |
451 | $where = ""; | |
452 | } | |
4f0c2d00 | 453 | |
a2ed6e69 | 454 | $totalcount = $DB->count_records_sql("SELECT COUNT(u.id) $from $where", $params); |
77c645df | 455 | |
a2ed6e69 SH |
456 | if (!empty($search)) { |
457 | $fullname = $DB->sql_fullname('u.firstname', 'u.lastname'); | |
458 | $wheres[] = "(". $DB->sql_like($fullname, ':search1', false, false) . | |
459 | " OR ". $DB->sql_like('email', ':search2', false, false) . | |
460 | " OR ". $DB->sql_like('idnumber', ':search3', false, false) .") "; | |
461 | $params['search1'] = "%$search%"; | |
462 | $params['search2'] = "%$search%"; | |
463 | $params['search3'] = "%$search%"; | |
464 | } | |
77c645df | 465 | |
a2ed6e69 SH |
466 | list($twhere, $tparams) = $table->get_sql_where(); |
467 | if ($twhere) { | |
468 | $wheres[] = $twhere; | |
469 | $params = array_merge($params, $tparams); | |
470 | } | |
77c645df | 471 | |
a2ed6e69 SH |
472 | $from = implode("\n", $joins); |
473 | if ($wheres) { | |
474 | $where = "WHERE " . implode(" AND ", $wheres); | |
475 | } else { | |
476 | $where = ""; | |
477 | } | |
77c645df | 478 | |
a2ed6e69 SH |
479 | if ($table->get_sql_sort()) { |
480 | $sort = ' ORDER BY '.$table->get_sql_sort(); | |
481 | } else { | |
482 | $sort = ''; | |
483 | } | |
77c645df | 484 | |
a2ed6e69 | 485 | $matchcount = $DB->count_records_sql("SELECT COUNT(u.id) $from $where", $params); |
77c645df | 486 | |
a2ed6e69 SH |
487 | $table->initialbars(true); |
488 | $table->pagesize($perpage, $matchcount); | |
77c645df | 489 | |
a2ed6e69 SH |
490 | // List of users at the current visible page - paging makes it relatively short. |
491 | $userlist = $DB->get_recordset_sql("$select $from $where $sort", $params, $table->get_page_start(), $table->get_page_size()); | |
3e219038 | 492 | |
a2ed6e69 SH |
493 | // If there are multiple Roles in the course, then show a drop down menu for switching. |
494 | if (count($rolenames) > 1) { | |
495 | echo '<div class="rolesform">'; | |
32bd11cb BB |
496 | echo $OUTPUT->single_select($rolenamesurl, 'roleid', $rolenames, $roleid, null, |
497 | 'rolesform', array('label' => get_string('currentrole', 'role'))); | |
a2ed6e69 | 498 | echo '</div>'; |
5f9e296a | 499 | |
a2ed6e69 SH |
500 | } else if (count($rolenames) == 1) { |
501 | // When all users with the same role - print its name. | |
502 | echo '<div class="rolesform">'; | |
503 | echo get_string('role').get_string('labelsep', 'langconfig'); | |
504 | $rolename = reset($rolenames); | |
505 | echo $rolename; | |
506 | echo '</div>'; | |
507 | } | |
3e219038 | 508 | |
7057c3ef DP |
509 | $editlink = ''; |
510 | if ($course->id != SITEID && has_capability('moodle/course:enrolreview', $context)) { | |
511 | $editlink = new moodle_url('/enrol/users.php', array('id' => $course->id)); | |
512 | } | |
513 | ||
a2ed6e69 SH |
514 | if ($roleid > 0) { |
515 | $a = new stdClass(); | |
516 | $a->number = $totalcount; | |
517 | $a->role = $rolenames[$roleid]; | |
518 | $heading = format_string(get_string('xuserswiththerole', 'role', $a)); | |
f642a21a | 519 | |
9488b6f3 | 520 | if ($currentgroup and !empty($group)) { |
a2ed6e69 SH |
521 | $a->group = $group->name; |
522 | $heading .= ' ' . format_string(get_string('ingroup', 'role', $a)); | |
523 | } | |
f642a21a | 524 | |
9488b6f3 | 525 | if ($accesssince && !empty($timeoptions[$accesssince])) { |
a2ed6e69 SH |
526 | $a->timeperiod = $timeoptions[$accesssince]; |
527 | $heading .= ' ' . format_string(get_string('inactiveformorethan', 'role', $a)); | |
528 | } | |
f642a21a | 529 | |
a2ed6e69 | 530 | $heading .= ": $a->number"; |
b85b25eb | 531 | |
7057c3ef DP |
532 | if (!empty($editlink)) { |
533 | $editlink->param('role', $roleid); | |
534 | $heading .= $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'))); | |
a2ed6e69 SH |
535 | } |
536 | echo $OUTPUT->heading($heading, 3); | |
537 | } else { | |
a2ed6e69 SH |
538 | if ($course->id == SITEID and $roleid < 0) { |
539 | $strallparticipants = get_string('allsiteusers', 'role'); | |
540 | } else { | |
541 | $strallparticipants = get_string('allparticipants'); | |
542 | } | |
7057c3ef DP |
543 | |
544 | if (!empty($editlink)) { | |
545 | $editlink = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'))); | |
546 | } | |
547 | ||
a2ed6e69 SH |
548 | if ($matchcount < $totalcount) { |
549 | echo $OUTPUT->heading($strallparticipants.get_string('labelsep', 'langconfig').$matchcount.'/'.$totalcount . $editlink, 3); | |
550 | } else { | |
551 | echo $OUTPUT->heading($strallparticipants.get_string('labelsep', 'langconfig').$matchcount . $editlink, 3); | |
552 | } | |
553 | } | |
3e219038 | 554 | |
77c645df | 555 | |
a2ed6e69 SH |
556 | if ($bulkoperations) { |
557 | echo '<form action="action_redir.php" method="post" id="participantsform">'; | |
558 | echo '<div>'; | |
559 | echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />'; | |
560 | echo '<input type="hidden" name="returnto" value="'.s($PAGE->url->out(false)).'" />'; | |
561 | } | |
77c645df | 562 | |
a2ed6e69 SH |
563 | if ($mode === MODE_USERDETAILS) { // Print simple listing. |
564 | if ($totalcount < 1) { | |
565 | echo $OUTPUT->heading(get_string('nothingtodisplay')); | |
566 | } else { | |
567 | if ($totalcount > $perpage) { | |
77c645df | 568 | |
a2ed6e69 SH |
569 | $firstinitial = $table->get_initial_first(); |
570 | $lastinitial = $table->get_initial_last(); | |
571 | $strall = get_string('all'); | |
c6b44cb4 | 572 | $alpha = explode(',', get_string('alphabet', 'langconfig')); |
77c645df | 573 | |
a2ed6e69 | 574 | // Bar of first initials. |
77c645df | 575 | |
a2ed6e69 SH |
576 | echo '<div class="initialbar firstinitial">'.get_string('firstname').' : '; |
577 | if (!empty($firstinitial)) { | |
578 | echo '<a href="'.$baseurl->out().'&sifirst=">'.$strall.'</a>'; | |
579 | } else { | |
580 | echo '<strong>'.$strall.'</strong>'; | |
581 | } | |
582 | foreach ($alpha as $letter) { | |
583 | if ($letter == $firstinitial) { | |
584 | echo ' <strong>'.$letter.'</strong>'; | |
77c645df | 585 | } else { |
a2ed6e69 | 586 | echo ' <a href="'.$baseurl->out().'&sifirst='.$letter.'">'.$letter.'</a>'; |
ee4a52c5 | 587 | } |
a2ed6e69 SH |
588 | } |
589 | echo '</div>'; | |
77c645df | 590 | |
a2ed6e69 | 591 | // Bar of last initials. |
77c645df | 592 | |
a2ed6e69 SH |
593 | echo '<div class="initialbar lastinitial">'.get_string('lastname').' : '; |
594 | if (!empty($lastinitial)) { | |
595 | echo '<a href="'.$baseurl->out().'&silast=">'.$strall.'</a>'; | |
596 | } else { | |
597 | echo '<strong>'.$strall.'</strong>'; | |
598 | } | |
599 | foreach ($alpha as $letter) { | |
600 | if ($letter == $lastinitial) { | |
601 | echo ' <strong>'.$letter.'</strong>'; | |
77c645df | 602 | } else { |
a2ed6e69 | 603 | echo ' <a href="'.$baseurl->out().'&silast='.$letter.'">'.$letter.'</a>'; |
ee4a52c5 | 604 | } |
77c645df | 605 | } |
a2ed6e69 | 606 | echo '</div>'; |
77c645df | 607 | |
a2ed6e69 SH |
608 | $pagingbar = new paging_bar($matchcount, intval($table->get_page_start() / $perpage), $perpage, $baseurl); |
609 | $pagingbar->pagevar = 'spage'; | |
610 | echo $OUTPUT->render($pagingbar); | |
611 | } | |
612 | ||
613 | if ($matchcount > 0) { | |
614 | $usersprinted = array(); | |
615 | foreach ($userlist as $user) { | |
616 | if (in_array($user->id, $usersprinted)) { // Prevent duplicates by r.hidden - MDL-13935. | |
617 | continue; | |
618 | } | |
619 | $usersprinted[] = $user->id; // Add new user to the array of users printed. | |
1f807bc4 | 620 | |
a2ed6e69 | 621 | context_helper::preload_from_record($user); |
c351150f | 622 | |
a2ed6e69 SH |
623 | $context = context_course::instance($course->id); |
624 | $usercontext = context_user::instance($user->id); | |
c351150f | 625 | |
a2ed6e69 | 626 | $countries = get_string_manager()->get_list_of_countries(); |
c351150f | 627 | |
a2ed6e69 SH |
628 | // Get the hidden field list. |
629 | if (has_capability('moodle/course:viewhiddenuserfields', $context)) { | |
630 | $hiddenfields = array(); | |
631 | } else { | |
c6b44cb4 | 632 | $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields)); |
a2ed6e69 SH |
633 | } |
634 | $table = new html_table(); | |
635 | $table->attributes['class'] = 'userinfobox'; | |
c351150f | 636 | |
a2ed6e69 SH |
637 | $row = new html_table_row(); |
638 | $row->cells[0] = new html_table_cell(); | |
639 | $row->cells[0]->attributes['class'] = 'left side'; | |
f2f085ee | 640 | |
a2ed6e69 SH |
641 | $row->cells[0]->text = $OUTPUT->user_picture($user, array('size' => 100, 'courseid' => $course->id)); |
642 | $row->cells[1] = new html_table_cell(); | |
643 | $row->cells[1]->attributes['class'] = 'content'; | |
c351150f | 644 | |
a2ed6e69 SH |
645 | $row->cells[1]->text = $OUTPUT->container(fullname($user, has_capability('moodle/site:viewfullnames', $context)), 'username'); |
646 | $row->cells[1]->text .= $OUTPUT->container_start('info'); | |
c351150f | 647 | |
a2ed6e69 SH |
648 | if (!empty($user->role)) { |
649 | $row->cells[1]->text .= get_string('role').get_string('labelsep', 'langconfig').$user->role.'<br />'; | |
650 | } | |
651 | if ($user->maildisplay == 1 or ($user->maildisplay == 2 and ($course->id != SITEID) and !isguestuser()) or | |
a2ed6e69 SH |
652 | in_array('email', $extrafields) or ($user->id == $USER->id)) { |
653 | $row->cells[1]->text .= get_string('email').get_string('labelsep', 'langconfig').html_writer::link("mailto:$user->email", $user->email) . '<br />'; | |
654 | } | |
655 | foreach ($extrafields as $field) { | |
656 | if ($field === 'email') { | |
657 | // Skip email because it was displayed with different logic above | |
658 | // because this page is intended for students too. | |
659 | continue; | |
c351150f | 660 | } |
a2ed6e69 SH |
661 | $row->cells[1]->text .= get_user_field_name($field) . |
662 | get_string('labelsep', 'langconfig') . s($user->{$field}) . '<br />'; | |
663 | } | |
664 | if (($user->city or $user->country) and (!isset($hiddenfields['city']) or !isset($hiddenfields['country']))) { | |
665 | $row->cells[1]->text .= get_string('city').get_string('labelsep', 'langconfig'); | |
666 | if ($user->city && !isset($hiddenfields['city'])) { | |
667 | $row->cells[1]->text .= $user->city; | |
43aa295b | 668 | } |
a2ed6e69 | 669 | if (!empty($countries[$user->country]) && !isset($hiddenfields['country'])) { |
c351150f | 670 | if ($user->city && !isset($hiddenfields['city'])) { |
a2ed6e69 | 671 | $row->cells[1]->text .= ', '; |
c351150f | 672 | } |
a2ed6e69 | 673 | $row->cells[1]->text .= $countries[$user->country]; |
c351150f | 674 | } |
a2ed6e69 SH |
675 | $row->cells[1]->text .= '<br />'; |
676 | } | |
c351150f | 677 | |
a2ed6e69 SH |
678 | if (!isset($hiddenfields['lastaccess'])) { |
679 | if ($user->lastaccess) { | |
680 | $row->cells[1]->text .= get_string('lastaccess').get_string('labelsep', 'langconfig').userdate($user->lastaccess); | |
681 | $row->cells[1]->text .= ' ('. format_time(time() - $user->lastaccess, $datestring) .')'; | |
682 | } else { | |
683 | $row->cells[1]->text .= get_string('lastaccess').get_string('labelsep', 'langconfig').get_string('never'); | |
c351150f | 684 | } |
a2ed6e69 | 685 | } |
c351150f | 686 | |
a2ed6e69 | 687 | $row->cells[1]->text .= $OUTPUT->container_end(); |
3aac07d8 | 688 | |
a2ed6e69 SH |
689 | $row->cells[2] = new html_table_cell(); |
690 | $row->cells[2]->attributes['class'] = 'links'; | |
691 | $row->cells[2]->text = ''; | |
3aac07d8 | 692 | |
a2ed6e69 | 693 | $links = array(); |
c351150f | 694 | |
66b864c7 | 695 | if ($CFG->enableblogs && ($CFG->bloglevel != BLOG_USER_LEVEL || $USER->id == $user->id)) { |
a2ed6e69 SH |
696 | $links[] = html_writer::link(new moodle_url('/blog/index.php?userid='.$user->id), get_string('blogs', 'blog')); |
697 | } | |
c351150f | 698 | |
a2ed6e69 SH |
699 | if (!empty($CFG->enablenotes) and (has_capability('moodle/notes:manage', $context) || has_capability('moodle/notes:view', $context))) { |
700 | $links[] = html_writer::link(new moodle_url('/notes/index.php?course=' . $course->id. '&user='.$user->id), get_string('notes', 'notes')); | |
701 | } | |
c351150f | 702 | |
a2ed6e69 SH |
703 | if (has_capability('moodle/site:viewreports', $context) or has_capability('moodle/user:viewuseractivitiesreport', $usercontext)) { |
704 | $links[] = html_writer::link(new moodle_url('/course/user.php?id='. $course->id .'&user='. $user->id), get_string('activity')); | |
705 | } | |
c351150f | 706 | |
a2ed6e69 SH |
707 | if ($USER->id != $user->id && !\core\session\manager::is_loggedinas() && has_capability('moodle/user:loginas', $context) && !is_siteadmin($user->id)) { |
708 | $links[] = html_writer::link(new moodle_url('/course/loginas.php?id='. $course->id .'&user='. $user->id .'&sesskey='. sesskey()), get_string('loginas')); | |
709 | } | |
c351150f | 710 | |
a2ed6e69 | 711 | $links[] = html_writer::link(new moodle_url('/user/view.php?id='. $user->id .'&course='. $course->id), get_string('fullprofile') . '...'); |
3aac07d8 | 712 | |
a2ed6e69 | 713 | $row->cells[2]->text .= implode('', $links); |
c351150f | 714 | |
a2ed6e69 SH |
715 | if ($bulkoperations) { |
716 | $row->cells[2]->text .= '<br /><input type="checkbox" class="usercheckbox" name="user'.$user->id.'" /> '; | |
ee4a52c5 | 717 | } |
a2ed6e69 SH |
718 | $table->data = array($row); |
719 | echo html_writer::table($table); | |
ee4a52c5 | 720 | } |
a2ed6e69 SH |
721 | |
722 | } else { | |
723 | echo $OUTPUT->heading(get_string('nothingtodisplay')); | |
ee4a52c5 | 724 | } |
a2ed6e69 | 725 | } |
77c645df | 726 | |
a2ed6e69 SH |
727 | } else { |
728 | $countrysort = (strpos($sort, 'country') !== false); | |
729 | $timeformat = get_string('strftimedate'); | |
3997cb40 | 730 | |
731 | ||
a2ed6e69 | 732 | if ($userlist) { |
664fe87f | 733 | |
a2ed6e69 SH |
734 | $usersprinted = array(); |
735 | foreach ($userlist as $user) { | |
736 | if (in_array($user->id, $usersprinted)) { // Prevent duplicates by r.hidden - MDL-13935. | |
737 | continue; | |
738 | } | |
739 | $usersprinted[] = $user->id; // Add new user to the array of users printed. | |
1f807bc4 | 740 | |
a2ed6e69 | 741 | context_helper::preload_from_record($user); |
0be6f678 | 742 | |
a2ed6e69 SH |
743 | if ($user->lastaccess) { |
744 | $lastaccess = format_time(time() - $user->lastaccess, $datestring); | |
745 | } else { | |
746 | $lastaccess = $strnever; | |
747 | } | |
77c645df | 748 | |
a2ed6e69 SH |
749 | if (empty($user->country)) { |
750 | $country = ''; | |
77c645df | 751 | |
a2ed6e69 SH |
752 | } else { |
753 | if ($countrysort) { | |
754 | $country = '('.$user->country.') '.$countries[$user->country]; | |
77c645df | 755 | } else { |
a2ed6e69 | 756 | $country = $countries[$user->country]; |
77c645df | 757 | } |
a2ed6e69 | 758 | } |
0be6f678 | 759 | |
a2ed6e69 | 760 | $usercontext = context_user::instance($user->id); |
0be6f678 | 761 | |
a2ed6e69 SH |
762 | if ($piclink = ($USER->id == $user->id || has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext))) { |
763 | $profilelink = '<strong><a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&course='.$course->id.'">'.fullname($user).'</a></strong>'; | |
764 | } else { | |
765 | $profilelink = '<strong>'.fullname($user).'</strong>'; | |
766 | } | |
0be6f678 | 767 | |
a2ed6e69 SH |
768 | $data = array(); |
769 | if ($bulkoperations) { | |
770 | $data[] = '<input type="checkbox" class="usercheckbox" name="user'.$user->id.'" />'; | |
771 | } | |
772 | $data[] = $OUTPUT->user_picture($user, array('size' => 35, 'courseid' => $course->id)); | |
773 | $data[] = $profilelink; | |
22ae509e | 774 | |
a2ed6e69 SH |
775 | if ($mode === MODE_BRIEF) { |
776 | foreach ($extrafields as $field) { | |
777 | $data[] = $user->{$field}; | |
77c645df | 778 | } |
a2ed6e69 SH |
779 | } |
780 | if ($mode === MODE_BRIEF && !isset($hiddenfields['city'])) { | |
781 | $data[] = $user->city; | |
782 | } | |
783 | if ($mode === MODE_BRIEF && !isset($hiddenfields['country'])) { | |
784 | $data[] = $country; | |
785 | } | |
786 | if (!isset($hiddenfields['lastaccess'])) { | |
787 | $data[] = $lastaccess; | |
788 | } | |
664fe87f | 789 | |
a2ed6e69 | 790 | $table->add_data($data); |
eca3af25 | 791 | } |
a2ed6e69 | 792 | } |
576ad290 | 793 | |
a2ed6e69 | 794 | $table->print_html(); |
d88c5043 | 795 | |
a2ed6e69 | 796 | } |
b90e2f19 | 797 | |
a2ed6e69 SH |
798 | if ($bulkoperations) { |
799 | echo '<br /><div class="buttons">'; | |
800 | echo '<input type="button" id="checkall" value="'.get_string('selectall').'" /> '; | |
801 | echo '<input type="button" id="checknone" value="'.get_string('deselectall').'" /> '; | |
802 | $displaylist = array(); | |
803 | $displaylist['messageselect.php'] = get_string('messageselectadd'); | |
804 | if (!empty($CFG->enablenotes) && has_capability('moodle/notes:manage', $context) && $context->id != $frontpagectx->id) { | |
805 | $displaylist['addnote.php'] = get_string('addnewnote', 'notes'); | |
806 | $displaylist['groupaddnote.php'] = get_string('groupaddnewnote', 'notes'); | |
807 | } | |
808 | ||
809 | echo $OUTPUT->help_icon('withselectedusers'); | |
810 | echo html_writer::tag('label', get_string("withselectedusers"), array('for' => 'formactionid')); | |
811 | echo html_writer::select($displaylist, 'formaction', '', array('' => 'choosedots'), array('id' => 'formactionid')); | |
812 | ||
813 | echo '<input type="hidden" name="id" value="'.$course->id.'" />'; | |
814 | echo '<noscript style="display:inline">'; | |
815 | echo '<div><input type="submit" value="'.get_string('ok').'" /></div>'; | |
816 | echo '</noscript>'; | |
817 | echo '</div></div>'; | |
818 | echo '</form>'; | |
819 | ||
820 | $module = array('name' => 'core_user', 'fullpath' => '/user/module.js'); | |
821 | $PAGE->requires->js_init_call('M.core_user.init_participation', null, false, $module); | |
822 | } | |
b90e2f19 | 823 | |
a2ed6e69 SH |
824 | // Show a search box if all participants don't fit on a single screen. |
825 | if ($totalcount > $perpage) { | |
826 | echo '<form action="index.php" class="searchform"><div><input type="hidden" name="id" value="'.$course->id.'" />'; | |
827 | echo '<label for="search">' . get_string('search', 'search') . ' </label>'; | |
828 | echo '<input type="text" id="search" name="search" value="'.s($search).'" /> <input type="submit" value="'.get_string('search').'" /></div></form>'."\n"; | |
829 | } | |
77c645df | 830 | |
a2ed6e69 SH |
831 | $perpageurl = clone($baseurl); |
832 | $perpageurl->remove_params('perpage'); | |
833 | if ($perpage == SHOW_ALL_PAGE_SIZE) { | |
834 | $perpageurl->param('perpage', DEFAULT_PAGE_SIZE); | |
835 | echo $OUTPUT->container(html_writer::link($perpageurl, get_string('showperpage', '', DEFAULT_PAGE_SIZE)), array(), 'showall'); | |
77c645df | 836 | |
a2ed6e69 SH |
837 | } else if ($matchcount > 0 && $perpage < $matchcount) { |
838 | $perpageurl->param('perpage', SHOW_ALL_PAGE_SIZE); | |
839 | echo $OUTPUT->container(html_writer::link($perpageurl, get_string('showall', '', $matchcount)), array(), 'showall'); | |
840 | } | |
99cca847 | 841 | |
a2ed6e69 | 842 | echo '</div>'; // Userlist. |
f9903ed0 | 843 | |
a2ed6e69 | 844 | echo $OUTPUT->footer(); |
77c645df | 845 | |
a2ed6e69 SH |
846 | if ($userlist) { |
847 | $userlist->close(); | |
848 | } | |
77c645df | 849 | |
a2ed6e69 SH |
850 | /** |
851 | * Returns SQL that can be used to limit a query to a period where the user last accessed a course.. | |
852 | * | |
853 | * @param string $accesssince | |
854 | * @return string | |
855 | */ | |
0749caef | 856 | function get_course_lastaccess_sql($accesssince='') { |
31b71336 | 857 | if (empty($accesssince)) { |
858 | return ''; | |
859 | } | |
a2ed6e69 | 860 | if ($accesssince == -1) { // Never. |
4f0c2d00 | 861 | return 'ul.timeaccess = 0'; |
31b71336 | 862 | } else { |
4f0c2d00 | 863 | return 'ul.timeaccess != 0 AND ul.timeaccess < '.$accesssince; |
0749caef | 864 | } |
865 | } | |
866 | ||
a2ed6e69 SH |
867 | /** |
868 | * Returns SQL that can be used to limit a query to a period where the user last accessed the system. | |
869 | * | |
870 | * @param string $accesssince | |
871 | * @return string | |
872 | */ | |
0749caef | 873 | function get_user_lastaccess_sql($accesssince='') { |
874 | if (empty($accesssince)) { | |
875 | return ''; | |
876 | } | |
a2ed6e69 | 877 | if ($accesssince == -1) { // Never. |
4f0c2d00 | 878 | return 'u.lastaccess = 0'; |
0749caef | 879 | } else { |
4f0c2d00 | 880 | return 'u.lastaccess != 0 AND u.lastaccess < '.$accesssince; |
31b71336 | 881 | } |
882 | } |