Merge branch 'wip-MDL-40368-m26' of git://github.com/samhemelryk/moodle
authorDamyon Wiese <damyon@moodle.com>
Tue, 9 Jul 2013 02:48:47 +0000 (10:48 +0800)
committerDamyon Wiese <damyon@moodle.com>
Tue, 9 Jul 2013 02:48:47 +0000 (10:48 +0800)
Conflicts:
admin/tool/capability/index.php

15 files changed:
admin/tool/capability/classes/settings_form.php [new file with mode: 0644]
admin/tool/capability/index.php
admin/tool/capability/lang/en/tool_capability.php
admin/tool/capability/locallib.php [new file with mode: 0644]
admin/tool/capability/module.js [deleted file]
admin/tool/capability/renderer.php [new file with mode: 0644]
admin/tool/capability/settings.php
admin/tool/capability/styles.css [new file with mode: 0644]
admin/tool/capability/version.php
admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search-debug.js [new file with mode: 0644]
admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search-min.js [new file with mode: 0644]
admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search.js [new file with mode: 0644]
admin/tool/capability/yui/src/search/build.json [new file with mode: 0644]
admin/tool/capability/yui/src/search/js/search.js [new file with mode: 0644]
admin/tool/capability/yui/src/search/meta/search.json [new file with mode: 0644]

