10
10
define('DEFAULT_PAGE_SIZE', 20);
11
11
define('SHOW_ALL_PAGE_SIZE', 5000);
13
$group = optional_param('group', -1, PARAM_INT); // Group to show
14
13
$page = optional_param('page', 0, PARAM_INT); // which page to show
15
14
$perpage = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT); // how many per page
16
15
$mode = optional_param('mode', NULL); // '0' for less details, '1' for more
17
$accesssince = optional_param('accesssince',0,PARAM_INT); // filter by last access. -1 = never
16
$accesssince = optional_param('accesssince',0,PARAM_INT); // filter by last access. -1 = never
18
17
$search = optional_param('search','',PARAM_CLEAN);
19
$roleid = optional_param('roleid', 0, PARAM_INT); // optional roleid
18
$roleid = optional_param('roleid', 0, PARAM_INT); // optional roleid, -1 means all site users on frontpage
21
$contextid = optional_param('contextid', 0, PARAM_INT); // one of this or
22
$courseid = optional_param('id', 0, PARAM_INT); // this are required
20
$contextid = optional_param('contextid', 0, PARAM_INT); // one of this or
21
$courseid = optional_param('id', 0, PARAM_INT); // this are required
25
24
if (! $context = get_context_instance_by_id($contextid)) {
43
42
require_login($course);
45
44
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
45
$frontpagectx = get_context_instance(CONTEXT_COURSE, SITEID);
47
if (!has_capability('moodle/course:viewparticipants', $context)) {
48
print_error('nopermissions');
47
if ($context->id != $frontpagectx->id) {
48
require_capability('moodle/course:viewparticipants', $context);
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
51
56
$rolenames = array();
52
57
$avoidroles = array();
54
59
if ($roles = get_roles_used_in_context($context, true)) {
55
// We should ONLY allow roles with moodle/course:view because otherwise we get little niggly issues
60
// We should ONLY allow roles with moodle/course:view because otherwise we get little niggly issues
57
// We should further exclude "admin" users (those with "doanything" at site level) because
62
// We should further exclude "admin" users (those with "doanything" at site level) because
58
63
// Otherwise they appear in every participant list
60
65
$canviewroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
61
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();
63
76
foreach ($roles as $role) {
64
77
if (!isset($canviewroles[$role->id])) { // Avoid this role (eg course creator)
65
78
$avoidroles[] = $role->id;
71
84
unset($roles[$role->id]);
87
$rolenames[$role->id] = strip_tags(role_get_name($role, $context)); // Used in menus etc later on
76
foreach ($roles as $role) {
77
$rolenames[$role->id] = strip_tags(format_string($role->name)); // 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]);
81
96
// no roles to display yet?
82
if (empty($rolenames)) {
83
if (has_capability('moodle/user:assign', $context)) {
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)) {
84
100
redirect($CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id);
86
102
error ('No participants found for this course');
127
143
$isseparategroups = ($course->groupmode == SEPARATEGROUPS and $course->groupmodeforce and
128
144
!has_capability('moodle/site:accessallgroups', $context));
130
if ($isseparategroups and (!$currentgroup) ) {
131
print_header("$course->shortname: ".get_string('participants'), $course->fullname,
132
"<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a> -> ".
133
get_string('participants'), "", "", true, " ", navmenu($course));
134
print_heading(get_string("notingroup", "forum"));
146
if ($isseparategroups and (!$currentgroup) ) {
148
$navlinks[] = array('name' => get_string('participants'), 'link' => null, 'type' => 'misc');
149
$navigation = build_navigation($navlinks);
151
print_header("$course->shortname: ".get_string('participants'), $course->fullname, $navigation, "", "", true, " ", navmenu($course));
152
print_heading(get_string("notingroup"));
135
153
print_footer($course);
139
157
// Should use this variable so that we don't break stuff every time a variable is added or changed.
140
$baseurl = $CFG->wwwroot.'/user/index.php?contextid='.$context->id.'&roleid='.$roleid.'&id='.$course->id.'&group='.$currentgroup.'&perpage='.$perpage.'&accesssince='.$accesssince.'&search='.s($search);
158
$baseurl = $CFG->wwwroot.'/user/index.php?contextid='.$context->id.'&roleid='.$roleid.'&id='.$course->id.'&perpage='.$perpage.'&accesssince='.$accesssince.'&search='.s($search);
142
160
/// Print headers
144
if ($course->id != SITEID) {
145
print_header("$course->shortname: ".get_string('participants'), $course->fullname,
146
"<a href=\"../course/view.php?id=$course->id\">$course->shortname</a> -> ".
147
get_string('participants'), "", "", true, " ", navmenu($course));
149
print_header("$course->shortname: ".get_string('participants'), $course->fullname,
150
get_string('participants'), "", "", true, " ", navmenu($course));
163
$navlinks[] = array('name' => get_string('participants'), 'link' => null, 'type' => 'misc');
164
$navigation = build_navigation($navlinks);
166
print_header("$course->shortname: ".get_string('participants'), $course->fullname, $navigation, "", "", true, " ", navmenu($course));
155
168
/// setting up tags
156
169
if ($course->id == SITEID) {
187
204
foreach ($mycourses as $mycourse) {
188
205
$courselist[$mycourse->id] = format_string($mycourse->shortname);
207
if (has_capability('moodle/site:viewparticipants', $sitecontext)) {
208
unset($courselist[SITEID]);
209
$courselist = array(SITEID => format_string($SITE->shortname)) + $courselist;
190
211
popup_form($CFG->wwwroot.'/user/index.php?roleid='.$roleid.'&sifirst=&silast=&id=',
191
212
$courselist, 'courseform', $course->id, '', '', '', false, 'self', get_string('mycourses'));
195
216
echo '<td class="left">';
196
setup_and_print_groups($course, $groupmode, $baseurl);
217
groups_print_course_menu($course, $baseurl);
199
// get minimum lastaccess for this course and display a dropbox to filter by lastaccess going back this far.
200
// this might not work anymore because you always going to get yourself as the most recent entry? added $USER!=$user ch
201
$minlastaccess = get_field_sql('SELECT min(timeaccess) FROM '.$CFG->prefix.'user_lastaccess WHERE courseid = '.$course->id.' AND timeaccess != 0 AND userid!='.$USER->id);
202
$lastaccess0exists = record_exists('user_lastaccess','courseid',$course->id,'timeaccess',0);
203
$now = usergetmidnight(time());
204
$timeaccess = array();
206
// makes sense for this to go first.
207
$timeoptions[0] = get_string('selectperiod');
210
for ($i = 1; $i < 7; $i++) {
211
if (strtotime('-'.$i.' days',$now) >= $minlastaccess) {
212
$timeoptions[strtotime('-'.$i.' days',$now)] = get_string('numdays','moodle',$i);
216
for ($i = 1; $i < 10; $i++) {
217
if (strtotime('-'.$i.' weeks',$now) >= $minlastaccess) {
218
$timeoptions[strtotime('-'.$i.' weeks',$now)] = get_string('numweeks','moodle',$i);
222
for ($i = 2; $i < 12; $i++) {
223
if (strtotime('-'.$i.' months',$now) >= $minlastaccess) {
224
$timeoptions[strtotime('-'.$i.' months',$now)] = get_string('nummonths','moodle',$i);
228
if (strtotime('-1 year',$now) >= $minlastaccess) {
229
$timeoptions[strtotime('-1 year',$now)] = get_string('lastyear');
232
if (!empty($lastaccess0exists)) {
233
$timeoptions[-1] = get_string('never');
236
if (count($timeoptions) > 1) {
237
echo '<td class="left">';
238
$baseurl = preg_replace('/&accesssince='.$accesssince.'/','',$baseurl);
239
popup_form($baseurl.'&accesssince=',$timeoptions,'timeoptions',$accesssince, '', '', '', false, 'self', get_string('usersnoaccesssince'));
220
if (!isset($hiddenfields['lastaccess'])) {
221
// get minimum lastaccess for this course and display a dropbox to filter by lastaccess going back this far.
222
// we need to make it diferently for normal courses and site course
223
if ($context->id != $frontpagectx->id) {
224
$minlastaccess = get_field_sql('SELECT min(timeaccess)
225
FROM '.$CFG->prefix.'user_lastaccess
226
WHERE courseid = '.$course->id.'
227
AND timeaccess != 0');
228
$lastaccess0exists = record_exists('user_lastaccess', 'courseid', $course->id, 'timeaccess', 0);
230
$minlastaccess = get_field_sql('SELECT min(lastaccess)
231
FROM '.$CFG->prefix.'user
232
WHERE lastaccess != 0');
233
$lastaccess0exists = record_exists('user','lastaccess',0);
236
$now = usergetmidnight(time());
237
$timeaccess = array();
239
// makes sense for this to go first.
240
$timeoptions[0] = get_string('selectperiod');
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);
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);
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);
261
if (strtotime('-1 year',$now) >= $minlastaccess) {
262
$timeoptions[strtotime('-1 year',$now)] = get_string('lastyear');
265
if (!empty($lastaccess0exists)) {
266
$timeoptions[-1] = get_string('never');
269
if (count($timeoptions) > 1) {
270
echo '<td class="left">';
271
$baseurl = preg_replace('/&accesssince='.$accesssince.'/','',$baseurl);
272
popup_form($baseurl.'&accesssince=',$timeoptions,'timeoptions',$accesssince, '', '', '', false, 'self', get_string('usersnoaccesssince'));
248
282
echo '</td></tr></table>';
250
284
if ($currentgroup and (!$isseparategroups or has_capability('moodle/site:accessallgroups', $context))) { /// Display info about the group
251
if ($group = groups_get_group($currentgroup)) { //TODO:
285
if ($group = groups_get_group($currentgroup)) {
252
286
if (!empty($group->description) or (!empty($group->picture) and empty($group->hidepicture))) {
253
287
echo '<table class="groupinfobox"><tr><td class="left side picture">';
254
288
print_group_picture($group, $course->id, true, false, false);
255
289
echo '</td><td class="content">';
256
290
echo '<h3>'.$group->name;
257
291
if (has_capability('moodle/course:managegroups', $context)) {
258
echo ' <a title="'.get_string('editgroupprofile').'" href="'.groups_group_edit_url($course->id, $group->id).'">';
292
echo ' <a title="'.get_string('editgroupprofile').'" href="'.$CFG->wwwroot.'/group/group.php?id='.$group->id.'&courseid='.$group->courseid.'">';
259
293
echo '<img src="'.$CFG->pixpath.'/t/edit.gif" alt="'.get_string('editgroupprofile').'" />';
324
359
$listofcontexts = '('.$sitecontext->id.')'; // must be site
327
362
$selectrole = " AND r.roleid = $roleid ";
329
364
$selectrole = " ";
331
$select = 'SELECT u.id, u.username, u.firstname, u.lastname, u.email, u.city, u.country, u.picture, u.lang, u.timezone, u.emailstop, u.maildisplay, ul.timeaccess AS lastaccess, r.hidden '; // s.lastaccess
332
$select .= $course->enrolperiod?', r.timeend ':'';
334
$from = "FROM {$CFG->prefix}user u INNER JOIN
335
{$CFG->prefix}role_assignments r on u.id=r.userid LEFT OUTER JOIN
336
{$CFG->prefix}user_lastaccess ul on (r.userid=ul.userid and ul.courseid = $course->id)";
338
$hiddensql = has_capability('moodle/role:viewhiddenassigns', $context)? '':' AND r.hidden = 0 ';
367
if ($context->id != $frontpagectx->id) {
368
$select = 'SELECT DISTINCT u.id, u.username, u.firstname, u.lastname,
369
u.email, u.city, u.country, u.picture,
370
u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
371
COALESCE(ul.timeaccess, 0) AS lastaccess,
373
ctx.id AS ctxid, ctx.path AS ctxpath,
374
ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel ';
375
$select .= $course->enrolperiod?', r.timeend ':'';
378
$select = 'SELECT u.id, u.username, u.firstname, u.lastname,
379
u.email, u.city, u.country, u.picture,
380
u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
381
u.lastaccess, r.hidden,
382
ctx.id AS ctxid, ctx.path AS ctxpath,
383
ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel ';
385
$select = 'SELECT u.id, u.username, u.firstname, u.lastname,
386
u.email, u.city, u.country, u.picture,
387
u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt,
389
ctx.id AS ctxid, ctx.path AS ctxpath,
390
ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel ';
394
if ($context->id != $frontpagectx->id or $roleid >= 0) {
395
$from = "FROM {$CFG->prefix}user u
396
LEFT OUTER JOIN {$CFG->prefix}context ctx
397
ON (u.id=ctx.instanceid AND ctx.contextlevel = ".CONTEXT_USER.")
398
JOIN {$CFG->prefix}role_assignments r
400
LEFT OUTER JOIN {$CFG->prefix}user_lastaccess ul
401
ON (r.userid=ul.userid and ul.courseid = $course->id) ";
403
// on frontpage and we want all registered users
404
$from = "FROM {$CFG->prefix}user u
405
LEFT OUTER JOIN {$CFG->prefix}context ctx
406
ON (u.id=ctx.instanceid AND ctx.contextlevel = ".CONTEXT_USER.") ";
409
$hiddensql = has_capability('moodle/role:viewhiddenassigns', $context)? '':' AND r.hidden = 0 ';
340
411
// exclude users with roles we are avoiding
341
412
if ($avoidroles) {
346
417
$adminroles = '';
349
420
// join on 2 conditions
350
421
// otherwise we run into the problem of having records in ul table, but not relevant course
351
422
// and user record is not pulled out
352
$where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
353
AND u.deleted = 0 $selectrole
354
AND (ul.courseid = $course->id OR ul.courseid IS NULL)
355
AND u.username != 'guest'
358
$where .= get_lastaccess_sql($accesssince);
424
if ($context->id != $frontpagectx->id) {
425
$where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
426
AND u.deleted = 0 $selectrole
427
AND (ul.courseid = $course->id OR ul.courseid IS NULL)
428
AND u.username != 'guest'
431
$where .= get_course_lastaccess_sql($accesssince);
434
$where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
435
AND u.deleted = 0 $selectrole
436
AND u.username != 'guest'";
437
$where .= get_user_lastaccess_sql($accesssince);
439
$where = "WHERE u.deleted = 0
440
AND u.username != 'guest'";
441
$where .= get_user_lastaccess_sql($accesssince);
360
444
$wheresearch = '';
362
446
if (!empty($search)) {
378
462
$where .= ' AND '.$table->get_sql_where();
465
/// Always add r.hidden to sort in order to guarantee hiddens to "win"
466
/// in the resolution of duplicates later - MDL-13935
467
/// Only exception is frontpage that doesn't have such r.hidden info
468
/// because it retrieves ALL users (without role checking) - MDL-14034
381
469
if ($table->get_sql_sort()) {
382
470
$sort = ' ORDER BY '.$table->get_sql_sort();
471
if ($context->id != $frontpagectx->id or $roleid >= 0) {
472
$sort .= ', r.hidden DESC';
476
if ($context->id != $frontpagectx->id or $roleid >= 0) {
477
$sort .= ' ORDER BY r.hidden DESC';
387
481
$matchcount = count_records_sql('SELECT COUNT(distinct u.id) '.$from.$where.$wheresearch);
389
$table->initialbars($totalcount > $perpage);
483
$table->initialbars(true);
390
484
$table->pagesize($perpage, $matchcount);
392
$userlist = get_records_sql($select.$from.$where.$wheresearch.$sort,
486
$userlist = get_recordset_sql($select.$from.$where.$wheresearch.$sort,
393
487
$table->get_page_start(), $table->get_page_size());
489
if ($context->id == $frontpagectx->id) {
490
$strallsiteusers = get_string('allsiteusers', 'role');
491
if ($CFG->defaultfrontpageroleid) {
492
if ($fprole = get_record('role', 'id', $CFG->defaultfrontpageroleid)) {
493
$fprole = role_get_name($fprole, $frontpagectx);
494
$strallsiteusers = "$strallsiteusers ($fprole)";
497
$rolenames = array(-1 => $strallsiteusers) + $rolenames;
395
500
/// If there are multiple Roles in the course, then show a drop down menu for switching
397
501
if (count($rolenames) > 1) {
398
502
echo '<div class="rolesform">';
399
echo get_string('currentrole', 'role').': ';
400
$rolenames = array(0 => get_string('all')) + $rolenames;
503
echo '<label for="rolesform_jump">'.get_string('currentrole', 'role').' </label>';
504
if ($context->id != $frontpagectx->id) {
505
$rolenames = array(0 => get_string('all')) + $rolenames;
507
if (!$CFG->defaultfrontpageroleid) {
508
// we do not want "All users with role" - we already have all users in defualt frontpage role option
509
$rolenames = array(0 => get_string('userswithrole', 'role')) + $rolenames;
401
512
popup_form("$CFG->wwwroot/user/index.php?contextid=$context->id&sifirst=&silast=&roleid=", $rolenames,
402
513
'rolesform', $roleid, '');
516
} else if (count($rolenames) == 1) {
517
// when all users with the same role - print its name
518
echo '<div class="rolesform">';
519
echo get_string('role').': ';
520
$rolename = reset($rolenames);
406
526
if (!$currentrole = get_record('role','id',$roleid)) {
407
527
error('That role does not exist');
409
529
$a->number = $totalcount;
410
$a->role = $currentrole->name;
530
// MDL-12217, use course specific rolename
531
if (isset($rolenames[$currentrole->id])){
532
$a->role = $rolenames[$currentrole->id];
534
$a->role = $currentrole->name;//safety net
411
536
$heading = format_string(get_string('xuserswiththerole', 'role', $a));
538
if ($currentgroup and $group) {
539
$a->group = $group->name;
540
$heading .= ' ' . format_string(get_string('ingroup', 'role', $a));
544
$a->timeperiod = $timeoptions[$accesssince];
545
$heading .= ' ' . format_string(get_string('inactiveformorethan', 'role', $a));
548
$heading .= ": $a->number";
412
549
if (user_can_assign($context, $roleid)) {
413
550
$heading .= ' <a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?roleid='.$roleid.'&contextid='.$context->id.'">';
414
551
$heading .= '<img src="'.$CFG->pixpath.'/i/edit.gif" class="icon" alt="" /></a>';
416
553
print_heading($heading, 'center', 3);
555
if ($course->id != SITEID && has_capability('moodle/role:assign', $context)) {
556
$editlink = ' <a href="'.$CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id.'">';
557
$editlink .= '<img src="'.$CFG->pixpath.'/i/edit.gif" class="icon" alt="" /></a>';
561
if ($course->id == SITEID and $roleid < 0) {
562
$strallparticipants = get_string('allsiteusers', 'role');
564
$strallparticipants = get_string('allparticipants');
418
566
if ($matchcount < $totalcount) {
419
print_heading(get_string('allparticipants').': '.$matchcount.'/'.$totalcount, '', 3);
567
print_heading($strallparticipants.': '.$matchcount.'/'.$totalcount . $editlink, '', 3);
421
print_heading(get_string('allparticipants').': '.$matchcount, '', 3);
569
print_heading($strallparticipants.': '.$matchcount . $editlink, '', 3);
550
712
$country = $countries[$user->country];
554
$usercontext = get_context_instance(CONTEXT_USER, $user->id);
556
if ($piclink = ($USER->id == $user->id || has_capability('moodle/user:viewdetails', $context) ||has_capability('moodle/user:viewdetails', $context))) {
716
if (!isset($user->context)) {
717
$usercontext = get_context_instance(CONTEXT_USER, $user->id);
719
$usercontext = $user->context;
722
if ($piclink = ($USER->id == $user->id || has_capability('moodle/user:viewdetails', $context) || has_capability('moodle/user:viewdetails', $usercontext))) {
557
723
$profilelink = '<strong><a href="'.$CFG->wwwroot.'/user/view.php?id='.$user->id.'&course='.$course->id.'">'.fullname($user).'</a></strong>';
559
$profilelink = '<strong>'.fullname($user).'</strong>';
725
$profilelink = '<strong>'.fullname($user).'</strong>';
563
print_user_picture($user->id, $course->id, $user->picture, false, true, $piclink),
729
print_user_picture($user, $course->id, $user->picture, false, true, $piclink),
730
$profilelink . $hidden);
566
732
if (!isset($hiddenfields['city'])) {
567
733
$data[] = $user->city;
596
762
echo '<input type="button" onclick="checkall()" value="'.get_string('selectall').'" /> ';
597
763
echo '<input type="button" onclick="checknone()" value="'.get_string('deselectall').'" /> ';
598
764
$displaylist = array();
599
// fix for MDL-8885, only show this if user has capability
600
if (has_capability('moodle/site:readallmessages', $context) && !empty($CFG->messaging)) {
601
$displaylist['messageselect.php'] = get_string('messageselectadd');
765
$displaylist['messageselect.php'] = get_string('messageselectadd');
766
if (!empty($CFG->enablenotes) && has_capability('moodle/notes:manage', $context) && $context->id != $frontpagectx->id) {
767
$displaylist['addnote.php'] = get_string('addnewnote', 'notes');
768
$displaylist['groupaddnote.php'] = get_string('groupaddnewnote', 'notes');
603
if ($course->enrolperiod) {
771
if ($context->id != $frontpagectx->id) {
604
772
$displaylist['extendenrol.php'] = get_string('extendenrol');
773
$displaylist['groupextendenrol.php'] = get_string('groupextendenrol');
606
776
helpbutton("participantswithselectedusers", get_string("withselectedusers"));
607
777
choose_from_menu ($displaylist, "formaction", "", get_string("withselectedusers"), "if(checksubmit(this.form))this.form.submit();", "");
608
778
echo '<input type="hidden" name="id" value="'.$course->id.'" />';
609
echo '<input type="submit" value="' . get_string('ok') . '" />';
779
echo '<div id="noscriptparticipantsform" style="display: inline;">';
780
echo '<input type="submit" value="'.get_string('ok').'" /></div>';
781
echo '<script type="text/javascript">'.
783
'document.getElementById("noscriptparticipantsform").style.display = "none";'.
784
"\n//]]>\n".'</script>';