1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * Capability tool renderer.
19 *
20 * @package    tool_capability
21 * @copyright  2013 Sam Hemelryk
22 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25/**
26 * The primary renderer for the capability tool.
27 *
28 * @copyright  2013 Sam Hemelryk
29 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
30 */
31class tool_capability_renderer extends plugin_renderer_base {
32
33    /**
34     * Returns an array of permission strings.
35     *
36     * @return lang_string[]
37     */
38    protected function get_permission_strings() {
39        static $strpermissions;
40        if (!$strpermissions) {
41            $strpermissions = array(
42                CAP_INHERIT => new lang_string('inherit', 'role'),
43                CAP_ALLOW => new lang_string('allow', 'role'),
44                CAP_PREVENT => new lang_string('prevent', 'role'),
45                CAP_PROHIBIT => new lang_string('prohibit', 'role')
46            );
47        }
48        return $strpermissions;
49    }
50
51    /**
52     * Returns an array of permission CSS classes.
53     *
54     * @return string[]
55     */
56    protected function get_permission_classes() {
57        static $permissionclasses;
58        if (!$permissionclasses) {
59            $permissionclasses = array(
60                CAP_INHERIT => 'inherit',
61                CAP_ALLOW => 'allow',
62                CAP_PREVENT => 'prevent',
63                CAP_PROHIBIT => 'prohibit',
64            );
65        }
66        return $permissionclasses;
67    }
68
69    /**
70     * Produces a table to visually compare roles and capabilities.
71     *
72     * @param array $capabilities An array of capabilities to show comparison for.
73     * @param int $contextid The context we are displaying for.
74     * @param array $roles An array of roles to show comparison for.
75     * @param bool $onlydiff show only different permissions
76     * @return string
77     */
78    public function capability_comparison_table(array $capabilities, $contextid, array $roles, $onlydiff=false) {
79        static $capabilitycontexts = array();
80
81        $strpermissions = $this->get_permission_strings();
82        $permissionclasses = $this->get_permission_classes();
83
84        if ($contextid === context_system::instance()->id) {
85            $strpermissions[CAP_INHERIT] = new lang_string('notset', 'role');
86        }
87
88        $table = new html_table();
89        $table->attributes['class'] = 'comparisontable';
90        $table->head = array('&nbsp;');
91        foreach ($roles as $role) {
92            $url = new moodle_url('/admin/roles/define.php', array('action' => 'view', 'roleid' => $role->id));
93            $table->head[] = html_writer::div(html_writer::link($url, $role->localname));
94        }
95        $table->data = array();
96
97        $childcontextsids = [];
98        foreach ($capabilities as $capability) {
99            if (empty($capabilitycontexts[$capability])) {
100                $capabilitycontexts[$capability] = tool_capability_calculate_role_data($capability, $roles);
101            }
102            $contexts = $capabilitycontexts[$capability];
103
104            $captitle = new html_table_cell(get_capability_string($capability) . html_writer::span($capability));
105            $captitle->header = true;
106
107            $row = new html_table_row(array($captitle));
108
109            $permissiontypes = array();
110            foreach ($roles as $role) {
111                if (isset($contexts[$contextid]->rolecapabilities[$role->id])) {
112                    $permission = $contexts[$contextid]->rolecapabilities[$role->id];
113                } else {
114                    $permission = CAP_INHERIT;
115                }
116                if (!in_array($permission, $permissiontypes)) {
117                    $permissiontypes[] = $permission;
118                }
119                $cell = new html_table_cell($strpermissions[$permission]);
120                $cell->attributes['class'] = $permissionclasses[$permission];
121                $row->cells[] = $cell;
122            }
123            if (!$onlydiff || count($permissiontypes) > 1) {
124                $table->data[] = $row;
125            }
126            if (!empty($contexts[$contextid]->children)) {
127                $childcontextsids = array_merge($childcontextsids, $contexts[$contextid]->children);
128                $childcontextsids = array_unique($childcontextsids);
129            }
130        }
131
132        // Start the list item, and print the context name as a link to the place to make changes.
133        $context = context::instance_by_id($contextid);
134
135        if ($context instanceof context_system) {
136            $url = new moodle_url('/admin/roles/manage.php');
137        } else {
138            $url = new moodle_url('/admin/roles/permissions.php', ['contextid' => $contextid]);
139        }
140
141        $title = get_string('permissionsincontext', 'core_role', $context->get_context_name());
142
143        $html = $this->output->heading(html_writer::link($url, $title), 3);
144        if (!empty($table->data)) {
145            $html .= html_writer::table($table);
146        } else {
147            $html .= html_writer::tag('p', get_string('nodifferences', 'tool_capability'));
148        }
149        // If there are any child contexts, print them recursively.
150        if (!empty($childcontextsids)) {
151            foreach ($childcontextsids as $childcontextid) {
152                $html .= $this->capability_comparison_table($capabilities, $childcontextid, $roles, $onlydiff);
153            }
154        }
155        return $html;
156    }
157
158}
159