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);
22 redirect('manage.php');
28 $roles = get_all_roles();
29 $rolescount = count($roles);
31 /// fix sort order if needed
34 foreach ($roles as $rolex) {
35 $rolesort[$i] = $rolex->id
;
36 if ($rolex->sortorder
!= $i) {
40 update_record('role', $r);
41 $roles[$rolex->id
]->sortorder
= $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.
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)) {
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');
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
);
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
})) {
102 // legacy caps have their own selector
103 if (islegacy($data->{$cap->name
})) {
107 $capname = $cap->name
;
108 $value = clean_param($data->{$cap->name
}, PARAM_INT
);
109 if (!in_array($value, $allowed_values)) {
113 if (empty($errors)) {
114 assign_capability($capname, $value, $newroleid, $sitecontext->id
);
116 $newrole->$capname = $value;
120 // added a role sitewide...
121 mark_context_dirty($sitecontext->path
);
123 if (empty($errors)) {
124 redirect('manage.php');
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)) {
141 $errors['name'] = get_string('errorbadrolename', 'role');
142 } else if ($rs = get_records('role', 'name', $name)) {
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)) {
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
})) {
173 // legacy caps have their own selector
174 if (islegacy($data->{$cap->name
}) === 0 ) {
178 $capname = $cap->name
;
179 $value = clean_param($data->{$cap->name
}, PARAM_INT
);
180 if (!in_array($value, $allowed_values)) {
184 if (!empty($errors)) {
185 $newrole->$capname = $value;
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
);
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
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
);
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
);
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()){
262 admin_externalpage_print_header();
263 $optionsyes = array('action'=>'delete', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
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();
274 redirect('manage.php');
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');
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');
308 if (!array_key_exists($roleid, $roles)) {
309 redirect('manage.php');
312 if ($confirm and data_submitted() and confirm_sesskey()) {
313 //ok - lets duplicate!
316 admin_externalpage_print_header();
317 $optionsyes = array('action'=>'duplicate', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
318 $optionsno = array('action'=>'view', 'roleid'=>$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();
328 // duplicate current role
329 $sourcerole = get_record('role','id',$roleid);
331 $fullname = $sourcerole->name
;
332 $shortname = $sourcerole->shortname
;
333 $currentfullname = "";
334 $currentshortname = "";
337 // find a name for the duplicated role
340 $suffixfull = " ".get_string("copyasnoun")." ".$counter;
341 $suffixshort = "_".$counter;
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));
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');
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&roleid='.$roleid);
381 admin_externalpage_print_header();
382 $optionsyes = array('action'=>'reset', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
383 $optionsno = array('action'=>'view', 'roleid'=>$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);
392 $warning = get_string('resetrolesure', 'role', $a);
394 notice_yesno($warning, 'manage.php', 'manage.php', $optionsyes, $optionsno, 'post', 'get');
395 admin_externalpage_print_footer();
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') {
416 if (empty($errors) or empty($newrole)) {
417 $role = new object();
419 $role->shortname
= '';
420 $role->description
= '';
421 $role->legacytype
= '';
423 $role = stripslashes_safe($newrole);
425 } else if ($action == 'edit' and !empty($errors) and !empty($newrole)) {
426 $role = stripslashes_safe($newrole);
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();
448 print_heading_with_help(get_string('addrole', 'role'), 'roles');
451 print_heading_with_help(get_string('viewrole', 'role'), 'roles');
454 print_heading_with_help(get_string('editrole', 'role'), 'roles');
458 echo '<div class="selector">';
459 if ($action == 'view') {
460 popup_form('manage.php?action=view&roleid=', $roleoptions, 'switchrole', $roleid, '', '', '',
461 false, 'self', get_string('selectrole', 'role'));
463 echo '<div class="buttons">';
465 $legacytype = get_legacy_type($roleid);
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'));
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'));
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');
495 print_heading_with_help(get_string('roles', 'role'), 'roles');
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'),
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');
524 $row[0] = '<a href="manage.php?roleid='.$role->id
.'&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&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="" /> ';
532 $row[3] .= '<a title="'.$strdelete.'" href="manage.php?action=delete&roleid='.$role->id
.'&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&roleid='.$role->id
.'&sesskey='.sesskey().'">'.
537 '<img src="'.$CFG->pixpath
.'/t/up.gif" class="iconsmall" alt="'.$strmoveup.'" /></a> ';
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&roleid='.$role->id
.'&sesskey='.sesskey().'">'.
543 '<img src="'.$CFG->pixpath
.'/t/down.gif" class="iconsmall" alt="'.$strmovedown.'" /></a> ';
545 $row[3] .= '<img src="'.$CFG->wwwroot
.'/pix/spacer.gif" class="iconsmall" alt="" /> ';
548 $table->data
[] = $row;
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');
560 admin_externalpage_print_footer();
564 /// ================ some internal functions ====================////
566 function switch_roles($first, $second) {
568 //first find temorary sortorder number
569 $tempsort = count_records('role') +
3;
570 while (get_record('role','sortorder', $tempsort)) {
575 $r1->id
= $first->id
;
576 $r1->sortorder
= $tempsort;
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!");
586 if (!update_record('role', $r2)) {
587 debugging("Can not update role with ID $r2->id!");
591 $r1->sortorder
= $second->sortorder
;
592 if (!update_record('role', $r1)) {
593 debugging("Can not update role with ID $r1->id!");
600 // duplicates all the base definitions of a role
601 function role_cap_duplicate($sourcerole, $targetrole) {
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) {
610 $cap->roleid
= $targetrole;
611 insert_record('role_capabilities', $cap);