2 // Script to assign users to contexts
4 require_once('../../config.php');
5 require_once($CFG->dirroot
.'/mod/forum/lib.php');
6 require_once($CFG->libdir
.'/adminlib.php');
8 define("MAX_USERS_PER_PAGE", 5000);
9 define("MAX_USERS_TO_LIST_PER_ROLE", 10);
11 $contextid = required_param('contextid',PARAM_INT
); // context id
12 $roleid = optional_param('roleid', 0, PARAM_INT
); // required role id
13 $add = optional_param('add', 0, PARAM_BOOL
);
14 $remove = optional_param('remove', 0, PARAM_BOOL
);
15 $showall = optional_param('showall', 0, PARAM_BOOL
);
16 $searchtext = optional_param('searchtext', '', PARAM_RAW
); // search string
17 $previoussearch = optional_param('previoussearch', 0, PARAM_BOOL
);
18 $hidden = optional_param('hidden', 0, PARAM_BOOL
); // whether this assignment is hidden
19 $extendperiod = optional_param('extendperiod', 0, PARAM_INT
);
20 $extendbase = optional_param('extendbase', 0, PARAM_INT
);
21 $userid = optional_param('userid', 0, PARAM_INT
); // needed for user tabs
22 $courseid = optional_param('courseid', 0, PARAM_INT
); // needed for user tabs
26 $previoussearch = ($searchtext != '') or ($previoussearch) ?
1:0;
28 $baseurl = 'assign.php?contextid='.$contextid;
29 if (!empty($userid)) {
30 $baseurl .= '&userid='.$userid;
32 if (!empty($courseid)) {
33 $baseurl .= '&courseid='.$courseid;
36 if (! $context = get_context_instance_by_id($contextid)) {
37 error("Context ID was incorrect (can't find it)");
41 if ($context->contextlevel
== CONTEXT_COURSE
) {
42 $courseid = $context->instanceid
;
43 if ($course = get_record('course', 'id', $courseid)) {
44 $inmeta = $course->metacourse
;
46 error('Invalid course id');
49 } else if (!empty($courseid)){ // we need this for user tabs in user context
50 if (!$course = get_record('course', 'id', $courseid)) {
51 error('Invalid course id');
56 $course = clone($SITE);
59 require_login($course);
61 require_capability('moodle/role:assign', $context);
63 /// needed for tabs.php
65 $overridableroles = get_overridable_roles($context, 'name', ROLENAME_BOTH
);
66 $assignableroles = get_assignable_roles($context, 'name', ROLENAME_BOTH
);
68 /// Get some language strings
70 $strpotentialusers = get_string('potentialusers', 'role');
71 $strexistingusers = get_string('existingusers', 'role');
72 $straction = get_string('assignroles', 'role');
73 $strroletoassign = get_string('roletoassign', 'role');
74 $strsearch = get_string('search');
75 $strshowall = get_string('showall');
76 $strparticipants = get_string('participants');
77 $strsearchresults = get_string('searchresults');
79 $unlimitedperiod = get_string('unlimited');
80 $defaultperiod = $course->enrolperiod
;
81 for ($i=1; $i<=365; $i++
) {
82 $seconds = $i * 86400;
83 $periodmenu[$seconds] = get_string('numdays', '', $i);
86 $timeformat = get_string('strftimedate');
88 $today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0);
90 // MDL-12420, preventing course start date showing up as an option at system context and front page roles.
91 if ($course->startdate
> 0) {
92 $basemenu[0] = get_string('startdate') . ' (' . userdate($course->startdate
, $timeformat) . ')';
94 if ($course->enrollable
!= 2 ||
($course->enrolstartdate
== 0 ||
$course->enrolstartdate
<= $today) && ($course->enrolenddate
== 0 ||
$course->enrolenddate
> $today)) {
95 $basemenu[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ;
97 if($course->enrollable
== 2) {
98 if($course->enrolstartdate
> 0) {
99 $basemenu[4] = get_string('courseenrolstartdate') . ' (' . userdate($course->enrolstartdate
, $timeformat) . ')';
101 if($course->enrolenddate
> 0) {
102 $basemenu[5] = get_string('courseenrolenddate') . ' (' . userdate($course->enrolenddate
, $timeformat) . ')';
106 /// Make sure this user can assign that role
109 if (!isset($assignableroles[$roleid])) {
110 error ('you can not override this role in this context');
115 $user = get_record('user', 'id', $userid);
116 $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
120 /// Print the header and tabs
122 if ($context->contextlevel
== CONTEXT_USER
) {
125 if ($courseid != SITEID
) {
126 if (has_capability('moodle/course:viewparticipants', get_context_instance(CONTEXT_COURSE
, $course->id
))) {
127 $navlinks[] = array('name' => $strparticipants, 'link' => "$CFG->wwwroot/user/index.php?id=$course->id", 'type' => 'misc');
129 $navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$userid&course=$courseid", 'type' => 'misc');
130 $navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
131 $navigation = build_navigation($navlinks);
133 print_header("$fullname", "$fullname", $navigation, "", "", true, " ", navmenu($course));
137 $navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$userid&course=$courseid", 'type' => 'misc');
138 $navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
139 $navigation = build_navigation($navlinks);
140 print_header("$course->fullname: $fullname", $course->fullname
, $navigation, "", "", true, " ", navmenu($course));
144 $currenttab = 'assign';
145 include_once($CFG->dirroot
.'/user/tabs.php');
146 } else if ($context->contextlevel
== CONTEXT_SYSTEM
) {
147 admin_externalpage_setup('assignroles');
148 admin_externalpage_print_header();
149 } else if ($context->contextlevel
==CONTEXT_COURSE
and $context->instanceid
== SITEID
) {
150 admin_externalpage_setup('frontpageroles');
151 admin_externalpage_print_header();
152 $currenttab = 'assign';
153 include_once('tabs.php');
155 $currenttab = 'assign';
156 include_once('tabs.php');
161 /// Process incoming role assignment
163 if ($frm = data_submitted()) {
165 if ($add and !empty($frm->addselect
) and confirm_sesskey()) {
167 foreach ($frm->addselect
as $adduser) {
168 if (!$adduser = clean_param($adduser, PARAM_INT
)) {
173 if (has_capability('moodle/course:managemetacourse', $context, $adduser)) {
176 $managerroles = get_roles_with_capability('moodle/course:managemetacourse', CAP_ALLOW
, $context);
177 if (!empty($managerroles) and !array_key_exists($roleid, $managerroles)) {
178 $erruser = get_record('user', 'id', $adduser, '','','','', 'id, firstname, lastname');
179 $errors[] = get_string('metaassignerror', 'role', fullname($erruser));
185 switch($extendbase) {
187 $timestart = $course->startdate
;
193 $timestart = $course->enrolstartdate
;
196 $timestart = $course->enrolenddate
;
200 if($extendperiod > 0) {
201 $timeend = $timestart +
$extendperiod;
205 if (! role_assign($roleid, $adduser, 0, $context->id
, $timestart, $timeend, $hidden)) {
206 $errors[] = "Could not add user with id $adduser to this role!";
211 $rolename = get_field('role', 'name', 'id', $roleid);
212 add_to_log($course->id
, 'role', 'assign', 'admin/roles/assign.php?contextid='.$context->id
.'&roleid='.$roleid, $rolename, '', $USER->id
);
213 } else if ($remove and !empty($frm->removeselect
) and confirm_sesskey()) {
215 $sitecontext = get_context_instance(CONTEXT_SYSTEM
);
216 $topleveladmin = false;
218 // we only worry about this if the role has doanything capability at site level
219 if ($context->id
== $sitecontext->id
&& $adminroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW
, $sitecontext)) {
220 foreach ($adminroles as $adminrole) {
221 if ($adminrole->id
== $roleid) {
222 $topleveladmin = true;
227 foreach ($frm->removeselect
as $removeuser) {
228 $removeuser = clean_param($removeuser, PARAM_INT
);
230 if ($topleveladmin && ($removeuser == $USER->id
)) { // Prevent unassigning oneself from being admin
234 if (! role_unassign($roleid, $removeuser, 0, $context->id
)) {
235 $errors[] = "Could not remove user with id $removeuser from this role!";
236 } else if ($inmeta) {
237 sync_metacourse($courseid);
238 $newroles = get_user_roles($context, $removeuser, false);
239 if (!empty($newroles) and !array_key_exists($roleid, $newroles)) {
240 $erruser = get_record('user', 'id', $removeuser, '','','','', 'id, firstname, lastname');
241 $errors[] = get_string('metaunassignerror', 'role', fullname($erruser));
247 $rolename = get_field('role', 'name', 'id', $roleid);
248 add_to_log($course->id
, 'role', 'unassign', 'admin/roles/assign.php?contextid='.$context->id
.'&roleid='.$roleid, $rolename, '', $USER->id
);
249 } else if ($showall) {
258 if ($context->contextlevel
==CONTEXT_COURSE
and $context->instanceid
== SITEID
) {
259 print_heading_with_help(get_string('frontpageroles', 'admin'), 'assignroles');
261 print_heading_with_help(get_string('assignrolesin', 'role', print_context_name($context)), 'assignroles');
264 if ($context->contextlevel
==CONTEXT_SYSTEM
) {
265 print_box(get_string('globalroleswarning', 'role'));
268 if ($roleid) { /// prints a form to swap roles
270 /// Get all existing participants in this context.
271 // Why is this not done with get_users???
273 if (!$contextusers = get_role_users($roleid, $context, false, 'u.id, u.firstname, u.lastname, u.email, ra.hidden')) {
274 $contextusers = array();
277 $select = "username <> 'guest' AND deleted = 0 AND confirmed = 1";
279 $usercount = count_records_select('user', $select) - count($contextusers);
281 $searchtext = trim($searchtext);
283 if ($searchtext !== '') { // Search for a subset of remaining users
285 $FULLNAME = sql_fullname();
287 $selectsql = " AND ($FULLNAME $LIKE '%$searchtext%' OR email $LIKE '%$searchtext%') ";
288 $select .= $selectsql;
293 if ($context->contextlevel
> CONTEXT_COURSE
) { // mod or block (or group?)
295 /************************************************************************
297 * context level is above or equal course context level *
298 * in this case we pull out all users matching search criteria (if any) *
301 * a mini get_users_by_capability() call here, this is done instead of *
302 * get_users_by_capability() because *
303 * 1) get_users_by_capability() does not deal with searching by name *
304 * 2) exceptions array can be potentially large for large courses *
305 * 3) get_recordset_sql() is more efficient *
307 ************************************************************************/
309 if ($possibleroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW
, $context)) {
311 $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW
, get_context_instance(CONTEXT_SYSTEM
));
313 $validroleids = array();
314 foreach ($possibleroles as $possiblerole) {
315 if (isset($doanythingroles[$possiblerole->id
])) { // We don't want these included
318 if ($caps = role_context_capabilities($possiblerole->id
, $context, 'moodle/course:view')) { // resolved list
319 if (isset($caps['moodle/course:view']) && $caps['moodle/course:view'] > 0) { // resolved capability > 0
320 $validroleids[] = $possiblerole->id
;
326 $roleids = '('.implode(',', $validroleids).')';
328 $select = " SELECT u.id, u.firstname, u.lastname, u.email";
329 $countselect = "SELECT COUNT(u.id)";
330 $from = " FROM {$CFG->prefix}user u
331 INNER JOIN {$CFG->prefix}role_assignments ra ON ra.userid = u.id
332 INNER JOIN {$CFG->prefix}role r ON r.id = ra.roleid";
333 $where = " WHERE ra.contextid ".get_related_contexts_string($context)."
335 AND ra.roleid in $roleids";
336 $excsql = " AND u.id NOT IN (
338 FROM {$CFG->prefix}role_assignments r,
340 WHERE r.contextid = $contextid
342 AND r.roleid = $roleid
345 $availableusers = get_recordset_sql($select . $from . $where . $selectsql . $excsql);
348 $usercount = $availableusers->_numOfRows
;
353 /************************************************************************
355 * context level is above or equal course context level *
356 * in this case we pull out all users matching search criteria (if any) *
358 ************************************************************************/
360 /// MDL-11111 do not include user already assigned this role in this context as available users
361 /// so that the number of available users is right and we save time looping later
362 $availableusers = get_recordset_sql('SELECT id, firstname, lastname, email
363 FROM '.$CFG->prefix
.'user
367 FROM '.$CFG->prefix
.'role_assignments r,
368 '.$CFG->prefix
.'user u
369 WHERE r.contextid = '.$contextid.'
371 AND r.roleid = '.$roleid.'
373 ORDER BY lastname ASC, firstname ASC');
375 $usercount = $availableusers->_numOfRows
;
378 echo '<div class="selector">';
379 $assignableroles = array('0'=>get_string('listallroles', 'role').'...') +
$assignableroles;
380 popup_form("$CFG->wwwroot/$CFG->admin/roles/assign.php?userid=$userid&courseid=$courseid&contextid=$contextid&roleid=",
381 $assignableroles, 'switchrole', $roleid, '', '', '', false, 'self', $strroletoassign);
384 print_simple_box_start('center');
385 include('assign.html');
386 print_simple_box_end();
388 if (!empty($errors)) {
390 foreach ($errors as $e) {
394 print_simple_box_start('center');
396 print_simple_box_end();
399 } else { // Print overview table
401 // sync metacourse enrolments if needed
403 sync_metacourse($course);
406 // Get the names of role holders for roles with between 1 and MAX_USERS_TO_LIST_PER_ROLE users,
407 // and so determine whether to show the extra column.
408 $rolehodlercount = array();
409 $rolehodlernames = array();
410 $strmorethanten = get_string('morethan', 'role', MAX_USERS_TO_LIST_PER_ROLE
);
411 $showroleholders = false;
412 foreach ($assignableroles as $roleid => $rolename) {
413 $countusers = count_role_users($roleid, $context);
414 $rolehodlercount[$roleid] = $countusers;
416 if (0 < $countusers && $countusers <= MAX_USERS_TO_LIST_PER_ROLE
) {
417 $roleusers = get_role_users($roleid, $context, false, 'u.id, u.lastname, u.firstname');
418 if (!empty($roleusers)) {
419 $strroleusers = array();
420 foreach ($roleusers as $user) {
421 $strroleusers[] = '<a href="' . $CFG->wwwroot
. '/user/view.php?id=' . $user->id
. '" >' . fullname($user) . '</a>';
423 $rolehodlernames[$roleid] = implode('<br />', $strroleusers);
424 $showroleholders = true;
426 } else if ($countusers > MAX_USERS_TO_LIST_PER_ROLE
) {
427 $rolehodlernames[$roleid] = '<a href="'.$baseurl.'&roleid='.$roleid.'">'.$strmorethanten.'</a>';
429 $rolehodlernames[$roleid] = '';
433 // Print overview table
434 $table->tablealign
= 'center';
435 $table->cellpadding
= 5;
436 $table->cellspacing
= 0;
437 $table->width
= '60%';
438 $table->head
= array(get_string('roles', 'role'), get_string('description'), get_string('users'));
439 $table->wrap
= array('nowrap', '', 'nowrap');
440 $table->align
= array('right', 'left', 'center');
441 if ($showroleholders) {
443 $table->wrap
[] = 'nowrap';
444 $table->align
[] = 'left';
447 foreach ($assignableroles as $roleid => $rolename) {
448 $description = format_string(get_field('role', 'description', 'id', $roleid));
449 $row = array('<a href="'.$baseurl.'&roleid='.$roleid.'">'.$rolename.'</a>',$description, $rolehodlercount[$roleid]);
450 if ($showroleholders) {
451 $row[] = $rolehodlernames[$roleid];
453 $table->data
[] = $row;
459 print_footer($course);