From bbdb7070cafead78e824b1fdada55918760ad510 Mon Sep 17 00:00:00 2001
From: tjhunt ' . get_string('backtoallroles', 'role') . '
\n";
+ }
+ return $output;
+ }
+
+ protected function print_field($name, $caption, $field) {
+ // Attempt to generate HTML like formslib.
+ echo '
';
+ }
+ echo $field;
+ echo '';
if ($perm == CAP_ALLOW || $perm == CAP_INHERIT) {
$checked = '';
@@ -493,7 +739,8 @@ class define_role_table_basic extends define_role_table_advanced {
}
echo '';
echo '';
+ '" value="' . CAP_ALLOW . '"' . $checked . ' /> ' . $this->strallow .
+ '' . get_string('defaultx', 'role', $this->strperms[$defaultperm]) . '';
} else {
echo '';
echo $this->strperms[$permname] . '' . $this->stradvmessage . '';
@@ -505,18 +752,49 @@ class view_role_definition_table extends define_role_table_advanced {
public function __construct($context, $roleid) {
parent::__construct($context, $roleid);
$this->displaypermissions = array(CAP_ALLOW => $this->allpermissions[CAP_ALLOW]);
+ $this->disabled = 'disabled="disabled" ';
+ }
+
+ public function save_changes() {
+ throw new moodle_exception('invalidaccess');
+ }
+
+ protected function get_name_field($id) {
+ return strip_tags(format_string($this->role->name));
+ }
+
+ protected function get_shortname_field($id) {
+ return $this->role->shortname;
+ }
+
+ protected function get_description_field($id) {
+ return format_text($this->role->description, FORMAT_HTML);
+ }
+
+ protected function get_legacy_type_field($id) {
+ if (empty($this->role->legacytype)) {
+ return get_string('none');
+ } else {
+ return get_string('legacy:'.$this->role->legacytype, 'role');
+ }
}
protected function add_permission_cells($capability) {
$perm = $this->permissions[$capability->name];
$permname = $this->allpermissions[$perm];
- echo ' ' . $this->strperms[$permname] . ' ';
+ $defaultperm = $this->allpermissions[$this->parentpermissions[$capability->name]];
+ if ($permname != $defaultperm) {
+ $default = get_string('defaultx', 'role', $this->strperms[$defaultperm]);
+ } else {
+ $default = " ";
+ }
+ echo '' . $this->strperms[$permname] . '' .
+ $default . ' ';
}
}
class override_permissions_table_advanced extends capability_table_with_risks {
- protected $roleid;
protected $strnotset;
protected $haslockedcapabiltites = false;
@@ -533,8 +811,7 @@ class override_permissions_table_advanced extends capability_table_with_risks {
* capabilities with no risks.
*/
public function __construct($context, $roleid, $safeoverridesonly) {
- $this->roleid = $roleid;
- parent::__construct($context, 'overriderolestable');
+ parent::__construct($context, 'overriderolestable', $roleid);
$this->displaypermissions = $this->allpermissions;
$this->strnotset = get_string('notset', 'role');
@@ -557,19 +834,6 @@ class override_permissions_table_advanced extends capability_table_with_risks {
$this->parentpermissions = role_context_capabilities($this->roleid, $parentcontext);
}
- /**
- * Save any overrides that have been changed.
- */
- public function save_changes() {
- foreach ($this->changed as $changedcap) {
- assign_capability($changedcap, $this->permissions[$changedcap],
- $this->roleid, $this->context->id, true);
- }
-
- // force accessinfo refresh for users visiting this context...
- mark_context_dirty($this->context->path);
- }
-
public function has_locked_capabiltites() {
return $this->haslockedcapabiltites;
}
diff --git a/admin/roles/manage.html b/admin/roles/manage.html
deleted file mode 100755
index cfec37f847..0000000000
--- a/admin/roles/manage.html
+++ /dev/null
@@ -1,236 +0,0 @@
-
-
-
diff --git a/admin/roles/manage.php b/admin/roles/manage.php
index 48bed9abaf..70918a76f3 100755
--- a/admin/roles/manage.php
+++ b/admin/roles/manage.php
@@ -26,6 +26,16 @@
/**
* Lets the user define and edit roles.
*
+ * Responds to actions:
+ * [blank] - list roles.
+ * delete - delete a role (with are-you-sure)
+ * moveup - change the sort order
+ * movedown - change the sort order
+ * reset - set a role's permissions back to the default for that legacy role type.
+ *
+ * For all but the first two of those, you also need a roleid parameter, and
+ * possibly some other data.
+ *
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
* @package roles
*//** */
@@ -33,300 +43,45 @@
require_once(dirname(__FILE__) . '/../../config.php');
require_once($CFG->dirroot . '/' . $CFG->admin . '/roles/lib.php');
- require_once($CFG->libdir.'/adminlib.php');
-
- admin_externalpage_setup('defineroles');
-
- $roleid = optional_param('roleid', 0, PARAM_INT); // if set, we are editing a role
- $name = optional_param('name', '', PARAM_MULTILANG); // new role name
- $shortname = optional_param('shortname', '', PARAM_RAW); // new role shortname, special cleaning before storage
- $description = optional_param('description', '', PARAM_CLEAN); // new role desc
- $action = optional_param('action', '', PARAM_ALPHA);
- $confirm = optional_param('confirm', 0, PARAM_BOOL);
- $cancel = optional_param('cancel', 0, PARAM_BOOL);
-
- $sitecontext = get_context_instance(CONTEXT_SYSTEM);
-
- require_capability('moodle/role:manage', $sitecontext);
-
- if ($cancel) {
- redirect('manage.php');
+ $action = optional_param('action', '', PARAM_ALPHA);
+ if ($action) {
+ $roleid = required_param('roleid', PARAM_INT);
}
- $errors = array();
- $newrole = false;
+/// Get the base URL for this and related pages into a convenient variable.
+ $baseurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/manage.php';
+ $defineurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/define.php';
+/// Check access permissions.
+ $systemcontext = get_context_instance(CONTEXT_SYSTEM);
+ require_login();
+ require_capability('moodle/role:manage', $systemcontext);
+ admin_externalpage_setup('defineroles');
+
+/// Get some basic data we are going to need.
$roles = get_all_roles();
+ role_fix_names($roles, $systemcontext, ROLENAME_ORIGINAL);
$rolescount = count($roles);
- $allcontextlevels = array(
- CONTEXT_SYSTEM => get_string('coresystem'),
- CONTEXT_USER => get_string('user'),
- CONTEXT_COURSECAT => get_string('category'),
- CONTEXT_COURSE => get_string('course'),
- CONTEXT_MODULE => get_string('activitymodule'),
- CONTEXT_BLOCK => get_string('block')
- );
-
-/// fix sort order if needed
- $rolesort = array();
- $i = 0;
- foreach ($roles as $rolex) {
- $rolesort[$i] = $rolex->id;
- if ($rolex->sortorder != $i) {
- $r = new object();
- $r->id = $rolex->id;
- $r->sortorder = $i;
- $DB->update_record('role', $r);
- $roles[$rolex->id]->sortorder = $i;
- }
- $i++;
+ $undeletableroles = array();
+ $undeletableroles[$CFG->notloggedinroleid] = 1;
+ $undeletableroles[$CFG->guestroleid] = 1;
+ $undeletableroles[$CFG->defaultuserroleid] = 1;
+ $undeletableroles[$CFG->defaultcourseroleid] = 1;
+ // If there is only one admin role, add that to $undeletableroles too.
+ $adminroles = get_admin_roles();
+ if (count($adminroles) == 1) {
+ $undeletableroles[reset($adminroles)->id] = 1;
}
- // do not delete these default system roles
- $defaultroles = array();
- $defaultroles[] = $CFG->notloggedinroleid;
- $defaultroles[] = $CFG->guestroleid;
- $defaultroles[] = $CFG->defaultuserroleid;
- $defaultroles[] = $CFG->defaultcourseroleid;
-
-/// form processing, editing a role, adding a role, deleting a role etc.
+///.Process submitted data.
+ $confirmed = optional_param('confirm', false, PARAM_BOOL) && data_submitted() && confirm_sesskey();
switch ($action) {
- case 'add':
- if ($data = data_submitted() and confirm_sesskey()) {
-
- $shortname = textlib_get_instance()->specialtoascii($shortname);
-
- $shortname = moodle_strtolower(clean_param($shortname, PARAM_ALPHANUMEXT)); // only lowercase safe ASCII characters
- $legacytype = required_param('legacytype', PARAM_RAW);
-
- $legacyroles = get_legacy_roles();
- if (!array_key_exists($legacytype, $legacyroles)) {
- $legacytype = '';
- }
-
- if (empty($name)) {
- $errors['name'] = get_string('errorbadrolename', 'role');
- } else if ($DB->count_records('role', array('name'=>$name))) {
- $errors['name'] = get_string('errorexistsrolename', 'role');
- }
-
- if (empty($shortname)) {
- $errors['shortname'] = get_string('errorbadroleshortname', 'role');
- } else if ($DB->count_records('role', array('shortname'=>$shortname))) {
- $errors['shortname'] = get_string('errorexistsroleshortname', 'role');
- }
-
- if (empty($errors)) {
- $newroleid = create_role($name, $shortname, $description);
-
- // set proper legacy type
- if (!empty($legacytype)) {
- assign_capability($legacyroles[$legacytype], CAP_ALLOW, $newroleid, $sitecontext->id);
- }
-
- } else {
- $newrole = new object();
- $newrole->name = $name;
- $newrole->shortname = $shortname;
- $newrole->description = $description;
- $newrole->legacytype = $legacytype;
- }
-
- $newcontextlevels = array();
- foreach (array_keys($allcontextlevels) as $cl) {
- if (optional_param('contextlevel' . $cl, false, PARAM_BOOL)) {
- $newcontextlevels[$cl] = $cl;
- }
- }
- if (empty($errors)) {
- set_role_contextlevels($newroleid, $newcontextlevels);
- }
-
- $allowed_values = array(CAP_INHERIT, CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT);
- $capabilities = fetch_context_capabilities($sitecontext); // capabilities applicable in this context
-
- foreach ($capabilities as $cap) {
- if (!isset($data->{$cap->name})) {
- continue;
- }
-
- // legacy caps have their own selector
- if (is_legacy($data->{$cap->name})) {
- continue;
- }
-
- $capname = $cap->name;
- $value = clean_param($data->{$cap->name}, PARAM_INT);
- if (!in_array($value, $allowed_values)) {
- continue;
- }
-
- if (empty($errors)) {
- assign_capability($capname, $value, $newroleid, $sitecontext->id);
- } else {
- $newrole->$capname = $value;
- }
- }
-
- // added a role sitewide...
- mark_context_dirty($sitecontext->path);
-
- if (empty($errors)) {
- $rolename = $DB->get_field('role', 'name', array('id'=>$newroleid));
- add_to_log(SITEID, 'role', 'add', 'admin/roles/manage.php?action=add', $rolename, '', $USER->id);
- redirect('manage.php');
- }
- }
-
- break;
-
- case 'edit':
- if ($data = data_submitted() and confirm_sesskey()) {
-
- $shortname = moodle_strtolower(clean_param(clean_filename($shortname), PARAM_SAFEDIR)); // only lowercase safe ASCII characters
- $legacytype = required_param('legacytype', PARAM_RAW);
-
- $legacyroles = get_legacy_roles();
- if (!array_key_exists($legacytype, $legacyroles)) {
- $legacytype = '';
- }
-
- if (empty($name)) {
- $errors['name'] = get_string('errorbadrolename', 'role');
- } else if ($rs = $DB->get_records('role', array('name'=>$name))) {
- unset($rs[$roleid]);
- if (!empty($rs)) {
- $errors['name'] = get_string('errorexistsrolename', 'role');
- }
- }
-
- if (empty($shortname)) {
- $errors['shortname'] = get_string('errorbadroleshortname', 'role');
- } else if ($rs = $DB->get_records('role', array('shortname'=>$shortname))) {
- unset($rs[$roleid]);
- if (!empty($rs)) {
- $errors['shortname'] = get_string('errorexistsroleshortname', 'role');
- }
- }
- if (!empty($errors)) {
- $newrole = new object();
- $newrole->name = $name;
- $newrole->shortname = $shortname;
- $newrole->description = $description;
- $newrole->legacytype = $legacytype;
- }
-
- $newcontextlevels = array();
- foreach (array_keys($allcontextlevels) as $cl) {
- if (optional_param('contextlevel' . $cl, false, PARAM_BOOL)) {
- $newcontextlevels[$cl] = $cl;
- }
- }
- if (empty($errors)) {
- set_role_contextlevels($roleid, $newcontextlevels);
- }
-
- $allowed_values = array(CAP_INHERIT, CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT);
- $capabilities = fetch_context_capabilities($sitecontext); // capabilities applicable in this context
-
- foreach ($capabilities as $cap) {
- if (!isset($data->{$cap->name})) {
- continue;
- }
-
- // legacy caps have their own selector
- if (is_legacy($data->{$cap->name}) === 0 ) {
- continue;
- }
-
- $capname = $cap->name;
- $value = clean_param($data->{$cap->name}, PARAM_INT);
- if (!in_array($value, $allowed_values)) {
- continue;
- }
-
- if (!empty($errors)) {
- $newrole->$capname = $value;
- continue;
- }
-
- // edit default caps
- $SQL = "SELECT *
- FROM {role_capabilities}
- WHERE roleid = ? AND capability = ?
- AND contextid = ?";
- $params = array($roleid, $capname, $sitecontext->id);
-
- $localoverride = $DB->get_record_sql($SQL, $params);
-
- if ($localoverride) { // update current overrides
- if ($value == CAP_INHERIT) { // inherit = delete
- unassign_capability($capname, $roleid, $sitecontext->id);
-
- } else {
- $localoverride->permission = $value;
- $localoverride->timemodified = time();
- $localoverride->modifierid = $USER->id;
- $DB->update_record('role_capabilities', $localoverride);
- }
- } else { // insert a record
- if ($value != CAP_INHERIT) {
- assign_capability($capname, $value, $roleid, $sitecontext->id);
- }
- }
-
- }
-
- if (empty($errors)) {
- // update normal role settings
- $role->id = $roleid;
- $role->name = $name;
- $role->shortname = $shortname;
- $role->description = $description;
-
- if (!$DB->update_record('role', $role)) {
- print_error('cannotupdaterole', 'error');
- }
-
- // set proper legacy type
- foreach($legacyroles as $ltype=>$lcap) {
- if ($ltype == $legacytype) {
- assign_capability($lcap, CAP_ALLOW, $roleid, $sitecontext->id);
- } else {
- unassign_capability($lcap, $roleid);
- }
- }
-
- // edited a role sitewide...
- mark_context_dirty($sitecontext->path);
- add_to_log(SITEID, 'role', 'edit', 'admin/roles/manage.php?action=edit&roleid='.$role->id, $role->name, '', $USER->id);
-
- redirect('manage.php');
- }
-
- // edited a role sitewide - with errors, but still...
- mark_context_dirty($sitecontext->path);
- }
-
- break;
-
case 'delete':
- if (in_array($roleid, $defaultroles)) {
- print_error('cannotdeleterole', 'error', '', 'this role is used as one of the default system roles, it can not be deleted');
+ if (isset($undeletableroles[$roleid])) {
+ print_error('cannotdeletethisrole', '', $baseurl);
}
- if ($confirm and data_submitted() and confirm_sesskey()) {
- if (!delete_role($roleid)) {
-
- // partially deleted a role sitewide...?
- mark_context_dirty($sitecontext->path);
-
- print_error('cannotdeleterolewithid', 'error', '', $roleid);
- }
- // deleted a role sitewide...
- mark_context_dirty($sitecontext->path);
-
- } else if (confirm_sesskey()){
+ if (!$confirmed) {
// show confirmation
admin_externalpage_print_header();
$optionsyes = array('action'=>'delete', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
@@ -335,126 +90,72 @@
$a->name = $roles[$roleid]->name;
$a->shortname = $roles[$roleid]->shortname;
$a->count = $DB->count_records('role_assignments', array('roleid'=>$roleid));
- notice_yesno(get_string('deleterolesure', 'role', $a), 'manage.php', 'manage.php', $optionsyes, NULL, 'post', 'get');
+ notice_yesno(get_string('deleterolesure', 'role', $a), $baseurl, $baseurl, $optionsyes, NULL, 'post', 'get');
admin_externalpage_print_footer();
die;
}
-
- redirect('manage.php');
+ if (!delete_role($roleid)) {
+ // The delete failed, but mark the context dirty in case.
+ mark_context_dirty($systemcontext->path);
+ print_error('cannotdeleterolewithid', 'error', $baseurl, $roleid);
+ }
+ // Deleted a role sitewide...
+ mark_context_dirty($systemcontext->path);
+ add_to_log(SITEID, 'role', 'delete', 'admin/roles/manage.php', $roles[$roleid]->localname, '', $USER->id);
+ redirect($baseurl);
break;
case 'moveup':
- if (array_key_exists($roleid, $roles) and confirm_sesskey()) {
- $role = $roles[$roleid];
- if ($role->sortorder > 0) {
- $above = $roles[$rolesort[$role->sortorder - 1]];
-
- if (!switch_roles($role, $above)) {
- print_error('cannotmoverolewithid', 'error', '', $roleid);
+ if (confirm_sesskey()) {
+ $prevrole = null;
+ $thisrole = null;
+ foreach ($roles as $role) {
+ if ($role->id == $roleid) {
+ $thisrole = $role;
+ break;
+ } else {
+ $prevrole = $role;
}
}
+ if (is_null($thisrole) || is_null($prevrole)) {
+ print_error('cannotmoverolewithid', 'error', '', $roleid);
+ }
+ if (!switch_roles($thisrole, $prevrole)) {
+ print_error('cannotmoverolewithid', 'error', '', $roleid);
+ }
}
- redirect('manage.php');
+ redirect($baseurl);
break;
case 'movedown':
- if (array_key_exists($roleid, $roles) and confirm_sesskey()) {
- $role = $roles[$roleid];
- if ($role->sortorder + 1 < $rolescount) {
- $below = $roles[$rolesort[$role->sortorder + 1]];
-
- if (!switch_roles($role, $below)) {
- print_error('cannotmoverolewithid', 'error', '', $roleid);
+ if (confirm_sesskey()) {
+ $thisrole = null;
+ $nextrole = null;
+ foreach ($roles as $role) {
+ if ($role->id == $roleid) {
+ $thisrole = $role;
+ } else if (!is_null($thisrole)) {
+ $nextrole = $role;
+ break;
}
}
- }
-
- redirect('manage.php');
- break;
-
- case 'duplicate':
- if (!array_key_exists($roleid, $roles)) {
- redirect('manage.php');
- }
-
- if ($confirm and data_submitted() and confirm_sesskey()) {
- //ok - lets duplicate!
- } else {
- // show confirmation
- admin_externalpage_print_header();
- $optionsyes = array('action'=>'duplicate', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
- $optionsno = array('action'=>'view', 'roleid'=>$roleid);
- $a = new object();
- $a->id = $roleid;
- $a->name = $roles[$roleid]->name;
- $a->shortname = $roles[$roleid]->shortname;
- notice_yesno(get_string('duplicaterolesure', 'role', $a), 'manage.php', 'manage.php', $optionsyes, $optionsno, 'post', 'get');
- admin_externalpage_print_footer();
- die;
- }
-
- // duplicate current role
- $sourcerole = $DB->get_record('role', array('id'=>$roleid));
-
- $fullname = $sourcerole->name;
- $shortname = $sourcerole->shortname;
- $currentfullname = "";
- $currentshortname = "";
- $counter = 0;
-
- // find a name for the duplicated role
- do {
- if ($counter) {
- $suffixfull = " ".get_string("copyasnoun")." ".$counter;
- $suffixshort = "_".$counter;
- } else {
- $suffixfull = "";
- $suffixshort = "";
+ if (is_null($nextrole)) {
+ print_error('cannotmoverolewithid', 'error', '', $roleid);
+ }
+ if (!switch_roles($thisrole, $nextrole)) {
+ print_error('cannotmoverolewithid', 'error', '', $roleid);
}
- $currentfullname = $fullname.$suffixfull;
- // Limit the size of shortname - database column accepts <= 100 chars
- $currentshortname = substr($shortname, 0, 100 - strlen($suffixshort)).$suffixshort;
- $coursefull = $DB->get_record("role", array("name"=>$currentfullname));
- $courseshort = $DB->get_record("role", array("shortname"=>$currentshortname));
- $counter++;
- } while ($coursefull || $courseshort);
-
- $description = 'duplicate of '.$fullname;
- if ($newrole = create_role($currentfullname, $currentshortname, $description)) {
- // dupilcate all the capabilities
- role_cap_duplicate($sourcerole, $newrole);
-
- set_role_contextlevels($newrole, get_role_contextlevels($roleid));
-
- // dup'ed a role sitewide...
- mark_context_dirty($sitecontext->path);
-
}
- $rolename = $DB->get_field('role', 'name', array('id'=>$newrole));
- add_to_log(SITEID, 'role', 'duplicate', 'admin/roles/manage.php?roleid='.$newrole.'&action=duplicate', $rolename, '', $USER->id);
- redirect('manage.php');
+
+ redirect($baseurl);
break;
case 'reset':
- if (!array_key_exists($roleid, $roles)) {
- redirect('manage.php');
+ if (isset($undeletableroles[$roleid])) {
+ print_error('cannotresetthisrole', '', $baseurl);
}
-
- if ($confirm and data_submitted() and confirm_sesskey()) {
- set_role_contextlevels($roleid, get_default_contextlevels(get_legacy_type($roleid)));
-
- reset_role_capabilities($roleid);
-
- // reset a role sitewide...
- mark_context_dirty($sitecontext->path);
-
- $rolename = $DB->get_field('role', 'name', array('id'=>$roleid));
- add_to_log(SITEID, 'role', 'reset', 'admin/roles/manage.php?roleid='.$roleid.'&action=reset', $rolename, '', $USER->id);
-
- redirect('manage.php?action=view&roleid='.$roleid);
-
- } else {
+ if (!$confirmed) {
// show confirmation
admin_externalpage_print_header();
$optionsyes = array('action'=>'reset', 'roleid'=>$roleid, 'sesskey'=>sesskey(), 'confirm'=>1);
@@ -474,178 +175,106 @@
die;
}
- break;
+ // Do the reset.
+ $legacytype = get_legacy_type($roleid);
+ if ($legacytype) {
+ set_role_contextlevels($roleid, get_default_contextlevels($legacytype));
+ }
+ reset_role_capabilities($roleid);
- default:
+ // Mark context dirty, log and redirect.
+ mark_context_dirty($systemcontext->path);
+ add_to_log(SITEID, 'role', 'reset', 'admin/roles/manage.php?action=reset&roleid=' . $roleid, $roles[$roleid]->localname, '', $USER->id);
+ redirect($defineurl . '?action=view&roleid=' . $roleid);
break;
}
-/// print UI now
- require_js(array('yui_yahoo', 'yui_dom', 'yui_event'));
- require_js($CFG->admin . '/roles/roles.js');
+/// Print the page header and tabs.
admin_externalpage_print_header();
$currenttab = 'manage';
include_once('managetabs.php');
- if (($roleid and ($action == 'view' or $action == 'edit')) or $action == 'add') { // view or edit role details
+ print_heading_with_help(get_string('roles', 'role'), 'roles');
+
+/// Initialise table.
+ $table = new object;
+ $table->tablealign = 'center';
+ $table->align = array('left', 'left', 'left', 'left');
+ $table->wrap = array('nowrap', '', 'nowrap','nowrap');
+ $table->width = '90%';
+ $table->head = array(
+ get_string('role'),
+ get_string('description'),
+ get_string('shortname'),
+ get_string('edit')
+ );
- if ($action == 'add') {
- $roleid = 0;
- if (empty($errors) or empty($newrole)) {
- $role = new object();
- $role->name = '';
- $role->shortname = '';
- $role->description = '';
- $role->legacytype = '';
- $rolecontextlevels = array();
- } else {
- $role = $newrole;
- $rolecontextlevels = $newcontextlevels;
- }
- } else if ($action == 'edit' and !empty($errors) and !empty($newrole)) {
- $role = $newrole;
- $rolecontextlevels = $newcontextlevels;
-
+/// Get some strings outside the loop.
+ $stredit = get_string('edit');
+ $strduplicate = get_string('duplicate');
+ $strdelete = get_string('delete');
+ $strmoveup = get_string('moveup');
+ $strmovedown = get_string('movedown');
+
+/// Print a list of roles with edit/copy/delete/reorder icons.
+ $table->data = array();
+ $lastrole = end($roles);
+ foreach ($roles as $role) {
+
+ /// Basic data.
+ $row = array(
+ '' . $role->localname . '',
+ format_text($role->description, FORMAT_HTML),
+ s($role->shortname),
+ '',
+ );
+
+ /// Icons:
+ // move up
+ if ($role->sortorder != 0) {
+ $row[3] .= get_action_icon($baseurl . '?action=moveup&roleid=' . $role->id . '&sesskey=' . sesskey(), 'up', $strmoveup, $strmoveup);
} else {
- if(!$role = $DB->get_record('role', array('id'=>$roleid))) {
- print_error('wrongroleid', 'error');
- }
- $role->legacytype = get_legacy_type($role->id);
- $rolecontextlevels = get_role_contextlevels($roleid);
- }
-
- foreach ($roles as $rolex) {
- $roleoptions[$rolex->id] = strip_tags(format_string($rolex->name));
- }
-
- // this is the array holding capabilities of this role sorted till this context
- $r_caps = role_context_capabilities($roleid, $sitecontext);
-
- // this is the available capabilities assignable in this context
- $capabilities = fetch_context_capabilities($sitecontext);
-
- $usehtmleditor = can_use_html_editor();
-
- switch ($action) {
- case 'add':
- print_heading_with_help(get_string('addrole', 'role'), 'roles');
- break;
- case 'view':
- print_heading_with_help(get_string('viewrole', 'role'), 'roles');
- break;
- case 'edit':
- print_heading_with_help(get_string('editrole', 'role'), 'roles');
- break;
- }
-
- echo ' ';
- if (in_array($role->id, $defaultroles)) {
- $row[3] .= '
';
- } else {
- $row[3] .= ''.
- '
';
- }
- if ($role->sortorder != 0) {
- $row[3] .= ''.
- '
';
- } else {
- $row[3] .= '
';
- }
- if ($role->sortorder+1 < $rolescount) {
- $row[3] .= ''.
- '
';
- } else {
- $row[3] .= '
';
- }
-
- $table->data[] = $row;
-
+ // edit
+ $row[3] .= get_action_icon($defineurl . '?action=edit&roleid=' . $role->id,
+ 'edit', $stredit, get_string('editxrole', 'role', $role->localname));
+ // duplicate
+ $row[3] .= get_action_icon($defineurl . '?action=duplicate&roleid=' . $role->id,
+ 'copy', $strduplicate, get_string('createrolebycopying', 'role', $role->localname));
+ // delete
+ if (isset($undeletableroles[$role->id])) {
+ $row[3] .= get_spacer();
+ } else {
+ $row[3] .= get_action_icon($baseurl . '?action=delete&roleid=' . $role->id,
+ 'delete', $strdelete, get_string('deletexrole', 'role', $role->localname));
}
- print_table($table);
- $options = new object();
- $options->action = 'add';
- echo ' ';
+ $table->data[] = $row;
}
+ print_table($table);
+
+ echo ' ';
admin_externalpage_print_footer();
die;
-
-
+function get_action_icon($url, $icon, $alt, $tooltip) {
+ global $CFG;
+ return '' .
+ '
';
+}
+function get_spacer() {
+ global $CFG;
+ return '
';
+}
?>
diff --git a/lang/en_utf8/error.php b/lang/en_utf8/error.php
index e936595175..f1c71f72e8 100644
--- a/lang/en_utf8/error.php
+++ b/lang/en_utf8/error.php
@@ -47,6 +47,7 @@ $string['cannotdeletecourse'] = 'You do not have the permission to delete this c
$string['cannotdeletecustomfield'] = 'Error deleting custom field data';
$string['cannotdeletedir'] = 'Cannot delete ($a)';
$string['cannotdeleterole'] = 'It cannot be deleted, because $a';
+$string['cannotdeletethisrole'] = 'You cannot delete this role because it is used by the system, or because it is the last role with administrator capabilities.';
$string['cannotdeleterolewithid'] = 'Could not delete role with ID $a';
$string['cannotdownloadcomponents'] = 'Cannot download components';
$string['cannotdownloadlanguageupdatelist'] = 'Cannot download list of language updates from download.moodle.org';
@@ -105,6 +106,7 @@ $string['cannotremovefrommeta'] = 'Could not remove the selected course from thi
$string['cannotrestore'] = 'An error has occurred and the restore could not be completed!';
$string['cannotresetguestpwd'] = 'You cannot reset the guest password';
$string['cannotresetmail'] = 'Error resetting password and mailing you';
+$string['cannotresetthisrole'] ='Cannot reset this role';
$string['cannotrestoreadminorcreator'] = 'You need to be a creator or admin user to restore into new course!';
$string['cannotrestoreadminoredit'] = 'You need to be a editing teacher or admin user to restore into selected course!';
$string['cannotsaveblock'] = 'Error saving block configuration';
@@ -205,6 +207,7 @@ $string['errorcleaningdirectory'] = 'Error cleaning directory \"$a\"';
$string['errorcopyingfiles'] = 'Error copying files';
$string['errorcreatingdirectory'] = 'Error creating directory \"$a\"';
$string['errorcreatingfile'] = 'Error creating file \"$a\"';
+$string['errorcreatingrole'] = 'Error creating role';
$string['erroronline'] = 'Error on line $a';
$string['errorreadingfile'] = 'Error reading file \"$a\"';
$string['errorunzippingfiles'] = 'Error unzipping files';
diff --git a/lang/en_utf8/role.php b/lang/en_utf8/role.php
index 8a87037951..ed1c1b8c31 100644
--- a/lang/en_utf8/role.php
+++ b/lang/en_utf8/role.php
@@ -4,6 +4,7 @@
$string['addinganewrole'] = 'Adding a new role';
$string['addrole'] = 'Add a new role';
+$string['addingrolebycopying'] = 'Adding a new role based on $a';
$string['allow'] = 'Allow';
$string['allowassign'] = 'Allow role assignments';
$string['allowed'] = 'Allowed';
@@ -64,17 +65,21 @@ $string['course:viewparticipants'] = 'View participants';
$string['course:viewscales'] = 'View scales';
$string['course:visibility'] = 'Hide/show courses';
$string['createhiddenassign'] = 'Create hidden role assignments';
+$string['createrolebycopying'] = 'Create a new role by copying $a';
$string['currentcontext'] = 'Current context';
$string['currentrole'] = 'Current role';
$string['defaultrole'] = 'Default role';
+$string['defaultx'] = 'Default: $a';
$string['defineroles'] = 'Define roles';
$string['deletecourseoverrides'] = 'Delete all overrides in course';
$string['deletelocalroles'] = 'Delete all local role assignments';
$string['deleterolesure'] = 'Are you sure that you want to delete role \"$a->name ($a->shortname)\"?
Currently this role is assigned to $a->count users.'; +$string['deletexrole'] = 'Delete $a role'; $string['duplicaterolesure'] = 'Are you sure that you want to duplicate role \"$a->name ($a->shortname)\"?
'; $string['duplicaterole'] = 'Duplicate role'; $string['editingrolex'] = 'Editing role \'$a\''; $string['editrole'] = 'Edit role'; +$string['editxrole'] = 'Edit $a role'; $string['errorbadrolename'] = 'Incorrect role name'; $string['errorbadroleshortname'] = 'Incorrect role name'; $string['errorexistsrolename'] = 'Role name already exists'; diff --git a/lib/accesslib.php b/lib/accesslib.php index e2b2792ae0..ea9d07a634 100755 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -533,7 +533,7 @@ function is_siteadmin($userid) { * @return boolean, whether this role is an admin role. */ function is_admin_role($roleid) { - global $CFG, $DB; + global $DB; $sql = "SELECT 1 FROM {role_capabilities} rc @@ -548,6 +548,30 @@ function is_admin_role($roleid) { return $DB->record_exists_sql($sql, $params); } +/** + * @return all the roles for which is_admin_role($role->id) is true. + */ +function get_admin_roles() { + global $DB; + + $sql = "SELECT * + FROM {role} r + WHERE EXISTS ( + SELECT 1 + FROM {role_capabilities} rc + JOIN {context} ctx ON ctx.id = rc.contextid + WHERE ctx.contextlevel = 10 + AND rc.roleid = r.id + AND rc.capability IN (?, ?, ?) + GROUP BY rc.capability + HAVING SUM(rc.permission) > 0 + ) + ORDER BY r.sortorder"; + $params = array('moodle/site:config', 'moodle/legacy:admin', 'moodle/site:doanything'); + + return $DB->get_records_sql($sql, $params); +} + function get_course_from_path ($path) { // assume that nothing is more than 1 course deep if (preg_match('!^(/.+)/\d+$!', $path, $matches)) { @@ -2505,54 +2529,39 @@ function get_local_override($roleid, $contextid, $capability) { function create_role($name, $shortname, $description, $legacy='') { global $DB; - // check for duplicate role name - - if ($role = $DB->get_record('role', array('name'=>$name))) { - print_error('duplicaterolename'); - } - - if ($role = $DB->get_record('role', array('shortname'=>$shortname))) { - print_error('duplicateroleshortname'); + // Get the system context. + if (!$context = get_context_instance(CONTEXT_SYSTEM)) { + return false; } + // Insert the role record. $role = new object(); $role->name = $name; $role->shortname = $shortname; $role->description = $description; //find free sortorder number - $role->sortorder = $DB->count_records('role'); - while ($DB->get_record('role',array('sortorder'=>$role->sortorder))) { - $role->sortorder += 1; - } + $role->sortorder = $DB->get_field('role', 'MAX(sortorder) + 1', array()); + $id = $DB->insert_record('role', $role); - if (!$context = get_context_instance(CONTEXT_SYSTEM)) { + if (!$id) { return false; } - if ($id = $DB->insert_record('role', $role)) { - if ($legacy) { - assign_capability($legacy, CAP_ALLOW, $id, $context->id); - } - - /// By default, users with role:manage at site level - /// should be able to assign users to this new role, and override this new role's capabilities + if ($legacy) { + assign_capability($legacy, CAP_ALLOW, $id, $context->id); + } - // find all admin roles - if ($adminroles = get_roles_with_capability('moodle/role:manage', CAP_ALLOW, $context)) { - // foreach admin role - foreach ($adminroles as $arole) { - // write allow_assign and allow_overrid - allow_assign($arole->id, $id); - allow_override($arole->id, $id); - } + // By default, users with role:manage at site level should be able to assign + // users to this new role, and override this new role's capabilities. + if ($adminroles = get_admin_roles()) { + foreach ($adminroles as $arole) { + allow_assign($arole->id, $id); + allow_override($arole->id, $id); } - - return $id; - } else { - return false; } + return $id; } /** @@ -4374,8 +4383,11 @@ function get_default_contextlevels($roletype) { 'guest' => array(), 'user' => array() ); - - return $defaults[$roletype]; + if (isset($defaults[$roletype])) { + return $defaults[$roletype]; + } else { + return array(); + } } /** @@ -4395,7 +4407,7 @@ function set_role_contextlevels($roleid, array $contextlevels) { foreach ($contextlevels as $level) { $rcl->contextlevel = $level; if (!$DB->insert_record('role_context_levels', $rcl, false, true)) { - throw new moodle_exception('couldnotdeleterolecontextlevels', '', '', $rcl); + throw new moodle_exception('couldnotdeleterolecontextlevels', '', '', $rcl); } } } @@ -5816,47 +5828,19 @@ function fix_role_sortorder($allroles) { } /** - * switch role order (used in admin/roles/manage.php) - * - * @param int $first id of role to move down - * @param int $second id of role to move up + * Switch the sort order of two roles (used in admin/roles/manage.php). * - * @return bool success or failure + * @param object $first The first role. Actually, only ->sortorder is used. + * @param object $second The second role. Actually, only ->sortorder is used. + * @return boolean success or failure */ function switch_roles($first, $second) { global $DB; - - $status = true; - //first find temorary sortorder number - $tempsort = $DB->count_records('role') + 3; - while ($DB->get_record('role',array('sortorder'=>$tempsort))) { - $tempsort += 3; - } - - $r1 = new object(); - $r1->id = $first->id; - $r1->sortorder = $tempsort; - $r2 = new object(); - $r2->id = $second->id; - $r2->sortorder = $first->sortorder; - - if (!$DB->update_record('role', $r1)) { - debugging("Can not update role with ID $r1->id!"); - $status = false; - } - - if (!$DB->update_record('role', $r2)) { - debugging("Can not update role with ID $r2->id!"); - $status = false; - } - - $r1->sortorder = $second->sortorder; - if (!$DB->update_record('role', $r1)) { - debugging("Can not update role with ID $r1->id!"); - $status = false; - } - - return $status; + $temp = $DB->get_field('role', 'MAX(sortorder) + 1', array()); + $result = $DB->set_field('role', 'sortorder', $temp, array('sortorder' => $first->sortorder)); + $result = $result && $DB->set_field('role', 'sortorder', $first->sortorder, array('sortorder' => $second->sortorder)); + $result = $result && $DB->set_field('role', 'sortorder', $second->sortorder, array('sortorder' => $temp)); + return $result; } /** diff --git a/theme/standard/styles_color.css b/theme/standard/styles_color.css index 7a06032cf5..22f95b5a0d 100644 --- a/theme/standard/styles_color.css +++ b/theme/standard/styles_color.css @@ -1197,8 +1197,7 @@ table.explainpermissions .overridden { border-bottom-color: #cecece; } -#admin-roles-manage .rolecap .cap-desc .cap-name, -#admin-roles-override .rolecap .cap-desc .cap-name, +.rolecap .cap-name, .rolecap .note { color: #888; } diff --git a/theme/standard/styles_fonts.css b/theme/standard/styles_fonts.css index 99a762568a..ea459dd254 100644 --- a/theme/standard/styles_fonts.css +++ b/theme/standard/styles_fonts.css @@ -249,8 +249,7 @@ body#admin-index .copyright { font-size: 0.8em; } -#admin-roles-manage .rolecap .cap-desc .cap-name, -#admin-roles-override .rolecap .cap-desc .cap-name, +.rolecap .cap-name, .rolecap .note { font-size: 0.75em; } diff --git a/theme/standard/styles_layout.css b/theme/standard/styles_layout.css index 2170276ea4..b7bfbaa398 100644 --- a/theme/standard/styles_layout.css +++ b/theme/standard/styles_layout.css @@ -991,10 +991,6 @@ body#admin-modules table.generaltable td.c0 padding-bottom: 20px; } -#admin-roles-manage table.generalbox { - margin: auto; -} - #admin-stickyblocks .generalbox { text-align:center; } @@ -1050,17 +1046,20 @@ body#admin-modules table.generaltable td.c0 #admin-roles-allowassign .buttons, #admin-roles-allowoverride .buttons, #admin-roles-manage .buttons, +#admin-roles-define .buttons, #admin-roles-override .buttons { margin: 20px; text-align:center; } - #admin-roles-manage .buttons .singlebutton, +#admin-roles-define .buttons .singlebutton, #admin-roles-override .buttons .singlebutton { display: inline; padding: 5px; } - +#admin-roles-define .topfields { + margin: 1em 0 2em; +} .roleassigntable { width: 100%; } @@ -1110,13 +1109,11 @@ body#admin-modules table.generaltable td.c0 .roleassigntable #addselect_wrapper label { font-weight: normal; } - -table.roledesc { - margin-left:auto; - margin-right:auto; +#admin-roles-define .mform { + width: 100%; } - #admin-roles-manage .backlink, +#admin-roles-define .backlink, #admin-roles-explain .backlink, #admin-roles-assign .backlink, #admin-roles-override .backlink { @@ -1159,9 +1156,9 @@ table.rolecap .prohibit { table.rolecap label { display: block; width: 100%; - height: 2.5em; + min-height: 2.5em; } -table.rolecap .cap-desc .cap-name, +.rolecap .cap-name, .rolecap .note { display: block; padding: 0 0.5em; -- 2.39.5