diff --git a/admin/tool/capability/classes/settings_form.php b/admin/tool/capability/classes/settings_form.php
new file mode 100644 (file)
index 0000000..cf5fa3e
--- /dev/null
@@ -0,0 +1,66 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Capability tool settings form.
+ *
+ * Do no include this file, it is automatically loaded by the class loader!
+ *
+ * @package    tool_capability
+ * @copyright  2013 Sam Hemelryk
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once($CFG->libdir.'/formslib.php');
+
+/**
+ * Class tool_capability_settings_form
+ *
+ * The settings form for the comparison of roles/capabilities.
+ *
+ * @copyright  2013 Sam Hemelryk
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class tool_capability_settings_form extends moodleform {
+
+    /**
+     * The form definition.
+     */
+    public function definition() {
+        $form = $this->_form;
+        $capabilities = $this->_customdata['capabilities'];
+        $roles = $this->_customdata['roles'];
+        // Set the form ID.
+        $form->setAttributes(array('id' => 'capability-overview-form') + $form->getAttributes());
+
+        $form->addElement('header', 'reportsettings', get_string('reportsettings', 'tool_capability'));
+        $form->addElement('html', html_writer::tag('p', get_string('intro', 'tool_capability'), array('id' => 'intro')));
+
+        $form->addElement('hidden', 'search');
+        $form->setType('search', PARAM_TEXT);
+
+        $attributes = array('multiple' => 'multiple', 'size' => 10, 'data-search' => 'capability');
+        $form->addElement('select', 'capability', get_string('capabilitylabel', 'tool_capability'), $capabilities, $attributes);
+        $form->setType('capability', PARAM_CAPABILITY);
+
+        $attributes = array('multiple' => 'multiple', 'size' => 10);
+        $form->addElement('select', 'roles', get_string('roleslabel', 'tool_capability'), $roles, $attributes);
+        $form->setType('roles', PARAM_TEXT);
+
+        $form->addElement('submit', 'submitbutton', get_string('getreport', 'tool_capability'));
+    }
+
+}
\ No newline at end of file
index e0a0e66..d1707d2 100644 (file)
 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 
 /**
- * For a given capability, show what permission it has for every role, and
- * everywhere that it is overridden.
+ * For a given capability, show what permission it has for every role, and everywhere that it is overridden.
  *
- * @package    tool
- * @subpackage capability
+ * @package    tool_capability
  * @copyright  2008 Tim Hunt
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 require_once(dirname(__FILE__) . '/../../../config.php');
+require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/capability/locallib.php');
 require_once($CFG->libdir.'/adminlib.php');
 
-// Check permissions.
-require_login();
-$systemcontext = context_system::instance();
-require_capability('moodle/role:manage', $systemcontext);
-
 // Get URL parameters.
-$capability = optional_param('capability', '', PARAM_CAPABILITY);
-$roleids = optional_param_array('roles', array('0'), PARAM_INT);
-
-// Clean the passed in list of role ids. If 'All' selected as an option, or
-// if none were selected, do all roles.
-$allroles = role_fix_names(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.
-$PAGE->requires->js_init_call('M.tool_capability.init', array(get_string('search')));
+$systemcontext = context_system::instance();
+$contextid = optional_param('context', $systemcontext->id, PARAM_INT);
 
-// Log.
-add_to_log(SITEID, "admin", "tool capability", "tool/capability/index.php?capability=$capability", $capability);
+// Check permissions.
+list($context, $course, $cm) = get_context_info_array($contextid);
+require_login($course, false, $cm);
+require_capability('moodle/role:manage', $context);
 
 // Print the header.
 admin_externalpage_setup('toolcapability');
-echo $OUTPUT->header();
 
-// Prepare the list of capabilities to choose from
-$allcapabilities = fetch_context_capabilities($systemcontext);
+// Prepare the list of capabilities to choose from.
 $capabilitychoices = array();
-foreach ($allcapabilities as $cap) {
+foreach ($context->get_capabilities() as $cap) {
     $capabilitychoices[$cap->name] = $cap->name . ': ' . get_capability_string($cap->name);
 }
 
-// Prepare the list of roles to choose from
+$allroles = role_fix_names(get_all_roles($context));
+// Prepare the list of roles to choose from.
 $rolechoices = array('0' => get_string('all'));
 foreach ($allroles as $role) {
     $rolechoices[$role->id] = $role->localname;
 }
-if (count($cleanedroleids) == count($allroles)) {
-    // Select 'All', rather than each role individually.
-    $selectedroleids = array('0');
-} else {
-    $selectedroleids = $cleanedroleids;
-}
 
-// Print the settings form.
-echo $OUTPUT->box_start('generalbox boxwidthwide boxaligncenter');
-echo '<form method="get" action="" id="settingsform"><div>';
-echo $OUTPUT->heading(get_string('reportsettings', 'tool_capability'));
-echo '<p id="intro">', get_string('intro', 'tool_capability') , '</p>';
-echo '<p><label for="menucapability"> ' . get_string('capabilitylabel', 'tool_capability') . '</label></p>';
-echo  html_writer::select($capabilitychoices, 'capability', $capability, array(''=>'choose'), array('size'=>10));
-echo '<p><label for="menuroles"> ' . get_string('roleslabel', 'tool_capability') . '</label></p>';
-echo  html_writer::select($rolechoices, 'roles[]', $selectedroleids, false, array('size'=>10, 'multiple'=>'multiple'));
-echo '<p><input type="submit" id="settingssubmit" value="' . get_string('getreport', 'tool_capability') . '" /></p>';
-echo '</div></form>';
-echo $OUTPUT->box_end();
+$form = new tool_capability_settings_form(null, array(
+    'capabilities' => $capabilitychoices,
+    'roles' => $rolechoices
+));
+$PAGE->requires->yui_module(
+    'moodle-tool_capability-search',
+    'M.tool_capability.init_capability_search',
+    array(array('strsearch' => get_string('search')))
+);
 
-// 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;
-    }
+// Log.
+$capabilities = array();
+$rolestoshow = array();
+$roleids = array('0');
+$cleanedroleids = array();
+if ($data = $form->get_data()) {
 
-    // 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($systemcontext->id);
-    foreach ($relevantpaths as $path => $notused) {
-        $requiredcontexts = array_merge($requiredcontexts, explode('/', trim($path, '/')));
+    $roleids = array();
+    if (!empty($data->roles)) {
+        $roleids = $data->roles;
     }
-    $requiredcontexts = array_unique($requiredcontexts);
-
-    // Now load those contexts.
-    list($sqlcontexttest, $contextparams) = $DB->get_in_or_equal($requiredcontexts);
-    $contexts = get_sorted_contexts('ctx.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]->rolecapabilities = array();
+    $capabilities = array();
+    if (!empty($data->capability)) {
+        $capabilities = $data->capability;
     }
 
-    // Put the contexts into a tree structure.
-    foreach ($contexts as $conid => $con) {
-        $context = context::instance_by_id($conid);
-        $parentcontextid = get_parent_contextid($context);
-        if ($parentcontextid) {
-            $contexts[$parentcontextid]->children[] = $conid;
+    if (in_array('0', $roleids)) {
+        $rolestoshow = $allroles;
+    } else {
+        $cleanedroleids = array_intersect(array_keys($allroles), $roleids);
+        if (count($cleanedroleids) === 0) {
+            $rolestoshow = $allroles;
+        } else {
+            foreach ($cleanedroleids as $id) {
+                $rolestoshow[$id] = $allroles[$id];
+            }
         }
     }
+}
 
-    // Put the role capabilities into the context tree.
-    foreach ($rolecaps as $rolecap) {
-        $contexts[$rolecap->contextid]->rolecapabilities[$rolecap->roleid] = $rolecap->permission;
-    }
+add_to_log(SITEID, "admin", "tool capability", "tool/capability/index.php", count($capabilities));
 
-    // Fill in any missing rolecaps for the system context.
-    foreach ($cleanedroleids as $roleid) {
-        if (!isset($contexts[$systemcontext->id]->rolecapabilities[$roleid])) {
-            $contexts[$systemcontext->id]->rolecapabilities[$roleid] = CAP_INHERIT;
-        }
-    }
+$renderer = $PAGE->get_renderer('tool_capability');
 
-    // Print the report heading.
-    echo $OUTPUT->heading(get_string('reportforcapability', 'tool_capability', get_capability_string($capability)), 2, 'main', 'report');
-    if (count($cleanedroleids) != count($allroles)) {
-        $rolenames = array();
-        foreach ($cleanedroleids as $roleid) {
-            $rolenames[] = $allroles[$roleid]->localname;
-        }
-        echo '<p>', get_string('forroles', 'tool_capability', implode(', ', $rolenames)), '</p>';
-    }
+echo $OUTPUT->header();
+
+$form->display();
 
-    // Now, recursively print the contexts, and the role information.
-    print_report_tree($systemcontext->id, $contexts, $allroles);
+// If we have a capability, generate the report.
+if (count($capabilities) && count($rolestoshow)) {
+    /* @var tool_capability_renderer $renderer */
+    echo $renderer->capability_comparison_table($capabilities, $context->id, $rolestoshow);
 }
 
 // Footer.
