MDL-11517 reserved word MOD used in table alias in questions backup code
[moodle-pu.git] / admin / roles / manage.php
blob2a7734125e787455baeb30bade054708f7a12398
1 <?php //$Id$
3 require_once('../../config.php');
5 require_once($CFG->libdir.'/adminlib.php');
7 admin_externalpage_setup('defineroles');
9 $roleid = optional_param('roleid', 0, PARAM_INT); // if set, we are editing a role
10 $name = optional_param('name', '', PARAM_MULTILANG); // new role name
11 $shortname = optional_param('shortname', '', PARAM_RAW); // new role shortname, special cleaning before storage
12 $description = optional_param('description', '', PARAM_CLEAN); // new role desc
13 $action = optional_param('action', '', PARAM_ALPHA);
14 $confirm = optional_param('confirm', 0, PARAM_BOOL);
15 $cancel = optional_param('cancel', 0, PARAM_BOOL);
17 $sitecontext = get_context_instance(CONTEXT_SYSTEM);
19 require_capability('moodle/role:manage', $sitecontext);
21 if ($cancel) {
22 redirect('manage.php');
25 $errors = array();
26 $newrole = false;
28 $roles = get_all_roles();
29 $rolescount = count($roles);
31 /// fix sort order if needed
32 $rolesort = array();
33 $i = 0;
34 foreach ($roles as $rolex) {
35 $rolesort[$i] = $rolex->id;
36 if ($rolex->sortorder != $i) {
37 $r = new object();
38 $r->id = $rolex->id;
39 $r->sortorder = $i;
40 update_record('role', $r);
41 $roles[$rolex->id]->sortorder = $i;
43 $i++;
46 // do not delete these default system roles
47 $defaultroles = array();
48 $defaultroles[] = $CFG->notloggedinroleid;
49 $defaultroles[] = $CFG->guestroleid;
50 $defaultroles[] = $CFG->defaultuserroleid;
51 $defaultroles[] = $CFG->defaultcourseroleid;
53 /// form processing, editing a role, adding a role, deleting a role etc.
54 switch ($action) {
55 case 'add':
56 if ($data = data_submitted() and confirm_sesskey()) {
58 $shortname = moodle_strtolower(clean_param(clean_filename($shortname), PARAM_SAFEDIR)); // only lowercase safe ASCII characters
59 $legacytype = required_param('legacytype', PARAM_RAW);
61 $legacyroles = get_legacy_roles();
62 if (!array_key_exists($legacytype, $legacyroles)) {
63 $legacytype = '';
66 if (empty($name)) {
67 $errors['name'] = get_string('errorbadrolename', 'role');
68 } else if (count_records('role', 'name', $name)) {
69 $errors['name'] = get_string('errorexistsrolename', 'role');
72 if (empty($shortname)) {
73 $errors['shortname'] = get_string('errorbadroleshortname', 'role');
74 } else if (count_records('role', 'shortname', $shortname)) {
75 $errors['shortname'] = get_string('errorexistsroleshortname', 'role');
78 if (empty($errors)) {
79 $newroleid = create_role($name, $shortname, $description);
81 // set proper legacy type
82 if (!empty($legacytype)) {
83 assign_capability($legacyroles[$legacytype], CAP_ALLOW, $newroleid, $sitecontext->id);
86 } else {
87 $newrole = new object();
88 $newrole->name = $name;
89 $newrole->shortname = $shortname;
90 $newrole->description = $description;
91 $newrole->legacytype = $legacytype;
94 $allowed_values = array(CAP_INHERIT, CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT);
95 $capabilities = fetch_context_capabilities($sitecontext); // capabilities applicable in this context
97 foreach ($capabilities as $cap) {
98 if (!isset($data->{$cap->name})) {
99 continue;
102 // legacy caps have their own selector
103 if (islegacy($data->{$cap->name})) {
104 continue;
107 $capname = $cap->name;
108 $value = clean_param($data->{$cap->name}, PARAM_INT);
109 if (!in_array($value, $allowed_values)) {
110 continue;
113 if (empty($errors)) {
114 assign_capability($capname, $value, $newroleid, $sitecontext->id);
115 } else {
116 $newrole->$capname = $value;
120 // added a role sitewide...
121 mark_context_dirty($sitecontext->path);
123 if (empty($errors)) {
124 redirect('manage.php');
127 break;
129 case 'edit':
130 if ($data = data_submitted() and confirm_sesskey()) {
132 $shortname = moodle_strtolower(clean_param(clean_filename($shortname), PARAM_SAFEDIR)); // only lowercase safe ASCII characters
133 $legacytype = required_param('legacytype', PARAM_RAW);
135 $legacyroles = get_legacy_roles();
136 if (!array_key_exists($legacytype, $legacyroles)) {
137 $legacytype = '';
140 if (empty($name)) {
141 $errors['name'] = get_string('errorbadrolename', 'role');
142 } else if ($rs = get_records('role', 'name', $name)) {
143 unset($rs[$roleid]);
144 if (!empty($rs)) {
145 $errors['name'] = get_string('errorexistsrolename', 'role');
149 if (empty($shortname)) {
150 $errors['shortname'] = get_string('errorbadroleshortname', 'role');
151 } else if ($rs = get_records('role', 'shortname', $shortname)) {
152 unset($rs[$roleid]);
153 if (!empty($rs)) {
154 $errors['shortname'] = get_string('errorexistsroleshortname', 'role');
157 if (!empty($errors)) {
158 $newrole = new object();
159 $newrole->name = $name;
160 $newrole->shortname = $shortname;
161 $newrole->description = $description;
162 $newrole->legacytype = $legacytype;
165 $allowed_values = array(CAP_INHERIT, CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT);
166 $capabilities = fetch_context_capabilities($sitecontext); // capabilities applicable in this context
168 foreach ($capabilities as $cap) {
169 if (!isset($data->{$cap->name})) {
170 continue;
173 // legacy caps have their own selector
174 if (islegacy($data->{$cap->name}) === 0 ) {
175 continue;
178 $capname = $cap->name;
179 $value = clean_param($data->{$cap->name}, PARAM_INT);
180 if (!in_array($value, $allowed_values)) {
181 continue;
184 if (!empty($errors)) {
185 $newrole->$capname = $value;
186 continue;
189 // edit default caps
190 $SQL = "SELECT * FROM {$CFG->prefix}role_capabilities
191 WHERE roleid = $roleid AND capability = '$capname'
192 AND contextid = $sitecontext->id";
194 $localoverride = get_record_sql($SQL);
196 if ($localoverride) { // update current overrides
197 if ($value == CAP_INHERIT) { // inherit = delete
198 unassign_capability($capname, $roleid, $sitecontext->id);
200 } else {
201 $localoverride->permission = $value;
202 $localoverride->timemodified = time();
203 $localoverride->modifierid = $USER->id;
204 update_record('role_capabilities', $localoverride);
206 } else { // insert a record
207 if ($value != CAP_INHERIT) {
208 assign_capability($capname, $value, $roleid, $sitecontext->id);
214 if (empty($errors)) {
215 // update normal role settings
216 $role->id = $roleid;
217 $role->name = $name;
218 $role->shortname = $shortname;
219 $role->description = $description;
221 if (!update_record('role', $role)) {
222 error('Could not update role!');
225 // set proper legacy type
226 foreach($legacyroles as $ltype=>$lcap) {
227 if ($ltype == $legacytype) {
228 assign_capability($lcap, CAP_ALLOW, $roleid, $sitecontext->id);
229 } else {
230 unassign_capability($lcap, $roleid);
234 // edited a role sitewide...
235 mark_context_dirty($sitecontext->path);
237 redirect('manage.php');
240 // edited a role sitewide - with errors, but still...
241 mark_context_dirty($sitecontext->path);
243 break;
245 case 'delete':
246 if (in_array($roleid, $defaultroles)) {
247 error('This role is used as one of the default system roles, it can not be deleted');
249 if ($confirm and data_submitted() and confirm_sesskey()) {
250 if (!delete_role($roleid)) {
252 // partially deleted a role sitewide...?
253 mark_context_dirty($sitecontext->path);
255 error('Could not delete role with ID '.$roleid);
257 // deleted a role sitewide...
258 mark_context_dirty($sitecontext->path);
260 } else if (confirm_sesskey()){
261 // show confirmation
262 admin_externalpage_print_header();
263 $optionsyes = array('action'=>'delete', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
264 $a = new object();
265 $a->id = $roleid;
266 $a->name = $roles[$roleid]->name;
267 $a->shortname = $roles[$roleid]->shortname;
268 $a->count = (int)count_records('role_assignments', 'roleid', $roleid);
269 notice_yesno(get_string('deleterolesure', 'role', $a), 'manage.php', 'manage.php', $optionsyes, NULL, 'post', 'get');
270 admin_externalpage_print_footer();
271 die;
274 redirect('manage.php');
275 break;
277 case 'moveup':
278 if (array_key_exists($roleid, $roles) and confirm_sesskey()) {
279 $role = $roles[$roleid];
280 if ($role->sortorder > 0) {
281 $above = $roles[$rolesort[$role->sortorder - 1]];
283 if (!switch_roles($role, $above)) {
284 error("Cannot move role with ID $roleid");
289 redirect('manage.php');
290 break;
292 case 'movedown':
293 if (array_key_exists($roleid, $roles) and confirm_sesskey()) {
294 $role = $roles[$roleid];
295 if ($role->sortorder + 1 < $rolescount) {
296 $below = $roles[$rolesort[$role->sortorder + 1]];
298 if (!switch_roles($role, $below)) {
299 error("Cannot move role with ID $roleid");
304 redirect('manage.php');
305 break;
307 case 'duplicate':
308 if (!array_key_exists($roleid, $roles)) {
309 redirect('manage.php');
312 if ($confirm and data_submitted() and confirm_sesskey()) {
313 //ok - lets duplicate!
314 } else {
315 // show confirmation
316 admin_externalpage_print_header();
317 $optionsyes = array('action'=>'duplicate', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
318 $optionsno = array('action'=>'view', 'roleid'=>$roleid);
319 $a = new object();
320 $a->id = $roleid;
321 $a->name = $roles[$roleid]->name;
322 $a->shortname = $roles[$roleid]->shortname;
323 notice_yesno(get_string('duplicaterolesure', 'role', $a), 'manage.php', 'manage.php', $optionsyes, $optionsno, 'post', 'get');
324 admin_externalpage_print_footer();
325 die;
328 // duplicate current role
329 $sourcerole = get_record('role','id',$roleid);
331 $fullname = $sourcerole->name;
332 $shortname = $sourcerole->shortname;
333 $currentfullname = "";
334 $currentshortname = "";
335 $counter = 0;
337 // find a name for the duplicated role
338 do {
339 if ($counter) {
340 $suffixfull = " ".get_string("copyasnoun")." ".$counter;
341 $suffixshort = "_".$counter;
342 } else {
343 $suffixfull = "";
344 $suffixshort = "";
346 $currentfullname = $fullname.$suffixfull;
347 // Limit the size of shortname - database column accepts <= 15 chars
348 $currentshortname = substr($shortname, 0, 15 - strlen($suffixshort)).$suffixshort;
349 $coursefull = get_record("role","name",addslashes($currentfullname));
350 $courseshort = get_record("role","shortname",addslashes($currentshortname));
351 $counter++;
352 } while ($coursefull || $courseshort);
354 $description = 'duplicate of '.$fullname;
355 if ($newrole = create_role($currentfullname, $currentshortname, $description)) {
356 // dupilcate all the capabilities
357 role_cap_duplicate($sourcerole, $newrole);
359 // dup'ed a role sitewide...
360 mark_context_dirty($sitecontext->path);
363 redirect('manage.php');
364 break;
366 case 'reset':
367 if (!array_key_exists($roleid, $roles)) {
368 redirect('manage.php');
371 if ($confirm and data_submitted() and confirm_sesskey()) {
372 reset_role_capabilities($roleid);
374 // reset a role sitewide...
375 mark_context_dirty($sitecontext->path);
377 redirect('manage.php?action=view&amp;roleid='.$roleid);
379 } else {
380 // show confirmation
381 admin_externalpage_print_header();
382 $optionsyes = array('action'=>'reset', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
383 $optionsno = array('action'=>'view', 'roleid'=>$roleid);
384 $a = new object();
385 $a->id = $roleid;
386 $a->name = $roles[$roleid]->name;
387 $a->shortname = $roles[$roleid]->shortname;
388 $a->legacytype = get_legacy_type($roleid);
389 if (empty($a->legacytype)) {
390 $warning = get_string('resetrolesurenolegacy', 'role', $a);
391 } else {
392 $warning = get_string('resetrolesure', 'role', $a);
394 notice_yesno($warning, 'manage.php', 'manage.php', $optionsyes, $optionsno, 'post', 'get');
395 admin_externalpage_print_footer();
396 die;
399 break;
401 default:
402 break;
405 /// print UI now
407 admin_externalpage_print_header();
409 $currenttab = 'manage';
410 include_once('managetabs.php');
412 if (($roleid and ($action == 'view' or $action == 'edit')) or $action == 'add') { // view or edit role details
414 if ($action == 'add') {
415 $roleid = 0;
416 if (empty($errors) or empty($newrole)) {
417 $role = new object();
418 $role->name = '';
419 $role->shortname = '';
420 $role->description = '';
421 $role->legacytype = '';
422 } else {
423 $role = stripslashes_safe($newrole);
425 } else if ($action == 'edit' and !empty($errors) and !empty($newrole)) {
426 $role = stripslashes_safe($newrole);
427 } else {
428 if(!$role = get_record('role', 'id', $roleid)) {
429 error('Incorrect role ID!');
431 $role->legacytype = get_legacy_type($role->id);
434 foreach ($roles as $rolex) {
435 $roleoptions[$rolex->id] = strip_tags(format_string($rolex->name));
438 // this is the array holding capabilities of this role sorted till this context
439 $r_caps = role_context_capabilities($roleid, $sitecontext);
441 // this is the available capabilities assignable in this context
442 $capabilities = fetch_context_capabilities($sitecontext);
444 $usehtmleditor = can_use_html_editor();
446 switch ($action) {
447 case 'add':
448 print_heading_with_help(get_string('addrole', 'role'), 'roles');
449 break;
450 case 'view':
451 print_heading_with_help(get_string('viewrole', 'role'), 'roles');
452 break;
453 case 'edit':
454 print_heading_with_help(get_string('editrole', 'role'), 'roles');
455 break;
458 echo '<div class="selector">';
459 if ($action == 'view') {
460 popup_form('manage.php?action=view&amp;roleid=', $roleoptions, 'switchrole', $roleid, '', '', '',
461 false, 'self', get_string('selectrole', 'role'));
463 echo '<div class="buttons">';
465 $legacytype = get_legacy_type($roleid);
466 $options = array();
467 $options['roleid'] = $roleid;
468 $options['action'] = 'edit';
469 print_single_button('manage.php', $options, get_string('edit'));
470 $options['action'] = 'reset';
471 if (empty($legacytype)) {
472 print_single_button('manage.php', $options, get_string('resetrolenolegacy', 'role'));
473 } else {
474 print_single_button('manage.php', $options, get_string('resetrole', 'role'));
476 $options['action'] = 'duplicate';
477 print_single_button('manage.php', $options, get_string('duplicaterole', 'role'));
478 print_single_button('manage.php', null, get_string('listallroles', 'role'));
479 echo '</div>';
481 echo '</div>';
483 $lang = str_replace('_utf8', '', current_language());
485 print_simple_box_start('center');
486 include_once('manage.html');
487 print_simple_box_end();
489 if ($usehtmleditor) {
490 use_html_editor('description');
493 } else {
495 print_heading_with_help(get_string('roles', 'role'), 'roles');
497 $table = new object;
499 $table->tablealign = 'center';
500 $table->align = array('right', 'left', 'left', 'left');
501 $table->wrap = array('nowrap', '', 'nowrap','nowrap');
502 $table->cellpadding = 5;
503 $table->cellspacing = 0;
504 $table->width = '90%';
505 $table->data = array();
507 $table->head = array(get_string('name'),
508 get_string('description'),
509 get_string('shortname'),
510 get_string('edit'));
512 /*************************
513 * List all current roles *
514 **************************/
516 foreach ($roles as $role) {
518 $stredit = get_string('edit');
519 $strdelete = get_string('delete');
520 $strmoveup = get_string('moveup');
521 $strmovedown = get_string('movedown');
523 $row = array();
524 $row[0] = '<a href="manage.php?roleid='.$role->id.'&amp;action=view">'.format_string($role->name).'</a>';
525 $row[1] = format_text($role->description, FORMAT_HTML);
526 $row[2] = s($role->shortname);
527 $row[3] = '<a title="'.$stredit.'" href="manage.php?action=edit&amp;roleid='.$role->id.'">'.
528 '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'.$stredit.'" /></a> ';
529 if (in_array($role->id, $defaultroles)) {
530 $row[3] .= '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
531 } else {
532 $row[3] .= '<a title="'.$strdelete.'" href="manage.php?action=delete&amp;roleid='.$role->id.'&amp;sesskey='.sesskey().'">'.
533 '<img src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="'.$strdelete.'" /></a> ';
535 if ($role->sortorder != 0) {
536 $row[3] .= '<a title="'.$strmoveup.'" href="manage.php?action=moveup&amp;roleid='.$role->id.'&amp;sesskey='.sesskey().'">'.
537 '<img src="'.$CFG->pixpath.'/t/up.gif" class="iconsmall" alt="'.$strmoveup.'" /></a> ';
538 } else {
539 $row[3] .= '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
541 if ($role->sortorder+1 < $rolescount) {
542 $row[3] .= '<a title="'.$strmovedown.'" href="manage.php?action=movedown&amp;roleid='.$role->id.'&amp;sesskey='.sesskey().'">'.
543 '<img src="'.$CFG->pixpath.'/t/down.gif" class="iconsmall" alt="'.$strmovedown.'" /></a> ';
544 } else {
545 $row[3] .= '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
548 $table->data[] = $row;
551 print_table($table);
553 $options = new object();
554 $options->action = 'add';
555 echo '<div class="buttons">';
556 print_single_button('manage.php', $options, get_string('addrole', 'role'), 'get');
557 echo '</div>';
560 admin_externalpage_print_footer();
561 die;
564 /// ================ some internal functions ====================////
566 function switch_roles($first, $second) {
567 $status = true;
568 //first find temorary sortorder number
569 $tempsort = count_records('role') + 3;
570 while (get_record('role','sortorder', $tempsort)) {
571 $tempsort += 3;
574 $r1 = new object();
575 $r1->id = $first->id;
576 $r1->sortorder = $tempsort;
577 $r2 = new object();
578 $r2->id = $second->id;
579 $r2->sortorder = $first->sortorder;
581 if (!update_record('role', $r1)) {
582 debugging("Can not update role with ID $r1->id!");
583 $status = false;
586 if (!update_record('role', $r2)) {
587 debugging("Can not update role with ID $r2->id!");
588 $status = false;
591 $r1->sortorder = $second->sortorder;
592 if (!update_record('role', $r1)) {
593 debugging("Can not update role with ID $r1->id!");
594 $status = false;
597 return $status;
600 // duplicates all the base definitions of a role
601 function role_cap_duplicate($sourcerole, $targetrole) {
602 global $CFG;
603 $systemcontext = get_context_instance(CONTEXT_SYSTEM);
604 $caps = get_records_sql("SELECT * FROM {$CFG->prefix}role_capabilities
605 WHERE roleid = $sourcerole->id
606 AND contextid = $systemcontext->id");
607 // adding capabilities
608 foreach ($caps as $cap) {
609 unset($cap->id);
610 $cap->roleid = $targetrole;
611 insert_record('role_capabilities', $cap);