6c089f4a28
Cleaned up the display of role aliases by extending get_assignable_roles and get_overrideable_roles to use role_fix_names better. The lists of assignable and overrideable are now correctly derived from the actual context (eg activity or module) while the aliases are derived from course that is the parent. Some other cleanups along the way.
463 lines
20 KiB
PHP
Executable File
463 lines
20 KiB
PHP
Executable File
<?php // $Id$
|
|
// Script to assign users to contexts
|
|
|
|
require_once('../../config.php');
|
|
require_once($CFG->dirroot.'/mod/forum/lib.php');
|
|
require_once($CFG->libdir.'/adminlib.php');
|
|
|
|
define("MAX_USERS_PER_PAGE", 5000);
|
|
define("MAX_USERS_TO_LIST_PER_ROLE", 10);
|
|
|
|
$contextid = required_param('contextid',PARAM_INT); // context id
|
|
$roleid = optional_param('roleid', 0, PARAM_INT); // required role id
|
|
$add = optional_param('add', 0, PARAM_BOOL);
|
|
$remove = optional_param('remove', 0, PARAM_BOOL);
|
|
$showall = optional_param('showall', 0, PARAM_BOOL);
|
|
$searchtext = optional_param('searchtext', '', PARAM_RAW); // search string
|
|
$previoussearch = optional_param('previoussearch', 0, PARAM_BOOL);
|
|
$hidden = optional_param('hidden', 0, PARAM_BOOL); // whether this assignment is hidden
|
|
$extendperiod = optional_param('extendperiod', 0, PARAM_INT);
|
|
$extendbase = optional_param('extendbase', 0, PARAM_INT);
|
|
$userid = optional_param('userid', 0, PARAM_INT); // needed for user tabs
|
|
$courseid = optional_param('courseid', 0, PARAM_INT); // needed for user tabs
|
|
|
|
$errors = array();
|
|
|
|
$previoussearch = ($searchtext != '') or ($previoussearch) ? 1:0;
|
|
|
|
$baseurl = 'assign.php?contextid='.$contextid;
|
|
if (!empty($userid)) {
|
|
$baseurl .= '&userid='.$userid;
|
|
}
|
|
if (!empty($courseid)) {
|
|
$baseurl .= '&courseid='.$courseid;
|
|
}
|
|
|
|
if (! $context = get_context_instance_by_id($contextid)) {
|
|
error("Context ID was incorrect (can't find it)");
|
|
}
|
|
|
|
$inmeta = 0;
|
|
if ($context->contextlevel == CONTEXT_COURSE) {
|
|
$courseid = $context->instanceid;
|
|
if ($course = get_record('course', 'id', $courseid)) {
|
|
$inmeta = $course->metacourse;
|
|
} else {
|
|
error('Invalid course id');
|
|
}
|
|
|
|
} else if (!empty($courseid)){ // we need this for user tabs in user context
|
|
if (!$course = get_record('course', 'id', $courseid)) {
|
|
error('Invalid course id');
|
|
}
|
|
|
|
} else {
|
|
$courseid = SITEID;
|
|
$course = clone($SITE);
|
|
}
|
|
|
|
require_login($course);
|
|
|
|
require_capability('moodle/role:assign', $context);
|
|
|
|
/// needed for tabs.php
|
|
|
|
$overridableroles = get_overridable_roles($context, 'name', ROLENAME_BOTH);
|
|
$assignableroles = get_assignable_roles($context, 'name', ROLENAME_BOTH);
|
|
|
|
|
|
/// Get some language strings
|
|
|
|
$strpotentialusers = get_string('potentialusers', 'role');
|
|
$strexistingusers = get_string('existingusers', 'role');
|
|
$straction = get_string('assignroles', 'role');
|
|
$strroletoassign = get_string('roletoassign', 'role');
|
|
$strsearch = get_string('search');
|
|
$strshowall = get_string('showall');
|
|
$strparticipants = get_string('participants');
|
|
$strsearchresults = get_string('searchresults');
|
|
|
|
$unlimitedperiod = get_string('unlimited');
|
|
$defaultperiod = $course->enrolperiod;
|
|
for ($i=1; $i<=365; $i++) {
|
|
$seconds = $i * 86400;
|
|
$periodmenu[$seconds] = get_string('numdays', '', $i);
|
|
}
|
|
|
|
$timeformat = get_string('strftimedate');
|
|
$today = time();
|
|
$today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0);
|
|
|
|
// MDL-12420, preventing course start date showing up as an option at system context and front page roles.
|
|
if ($course->startdate > 0) {
|
|
$basemenu[0] = get_string('startdate') . ' (' . userdate($course->startdate, $timeformat) . ')';
|
|
}
|
|
if ($course->enrollable != 2 || ($course->enrolstartdate == 0 || $course->enrolstartdate <= $today) && ($course->enrolenddate == 0 || $course->enrolenddate > $today)) {
|
|
$basemenu[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ;
|
|
}
|
|
if($course->enrollable == 2) {
|
|
if($course->enrolstartdate > 0) {
|
|
$basemenu[4] = get_string('courseenrolstartdate') . ' (' . userdate($course->enrolstartdate, $timeformat) . ')';
|
|
}
|
|
if($course->enrolenddate > 0) {
|
|
$basemenu[5] = get_string('courseenrolenddate') . ' (' . userdate($course->enrolenddate, $timeformat) . ')';
|
|
}
|
|
}
|
|
|
|
/// Make sure this user can assign that role
|
|
|
|
if ($roleid) {
|
|
if (!user_can_assign($context, $roleid)) {
|
|
error ('you can not override this role in this context');
|
|
}
|
|
}
|
|
|
|
if ($userid) {
|
|
$user = get_record('user', 'id', $userid);
|
|
$fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
|
|
}
|
|
|
|
|
|
/// Print the header and tabs
|
|
|
|
if ($context->contextlevel == CONTEXT_USER) {
|
|
/// course header
|
|
$navlinks = array();
|
|
if ($courseid != SITEID) {
|
|
if (has_capability('moodle/course:viewparticipants', get_context_instance(CONTEXT_COURSE, $course->id))) {
|
|
$navlinks[] = array('name' => $strparticipants, 'link' => "$CFG->wwwroot/user/index.php?id=$course->id", 'type' => 'misc');
|
|
}
|
|
$navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$userid&course=$courseid", 'type' => 'misc');
|
|
$navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
|
|
$navigation = build_navigation($navlinks);
|
|
|
|
print_header("$fullname", "$fullname", $navigation, "", "", true, " ", navmenu($course));
|
|
|
|
/// site header
|
|
} else {
|
|
$navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$userid&course=$courseid", 'type' => 'misc');
|
|
$navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
|
|
$navigation = build_navigation($navlinks);
|
|
print_header("$course->fullname: $fullname", $course->fullname, $navigation, "", "", true, " ", navmenu($course));
|
|
}
|
|
|
|
$showroles = 1;
|
|
$currenttab = 'assign';
|
|
include_once($CFG->dirroot.'/user/tabs.php');
|
|
} else if ($context->contextlevel == CONTEXT_SYSTEM) {
|
|
admin_externalpage_setup('assignroles');
|
|
admin_externalpage_print_header();
|
|
} else if ($context->contextlevel==CONTEXT_COURSE and $context->instanceid == SITEID) {
|
|
admin_externalpage_setup('frontpageroles');
|
|
admin_externalpage_print_header();
|
|
$currenttab = 'assign';
|
|
include_once('tabs.php');
|
|
} else {
|
|
$currenttab = 'assign';
|
|
include_once('tabs.php');
|
|
}
|
|
|
|
|
|
|
|
/// Process incoming role assignment
|
|
|
|
if ($frm = data_submitted()) {
|
|
|
|
if ($add and !empty($frm->addselect) and confirm_sesskey()) {
|
|
|
|
foreach ($frm->addselect as $adduser) {
|
|
if (!$adduser = clean_param($adduser, PARAM_INT)) {
|
|
continue;
|
|
}
|
|
$allow = true;
|
|
if ($inmeta) {
|
|
if (has_capability('moodle/course:managemetacourse', $context, $adduser)) {
|
|
//ok
|
|
} else {
|
|
$managerroles = get_roles_with_capability('moodle/course:managemetacourse', CAP_ALLOW, $context);
|
|
if (!empty($managerroles) and !array_key_exists($roleid, $managerroles)) {
|
|
$erruser = get_record('user', 'id', $adduser, '','','','', 'id, firstname, lastname');
|
|
$errors[] = get_string('metaassignerror', 'role', fullname($erruser));
|
|
$allow = false;
|
|
}
|
|
}
|
|
}
|
|
if ($allow) {
|
|
switch($extendbase) {
|
|
case 0:
|
|
$timestart = $course->startdate;
|
|
break;
|
|
case 3:
|
|
$timestart = $today;
|
|
break;
|
|
case 4:
|
|
$timestart = $course->enrolstartdate;
|
|
break;
|
|
case 5:
|
|
$timestart = $course->enrolenddate;
|
|
break;
|
|
}
|
|
|
|
if($extendperiod > 0) {
|
|
$timeend = $timestart + $extendperiod;
|
|
} else {
|
|
$timeend = 0;
|
|
}
|
|
if (! role_assign($roleid, $adduser, 0, $context->id, $timestart, $timeend, $hidden)) {
|
|
$errors[] = "Could not add user with id $adduser to this role!";
|
|
}
|
|
}
|
|
}
|
|
|
|
$rolename = get_field('role', 'name', 'id', $roleid);
|
|
add_to_log($course->id, 'role', 'assign', 'admin/roles/assign.php?contextid='.$context->id.'&roleid='.$roleid, $rolename, '', $USER->id);
|
|
} else if ($remove and !empty($frm->removeselect) and confirm_sesskey()) {
|
|
|
|
$sitecontext = get_context_instance(CONTEXT_SYSTEM);
|
|
$topleveladmin = false;
|
|
|
|
// we only worry about this if the role has doanything capability at site level
|
|
if ($context->id == $sitecontext->id && $adminroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext)) {
|
|
foreach ($adminroles as $adminrole) {
|
|
if ($adminrole->id == $roleid) {
|
|
$topleveladmin = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach ($frm->removeselect as $removeuser) {
|
|
$removeuser = clean_param($removeuser, PARAM_INT);
|
|
|
|
if ($topleveladmin && ($removeuser == $USER->id)) { // Prevent unassigning oneself from being admin
|
|
continue;
|
|
}
|
|
|
|
if (! role_unassign($roleid, $removeuser, 0, $context->id)) {
|
|
$errors[] = "Could not remove user with id $removeuser from this role!";
|
|
} else if ($inmeta) {
|
|
sync_metacourse($courseid);
|
|
$newroles = get_user_roles($context, $removeuser, false);
|
|
if (!empty($newroles) and !array_key_exists($roleid, $newroles)) {
|
|
$erruser = get_record('user', 'id', $removeuser, '','','','', 'id, firstname, lastname');
|
|
$errors[] = get_string('metaunassignerror', 'role', fullname($erruser));
|
|
$allow = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
$rolename = get_field('role', 'name', 'id', $roleid);
|
|
add_to_log($course->id, 'role', 'unassign', 'admin/roles/assign.php?contextid='.$context->id.'&roleid='.$roleid, $rolename, '', $USER->id);
|
|
} else if ($showall) {
|
|
$searchtext = '';
|
|
$previoussearch = 0;
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if ($context->contextlevel==CONTEXT_COURSE and $context->instanceid == SITEID) {
|
|
print_heading_with_help(get_string('frontpageroles', 'admin'), 'assignroles');
|
|
} else {
|
|
print_heading_with_help(get_string('assignrolesin', 'role', print_context_name($context)), 'assignroles');
|
|
}
|
|
|
|
if ($context->contextlevel==CONTEXT_SYSTEM) {
|
|
print_box(get_string('globalroleswarning', 'role'));
|
|
}
|
|
|
|
if ($roleid) { /// prints a form to swap roles
|
|
|
|
/// Get all existing participants in this context.
|
|
// Why is this not done with get_users???
|
|
|
|
if (!$contextusers = get_role_users($roleid, $context, false, 'u.id, u.firstname, u.lastname, u.email, ra.hidden')) {
|
|
$contextusers = array();
|
|
}
|
|
|
|
$select = "username <> 'guest' AND deleted = 0 AND confirmed = 1";
|
|
|
|
$usercount = count_records_select('user', $select) - count($contextusers);
|
|
|
|
$searchtext = trim($searchtext);
|
|
|
|
if ($searchtext !== '') { // Search for a subset of remaining users
|
|
$LIKE = sql_ilike();
|
|
$FULLNAME = sql_fullname();
|
|
|
|
$selectsql = " AND ($FULLNAME $LIKE '%$searchtext%' OR email $LIKE '%$searchtext%') ";
|
|
$select .= $selectsql;
|
|
} else {
|
|
$selectsql = "";
|
|
}
|
|
|
|
if ($context->contextlevel > CONTEXT_COURSE) { // mod or block (or group?)
|
|
|
|
/************************************************************************
|
|
* *
|
|
* context level is above or equal course context level *
|
|
* in this case we pull out all users matching search criteria (if any) *
|
|
* *
|
|
* MDL-11324 *
|
|
* a mini get_users_by_capability() call here, this is done instead of *
|
|
* get_users_by_capability() because *
|
|
* 1) get_users_by_capability() does not deal with searching by name *
|
|
* 2) exceptions array can be potentially large for large courses *
|
|
* 3) get_recordset_sql() is more efficient *
|
|
* *
|
|
************************************************************************/
|
|
|
|
if ($possibleroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context)) {
|
|
|
|
$doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM));
|
|
|
|
$validroleids = array();
|
|
foreach ($possibleroles as $possiblerole) {
|
|
if (isset($doanythingroles[$possiblerole->id])) { // We don't want these included
|
|
continue;
|
|
}
|
|
if ($caps = role_context_capabilities($possiblerole->id, $context, 'moodle/course:view')) { // resolved list
|
|
if (isset($caps['moodle/course:view']) && $caps['moodle/course:view'] > 0) { // resolved capability > 0
|
|
$validroleids[] = $possiblerole->id;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($validroleids) {
|
|
$roleids = '('.implode(',', $validroleids).')';
|
|
|
|
$select = " SELECT u.id, u.firstname, u.lastname, u.email";
|
|
$countselect = "SELECT COUNT(u.id)";
|
|
$from = " FROM {$CFG->prefix}user u
|
|
INNER JOIN {$CFG->prefix}role_assignments ra ON ra.userid = u.id
|
|
INNER JOIN {$CFG->prefix}role r ON r.id = ra.roleid";
|
|
$where = " WHERE ra.contextid ".get_related_contexts_string($context)."
|
|
AND u.deleted = 0
|
|
AND ra.roleid in $roleids";
|
|
$excsql = " AND u.id NOT IN (
|
|
SELECT u.id
|
|
FROM {$CFG->prefix}role_assignments r,
|
|
{$CFG->prefix}user u
|
|
WHERE r.contextid = $contextid
|
|
AND u.id = r.userid
|
|
AND r.roleid = $roleid
|
|
$selectsql)";
|
|
|
|
$availableusers = get_recordset_sql($select . $from . $where . $selectsql . $excsql);
|
|
}
|
|
|
|
$usercount = $availableusers->_numOfRows;
|
|
}
|
|
|
|
} else {
|
|
|
|
/************************************************************************
|
|
* *
|
|
* context level is above or equal course context level *
|
|
* in this case we pull out all users matching search criteria (if any) *
|
|
* *
|
|
************************************************************************/
|
|
|
|
/// MDL-11111 do not include user already assigned this role in this context as available users
|
|
/// so that the number of available users is right and we save time looping later
|
|
$availableusers = get_recordset_sql('SELECT id, firstname, lastname, email
|
|
FROM '.$CFG->prefix.'user
|
|
WHERE '.$select.'
|
|
AND id NOT IN (
|
|
SELECT u.id
|
|
FROM '.$CFG->prefix.'role_assignments r,
|
|
'.$CFG->prefix.'user u
|
|
WHERE r.contextid = '.$contextid.'
|
|
AND u.id = r.userid
|
|
AND r.roleid = '.$roleid.'
|
|
'.$selectsql.')
|
|
ORDER BY lastname ASC, firstname ASC');
|
|
|
|
$usercount = $availableusers->_numOfRows;
|
|
}
|
|
|
|
echo '<div class="selector">';
|
|
$assignableroles = array('0'=>get_string('listallroles', 'role').'...') + $assignableroles;
|
|
popup_form("$CFG->wwwroot/$CFG->admin/roles/assign.php?userid=$userid&courseid=$courseid&contextid=$contextid&roleid=",
|
|
$assignableroles, 'switchrole', $roleid, '', '', '', false, 'self', $strroletoassign);
|
|
echo '</div>';
|
|
|
|
print_simple_box_start('center');
|
|
include('assign.html');
|
|
print_simple_box_end();
|
|
|
|
if (!empty($errors)) {
|
|
$msg = '<p>';
|
|
foreach ($errors as $e) {
|
|
$msg .= $e.'<br />';
|
|
}
|
|
$msg .= '</p>';
|
|
print_simple_box_start('center');
|
|
notify($msg);
|
|
print_simple_box_end();
|
|
}
|
|
|
|
} else { // Print overview table
|
|
|
|
// sync metacourse enrolments if needed
|
|
if ($inmeta) {
|
|
sync_metacourse($course);
|
|
}
|
|
|
|
// Get the names of role holders for roles with between 1 and MAX_USERS_TO_LIST_PER_ROLE users,
|
|
// and so determine whether to show the extra column.
|
|
$rolehodlercount = array();
|
|
$rolehodlernames = array();
|
|
$strmorethanten = get_string('morethan', 'role', MAX_USERS_TO_LIST_PER_ROLE);
|
|
$showroleholders = false;
|
|
foreach ($assignableroles as $roleid => $rolename) {
|
|
$countusers = count_role_users($roleid, $context);
|
|
$rolehodlercount[$roleid] = $countusers;
|
|
$roleusers = '';
|
|
if (0 < $countusers && $countusers <= MAX_USERS_TO_LIST_PER_ROLE) {
|
|
$roleusers = get_role_users($roleid, $context, false, 'u.id, u.lastname, u.firstname');
|
|
if (!empty($roleusers)) {
|
|
$strroleusers = array();
|
|
foreach ($roleusers as $user) {
|
|
$strroleusers[] = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $user->id . '" >' . fullname($user) . '</a>';
|
|
}
|
|
$rolehodlernames[$roleid] = implode('<br />', $strroleusers);
|
|
$showroleholders = true;
|
|
}
|
|
} else if ($countusers > MAX_USERS_TO_LIST_PER_ROLE) {
|
|
$rolehodlernames[$roleid] = '<a href="'.$baseurl.'&roleid='.$roleid.'">'.$strmorethanten.'</a>';
|
|
} else {
|
|
$rolehodlernames[$roleid] = '';
|
|
}
|
|
}
|
|
|
|
// Print overview table
|
|
$table->tablealign = 'center';
|
|
$table->cellpadding = 5;
|
|
$table->cellspacing = 0;
|
|
$table->width = '60%';
|
|
$table->head = array(get_string('roles', 'role'), get_string('description'), get_string('users'));
|
|
$table->wrap = array('nowrap', '', 'nowrap');
|
|
$table->align = array('right', 'left', 'center');
|
|
if ($showroleholders) {
|
|
$table->head[] = '';
|
|
$table->wrap[] = 'nowrap';
|
|
$table->align[] = 'left';
|
|
}
|
|
|
|
foreach ($assignableroles as $roleid => $rolename) {
|
|
$description = format_string(get_field('role', 'description', 'id', $roleid));
|
|
$row = array('<a href="'.$baseurl.'&roleid='.$roleid.'">'.$rolename.'</a>',$description, $rolehodlercount[$roleid]);
|
|
if ($showroleholders) {
|
|
$row[] = $rolehodlernames[$roleid];
|
|
}
|
|
$table->data[] = $row;
|
|
}
|
|
|
|
print_table($table);
|
|
}
|
|
|
|
print_footer($course);
|
|
|
|
?>
|