index bae923f..3862006 100644 (file)
@@ -17,8 +17,7 @@
 /**
  * Strings for component 'tool_capability', language 'en', branch 'MOODLE_22_STABLE'
  *
- * @package    tool
- * @subpackage capability
+ * @package    tool_capability
  * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
diff --git a/admin/tool/capability/locallib.php b/admin/tool/capability/locallib.php
new file mode 100644 (file)
index 0000000..aff0791
--- /dev/null
@@ -0,0 +1,96 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Functions used by the capability tool.
+ *
+ * @package    tool_capability
+ * @copyright  2013 Sam Hemelryk
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Calculates capability data organised by context for the given roles.
+ *
+ * @param string $capability The capability to get data for.
+ * @param array $roles An array of roles to get data for.
+ * @return context[] An array of contexts.
+ */
+function tool_capability_calculate_role_data($capability, array $roles) {
+    global $DB;
+
+    $systemcontext = context_system::instance();
+    $roleids = array_keys($roles);
+
+    // Work out the bits needed for the SQL WHERE clauses.
+    $params = array($capability);
+    list($sqlroletest, $roleparams) = $DB->get_in_or_equal($roleids);
+    $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.
+    $sql = 'SELECT id, roleid, contextid, permission
+              FROM {role_capabilities}
+             WHERE capability = ? '.$sqlroletest;
+    $rolecaps = $DB->get_records_sql($sql, $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.
+    $sql = 'SELECT DISTINCT con.path, 1
+              FROM {context} con
+              JOIN {role_capabilities} rc ON rc.contextid = con.id
+             WHERE capability = ? '.$sqlroletest;
+    $relevantpaths = $DB->get_records_sql_menu($sql, $params);
+    $requiredcontexts = array($systemcontext->id);
+    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 = get_sorted_contexts('ctx.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]->rolecapabilities = array();
+    }
+
+    // Put the contexts into a tree structure.
+    foreach ($contexts as $conid => $con) {
+        $context = context::instance_by_id($conid);
+        $parentcontextid = get_parent_contextid($context);
+        if ($parentcontextid) {
+            $contexts[$parentcontextid]->children[] = $conid;
+        }
+    }
+
+    // Put the role capabilities into the context tree.
+    foreach ($rolecaps as $rolecap) {
+        $contexts[$rolecap->contextid]->rolecapabilities[$rolecap->roleid] = $rolecap->permission;
+    }
+
+    // Fill in any missing rolecaps for the system context.
+    foreach ($roleids as $roleid) {
+        if (!isset($contexts[$systemcontext->id]->rolecapabilities[$roleid])) {
+            $contexts[$systemcontext->id]->rolecapabilities[$roleid] = CAP_INHERIT;
+        }
+    }
+
+    return $contexts;
+}
\ No newline at end of file
diff --git a/admin/tool/capability/module.js b/admin/tool/capability/module.js
deleted file mode 100644 (file)
index 254f194..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-
-M.tool_capability = {
-    select: null,
-    input: null,
-    button: null,
-
-    init: function(Y, strsearch) {
-        var context = M.tool_capability;
-
-        // Find the form controls.
-        context.select = document.getElementById('menucapability');
-        context.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';
-        context.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);
-        context.select.parentNode.insertBefore(div, context.select);
-        Y.on('keyup', context.typed, input);
-        Y.on('change', context.validate, context.select);
-        context.select.options[0].style.display = 'none';
-        context.validate();
-    },
-
-    typed: function() {
-        var context = M.tool_capability;
-
-        var filtertext = context.input.value;
-        var options = context.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) {
-            context.input.className = "error";
-        } else {
-            context.input.className = "";
-        }
-        context.validate();
-    },
-
-    validate: function() {
-        var context = M.tool_capability;
-        context.button.disabled = (context.select.value == '');
-    }
-}
\ No newline at end of file
diff --git a/admin/tool/capability/renderer.php b/admin/tool/capability/renderer.php
new file mode 100644 (file)
index 0000000..586725a
--- /dev/null
@@ -0,0 +1,136 @@
+<?php
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Capability tool renderer.
+ *
+ * @package    tool_capability
+ * @copyright  2013 Sam Hemelryk
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * The primary renderer for the capability tool.
+ *
+ * @copyright  2013 Sam Hemelryk
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class tool_capability_renderer extends plugin_renderer_base {
+
+    /**
+     * Returns an array of permission strings.
+     *
+     * @return lang_string[]
+     */
+    protected function get_permission_strings() {
+        static $strpermissions;
+        if (!$strpermissions) {
+            $strpermissions = array(
+                CAP_INHERIT => new lang_string('inherit', 'role'),
+                CAP_ALLOW => new lang_string('allow', 'role'),
+                CAP_PREVENT => new lang_string('prevent', 'role'),
+                CAP_PROHIBIT => new lang_string('prohibit', 'role')
+            );
+        }
+        return $strpermissions;
+    }
+
+    /**
+     * Returns an array of permission CSS classes.
+     *
+     * @return string[]
+     */
+    protected function get_permission_classes() {
+        static $permissionclasses;
+        if (!$permissionclasses) {
+            $permissionclasses = array(
+                CAP_INHERIT => 'inherit',
+                CAP_ALLOW => 'allow',
+                CAP_PREVENT => 'prevent',
+                CAP_PROHIBIT => 'prohibit',
+            );
+        }
+        return $permissionclasses;
+    }
+
+    /**
+     * Produces a table to visually compare roles and capabilities.
+     *
+     * @param array $capabilities An array of capabilities to show comparison for.
+     * @param int $contextid The context we are displaying for.
+     * @param array $roles An array of roles to show comparison for.
+     * @return string
+     */
+    public function capability_comparison_table(array $capabilities, $contextid, array $roles) {
+
+        $strpermissions = $this->get_permission_strings();
+        $permissionclasses = $this->get_permission_classes();
+
+        if ($contextid === context_system::instance()->id) {
+            $strpermissions[CAP_INHERIT] = new lang_string('notset', 'role');
+        }
+
+        $table = new html_table();
+        $table->attributes['class'] = 'comparisontable';
+        $table->head = array('&nbsp;');
+        foreach ($roles as $role) {
+            $url = new moodle_url('/admin/roles/override.php', array('contextid' => $contextid, 'roleid' => $role->id));
+            $table->head[] = html_writer::div(html_writer::link($url, $role->localname));
+        }
+        $table->data = array();
+
+        foreach ($capabilities as $capability) {
+            $contexts = tool_capability_calculate_role_data($capability, $roles);
+            $captitle = new html_table_cell(get_capability_string($capability) . html_writer::span($capability));
+            $captitle->header = true;
+
+            $row = new html_table_row(array($captitle));
+
+            foreach ($roles as $role) {
+                if (isset($contexts[$contextid]->rolecapabilities[$role->id])) {
+                    $permission = $contexts[$contextid]->rolecapabilities[$role->id];
+                } else {
+                    $permission = CAP_INHERIT;
+                }
+                $cell = new html_table_cell($strpermissions[$permission]);
+                $cell->attributes['class'] = $permissionclasses[$permission];
+                $row->cells[] = $cell;
+            }
+
+            $table->data[] = $row;
+        }
+
+        // Start the list item, and print the context name as a link to the place to make changes.
+        if ($contextid == context_system::instance()->id) {
+            $url = new moodle_url('/admin/roles/manage.php');
+            $title = get_string('changeroles', 'tool_capability');
+        } else {
+            $url = new moodle_url('/admin/roles/override.php', array('contextid' => $contextid));
+            $title = get_string('changeoverrides', 'tool_capability');
+        }
+        $context = context::instance_by_id($contextid);
+        $html = $this->output->heading(html_writer::link($url, $context->get_context_name(), array('title' => $title)), 3);
+        $html .= html_writer::table($table);
+        // If there are any child contexts, print them recursively.
+        if (!empty($contexts[$contextid]->children)) {
+            foreach ($contexts[$contextid]->children as $childcontextid) {
+                $html .= $this->capability_comparison_table($capabilities, $childcontextid, $roles, true);
+            }
+        }
+        return $html;
+    }
+
+}
\ No newline at end of file
index bf4d6ad..ba8d551 100644 (file)
 /**
  * Capability overview settings
  *
- * @package    tool
- * @subpackage capability
+ * @package    tool_capability
  * @copyright  2008 Tim Hunt
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die;
 
-$ADMIN->add('roles', new admin_externalpage('toolcapability', get_string('pluginname', 'tool_capability'), "$CFG->wwwroot/$CFG->admin/tool/capability/index.php",'moodle/role:manage'));
+$ADMIN->add('roles', new admin_externalpage(
+    'toolcapability',
+    get_string('pluginname', 'tool_capability'),
+    "$CFG->wwwroot/$CFG->admin/tool/capability/index.php",
+    'moodle/role:manage'
+));
diff --git a/admin/tool/capability/styles.css b/admin/tool/capability/styles.css
new file mode 100644 (file)
index 0000000..757066e
--- /dev/null
@@ -0,0 +1,32 @@
+.path-admin-tool-capability .comparisontable {margin-top:150px;}
+.path-admin-tool-capability .comparisontable th,
+.path-admin-tool-capability .comparisontable td {vertical-align:middle;padding:0.4em 0.5em 0.3em;}
+.path-admin-tool-capability .comparisontable thead th {vertical-align:bottom;background:none;}
+.path-admin-tool-capability .comparisontable thead th div {position:relative;}
+.path-admin-tool-capability .comparisontable thead th div > a {
+    position:absolute;
+    top:-1.75em;
+    left:1em;
+    width:150px;
+    text-align:left;
+    margin-bottom:1em;
+    text-indent:-1.45em;
+
+    -webkit-transform-origin: top left;
+    -moz-transform-origin:    top left;
+    -ms-transform-origin:     top left;
+    -o-transform-origin:      top left;
+
+    -webkit-transform: rotate(315deg);
+    -moz-transform:    rotate(315deg);
+    -ms-transform:     rotate(315deg);
+    -o-transform:      rotate(315deg);
+}
+.path-admin-tool-capability .comparisontable tbody th {background-color:#EEE;text-align:right;border:1px solid #DFDFDF;}
+.path-admin-tool-capability .comparisontable tbody th span {display:block;color:#666;font-size:80%;}
+.path-admin-tool-capability .comparisontable tbody td {border:1px solid #DFDFDF;}
+
+.path-admin-tool-capability .comparisontable .inherit {color:#666;}
+.path-admin-tool-capability .comparisontable .allow {color:#006600;font-weight:bold;}
+.path-admin-tool-capability .comparisontable .prevent {color:#ad6704;font-weight:bold;}
+.path-admin-tool-capability .comparisontable .prohibit {color:#880000;font-weight:bold;}
\ No newline at end of file
index e14328a..4ada1ea 100644 (file)
 /**
  * Version details.
  *
- * @package    tool
- * @subpackage capability
+ * @package    tool_capability
  * @copyright  2011 Petr Skoda
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
 
 defined('MOODLE_INTERNAL') || die();
 
-$plugin->version   = 2013050100; // The current plugin version (Date: YYYYMMDDXX)
-$plugin->requires  = 2013050100; // Requires this Moodle version
-$plugin->component = 'tool_capability'; // Full name of the plugin (used for diagnostics)
+$plugin->version   = 2013050100; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->requires  = 2013050100; // Requires this Moodle version.
+$plugin->component = 'tool_capability'; // Full name of the plugin (used for diagnostics).
diff --git a/admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search-debug.js b/admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search-debug.js
new file mode 100644 (file)
index 0000000..f0661d5
Binary files /dev/null and b/admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search-debug.js differ
diff --git a/admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search-min.js b/admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search-min.js
new file mode 100644 (file)
index 0000000..0153975
Binary files /dev/null and b/admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search-min.js differ
diff --git a/admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search.js b/admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search.js
new file mode 100644 (file)
index 0000000..f0661d5
Binary files /dev/null and b/admin/tool/capability/yui/build/moodle-tool_capability-search/moodle-tool_capability-search.js differ
diff --git a/admin/tool/capability/yui/src/search/build.json b/admin/tool/capability/yui/src/search/build.json
new file mode 100644 (file)
index 0000000..2157889
--- /dev/null
@@ -0,0 +1,10 @@
+{
+    "name": "moodle-tool_capability-search",
+    "builds": {
+        "moodle-tool_capability-search": {
+            "jsfiles": [
+                "search.js"
+            ]
+        }
+    }
+}
diff --git a/admin/tool/capability/yui/src/search/js/search.js b/admin/tool/capability/yui/src/search/js/search.js
new file mode 100644 (file)
index 0000000..5e9dc34
--- /dev/null
@@ -0,0 +1,159 @@
+/**
+ * This file contains the capability overview search functionality.
+ *
+ * @module moodle-tool_capability-search
+ */
+
+/**
+ * Constructs a new capability search manager.
+ *
+ * @namespace M.tool_capability.search
+ * @class Search
+ * @constructor
+ * @extends Y.Base
+ */
+var SEARCH = function() {
+    SEARCH.superclass.constructor.apply(this, arguments);
+};
+SEARCH.prototype = {
+    /**
+     * The search form.
+     * @property form
+     * @type Node
+     * @protected
+     */
+    form : null,
+    /**
+     * The capability select node.
+     * @property select
+     * @type Node
+     * @protected
+     */
+    select: null,
+    /**
+     * An associative array of search option. Populated from the select node above during initialisation.
+     * @property selectoptions
+     * @type Object
+     * @protected
+     */
+    selectoptions : {},
+    /**
+     * The search input field.
+     * @property input
+     * @type Node
+     * @protected
+     */
+    input: null,
+    /**
+     * The submit button for the form.
+     * @property button
+     * @type Node
+     * @protected
+     */
+    button: null,
+    /**
+     * The last search node if there is one.
+     * If there is a last search node then the last search term will be persisted between requests.
+     * @property lastsearch
+     * @type Node
+     * @protected
+     */
+    lastsearch : null,
+    /**
+     * Constructs the search manager.
+     * @method initializer
+     */
+    initializer : function() {
+        this.form = Y.one('#capability-overview-form');
+        this.select = this.form.one('select[data-search=capability]');
+        this.select.setStyle('minWidth', this.select.get('offsetWidth'));
+        this.select.get('options').each(function(option) {
+            var capability = option.get('value');
+            this.selectoptions[capability] = option;
+        }, this);
+        this.button = this.form.all('input[type=submit]');
+        this.lastsearch = this.form.one('input[name=search]');
+
+        var div = Y.Node.create('<div id="capabilitysearchui"></div>'),
+            label = Y.Node.create('<label for="capabilitysearch">'+this.get('strsearch')+'</label>');
+        this.input = Y.Node.create('<input type="text" id="capabilitysearch" />');
+
+        div.append(label).append(this.input);
+
+        this.select.insert(div, 'before');
+        this.select.one('option').setStyle('display', 'none');
+
+        this.input.on('keyup', this.typed, this);
+        this.select.on('change', this.validate, this);
+
+        if (this.lastsearch) {
+            this.input.set('value', this.lastsearch.get('value'));
+            this.typed();
+            if (this.select.one('option[selected]')) {
+                this.select.set('scrollTop', this.select.one('option[selected]').get('getX'));
+            }
+        }
+
+        this.validate();
+    },
+    /**
+     * Disables the submit button if there are no capabilities selected.
+     * @method validate
+     */
+    validate : function() {
+        this.button.set('disabled', (this.select.get('value') === ''));
+    },
+    /**
+     * Called when ever the user types into the search field.
+     * This method hides any capabilities that don't match the search term.
+     * @method typed
+     */
+    typed : function() {
+        var search = this.input.get('value'),
+            matching = 0,
+            last = null,
+            capability;
+        if (this.lastsearch) {
+            this.lastsearch.set('value', search);
+        }
+        this.select.all('option').remove();
+        for (capability in this.selectoptions) {
+            if (capability.indexOf(search) >= 0) {
+                matching++;
+                this.select.append(this.selectoptions[capability]);
+            }
+        }
+        if (matching === 0) {
+            this.input.addClass("error");
+        } else {
+            this.input.removeClass("error");
+            if (matching === 1) {
+                last.set('selected', true);
+            }
+        }
+        this.validate();
+    }
+};
+Y.extend(SEARCH, Y.Base, SEARCH.prototype, {
+    NAME : 'tool_capability-search',
+    ATTRS : {
+        strsearch : {}
+    }
+});
+
+/**
+ * Core namespace.
+ * @static
+ * @class tool_capability
+ */
+M.tool_capability = M.tool_capability || {};
+
+/**
+ * Initialises capability search functionality.
+ * @static
+ * @method init_capability_search
+ * @param {Object} options
+ */
+M.tool_capability.init_capability_search = function(options) {
+    new SEARCH(options);
+};
\ No newline at end of file
diff --git a/admin/tool/capability/yui/src/search/meta/search.json b/admin/tool/capability/yui/src/search/meta/search.json
new file mode 100644 (file)
index 0000000..720e20b
--- /dev/null
@@ -0,0 +1,8 @@
+{
+    "moodle-tool_capability-search": {
+        "requires": [
+            "base",
+            "node"
+        ]
+    }
+}