MDL-12531, make the new member value available to all the affected plugins, thanks...
[moodle-linuxchix.git] / admin / roles / assign.php
blobfe574597abc0da3ce3ecd48f39e93c1beabf83f0
1 <?php // $Id$
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
24 $errors = array();
26 $previoussearch = ($searchtext != '') or ($previoussearch) ? 1:0;
28 $baseurl = 'assign.php?contextid='.$contextid;
29 if (!empty($userid)) {
30 $baseurl .= '&amp;userid='.$userid;
32 if (!empty($courseid)) {
33 $baseurl .= '&amp;courseid='.$courseid;
36 if (! $context = get_context_instance_by_id($contextid)) {
37 error("Context ID was incorrect (can't find it)");
40 $inmeta = 0;
41 if ($context->contextlevel == CONTEXT_COURSE) {
42 $courseid = $context->instanceid;
43 if ($course = get_record('course', 'id', $courseid)) {
44 $inmeta = $course->metacourse;
45 } else {
46 error('Invalid course id');
48 $coursecontext = $context;
50 } else if (!empty($courseid)){ // we need this for user tabs in user context
51 if (!$course = get_record('course', 'id', $courseid)) {
52 error('Invalid course id');
54 $coursecontext = get_context_instance(CONTEXT_COURSE, $course->id);
56 } else {
57 $courseid = SITEID;
58 $course = clone($SITE);
61 require_login($course);
63 if ($context->contextlevel == CONTEXT_COURSE) {
64 require_login($context->instanceid);
65 } else {
66 require_login();
69 require_capability('moodle/role:assign', $context);
71 /// needed for tabs.php
72 $overridableroles = get_overridable_roles($context);
73 $assignableroles = get_assignable_roles($context); // Plain role names, may be altered later
76 /// Get some language strings
78 $strpotentialusers = get_string('potentialusers', 'role');
79 $strexistingusers = get_string('existingusers', 'role');
80 $straction = get_string('assignroles', 'role');
81 $strroletoassign = get_string('roletoassign', 'role');
82 $strsearch = get_string('search');
83 $strshowall = get_string('showall');
84 $strparticipants = get_string('participants');
85 $strsearchresults = get_string('searchresults');
87 $unlimitedperiod = get_string('unlimited');
88 $defaultperiod = $course->enrolperiod;
89 for ($i=1; $i<=365; $i++) {
90 $seconds = $i * 86400;
91 $periodmenu[$seconds] = get_string('numdays', '', $i);
94 $timeformat = get_string('strftimedate');
95 $today = time();
96 $today = make_timestamp(date('Y', $today), date('m', $today), date('d', $today), 0, 0, 0);
98 // MDL-12420, preventing course start date showing up as an option at system context and front page roles.
99 if ($course->startdate > 0) {
100 $basemenu[0] = get_string('startdate') . ' (' . userdate($course->startdate, $timeformat) . ')';
102 if ($course->enrollable != 2 || ($course->enrolstartdate == 0 || $course->enrolstartdate <= $today) && ($course->enrolenddate == 0 || $course->enrolenddate > $today)) {
103 $basemenu[3] = get_string('today') . ' (' . userdate($today, $timeformat) . ')' ;
105 if($course->enrollable == 2) {
106 if($course->enrolstartdate > 0) {
107 $basemenu[4] = get_string('courseenrolstartdate') . ' (' . userdate($course->enrolstartdate, $timeformat) . ')';
109 if($course->enrolenddate > 0) {
110 $basemenu[5] = get_string('courseenrolenddate') . ' (' . userdate($course->enrolenddate, $timeformat) . ')';
114 /// Make sure this user can assign that role
116 if ($roleid) {
117 if (!user_can_assign($context, $roleid)) {
118 error ('you can not override this role in this context');
122 if ($userid) {
123 $user = get_record('user', 'id', $userid);
124 $fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
128 /// Print the header and tabs
130 if ($context->contextlevel == CONTEXT_USER) {
131 /// course header
132 $navlinks = array();
133 if ($courseid != SITEID) {
134 if (has_capability('moodle/course:viewparticipants', get_context_instance(CONTEXT_COURSE, $course->id))) {
135 $navlinks[] = array('name' => $strparticipants, 'link' => "$CFG->wwwroot/user/index.php?id=$course->id", 'type' => 'misc');
137 $navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$userid&amp;course=$courseid", 'type' => 'misc');
138 $navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
139 $navigation = build_navigation($navlinks);
141 print_header("$fullname", "$fullname", $navigation, "", "", true, "&nbsp;", navmenu($course));
143 /// site header
144 } else {
145 $navlinks[] = array('name' => $fullname, 'link' => "$CFG->wwwroot/user/view.php?id=$userid&amp;course=$courseid", 'type' => 'misc');
146 $navlinks[] = array('name' => $straction, 'link' => null, 'type' => 'misc');
147 $navigation = build_navigation($navlinks);
148 print_header("$course->fullname: $fullname", $course->fullname, $navigation, "", "", true, "&nbsp;", navmenu($course));
151 $showroles = 1;
152 $currenttab = 'assign';
153 include_once($CFG->dirroot.'/user/tabs.php');
154 } else if ($context->contextlevel == CONTEXT_SYSTEM) {
155 admin_externalpage_setup('assignroles');
156 admin_externalpage_print_header();
157 } else if ($context->contextlevel==CONTEXT_COURSE and $context->instanceid == SITEID) {
158 admin_externalpage_setup('frontpageroles');
159 admin_externalpage_print_header();
160 $currenttab = 'assign';
161 include_once('tabs.php');
162 } else {
163 $currenttab = 'assign';
164 include_once('tabs.php');
168 /// Rename some of the role names if needed
169 if (isset($coursecontext)) {
170 if ($aliasnames = get_records('role_names', 'contextid', $coursecontext->id)) {
171 foreach ($aliasnames as $alias) {
172 if (isset($assignableroles[$alias->roleid])) {
173 $assignableroles[$alias->roleid] = $alias->name.' ('.$assignableroles[$alias->roleid].')';
180 /// Process incoming role assignment
182 if ($frm = data_submitted()) {
184 if ($add and !empty($frm->addselect) and confirm_sesskey()) {
186 foreach ($frm->addselect as $adduser) {
187 if (!$adduser = clean_param($adduser, PARAM_INT)) {
188 continue;
190 $allow = true;
191 if ($inmeta) {
192 if (has_capability('moodle/course:managemetacourse', $context, $adduser)) {
193 //ok
194 } else {
195 $managerroles = get_roles_with_capability('moodle/course:managemetacourse', CAP_ALLOW, $context);
196 if (!empty($managerroles) and !array_key_exists($roleid, $managerroles)) {
197 $erruser = get_record('user', 'id', $adduser, '','','','', 'id, firstname, lastname');
198 $errors[] = get_string('metaassignerror', 'role', fullname($erruser));
199 $allow = false;
203 if ($allow) {
204 switch($extendbase) {
205 case 0:
206 $timestart = $course->startdate;
207 break;
208 case 3:
209 $timestart = $today;
210 break;
211 case 4:
212 $timestart = $course->enrolstartdate;
213 break;
214 case 5:
215 $timestart = $course->enrolenddate;
216 break;
219 if($extendperiod > 0) {
220 $timeend = $timestart + $extendperiod;
221 } else {
222 $timeend = 0;
224 if (! role_assign($roleid, $adduser, 0, $context->id, $timestart, $timeend, $hidden)) {
225 $errors[] = "Could not add user with id $adduser to this role!";
230 $rolename = get_field('role', 'name', 'id', $roleid);
231 add_to_log($course->id, 'role', 'assign', 'admin/roles/assign.php?contextid='.$context->id.'&roleid='.$roleid, $rolename, '', $USER->id);
232 } else if ($remove and !empty($frm->removeselect) and confirm_sesskey()) {
234 $sitecontext = get_context_instance(CONTEXT_SYSTEM);
235 $topleveladmin = false;
237 // we only worry about this if the role has doanything capability at site level
238 if ($context->id == $sitecontext->id && $adminroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext)) {
239 foreach ($adminroles as $adminrole) {
240 if ($adminrole->id == $roleid) {
241 $topleveladmin = true;
246 foreach ($frm->removeselect as $removeuser) {
247 $removeuser = clean_param($removeuser, PARAM_INT);
249 if ($topleveladmin && ($removeuser == $USER->id)) { // Prevent unassigning oneself from being admin
250 continue;
253 if (! role_unassign($roleid, $removeuser, 0, $context->id)) {
254 $errors[] = "Could not remove user with id $removeuser from this role!";
255 } else if ($inmeta) {
256 sync_metacourse($courseid);
257 $newroles = get_user_roles($context, $removeuser, false);
258 if (!empty($newroles) and !array_key_exists($roleid, $newroles)) {
259 $erruser = get_record('user', 'id', $removeuser, '','','','', 'id, firstname, lastname');
260 $errors[] = get_string('metaunassignerror', 'role', fullname($erruser));
261 $allow = false;
266 $rolename = get_field('role', 'name', 'id', $roleid);
267 add_to_log($course->id, 'role', 'unassign', 'admin/roles/assign.php?contextid='.$context->id.'&roleid='.$roleid, $rolename, '', $USER->id);
268 } else if ($showall) {
269 $searchtext = '';
270 $previoussearch = 0;
277 if ($context->contextlevel==CONTEXT_COURSE and $context->instanceid == SITEID) {
278 print_heading_with_help(get_string('frontpageroles', 'admin'), 'assignroles');
279 } else {
280 print_heading_with_help(get_string('assignrolesin', 'role', print_context_name($context)), 'assignroles');
283 if ($context->contextlevel==CONTEXT_SYSTEM) {
284 print_box(get_string('globalroleswarning', 'role'));
287 if ($roleid) { /// prints a form to swap roles
289 /// Get all existing participants in this context.
290 // Why is this not done with get_users???
292 if (!$contextusers = get_role_users($roleid, $context, false, 'u.id, u.firstname, u.lastname, u.email, ra.hidden')) {
293 $contextusers = array();
296 $select = "username <> 'guest' AND deleted = 0 AND confirmed = 1";
298 $usercount = count_records_select('user', $select) - count($contextusers);
300 $searchtext = trim($searchtext);
302 if ($searchtext !== '') { // Search for a subset of remaining users
303 $LIKE = sql_ilike();
304 $FULLNAME = sql_fullname();
306 $selectsql = " AND ($FULLNAME $LIKE '%$searchtext%' OR email $LIKE '%$searchtext%') ";
307 $select .= $selectsql;
308 } else {
309 $selectsql = "";
312 if ($context->contextlevel > CONTEXT_COURSE) { // mod or block (or group?)
314 /************************************************************************
316 * context level is above or equal course context level *
317 * in this case we pull out all users matching search criteria (if any) *
319 * MDL-11324 *
320 * a mini get_users_by_capability() call here, this is done instead of *
321 * get_users_by_capability() because *
322 * 1) get_users_by_capability() does not deal with searching by name *
323 * 2) exceptions array can be potentially large for large courses *
324 * 3) get_recordset_sql() is more efficient *
326 ************************************************************************/
328 if ($possibleroles = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context)) {
330 $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, get_context_instance(CONTEXT_SYSTEM));
332 $validroleids = array();
333 foreach ($possibleroles as $possiblerole) {
334 if (isset($doanythingroles[$possiblerole->id])) { // We don't want these included
335 continue;
337 if ($caps = role_context_capabilities($possiblerole->id, $context, 'moodle/course:view')) { // resolved list
338 if (isset($caps['moodle/course:view']) && $caps['moodle/course:view'] > 0) { // resolved capability > 0
339 $validroleids[] = $possiblerole->id;
344 if ($validroleids) {
345 $roleids = '('.implode(',', $validroleids).')';
347 $select = " SELECT u.id, u.firstname, u.lastname, u.email";
348 $countselect = "SELECT COUNT(u.id)";
349 $from = " FROM {$CFG->prefix}user u
350 INNER JOIN {$CFG->prefix}role_assignments ra ON ra.userid = u.id
351 INNER JOIN {$CFG->prefix}role r ON r.id = ra.roleid";
352 $where = " WHERE ra.contextid ".get_related_contexts_string($context)."
353 AND u.deleted = 0
354 AND ra.roleid in $roleids";
355 $excsql = " AND u.id NOT IN (
356 SELECT u.id
357 FROM {$CFG->prefix}role_assignments r,
358 {$CFG->prefix}user u
359 WHERE r.contextid = $contextid
360 AND u.id = r.userid
361 AND r.roleid = $roleid
362 $selectsql)";
364 $availableusers = get_recordset_sql($select . $from . $where . $selectsql . $excsql);
367 $usercount = $availableusers->_numOfRows;
370 } else {
372 /************************************************************************
374 * context level is above or equal course context level *
375 * in this case we pull out all users matching search criteria (if any) *
377 ************************************************************************/
379 /// MDL-11111 do not include user already assigned this role in this context as available users
380 /// so that the number of available users is right and we save time looping later
381 $availableusers = get_recordset_sql('SELECT id, firstname, lastname, email
382 FROM '.$CFG->prefix.'user
383 WHERE '.$select.'
384 AND id NOT IN (
385 SELECT u.id
386 FROM '.$CFG->prefix.'role_assignments r,
387 '.$CFG->prefix.'user u
388 WHERE r.contextid = '.$contextid.'
389 AND u.id = r.userid
390 AND r.roleid = '.$roleid.'
391 '.$selectsql.')
392 ORDER BY lastname ASC, firstname ASC');
394 $usercount = $availableusers->_numOfRows;
397 echo '<div class="selector">';
398 $assignableroles = array('0'=>get_string('listallroles', 'role').'...') + $assignableroles;
399 popup_form("$CFG->wwwroot/$CFG->admin/roles/assign.php?userid=$userid&amp;courseid=$courseid&amp;contextid=$contextid&amp;roleid=",
400 $assignableroles, 'switchrole', $roleid, '', '', '', false, 'self', $strroletoassign);
401 echo '</div>';
403 print_simple_box_start('center');
404 include('assign.html');
405 print_simple_box_end();
407 if (!empty($errors)) {
408 $msg = '<p>';
409 foreach ($errors as $e) {
410 $msg .= $e.'<br />';
412 $msg .= '</p>';
413 print_simple_box_start('center');
414 notify($msg);
415 print_simple_box_end();
418 } else { // Print overview table
420 // sync metacourse enrolments if needed
421 if ($inmeta) {
422 sync_metacourse($course);
425 // Get the names of role holders for roles with between 1 and MAX_USERS_TO_LIST_PER_ROLE users,
426 // and so determine whether to show the extra column.
427 $rolehodlercount = array();
428 $rolehodlernames = array();
429 $strmorethanten = get_string('morethan', 'role', MAX_USERS_TO_LIST_PER_ROLE);
430 $showroleholders = false;
431 foreach ($assignableroles as $roleid => $rolename) {
432 $countusers = count_role_users($roleid, $context);
433 $rolehodlercount[$roleid] = $countusers;
434 $roleusers = '';
435 if (0 < $countusers && $countusers <= MAX_USERS_TO_LIST_PER_ROLE) {
436 $roleusers = get_role_users($roleid, $context, false, 'u.id, u.lastname, u.firstname');
437 if (!empty($roleusers)) {
438 $strroleusers = array();
439 foreach ($roleusers as $user) {
440 $strroleusers[] = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $user->id . '" >' . fullname($user) . '</a>';
442 $rolehodlernames[$roleid] = implode('<br />', $strroleusers);
443 $showroleholders = true;
445 } else if ($countusers > MAX_USERS_TO_LIST_PER_ROLE) {
446 $rolehodlernames[$roleid] = '<a href="'.$baseurl.'&amp;roleid='.$roleid.'">'.$strmorethanten.'</a>';
447 } else {
448 $rolehodlernames[$roleid] = '';
452 // Print overview table
453 $table->tablealign = 'center';
454 $table->cellpadding = 5;
455 $table->cellspacing = 0;
456 $table->width = '60%';
457 $table->head = array(get_string('roles', 'role'), get_string('description'), get_string('users'));
458 $table->wrap = array('nowrap', '', 'nowrap');
459 $table->align = array('right', 'left', 'center');
460 if ($showroleholders) {
461 $table->head[] = '';
462 $table->wrap[] = 'nowrap';
463 $table->align[] = 'left';
466 foreach ($assignableroles as $roleid => $rolename) {
467 $description = format_string(get_field('role', 'description', 'id', $roleid));
468 $row = array('<a href="'.$baseurl.'&amp;roleid='.$roleid.'">'.$rolename.'</a>',$description, $rolehodlercount[$roleid]);
469 if ($showroleholders) {
470 $row[] = $rolehodlernames[$roleid];
472 $table->data[] = $row;
475 print_table($table);
478 print_footer($course);