From c6505f1eaa181fb6f4418807a88672c20c92016c Mon Sep 17 00:00:00 2001 From: tjhunt Date: Fri, 14 Nov 2008 03:28:15 +0000 Subject: [PATCH] role override ui: MDL-8313 refactor the page in preparation for making an non-advanced mode. --- admin/roles/lib.php | 218 +++++++++++++++++++++++++++++++++++---- admin/roles/override.php | 205 +++++++----------------------------- 2 files changed, 238 insertions(+), 185 deletions(-) diff --git a/admin/roles/lib.php b/admin/roles/lib.php index 9a40a36892..33a641a294 100644 --- a/admin/roles/lib.php +++ b/admin/roles/lib.php @@ -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 ' ' .
-            get_string($type . 'short', 'admin') . ''; -} - // 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 '' . get_string('risks','role') . ''; + } + + 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 ''; + if ($risk & (int)$capability->riskbitmask) { + echo $this->get_risk_icon($riskname); + } + echo ''; + } + } + + /** + * 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', + '' . 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 '' . $strpermname . ''; + } + 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 ''; + echo ''; + echo ''; + } + parent::add_row_cells($capability); + } +} + // User selectors for managing role assignments ================================ /** diff --git a/admin/roles/override.php b/admin/roles/override.php index 8ee6ee0cb7..d2ced57a6e 100755 --- a/admin/roles/override.php +++ b/admin/roles/override.php @@ -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(); - } - // 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'); + $overridestable = new override_permissions_capability_table($context, $roleid, $safeoverridesonly); - 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); - } - } + 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); } - - // 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'); } -?> + ?>
- - - - $strpermname) { - echo ''; - } - echo ''; - echo "\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 ''; - } - $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 ''; - - /// Table cell for the capability name. - echo ''; - - /// 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 ''; - } - - /// One cell for each possible risk. - foreach ($allrisks as $riskname => $risk) { - echo ''; - } - - /// End of the row. - echo "\n"; - } -?> -
' . $strpermname . '' . get_string('risks','role') . '
' . - get_component_string($capability->component, $capability->contextlevel) . - '
' . get_capability_docs_link($capability) . - '' . $capability->name . ''; - echo ''; - echo ''; - if ($risk & (int)$capability->riskbitmask) { - print_risk_icon($riskname); - } - echo '
+
+ +
+ display(); - has_locked_capabiltites()) { echo '
' . get_string('safeoverridenotice', 'role') . "
\n"; } - if (count($capabilities) > 12) { - print_js_call('cap_table_filter.init', - array('overriderolestable', get_string('search'), get_string('clear'))); - } + ?> +
+ + +
+
- echo "\n"; +