]> git.mjollnir.org Git - moodle.git/commitdiff
role override ui: MDL-8313 refactor the page in preparation for making an non-advance...
authortjhunt <tjhunt>
Fri, 14 Nov 2008 03:28:15 +0000 (03:28 +0000)
committertjhunt <tjhunt>
Fri, 14 Nov 2008 03:28:15 +0000 (03:28 +0000)
admin/roles/lib.php
admin/roles/override.php

index 9a40a368928c1e1910593dbc014d165c30e3f3f2..33a641a29485e700b6a0923bfa1719c1cd5f84ce 100644 (file)
 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 ================================
 
 /**
index 8ee6ee0cb72348cd8c53f020cbd40559550cce46..d2ced57a6ee08f9bfbf1282955fd20a73794ca35 100755 (executable)
@@ -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)) {
         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);
     }
 
 /// 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));
     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
+
+            $overridestable->display();
 
-    <?php
-            if ($safeoverridenotice) {
+            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.