role override ui: MDL-8313 refactor the page in preparation for making an non-advanced mode.
This commit is contained in:
+200
-18
@@ -33,24 +33,6 @@
|
||||
require_once($CFG->libdir.'/adminlib.php');
|
||||
require_once($CFG->dirroot.'/user/selector/lib.php');
|
||||
|
||||
/**
|
||||
* Print a risk icon, as a link to the Risks page on Moodle Docs.
|
||||
*
|
||||
* @param string $type the type of risk, will be one of the keys from the
|
||||
* get_all_risks array. Must start with 'risk'.
|
||||
*/
|
||||
function print_risk_icon($type) {
|
||||
global $CFG;
|
||||
static $risksurl = null;
|
||||
if (is_null($risksurl)) {
|
||||
$risksurl = get_docs_url(s(get_string('risks', 'role')));
|
||||
}
|
||||
$iconurl = $CFG->pixpath . '/i/' . str_replace('risk', 'risk_', $type) . '.gif';
|
||||
echo '<a onclick="this.target=\'docspopup\'" title="' . get_string($type, 'admin') .
|
||||
'" href="' . $risksurl . '"> <img src="' . $iconurl . '" alt="' .
|
||||
get_string($type . 'short', 'admin') . '" /></a>';
|
||||
}
|
||||
|
||||
// Classes for producing tables with one row per capability ====================
|
||||
|
||||
/**
|
||||
@@ -275,6 +257,206 @@ class explain_capability_table extends capability_table_base {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class capability_table_with_risks extends capability_table_base {
|
||||
protected $allrisks;
|
||||
protected $allpermissions; // We don't need perms ourself, but all our subclasses do.
|
||||
protected $strperms; // Language string cache.
|
||||
protected $risksurl; // URL in moodledocs about risks.
|
||||
protected $riskicons = array(); // Cache to avoid regenerating the HTML for each risk icon.
|
||||
|
||||
public function __construct($context, $id) {
|
||||
parent::__construct($context, $id);
|
||||
|
||||
$this->allrisks = get_all_risks();
|
||||
$this->risksurl = get_docs_url(s(get_string('risks', 'role')));
|
||||
|
||||
$this->allpermissions = array(
|
||||
CAP_INHERIT => 'inherit',
|
||||
CAP_ALLOW => 'allow',
|
||||
CAP_PREVENT => 'prevent' ,
|
||||
CAP_PROHIBIT => 'prohibit',
|
||||
);
|
||||
|
||||
$this->strperms = array();
|
||||
foreach ($this->allpermissions as $permname) {
|
||||
$this->strperms[$permname] = get_string($permname, 'role');
|
||||
}
|
||||
}
|
||||
|
||||
protected function add_header_cells() {
|
||||
echo '<th class="risk" colspan="' . $this->num_extra_columns() . '" scope="col">' . get_string('risks','role') . '</th>';
|
||||
}
|
||||
|
||||
protected function num_extra_columns() {
|
||||
return count($this->allrisks);
|
||||
}
|
||||
|
||||
protected function get_row_classes($capability) {
|
||||
$rowclasses = array();
|
||||
foreach ($this->allrisks as $riskname => $risk) {
|
||||
if ($risk & (int)$capability->riskbitmask) {
|
||||
$rowclasses[] = $riskname;
|
||||
}
|
||||
}
|
||||
return $rowclasses;
|
||||
}
|
||||
|
||||
protected function add_row_cells($capability) {
|
||||
/// One cell for each possible risk.
|
||||
foreach ($this->allrisks as $riskname => $risk) {
|
||||
echo '<td class="risk ' . str_replace('risk', '', $riskname) . '">';
|
||||
if ($risk & (int)$capability->riskbitmask) {
|
||||
echo $this->get_risk_icon($riskname);
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a risk icon, as a link to the Risks page on Moodle Docs.
|
||||
*
|
||||
* @param string $type the type of risk, will be one of the keys from the
|
||||
* get_all_risks array. Must start with 'risk'.
|
||||
*/
|
||||
function get_risk_icon($type) {
|
||||
global $CFG;
|
||||
if (!isset($this->riskicons[$type])) {
|
||||
$iconurl = $CFG->pixpath . '/i/' . str_replace('risk', 'risk_', $type) . '.gif';
|
||||
$this->riskicons[$type] = link_to_popup_window($this->risksurl, 'docspopup',
|
||||
'<img src="' . $iconurl . '" alt="' . get_string($type . 'short', 'admin') . '" />',
|
||||
0, 0, get_string($type, 'admin'), null, true);
|
||||
}
|
||||
return $this->riskicons[$type];
|
||||
}
|
||||
}
|
||||
|
||||
class override_permissions_capability_table extends capability_table_with_risks {
|
||||
protected $roleid;
|
||||
protected $inheritedcapabilities;
|
||||
protected $localoverrides;
|
||||
protected $changed = array(); // $localoverrides that were changed by the submitted data, and so need to be saved.
|
||||
protected $haslockedcapabiltites = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* This method loads loads all the information about the current state of
|
||||
* the overrides, then updates that based on any submitted data. It also
|
||||
* works out which capabilities should be locked for this user.
|
||||
*
|
||||
* @param object $context the context this table relates to.
|
||||
* @param integer $roleid the role being overridden.
|
||||
* @param boolean $safeoverridesonly If true, the user is only allowed to override
|
||||
* capabilities with no risks.
|
||||
*/
|
||||
public function __construct($context, $roleid, $safeoverridesonly) {
|
||||
global $DB;
|
||||
parent::__construct($context, 'overriderolestable');
|
||||
$this->roleid = $roleid;
|
||||
|
||||
/// Get the capabiltites from the parent context, so that can be shown in the interface.
|
||||
$parentcontext = get_context_instance_by_id(get_parent_contextid($context));
|
||||
$this->inheritedcapabilities = role_context_capabilities($this->roleid, $parentcontext);
|
||||
|
||||
/// And get the current overrides in this context.
|
||||
$this->localoverrides = $DB->get_records_menu('role_capabilities', array('roleid' => $this->roleid,
|
||||
'contextid' => $context->id), '', 'capability,permission');
|
||||
|
||||
/// Determine which capabilities should be locked, also fill in any blank localoverrides
|
||||
/// with an explicit CAP_INHERIT.
|
||||
foreach ($this->capabilities as $capid => $cap) {
|
||||
if (!isset($this->localoverrides[$cap->name])) {
|
||||
$this->localoverrides[$cap->name] = CAP_INHERIT;
|
||||
}
|
||||
if (!isset($this->inheritedcapabilities[$cap->name])) {
|
||||
$this->inheritedcapabilities[$cap->name] = CAP_INHERIT;
|
||||
}
|
||||
$this->capabilities[$capid]->locked = false;
|
||||
if ($safeoverridesonly && !is_safe_capability($capability)) {
|
||||
$this->capabilities[$capid]->locked = true;
|
||||
$this->haslockedcapabiltites = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Update $this->localoverrides based on submitted data.
|
||||
foreach ($this->capabilities as $cap) {
|
||||
if ($cap->locked || $this->skip_row($cap)) {
|
||||
/// The user is not allowed to change the permission for this capapability
|
||||
continue;
|
||||
}
|
||||
|
||||
$permission = optional_param($cap->name, null, PARAM_PERMISSION);
|
||||
if (is_null($permission)) {
|
||||
/// A permission was not specified in submitted data.
|
||||
continue;
|
||||
}
|
||||
|
||||
/// If the permission has changed, update $this->localoverrides and
|
||||
/// Record the fact there is data to save.
|
||||
if ($this->localoverrides[$cap->name] != $permission) {
|
||||
$this->localoverrides[$cap->name] = $permission;
|
||||
$this->changed[] = $cap->name;
|
||||
}
|
||||
}
|
||||
|
||||
// force accessinfo refresh for users visiting this context...
|
||||
mark_context_dirty($this->context->path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save any overrides that have been changed.
|
||||
*/
|
||||
public function save_changes() {
|
||||
foreach ($this->changed as $changedcap) {
|
||||
assign_capability($changedcap, $this->localoverrides[$changedcap],
|
||||
$this->roleid, $this->context->id, true);
|
||||
}
|
||||
}
|
||||
|
||||
public function has_locked_capabiltites() {
|
||||
return $this->haslockedcapabiltites;
|
||||
}
|
||||
|
||||
protected function add_header_cells() {
|
||||
foreach ($this->strperms as $permname => $strpermname) {
|
||||
echo '<th class="' . $permname . '" scope="col">' . $strpermname . '</th>';
|
||||
}
|
||||
parent::add_header_cells();
|
||||
}
|
||||
|
||||
protected function num_extra_columns() {
|
||||
return count($this->strperms) + parent::num_extra_columns();
|
||||
}
|
||||
|
||||
protected function skip_row($capability) {
|
||||
return is_legacy($capability->name);
|
||||
}
|
||||
|
||||
protected function add_row_cells($capability) {
|
||||
$disabled = '';
|
||||
if ($capability->locked || $this->inheritedcapabilities[$capability->name] == CAP_PROHIBIT) {
|
||||
$disabled = ' disabled="disabled"';
|
||||
}
|
||||
|
||||
/// One cell for each possible permission.
|
||||
foreach ($this->allpermissions as $perm => $permname) {
|
||||
$extraclass = '';
|
||||
if ($perm != CAP_INHERIT && $perm == $this->inheritedcapabilities[$capability->name]) {
|
||||
$extraclass = ' capcurrent';
|
||||
}
|
||||
$checked = '';
|
||||
if ($this->localoverrides[$capability->name] == $perm) {
|
||||
$checked = ' checked="checked"';
|
||||
}
|
||||
echo '<td class="' . $permname . $extraclass . '">';
|
||||
echo '<input type="radio" title="' . $this->strperms[$permname] . '" name="' . $capability->name .
|
||||
'" value="' . $perm . '"' . $checked . $disabled . ' />';
|
||||
echo '</td>';
|
||||
}
|
||||
parent::add_row_cells($capability);
|
||||
}
|
||||
}
|
||||
|
||||
// User selectors for managing role assignments ================================
|
||||
|
||||
/**
|
||||
|
||||
+39
-168
@@ -34,9 +34,9 @@
|
||||
require_once($CFG->dirroot . '/' . $CFG->admin . '/roles/lib.php');
|
||||
|
||||
$contextid = required_param('contextid', PARAM_INT); // context id
|
||||
$roleid = optional_param('roleid', 0, PARAM_INT); // requested role id
|
||||
$userid = optional_param('userid', 0, PARAM_INT); // needed for user tabs
|
||||
$courseid = optional_param('courseid', 0, PARAM_INT); // needed for user tabs
|
||||
$roleid = optional_param('roleid', 0, PARAM_INT); // requested role id
|
||||
$userid = optional_param('userid', 0, PARAM_INT); // needed for user tabs
|
||||
$courseid = optional_param('courseid', 0, PARAM_INT); // needed for user tabs
|
||||
|
||||
$baseurl = $CFG->wwwroot . '/' . $CFG->admin . '/roles/override.php?contextid=' . $contextid;
|
||||
if (!empty($userid)) {
|
||||
@@ -81,6 +81,13 @@
|
||||
redirect($baseurl);
|
||||
}
|
||||
|
||||
// Deal with changes to the show advanced state.
|
||||
$showadvanced = get_user_preferences('overridepermissions_showadvanced', false);
|
||||
if (optional_param('toggleadvanced', false, PARAM_BOOL)) {
|
||||
$showadvanced = !$showadvanced;
|
||||
set_user_preference('overridepermissions_showadvanced', $showadvanced);
|
||||
}
|
||||
|
||||
/// These are needed early because of tabs.php
|
||||
$assignableroles = get_assignable_roles($context, ROLENAME_BOTH);
|
||||
list($overridableroles, $overridecounts, $nameswithcounts) = get_overridable_roles($context, ROLENAME_BOTH, true);
|
||||
@@ -111,60 +118,18 @@
|
||||
}
|
||||
|
||||
/// get all cababilities
|
||||
$safeoverridenotice = false;
|
||||
if ($roleid) {
|
||||
$capabilities = fetch_context_capabilities($context);
|
||||
if (!$capabilities) {
|
||||
$capabilities = array();
|
||||
$overridestable = new override_permissions_capability_table($context, $roleid, $safeoverridesonly);
|
||||
|
||||
if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) {
|
||||
$overridestable->save_changes();
|
||||
$rolename = $overridableroles[$roleid];
|
||||
add_to_log($course->id, 'role', 'override', 'admin/roles/override.php?contextid='.$context->id.'&roleid='.$roleid, $rolename, '', $USER->id);
|
||||
redirect($baseurl);
|
||||
}
|
||||
// Determine which capabilities should be locked.
|
||||
foreach ($capabilities as $capname=>$capability) {
|
||||
$capabilities[$capname]->locked = false;
|
||||
if ($safeoverridesonly && !is_safe_capability($capability)) {
|
||||
$capabilities[$capname]->locked = true;
|
||||
$safeoverridenotice = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($roleid && optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) {
|
||||
/// Process incoming role override
|
||||
$localoverrides = $DB->get_records('role_capabilities', array('roleid' => $roleid,
|
||||
'contextid' => $context->id), '', 'capability,permission,id');
|
||||
|
||||
foreach ($capabilities as $cap) {
|
||||
if ($cap->locked || is_legacy($cap->name)) {
|
||||
//user not allowed to change this cap
|
||||
continue;
|
||||
}
|
||||
|
||||
$capname = $cap->name;
|
||||
$value = optional_param($capname, null, PARAM_PERMISSION);
|
||||
if (is_null($value)) {
|
||||
//cap not specified in form
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($localoverrides[$capname])) {
|
||||
// Something exists, so update it
|
||||
assign_capability($capname, $value, $roleid, $context->id, true);
|
||||
} else { // insert a record
|
||||
if ($value != CAP_INHERIT) { // Ignore inherits
|
||||
assign_capability($capname, $value, $roleid, $context->id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// force accessinfo refresh for users visiting this context...
|
||||
mark_context_dirty($context->path);
|
||||
$rolename = $overridableroles[$roleid];
|
||||
add_to_log($course->id, 'role', 'override', 'admin/roles/override.php?contextid='.$context->id.'&roleid='.$roleid, $rolename, '', $USER->id);
|
||||
redirect($baseurl);
|
||||
}
|
||||
|
||||
/// Print the header and tabs
|
||||
require_js(array('yui_yahoo', 'yui_dom', 'yui_event'));
|
||||
require_js($CFG->admin . '/roles/roles.js');
|
||||
if ($context->contextlevel == CONTEXT_USER) {
|
||||
$user = $DB->get_record('user', array('id'=>$userid));
|
||||
$fullname = fullname($user, has_capability('moodle/site:viewfullnames', $context));
|
||||
@@ -206,142 +171,48 @@
|
||||
if ($roleid) {
|
||||
/// Show UI for overriding roles.
|
||||
|
||||
/// Get the capabiltites from the parent context, so that can be shown in the interface.
|
||||
$parentcontext = get_context_instance_by_id(get_parent_contextid($context));
|
||||
$r_caps = role_context_capabilities($roleid, $parentcontext);
|
||||
|
||||
/// And get the current overrides in this context.
|
||||
$localoverrides = $DB->get_records('role_capabilities', array('roleid' => $roleid,
|
||||
'contextid' => $context->id), '', 'capability,permission,id');
|
||||
|
||||
if (!empty($capabilities)) {
|
||||
print_box(get_string('nocapabilitiesincontext', 'role'), 'generalbox boxaligncenter');
|
||||
|
||||
} else {
|
||||
// Print the capabilities overrideable in this context
|
||||
print_box_start('generalbox boxwidthwide boxaligncenter');
|
||||
|
||||
$allrisks = get_all_risks();
|
||||
$allpermissions = array(
|
||||
CAP_INHERIT => 'inherit',
|
||||
CAP_ALLOW => 'allow',
|
||||
CAP_PREVENT => 'prevent' ,
|
||||
CAP_PROHIBIT => 'prohibit',
|
||||
);
|
||||
$strperms = array();
|
||||
foreach ($allpermissions as $permname) {
|
||||
$strperms[$permname] = get_string($permname, 'role');
|
||||
if ($showadvanced) {
|
||||
$showadvancedlabel = get_string('hideadvanced', 'form');
|
||||
} else {
|
||||
$showadvancedlabel = get_string('showadvanced', 'form');
|
||||
}
|
||||
?>
|
||||
?>
|
||||
<form id="overrideform" action="<?php echo $baseurl; ?>" method="post"><div>
|
||||
<input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
|
||||
<input type="hidden" name="roleid" value="<?php p($roleid); ?>" />
|
||||
|
||||
<table class="rolecap" id="overriderolestable">
|
||||
<tr>
|
||||
<th class="name" align="left" scope="col"><?php print_string('capability','role') ?></th>
|
||||
<?php
|
||||
foreach ($strperms as $permname => $strpermname) {
|
||||
echo '<th class="' . $permname . '" scope="col">' . $strpermname . '</th>';
|
||||
}
|
||||
echo '<th class="risk" colspan="' . count($allrisks) . '" scope="col">' . get_string('risks','role') . '</th>';
|
||||
echo "</tr>\n";
|
||||
|
||||
/// Loop over capabilities.
|
||||
$contextlevel = 0;
|
||||
$component = '';
|
||||
foreach ($capabilities as $capability) {
|
||||
|
||||
/// Legacy caps and doanything should not be overriden - we must use proper capabilities if needed
|
||||
if (is_legacy($capability->name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/// Prints a breaker if component or name or context level has changed
|
||||
if (component_level_changed($capability, $component, $contextlevel)) {
|
||||
echo '<tr class="rolecapheading header"><td colspan="' . (2 + count($allpermissions) + count($allrisks)) . '" class="header"><strong>' .
|
||||
get_component_string($capability->component, $capability->contextlevel) .
|
||||
'</strong></td></tr>';
|
||||
}
|
||||
$contextlevel = $capability->contextlevel;
|
||||
$component = $capability->component;
|
||||
|
||||
/// Check the capability override for this cap, this role in this context
|
||||
if (isset($localoverrides[$capability->name])) {
|
||||
$localpermission = $localoverrides[$capability->name]->permission;
|
||||
} else {
|
||||
$localpermission = 0; // Just inherit
|
||||
}
|
||||
|
||||
if (!isset($r_caps[$capability->name])) {
|
||||
$r_caps[$capability->name] = CAP_INHERIT;
|
||||
}
|
||||
|
||||
$disabled = '';
|
||||
if ($capability->locked || $r_caps[$capability->name] == CAP_PROHIBIT) {
|
||||
$disabled = ' disabled="disabled"';
|
||||
}
|
||||
|
||||
/// Start the table row.
|
||||
$rowclasses = array('rolecap');
|
||||
foreach ($allrisks as $riskname => $risk) {
|
||||
if ($risk & (int)$capability->riskbitmask) {
|
||||
$rowclasses[] = $riskname;
|
||||
}
|
||||
}
|
||||
echo '<tr class="' . implode(' ', $rowclasses) . '">';
|
||||
|
||||
/// Table cell for the capability name.
|
||||
echo '<td class="name"><span class="cap-desc">' . get_capability_docs_link($capability) .
|
||||
'<span class="cap-name">' . $capability->name . '</span></span></td>';
|
||||
|
||||
/// One cell for each possible permission.
|
||||
foreach ($allpermissions as $perm => $permname) {
|
||||
$extraclass = '';
|
||||
if ($perm != CAP_INHERIT && $perm == $r_caps[$capability->name]) {
|
||||
$extraclass = ' capcurrent';
|
||||
}
|
||||
$checked = '';
|
||||
if ($localpermission == $perm) {
|
||||
$checked = ' checked="checked"';
|
||||
}
|
||||
echo '<td class="' . $permname . $extraclass . '">';
|
||||
echo '<input type="radio" title="' . $strperms[$permname] . '" name="' . $capability->name .
|
||||
'" value="' . $perm . '"' . $checked . $disabled . ' />';
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
/// One cell for each possible risk.
|
||||
foreach ($allrisks as $riskname => $risk) {
|
||||
echo '<td class="risk ' . str_replace('risk', '', $riskname) . '">';
|
||||
if ($risk & (int)$capability->riskbitmask) {
|
||||
print_risk_icon($riskname);
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
/// End of the row.
|
||||
echo "</tr>\n";
|
||||
}
|
||||
?>
|
||||
</table>
|
||||
<div class="advancedbutton">
|
||||
<input type="submit" name="toggleadvanced" value="<?php echo $showadvancedlabel ?>" />
|
||||
</div>
|
||||
<div class="submit buttons">
|
||||
<input type="submit" name="savechanges" value="<?php print_string('savechanges') ?>" />
|
||||
<input type="submit" name="cancel" value="<?php print_string('cancel') ?>" />
|
||||
</div>
|
||||
<?php
|
||||
|
||||
<?php
|
||||
if ($safeoverridenotice) {
|
||||
$overridestable->display();
|
||||
|
||||
if ($overridestable->has_locked_capabiltites()) {
|
||||
echo '<div class="sefeoverridenotice">' . get_string('safeoverridenotice', 'role') . "</div>\n";
|
||||
}
|
||||
|
||||
if (count($capabilities) > 12) {
|
||||
print_js_call('cap_table_filter.init',
|
||||
array('overriderolestable', get_string('search'), get_string('clear')));
|
||||
}
|
||||
?>
|
||||
<div class="submit buttons">
|
||||
<input type="submit" name="savechanges" value="<?php print_string('savechanges') ?>" />
|
||||
<input type="submit" name="cancel" value="<?php print_string('cancel') ?>" />
|
||||
</div>
|
||||
</div></form>
|
||||
|
||||
echo "</div></form>\n";
|
||||
<?php
|
||||
print_box_end();
|
||||
|
||||
} else {
|
||||
print_box(get_string('nocapabilitiesincontext', 'role'), 'generalbox boxaligncenter');
|
||||
}
|
||||
|
||||
/// Print a form to swap roles, and a link back to the all roles list.
|
||||
|
||||
Reference in New Issue
Block a user