]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-16343 Report showing, for a given capability, how it is set in the definition...
authortjhunt <tjhunt>
Mon, 8 Sep 2008 07:01:41 +0000 (07:01 +0000)
committertjhunt <tjhunt>
Mon, 8 Sep 2008 07:01:41 +0000 (07:01 +0000)
admin/report/capability/index.php [new file with mode: 0644]
admin/report/capability/script.js [new file with mode: 0644]
lang/en_utf8/report_capability.php [new file with mode: 0644]
lib/weblib.php
theme/standard/styles_layout.css

diff --git a/admin/report/capability/index.php b/admin/report/capability/index.php
new file mode 100644 (file)
index 0000000..7877c5b
--- /dev/null
@@ -0,0 +1,221 @@
+<?php  // $Id$
+/**
+ * For a given capability, show what permission it has for every role, and
+ * everywhere that it is overridden.
+ *
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package roles
+ */
+
+/** */
+require_once(dirname(__FILE__).'/../../../config.php');
+require_once($CFG->libdir.'/adminlib.php');
+
+// Check permissions.
+require_login();
+$systemcontext = get_context_instance(CONTEXT_SYSTEM);
+require_capability('moodle/role:manage', $systemcontext);
+
+// Get URL parameters.
+$capability = optional_param('capability', '', PARAM_CAPABILITY);
+$roleids = optional_param('roles', array('0'), PARAM_INTEGER);
+
+// Clean the passed in list of role ids. If 'All' selected as an option, or
+// if none were selected, do all roles.
+$allroles = get_all_roles();
+$cleanedroleids = array();
+foreach ($roleids as $roleid) {
+    if ($roleid == 0) {
+        $cleanedroleids = array_keys($allroles);
+        break;
+    }
+    if (array_key_exists($roleid, $allroles)) {
+        $cleanedroleids[] = $roleid;
+    }
+}
+if (empty($cleanedroleids)) {
+    $cleanedroleids = array_keys($allroles);
+}
+
+// Include the required JavaScript.
+require_js(array('yui_yahoo','yui_event'));
+require_js($CFG->wwwroot . '/admin/report/capability/script.js');
+
+// Log.
+add_to_log(SITEID, "admin", "report capability", "report/capability/index.php?capability=$capability", $capability);
+
+// Print the header.
+admin_externalpage_setup('reportcapability');
+$strtitle = get_string('capabilityreport', 'report_capability');
+admin_externalpage_print_header();
+
+// Prepare the list of capabilites to choose from
+$allcapabilities = fetch_context_capabilities($systemcontext);
+$capabilitychoices = array();
+foreach ($allcapabilities as $cap) {
+    $capabilitychoices[$cap->name] = $cap->name . ': ' . get_capability_string($cap->name);
+}
+
+// Prepare the list of roles to choose from
+$rolechoices = array('0' => get_string('all'));
+foreach ($allroles as $role) {
+    $rolechoices[$role->id] = $role->name;
+}
+if (count($cleanedroleids) == count($allroles)) {
+    // Select 'All', rather than each role individually.
+    $selectedroleids = array('0');
+} else {
+    $selectedroleids = $cleanedroleids;
+}
+
+// Print the settings form.
+print_box_start('generalbox boxwidthwide boxaligncenter centerpara');
+echo '<form method="get" action="." id="settingsform">';
+print_heading(get_string('reportsettings', 'report_capability'));
+echo '<p id="intro">', get_string('intro', 'report_capability') , '</p>';
+echo '<p><label for="menucapability"> ' . get_string('capabilitylabel', 'report_capability') . '</label></p>';
+choose_from_menu($capabilitychoices, 'capability', $capability, 'choose', '', '', false, false, 0, '', true);
+echo '<p><label for="menuroles"> ' . get_string('roleslabel', 'report_capability') . '</label></p>';
+choose_from_menu($rolechoices, 'roles[]', $selectedroleids, '', '', '', false, false, 0, '', true, true);
+echo '<p><input type="submit" id="settingssubmit" value="' . get_string('getreport', 'report_capability') . '" /></p>';
+echo '<script type="text/javascript">capability_report.cap_filter_init("' . get_string('search') . '");</script>';
+echo '</div>';
+echo '</form>';
+print_box_end();
+
+// If we have a capability, generate the report.
+if ($capability) {
+
+    // Work out the bits needed for the SQL WHERE clauses.
+    $params = array($capability);
+    $sqlroletest = '';
+    if (count($cleanedroleids) != count($allroles)) {
+        list($sqlroletest, $roleparams) = $DB->get_in_or_equal($cleanedroleids);
+        $params = array_merge($params, $roleparams);
+        $sqlroletest = 'AND roleid ' . $sqlroletest;
+    }
+
+    // Get all the role_capabilities rows for this capability - that is, all
+    // role definitions, and all role overrides.
+    $rolecaps = $DB->get_records_sql("
+            SELECT id, roleid, contextid, permission
+            FROM {role_capabilities}
+            WHERE capability = ? $sqlroletest", $params);
+
+    // In order to display a nice tree of contexts, we need to get all the
+    // ancestors of all the contexts in the query we just did.
+    $relevantpaths = $DB->get_records_sql_menu("
+            SELECT DISTINCT con.path, 1
+            FROM {context} con JOIN {role_capabilities} rc ON rc.contextid = con.id
+            WHERE capability = ? $sqlroletest", $params);
+    $requiredcontexts = array();
+    foreach ($relevantpaths as $path => $notused) {
+        $requiredcontexts = array_merge($requiredcontexts, explode('/', trim($path, '/')));
+    }
+    $requiredcontexts = array_unique($requiredcontexts);
+
+    // Now load those contexts.
+    list($sqlcontexttest, $contextparams) = $DB->get_in_or_equal($requiredcontexts);
+    $contexts = $DB->get_records_select('context', 'id ' . $sqlcontexttest, $contextparams);
+
+    // Prepare some empty arrays to hold the data we are about to compute.
+    foreach ($contexts as $conid => $con) {
+        $contexts[$conid]->children = array();
+        $contexts[$conid]->rolecapabilites = array();
+    }
+
+    // Put the contexts into a tree structure.
+    foreach ($contexts as $conid => $con) {
+        $contexts[$conid]->children = array();
+        $parentcontextid = get_parent_contextid($con);
+        if ($parentcontextid) {
+            $contexts[$parentcontextid]->children[] = $conid;
+        }
+    }
+
+    // Put the role capabilites into the context tree.
+    foreach ($rolecaps as $rolecap) {
+        $contexts[$rolecap->contextid]->rolecapabilites[$rolecap->roleid] = $rolecap->permission;
+    }
+
+    // Fill in any missing rolecaps for the system context.
+    foreach ($cleanedroleids as $roleid) {
+        if (!isset($contexts[$systemcontext->id]->rolecapabilites[$roleid])) {
+            $contexts[$systemcontext->id]->rolecapabilites[$roleid] = CAP_INHERIT;
+        }
+    }
+
+    // Print the report heading.
+    print_heading(get_string('reportforcapability', 'report_capability', get_capability_string($capability)));
+    if (count($cleanedroleids) != count($allroles)) {
+        $rolenames = array();
+        foreach ($cleanedroleids as $roleid) {
+            $rolenames[] = $allroles[$roleid]->name;
+        }
+        echo '<p>', get_string('forroles', 'report_capability', implode(', ', $rolenames)), '</p>';
+    }
+
+    // Now, recursively print the contexts, and the role information.
+    print_report_tree($systemcontext->id, $contexts, $allroles);
+}
+
+// Footer.
+admin_externalpage_print_footer();
+
+function print_report_tree($contextid, $contexts, $allroles) {
+    global $CFG;
+
+    // Array for holding lang strings.
+    static $strpermissions = null;
+    if (is_null($strpermissions)) {
+        $strpermissions = array(
+            CAP_INHERIT => get_string('notset','role'),
+            CAP_ALLOW => get_string('allow','role'),
+            CAP_PREVENT => get_string('prevent','role'),
+            CAP_PROHIBIT => get_string('prohibit','role')
+        );
+    }
+
+    // Start the list item, and print the context name as a link to the place to
+    // make changes.
+    if ($contextid == get_system_context()->id) {
+        $url = $CFG->wwwroot . '/admin/roles/manage.php';
+        $title = get_string('changeroles', 'report_capability');
+    } else {
+        $url = $CFG->wwwroot . '/admin/roles/override.php?contextid=' . $contextid;
+        $title = get_string('changeoverrides', 'report_capability');
+    }
+    echo '<h3><a href="' . $url . '" title="' . $title . '">', print_context_name($contexts[$contextid]), '</a></h3>';
+
+    // If there are any role overrides here, print them.
+    if (!empty($contexts[$contextid]->rolecapabilites)) {
+        $rowcounter = 0;
+        echo '<table class="generaltable rolecaps"><tbody>';
+        foreach ($allroles as $role) {
+            if (isset($contexts[$contextid]->rolecapabilites[$role->id])) {
+                $permission = $contexts[$contextid]->rolecapabilites[$role->id];
+                echo '<tr class="r' . ($rowcounter % 2) . '"><th class="cell">', $role->name, 
+                        '</th><td class="cell">' . $strpermissions[$permission] . '</td></tr>';
+                $rowcounter++;
+            }
+        }
+        echo '</tbody></table>';
+    }
+
+    // After we have done the site context, change the string for CAP_INHERIT
+    // from 'notset' to 'inherit'.
+    $strpermissions[CAP_INHERIT] = get_string('inherit','role');
+
+    // If there are any child contexts, print them recursively.
+    if (!empty($contexts[$contextid]->children)) {
+        echo '<ul>';
+        foreach ($contexts[$contextid]->children as $childcontextid) {
+            echo '<li>';
+            print_report_tree($childcontextid, $contexts, $allroles);
+            echo '</li>';
+        }
+        echo '</ul>';
+    }
+}
+
+?>
diff --git a/admin/report/capability/script.js b/admin/report/capability/script.js
new file mode 100644 (file)
index 0000000..429bc92
--- /dev/null
@@ -0,0 +1,69 @@
+capability_report = {
+    select: null,
+    input: null,
+    button: null,
+
+    cap_filter_init: function(strsearch) {
+        // Find the form controls.
+        capability_report.select = document.getElementById('menucapability');
+        capability_report.button = document.getElementById('settingssubmit');
+
+        // Create a div to hold the search UI.
+        var div = document.createElement('div');
+        div.id = 'capabilitysearchui';
+
+        // Find the capability search input.
+        var input = document.createElement('input');
+        input.type = 'text';
+        input.id = 'capabilitysearch';
+        capability_report.input = input;
+
+        // Create a label for the search input.
+        var label = document.createElement('label');
+        label.htmlFor = input.id;
+        label.appendChild(document.createTextNode(strsearch + ' '));
+
+        // Tie it all together
+        div.appendChild(label);
+        div.appendChild(input);
+        capability_report.select.parentNode.insertBefore(div, capability_report.select);
+        YAHOO.util.Event.addListener(input, 'keyup', capability_report.cap_filter_change);
+        YAHOO.util.Event.addListener(capability_report.select, 'change', capability_report.validate);
+        capability_report.select.options[0].style.display = 'none';
+        capability_report.validate();
+    },
+
+    cap_filter_change: function() {
+        var filtertext = capability_report.input.value;
+        var options = capability_report.select.options;
+        var onlycapability = -1;
+        for (var i = 1; i < options.length; i++) {
+            if (options[i].text.indexOf(filtertext) >= 0) {
+                options[i].disabled = false;
+                options[i].style.display = 'block';
+                if (onlycapability == -1) {
+                    onlycapability = i;
+                } else {
+                    onlycapability = -2;
+                }
+            } else {
+                options[i].disabled = true;
+                options[i].selected = false;
+                options[i].style.display = 'none';
+            }
+        }
+        if (onlycapability >= 0) {
+            options[onlycapability].selected = true;
+        }
+        if (onlycapability == -1) {
+            capability_report.input.className = "error";
+        } else {
+            capability_report.input.className = "";
+        }
+        capability_report.validate();
+    },
+
+    validate: function() {
+        capability_report.button.disabled = (capability_report.select.value == '');
+    }
+}
\ No newline at end of file
diff --git a/lang/en_utf8/report_capability.php b/lang/en_utf8/report_capability.php
new file mode 100644 (file)
index 0000000..25b3fb2
--- /dev/null
@@ -0,0 +1,14 @@
+<?PHP  // $Id$
+
+$string['capability'] = 'Capability report';
+$string['capabilitylabel'] = 'Capability:';
+$string['capabilityreport'] = 'Capability report';
+$string['changeoverrides'] = 'Change overrides in this context';
+$string['changeroles'] = 'Change role definitions';
+$string['forroles'] = 'For roles $a';
+$string['getreport'] = 'Get the report';
+$string['intro'] = 'This report shows, for a particular capability, what permission that capability has in the definition of every role (or a selection of roles), and everywhere in the site where that capability is overridden.';
+$string['reportforcapability'] = 'Report for capability \'$a\'';
+$string['reportsettings'] = 'Report settings';
+$string['roleslabel'] = 'Roles:';
+?>
index 0f6ca41bdd0200044b56ee573545d8c6db9748ec..c95d71a2735b24e7998dc8aacfd13a0e1274f5a0 100644 (file)
@@ -780,9 +780,14 @@ function close_window($delay=0) {
  * @param int $tabindex if give, sets the tabindex attribute on the &lt;select> element. Default none.
  * @param string $id value to use for the id attribute of the &lt;select> element. If none is given,
  *      then a suitable one is constructed.
+ * @param mixed $listbox if false, display as a dropdown menu. If true, display as a list box.
+ *      By default, the list box will have a number of rows equal to min(10, count($options)), but if
+ *      $listbox is an integer, that number is used for size instead.
+ * @param 
  */
 function choose_from_menu ($options, $name, $selected='', $nothing='choose', $script='',
-                           $nothingvalue='0', $return=false, $disabled=false, $tabindex=0, $id='') {
+                           $nothingvalue='0', $return=false, $disabled=false, $tabindex=0,
+                           $id='', $listbox=false, $multiple=false) {
 
     if ($nothing == 'choose') {
         $nothing = get_string('choose') .'...';
@@ -804,6 +809,22 @@ function choose_from_menu ($options, $name, $selected='', $nothing='choose', $sc
         $id = str_replace(']', '', $id);
     }
 
+    if ($listbox) {
+        if (is_integer($listbox)) {
+            $size = $listbox;
+        } else {
+            $numchoices = count($options);
+            if ($nothing) {
+                $numchoices += 1;
+            }
+            $size = min(10, $numchoices);
+        }
+        $attributes .= ' size="' . $size . '"';
+        if ($multiple) {
+            $attributes .= ' multiple="multiple"';
+        }
+    }
+
     $output = '<select id="'.$id.'" name="'. $name .'" '. $attributes .'>' . "\n";
     if ($nothing) {
         $output .= '   <option value="'. s($nothingvalue) .'"'. "\n";
@@ -812,10 +833,12 @@ function choose_from_menu ($options, $name, $selected='', $nothing='choose', $sc
         }
         $output .= '>'. $nothing .'</option>' . "\n";
     }
+
     if (!empty($options)) {
         foreach ($options as $value => $label) {
             $output .= '   <option value="'. s($value) .'"';
-            if ((string)$value == (string)$selected) {
+            if ((string)$value == (string)$selected ||
+                    (is_array($selected) && in_array($value, $selected))) {
                 $output .= ' selected="selected"';
             }
             if ($label === '') {
index a51f746ae84e36c2ec786ee8b36ed087ab367b31..87638e4c02bfea4874f3da1ec4880c92d2854e96 100644 (file)
@@ -943,6 +943,29 @@ body#admin-modules table.generaltable td.c0
   margin-top: 1em;
 }
 
+#admin-report-capability-index .rolecaps th {
+  text-align: left;
+}
+#admin-report-capability-index #settingsform {
+  text-align: left;
+}
+#admin-report-capability-index #settingsform h2 {
+    margin-top: 0;
+}
+#admin-report-capability-index #settingsform p {
+  margin-bottom: 0;
+}
+#admin-report-capability-index #settingsform #menucapability,
+#admin-report-capability-index #settingsform #capabilitysearchui {
+  width: 100%;
+}
+#admin-report-capability-index #settingsform #capabilitysearch {
+  width: 30em;
+}
+#admin-report-capability-index h3 {
+  margin-bottom: 0;
+}
+
 #admin-roles-allowassign .buttons,
 #admin-roles-allowoverride .buttons,
 #admin-roles-manage .buttons,