libdir.'/tablelib.php'); define('USER_SMALL_CLASS', 20); // Below this is considered small define('USER_LARGE_CLASS', 200); // Above this is considered large define('DEFAULT_PAGE_SIZE', 20); define('SHOW_ALL_PAGE_SIZE', 5000); define('MODE_BRIEF', 0); define('MODE_USERDETAILS', 1); define('MODE_ENROLDETAILS', 2); $page = optional_param('page', 0, PARAM_INT); // which page to show $perpage = optional_param('perpage', DEFAULT_PAGE_SIZE, PARAM_INT); // how many per page $mode = optional_param('mode', NULL); // use the MODE_ constants $accesssince = optional_param('accesssince',0,PARAM_INT); // filter by last access. -1 = never $search = optional_param('search','',PARAM_CLEAN); $roleid = optional_param('roleid', 0, PARAM_INT); // optional roleid $contextid = optional_param('contextid', 0, PARAM_INT); // one of this or $courseid = optional_param('id', 0, PARAM_INT); // this are required if ($contextid) { if (! $context = get_context_instance_by_id($contextid)) { error("Context ID is incorrect"); } if (! $course = get_record('course', 'id', $context->instanceid)) { error("Course ID is incorrect"); } } else { if (! $course = get_record('course', 'id', $courseid)) { error("Course ID is incorrect"); } if (! $context = get_context_instance(CONTEXT_COURSE, $course->id)) { error("Context ID is incorrect"); } } // not needed anymore unset($contextid); unset($courseid); require_login($course); $sitecontext = get_context_instance(CONTEXT_SYSTEM); $frontpagectx = get_context_instance(CONTEXT_COURSE, SITEID); if ($context->id != $frontpagectx->id) { require_capability('moodle/course:viewparticipants', $context); } else { require_capability('moodle/site:viewparticipants', $sitecontext); } /// front page course is different $rolenames = array(); $avoidroles = array(); if ($roles = get_roles_used_in_context($context, true)) { // We should ONLY allow roles with moodle/course:view because otherwise we get little niggly issues // like MDL-8093 // We should further exclude "admin" users (those with "doanything" at site level) because // Otherwise they appear in every participant list $canviewroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context); $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext); foreach ($roles as $role) { if (!isset($canviewroles[$role->id])) { // Avoid this role (eg course creator) $avoidroles[] = $role->id; unset($roles[$role->id]); continue; } if (isset($doanythingroles[$role->id])) { // Avoid this role (ie admin) $avoidroles[] = $role->id; unset($roles[$role->id]); continue; } $rolenames[$role->id] = strip_tags(role_get_name($role, $context)); // Used in menus etc later on } } // no roles to display yet? // frontpage course is an exception, on the front page course we should display all users if (empty($rolenames) && $context->id != $frontpagectx->id) { if (has_capability('moodle/role:assign', $context)) { redirect($CFG->wwwroot.'/'.$CFG->admin.'/roles/assign.php?contextid='.$context->id); } else { error ('No participants found for this course'); } } add_to_log($course->id, 'user', 'view all', 'index.php?id='.$course->id, ''); $bulkoperations = has_capability('moodle/course:bulkmessaging', $context); $countries = get_list_of_countries(); $strnever = get_string('never'); $datestring->year = get_string('year'); $datestring->years = get_string('years'); $datestring->day = get_string('day'); $datestring->days = get_string('days'); $datestring->hour = get_string('hour'); $datestring->hours = get_string('hours'); $datestring->min = get_string('min'); $datestring->mins = get_string('mins'); $datestring->sec = get_string('sec'); $datestring->secs = get_string('secs'); if ($mode !== NULL) { $mode = (int)$mode; $SESSION->userindexmode = $mode; } else if (isset($SESSION->userindexmode)) { $mode = (int)$SESSION->userindexmode; } else { $mode = MODE_BRIEF; } /// Check to see if groups are being used in this forum /// and if so, set $currentgroup to reflect the current group $groupmode = groups_get_course_groupmode($course); // Groups are being used $currentgroup = groups_get_course_group($course, true); if (!$currentgroup) { // To make some other functions work better later $currentgroup = NULL; } $isseparategroups = ($course->groupmode == SEPARATEGROUPS and $course->groupmodeforce and !has_capability('moodle/site:accessallgroups', $context)); if ($isseparategroups and (!$currentgroup) ) { $navlinks = array(); $navlinks[] = array('name' => get_string('participants'), 'link' => null, 'type' => 'misc'); $navigation = build_navigation($navlinks); print_header("$course->shortname: ".get_string('participants'), $course->fullname, $navigation, "", "", true, " ", navmenu($course)); print_heading(get_string("notingroup", "forum")); print_footer($course); exit; } // Should use this variable so that we don't break stuff every time a variable is added or changed. $baseurl = $CFG->wwwroot.'/user/index.php?contextid='.$context->id.'&roleid='.$roleid.'&id='.$course->id.'&perpage='.$perpage.'&accesssince='.$accesssince.'&search='.s($search); /// Print headers $navlinks = array(); $navlinks[] = array('name' => get_string('participants'), 'link' => null, 'type' => 'misc'); $navigation = build_navigation($navlinks); print_header("$course->shortname: ".get_string('participants'), $course->fullname, $navigation, "", "", true, " ", navmenu($course)); /// setting up tags if ($course->id == SITEID) { $filtertype = 'site'; } else if ($course->id && !$currentgroup) { $filtertype = 'course'; $filterselect = $course->id; } else { $filtertype = 'group'; $filterselect = $currentgroup; } $currenttab = 'participants'; $user = $USER; require_once($CFG->dirroot .'/user/tabs.php'); /// Get the hidden field list if (has_capability('moodle/course:viewhiddenuserfields', $context)) { $hiddenfields = array(); // teachers and admins are allowed to see everything } else { $hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields)); } /// Print settings and things in a table across the top echo ''; /// Print my course menus if ($mycourses = get_my_courses($USER->id)) { echo ''; } echo ''; // get minimum lastaccess for this course and display a dropbox to filter by lastaccess going back this far. // this might not work anymore because you always going to get yourself as the most recent entry? added $USER!=$user ch $minlastaccess = get_field_sql('SELECT min(timeaccess) FROM '.$CFG->prefix.'user_lastaccess WHERE courseid = '.$course->id.' AND timeaccess != 0 AND userid!='.$USER->id); $lastaccess0exists = record_exists('user_lastaccess','courseid',$course->id,'timeaccess',0); $now = usergetmidnight(time()); $timeaccess = array(); // makes sense for this to go first. $timeoptions[0] = get_string('selectperiod'); // days for ($i = 1; $i < 7; $i++) { if (strtotime('-'.$i.' days',$now) >= $minlastaccess) { $timeoptions[strtotime('-'.$i.' days',$now)] = get_string('numdays','moodle',$i); } } // weeks for ($i = 1; $i < 10; $i++) { if (strtotime('-'.$i.' weeks',$now) >= $minlastaccess) { $timeoptions[strtotime('-'.$i.' weeks',$now)] = get_string('numweeks','moodle',$i); } } // months for ($i = 2; $i < 12; $i++) { if (strtotime('-'.$i.' months',$now) >= $minlastaccess) { $timeoptions[strtotime('-'.$i.' months',$now)] = get_string('nummonths','moodle',$i); } } // try a year if (strtotime('-1 year',$now) >= $minlastaccess) { $timeoptions[strtotime('-1 year',$now)] = get_string('lastyear'); } if (!empty($lastaccess0exists)) { $timeoptions[-1] = get_string('never'); } if (count($timeoptions) > 1) { echo ''; } // Decide wheteher we will fetch extra enrolment/groups data. // // MODE_ENROLDETAILS is expensive, and only suitable where the listing is small // (at or below DEFAULT_PAGE_SIZE) and $USER can enrol/unenrol // (will take 1 extra DB query - 2 on Oracle) // if ($course->id != SITEID && $perpage <= DEFAULT_PAGE_SIZE && has_capability('moodle/role:assign',$context)) { $allowenroldetails=true; } else { $allowenroldetails=false; } if ($mode === MODE_ENROLDETAILS && !($allowenroldetails)) { // conditions haven't been met - reset $mode = MODE_BRIEF; } echo '
'; $courselist = array(); foreach ($mycourses as $mycourse) { $courselist[$mycourse->id] = format_string($mycourse->shortname); } popup_form($CFG->wwwroot.'/user/index.php?roleid='.$roleid.'&sifirst=&silast=&id=', $courselist, 'courseform', $course->id, '', '', '', false, 'self', get_string('mycourses')); echo ''; groups_print_course_menu($course, $baseurl); echo ''; $baseurl = preg_replace('/&accesssince='.$accesssince.'/','',$baseurl); popup_form($baseurl.'&accesssince=',$timeoptions,'timeoptions',$accesssince, '', '', '', false, 'self', get_string('usersnoaccesssince')); echo ''; $formatmenu = array( '0' => get_string('brief'), '1' => get_string('userdetails')); if ($allowenroldetails) { $formatmenu['2']= get_string('enroldetails'); } popup_form($baseurl.'&mode=', $formatmenu, 'formatmenu', $mode, '', '', '', false, 'self', get_string('userlist')); echo '
'; if ($currentgroup and (!$isseparategroups or has_capability('moodle/site:accessallgroups', $context))) { /// Display info about the group if ($group = groups_get_group($currentgroup)) { if (!empty($group->description) or (!empty($group->picture) and empty($group->hidepicture))) { echo '
'; print_group_picture($group, $course->id, true, false, false); echo ''; echo '

'.$group->name; if (has_capability('moodle/course:managegroups', $context)) { echo ' '; echo ''.get_string('editgroupprofile').''; echo ''; } echo '

'; echo format_text($group->description); echo '
'; } } } /// Define a table showing a list of users in the current role selection $tablecolumns = array('userpic', 'fullname'); $tableheaders = array(get_string('userpic'), get_string('fullname')); if ($mode === MODE_BRIEF && !isset($hiddenfields['city'])) { $tablecolumns[] = 'city'; $tableheaders[] = get_string('city'); } if ($mode === MODE_BRIEF && !isset($hiddenfields['country'])) { $tablecolumns[] = 'country'; $tableheaders[] = get_string('country'); } if (!isset($hiddenfields['lastaccess'])) { $tablecolumns[] = 'lastaccess'; $tableheaders[] = get_string('lastaccess'); } if ($course->enrolperiod) { $tablecolumns[] = 'timeend'; $tableheaders[] = get_string('enrolmentend'); } if ($mode === MODE_ENROLDETAILS) { $tablecolumns[] = 'roles'; $tableheaders[] = get_string('roles'); if ($groupmode != 0) { $tablecolumns[] = 'groups'; $tableheaders[] = get_string('groups'); if (!empty($CFG->enablegroupings)) { $tablecolumns[] = 'groupings'; $tableheaders[] = get_string('groupings', 'group'); } } } if ($bulkoperations) { $tablecolumns[] = 'select'; $tableheaders[] = get_string('select'); } $table = new flexible_table('user-index-participants-'.$course->id); $table->define_columns($tablecolumns); $table->define_headers($tableheaders); $table->define_baseurl($baseurl); $table->sortable(true, 'lastaccess', SORT_DESC); $table->no_sorting('roles'); $table->no_sorting('groups'); $table->no_sorting('groupings'); $table->no_sorting('select'); $table->set_attribute('cellspacing', '0'); $table->set_attribute('id', 'participants'); $table->set_attribute('class', 'generaltable generalbox'); $table->set_control_variables(array( TABLE_VAR_SORT => 'ssort', TABLE_VAR_HIDE => 'shide', TABLE_VAR_SHOW => 'sshow', TABLE_VAR_IFIRST => 'sifirst', TABLE_VAR_ILAST => 'silast', TABLE_VAR_PAGE => 'spage' )); $table->setup(); // we are looking for all users with this role assigned in this context or higher if ($usercontexts = get_parent_contexts($context)) { $listofcontexts = '('.implode(',', $usercontexts).')'; } else { $listofcontexts = '('.$sitecontext->id.')'; // must be site } if ($roleid) { $selectrole = " AND r.roleid = $roleid "; } else { $selectrole = " "; } if ($context->id != $frontpagectx->id) { $select = 'SELECT DISTINCT u.id, u.username, u.firstname, u.lastname, u.email, u.city, u.country, u.picture, u.lang, u.timezone, u.emailstop, u.maildisplay, u.imagealt, COALESCE(ul.timeaccess, 0) AS lastaccess, r.hidden, ctx.id AS ctxid, ctx.path AS ctxpath, ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel '; $select .= $course->enrolperiod?', r.timeend ':''; } else { $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, u.imagealt, u.lastaccess, ctx.id AS ctxid, ctx.path AS ctxpath, ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel '; } if ($context->id != $frontpagectx->id) { $from = "FROM {$CFG->prefix}user u LEFT OUTER JOIN {$CFG->prefix}context ctx ON (u.id=ctx.instanceid AND ctx.contextlevel = ".CONTEXT_USER.") JOIN {$CFG->prefix}role_assignments r ON u.id=r.userid LEFT OUTER JOIN {$CFG->prefix}user_lastaccess ul ON (r.userid=ul.userid and ul.courseid = $course->id) "; } else { $from = "FROM {$CFG->prefix}user u LEFT OUTER JOIN {$CFG->prefix}context ctx ON (u.id=ctx.instanceid AND ctx.contextlevel = ".CONTEXT_USER.") "; } $hiddensql = has_capability('moodle/role:viewhiddenassigns', $context)? '':' AND r.hidden = 0 '; // exclude users with roles we are avoiding if ($avoidroles) { $adminroles = 'AND r.roleid NOT IN ('; $adminroles .= implode(',', $avoidroles); $adminroles .= ')'; } else { $adminroles = ''; } // join on 2 conditions // otherwise we run into the problem of having records in ul table, but not relevant course // and user record is not pulled out if ($context->id != $frontpagectx->id) { $where = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts) AND u.deleted = 0 $selectrole AND (ul.courseid = $course->id OR ul.courseid IS NULL) AND u.username != 'guest' $adminroles $hiddensql "; $where .= get_lastaccess_sql($accesssince); } else { $where = "WHERE u.deleted = 0 AND u.username != 'guest'"; $where .= get_lastaccess_sql($accesssince); } $wheresearch = ''; if (!empty($search)) { $LIKE = sql_ilike(); $fullname = sql_fullname('u.firstname','u.lastname'); $wheresearch .= ' AND ('. $fullname .' '. $LIKE .'\'%'. $search .'%\' OR email '. $LIKE .'\'%'. $search .'%\' OR idnumber '.$LIKE.' \'%'.$search.'%\') '; } if ($currentgroup) { // Displaying a group by choice // FIX: TODO: This will not work if $currentgroup == 0, i.e. "those not in a group" $from .= 'LEFT JOIN '.$CFG->prefix.'groups_members gm ON u.id = gm.userid '; $where .= ' AND gm.groupid = '.$currentgroup; } $totalcount = count_records_sql('SELECT COUNT(distinct u.id) '.$from.$where); // Each user could have > 1 role if ($table->get_sql_where()) { $where .= ' AND '.$table->get_sql_where(); } if ($table->get_sql_sort()) { $sort = ' ORDER BY '.$table->get_sql_sort(); } else { $sort = ''; } $matchcount = count_records_sql('SELECT COUNT(distinct u.id) '.$from.$where.$wheresearch); $table->initialbars(true); $table->pagesize($perpage, $matchcount); $userlist = get_recordset_sql($select.$from.$where.$wheresearch.$sort, $table->get_page_start(), $table->get_page_size()); // // The SELECT behind get_participants_extra() is cheaper if we pass an array // if IDs. We could pass the SELECT we did before (with the limit bits - tricky!) // but this is much cheaper. And in any case, it is only doable with limited numbers // of rows anyway. On a large course it will explode badly... // if ($mode===MODE_ENROLDETAILS) { $userids = array(); while ($user = rs_fetch_next_record($userlist)) { $userids[] = $user->id; } $userlist_extra = get_participants_extra($userids, $avoidroles, $course, $context); // Only Oracle cannot seek backwards // and must re-query... if ($userlist->canSeek === true) { $userlist->MoveFirst(); } else { $userlist = get_recordset_sql($select.$from.$where.$wheresearch.$sort, $table->get_page_start(), $table->get_page_size()); } } /// If there are multiple Roles in the course, then show a drop down menu for switching if (count($rolenames) > 1) { echo '
'; echo get_string('currentrole', 'role').': '; $rolenames = array(0 => get_string('all')) + $rolenames; popup_form("$CFG->wwwroot/user/index.php?contextid=$context->id&sifirst=&silast=&roleid=", $rolenames, 'rolesform', $roleid, ''); echo '
'; } if ($roleid) { if (!$currentrole = get_record('role','id',$roleid)) { error('That role does not exist'); } $a->number = $totalcount; // MDL-12217, use course specific rolename if (isset($rolenames[$currentrole->id])){ $a->role = $rolenames[$currentrole->id]; }else{ $a->role = $currentrole->name;//safety net } $heading = format_string(get_string('xuserswiththerole', 'role', $a)); if (user_can_assign($context, $roleid)) { $heading .= ' '; $heading .= ''; } print_heading($heading, 'center', 3); } else { if ($matchcount < $totalcount) { print_heading(get_string('allparticipants').': '.$matchcount.'/'.$totalcount, '', 3); } else { print_heading(get_string('allparticipants').': '.$matchcount, '', 3); } } if ($bulkoperations) { echo ' '; echo '
'; echo '
'; echo ''; echo ''; } if ($CFG->longtimenosee > 0 && $CFG->longtimenosee < 1000 && $totalcount > 0) { echo '

('.get_string('unusedaccounts', '', $CFG->longtimenosee).')

'; } if ($mode===MODE_USERDETAILS) { // Print simple listing if ($totalcount < 1) { print_heading(get_string('nothingtodisplay')); } else { if ($totalcount > $perpage) { $firstinitial = $table->get_initial_first(); $lastinitial = $table->get_initial_last(); $strall = get_string('all'); $alpha = explode(',', get_string('alphabet')); // Bar of first initials echo '
'.get_string('firstname').' : '; if(!empty($firstinitial)) { echo ''.$strall.''; } else { echo ''.$strall.''; } foreach ($alpha as $letter) { if ($letter == $firstinitial) { echo ' '.$letter.''; } else { echo ' '.$letter.''; } } echo '
'; // Bar of last initials echo '
'.get_string('lastname').' : '; if(!empty($lastinitial)) { echo ''.$strall.''; } else { echo ''.$strall.''; } foreach ($alpha as $letter) { if ($letter == $lastinitial) { echo ' '.$letter.''; } else { echo ' '.$letter.''; } } echo '
'; print_paging_bar($matchcount, intval($table->get_page_start() / $perpage), $perpage, $baseurl.'&', 'spage'); } if ($matchcount > 0) { while ($user = rs_fetch_next_record($userlist)) { $user = make_context_subobj($user); print_user($user, $course, $bulkoperations); } } else { print_heading(get_string('nothingtodisplay')); } } } else { $countrysort = (strpos($sort, 'country') !== false); $timeformat = get_string('strftimedate'); if ($userlist) { // only show the plugin if multiple enrolment plugins // are enabled... if (strpos($CFG->enrol_plugins_enabled, ',')=== false) { $showenrolplugin = true; } else { $showenrolplugin = false; } while ($user = rs_fetch_next_record($userlist)) { $user = make_context_subobj($user); if ( !empty($user->hidden) ) { // if the assignment is hidden, display icon $hidden = " pixpath}/t/hide.gif\" alt=\"".get_string('hiddenassign')."\" class=\"hide-show-image\"/>"; } else { $hidden = ''; } if ($user->lastaccess) { $lastaccess = format_time(time() - $user->lastaccess, $datestring); } else { $lastaccess = $strnever; } if (empty($user->country)) { $country = ''; } else { if($countrysort) { $country = '('.$user->country.') '.$countries[$user->country]; } else { $country = $countries[$user->country]; } } if (!isset($user->context)) { $usercontext = get_context_instance(CONTEXT_USER, $user->id); } else { $usercontext = $user->context; } if ($piclink = ($USER->id == $user->id || has_capability('moodle/user:viewdetails', $context) ||has_capability('moodle/user:viewdetails', $context))) { $profilelink = ''.fullname($user).''; } else { $profilelink = ''.fullname($user).''; } $data = array ( print_user_picture($user, $course->id, $user->picture, false, true, $piclink), $profilelink . $hidden); if ($mode === MODE_BRIEF && !isset($hiddenfields['city'])) { $data[] = $user->city; } if ($mode === MODE_BRIEF && !isset($hiddenfields['country'])) { $data[] = $country; } if (!isset($hiddenfields['lastaccess'])) { $data[] = $lastaccess; } if ($course->enrolperiod) { if ($user->timeend) { $data[] = userdate($user->timeend, $timeformat); } else { $data[] = get_string('unlimited'); } } if (isset($userlist_extra) && isset($userlist_extra[$user->id])) { $ras = $userlist_extra[$user->id]['ra']; $rastring = ''; foreach ($ras AS $key=>$ra) { $rolename = $rolenames [ $ra['roleid'] ] ; if ($ra['ctxlevel'] == CONTEXT_COURSECAT) { $rastring .= $rolename. ' @ ' . ''.s($ra['ccname']).''; } elseif ($ra['ctxlevel'] == CONTEXT_SYSTEM) { $rastring .= $rolename. ' - ' . get_string('globalrole','role'); } else { $rastring .= $rolename; } if ($showenrolplugin) { $rastring .= '
'; } else { $rastring .= ' ('. $ra['enrolplugin'] .')
'; } } $data[] = $rastring; if ($groupmode != 0) { // htmlescape with s() and implode the array $data[] = implode(', ', array_map('s',$userlist_extra[$user->id]['group'])); if (!empty($CFG->enablegroupings)) { $data[] = implode(', ', array_map('s', $userlist_extra[$user->id]['gping'])); } } } if ($bulkoperations) { $data[] = ''; } $table->add_data($data); } } $table->print_html(); } if ($bulkoperations) { echo '
'; echo ' '; echo ' '; $displaylist = array(); $displaylist['messageselect.php'] = get_string('messageselectadd'); if (has_capability('moodle/notes:manage', $context) && $context->id != $frontpagectx->id) { $displaylist['addnote.php'] = get_string('addnewnote', 'notes'); $displaylist['groupaddnote.php'] = get_string('groupaddnewnote', 'notes'); } if ($context->id != $frontpagectx->id) { $displaylist['extendenrol.php'] = get_string('extendenrol'); $displaylist['groupextendenrol.php'] = get_string('groupextendenrol'); } helpbutton("participantswithselectedusers", get_string("withselectedusers")); choose_from_menu ($displaylist, "formaction", "", get_string("withselectedusers"), "if(checksubmit(this.form))this.form.submit();", ""); echo ''; echo ''; echo '
'; echo '
'; echo '
'; } if ($bulkoperations && $totalcount > ($perpage*3)) { echo '
'.get_string('search').': '."\n"; echo ' 
'."\n"; } $perpageurl = preg_replace('/&perpage=\d*/','', $baseurl); if ($perpage == SHOW_ALL_PAGE_SIZE) { echo '
'.get_string('showperpage', '', DEFAULT_PAGE_SIZE).'
'; } else if ($matchcount > 0 && $perpage < $matchcount) { echo '
'.get_string('showall', '', $matchcount).'
'; } print_footer($course); if ($userlist) { rs_close($userlist); } function get_lastaccess_sql($accesssince='') { if (empty($accesssince)) { return ''; } if ($accesssince == -1) { // never return ' AND ul.timeaccess = 0'; } else { return ' AND ul.timeaccess != 0 AND timeaccess < '.$accesssince; } } function get_participants_extra ($userids, $avoidroles, $course, $context) { global $CFG; if (count($userids) === 0 || count($avoidroles) === 0) { return array(); } $userids = implode(',', $userids); // turn the path into a list of context ids $contextids = substr($context->path, 1); // kill leading slash $contextids = str_replace('/', ',', $contextids);; if (count($avoidroles) > 0) { $avoidroles = implode(',', $avoidroles); $avoidrolescond = " AND ra.roleid NOT IN ($avoidroles) "; } else { $avoidrolescond = ''; } if (!empty($CFG->enablegroupings)) { $gpjoin = "LEFT OUTER JOIN {$CFG->prefix}groupings_groups gpg ON gpg.groupid=g.id LEFT OUTER JOIN {$CFG->prefix}groupings gp ON (gp.courseid={$course->id} AND gp.id=gpg.groupingid)"; $gpselect = ',gp.id AS gpid, gp.name AS gpname '; } else { $gpjoin = ''; $gpselect = ''; } // Note: this returns strange redundant rows, perhaps // due to the multiple OUTER JOINs. If we can tweak the // JOINs to avoid it ot $sql = "SELECT DISTINCT ra.userid, ctx.id AS ctxid, ctx.path AS ctxpath, ctx.depth AS ctxdepth, ctx.contextlevel AS ctxlevel, ctx.instanceid AS ctxinstanceid, cc.name AS ccname, ra.roleid AS roleid, ra.enrol AS enrolplugin, g.id AS gid, g.name AS gname $gpselect FROM {$CFG->prefix}role_assignments ra JOIN {$CFG->prefix}context ctx ON (ra.contextid=ctx.id) LEFT OUTER JOIN {$CFG->prefix}course_categories cc ON (ctx.contextlevel=40 AND ctx.instanceid=cc.id) /* only if groups active */ LEFT OUTER JOIN {$CFG->prefix}groups_members gm ON (ra.userid=gm.userid) LEFT OUTER JOIN {$CFG->prefix}groups g ON (gm.groupid=g.id AND g.courseid={$course->id}) /* and if groupings is enabled... */ $gpjoin WHERE ra.userid IN ( $userids ) AND ra.contextid in ( $contextids ) $avoidrolescond ORDER BY ra.userid, ctx.depth DESC"; $rs = get_recordset_sql($sql); $extra = array(); // Data structure - // $extra [ $userid ] [ 'group' ] [ $groupid => 'group name'] // [ 'gping' ] [ $gpingid => 'gping name'] // [ 'ra' ] [ [ "$ctxid:$roleid" => [ctxid => $ctxid // ctxdepth => $ctxdepth, // ctxpath => $ctxpath, // ctxname => 'name' (categories only) // ctxinstid => // roleid => $roleid // enrol => $pluginname // // Might be interesting to add to RA timestart, timeend, timemodified, // and modifierid (with an outer join to mdl_user! // while ($rec = rs_fetch_next_record($rs)) { $userid = $rec->userid; // Prime an initial user rec... if (!isset($extra[$userid])) { $extra[$userid] = array( 'group' => array(), 'gping' => array(), 'ra' => array() ); } if (!empty($rec->gid)) { $extra[$userid]['group'][$rec->gid]= $rec->gname; } if (!empty($rec->gpid)) { $extra[$userid]['gping'][$rec->gpid]= $rec->gpname; } $rakey = $rec->ctxid . ':' . $rec->roleid; if (!isset($extra[$userid]['ra'][$rakey])) { $extra[$userid]['ra'][$rakey] = array('ctxid' => $rec->ctxid, 'ctxlevel' => $rec->ctxlevel, 'ctxinstanceid' => $rec->ctxinstanceid, 'ccname' => $rec->ccname, 'roleid' => $rec->roleid, 'enrolplugin' => $rec->enrolplugin); } } return $extra; } ?>