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 | * Capabilities table with risks. |
---|
19 | * |
---|
20 | * @package core_role |
---|
21 | * @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com) |
---|
22 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later |
---|
23 | */ |
---|
24 | |
---|
25 | defined('MOODLE_INTERNAL') || die(); |
---|
26 | |
---|
27 | /** |
---|
28 | * This subclass is the bases for both the define roles and override roles |
---|
29 | * pages. As well as adding the risks columns, this also provides generic |
---|
30 | * facilities for showing a certain number of permissions columns, and |
---|
31 | * recording the current and submitted permissions for each capability. |
---|
32 | */ |
---|
33 | abstract class core_role_capability_table_with_risks extends core_role_capability_table_base { |
---|
34 | protected $allrisks; |
---|
35 | protected $allpermissions; // We don't need perms ourselves, but all our subclasses do. |
---|
36 | protected $strperms; // Language string cache. |
---|
37 | protected $risksurl; // URL in moodledocs about risks. |
---|
38 | protected $riskicons = array(); // Cache to avoid regenerating the HTML for each risk icon. |
---|
39 | /** @var array The capabilities to highlight as default/inherited. */ |
---|
40 | protected $parentpermissions; |
---|
41 | protected $displaypermissions; |
---|
42 | protected $permissions; |
---|
43 | protected $changed; |
---|
44 | protected $roleid; |
---|
45 | |
---|
46 | public function __construct($context, $id, $roleid) { |
---|
47 | parent::__construct($context, $id); |
---|
48 | |
---|
49 | $this->allrisks = get_all_risks(); |
---|
50 | $this->risksurl = get_docs_url(s(get_string('risks', 'core_role'))); |
---|
51 | |
---|
52 | $this->allpermissions = array( |
---|
53 | CAP_INHERIT => 'inherit', |
---|
54 | CAP_ALLOW => 'allow', |
---|
55 | CAP_PREVENT => 'prevent' , |
---|
56 | CAP_PROHIBIT => 'prohibit', |
---|
57 | ); |
---|
58 | |
---|
59 | $this->strperms = array(); |
---|
60 | foreach ($this->allpermissions as $permname) { |
---|
61 | $this->strperms[$permname] = get_string($permname, 'core_role'); |
---|
62 | } |
---|
63 | |
---|
64 | $this->roleid = $roleid; |
---|
65 | $this->load_current_permissions(); |
---|
66 | |
---|
67 | // Fill in any blank permissions with an explicit CAP_INHERIT, and init a locked field. |
---|
68 | foreach ($this->capabilities as $capid => $cap) { |
---|
69 | if (!isset($this->permissions[$cap->name])) { |
---|
70 | $this->permissions[$cap->name] = CAP_INHERIT; |
---|
71 | } |
---|
72 | $this->capabilities[$capid]->locked = false; |
---|
73 | } |
---|
74 | } |
---|
75 | |
---|
76 | protected function load_current_permissions() { |
---|
77 | global $DB; |
---|
78 | |
---|
79 | // Load the overrides/definition in this context. |
---|
80 | if ($this->roleid) { |
---|
81 | $this->permissions = $DB->get_records_menu('role_capabilities', array('roleid' => $this->roleid, |
---|
82 | 'contextid' => $this->context->id), '', 'capability,permission'); |
---|
83 | } else { |
---|
84 | $this->permissions = array(); |
---|
85 | } |
---|
86 | } |
---|
87 | |
---|
88 | protected abstract function load_parent_permissions(); |
---|
89 | |
---|
90 | /** |
---|
91 | * Update $this->permissions based on submitted data, while making a list of |
---|
92 | * changed capabilities in $this->changed. |
---|
93 | */ |
---|
94 | public function read_submitted_permissions() { |
---|
95 | $this->changed = array(); |
---|
96 | |
---|
97 | foreach ($this->capabilities as $cap) { |
---|
98 | if ($cap->locked || $this->skip_row($cap)) { |
---|
99 | // The user is not allowed to change the permission for this capability. |
---|
100 | continue; |
---|
101 | } |
---|
102 | |
---|
103 | $permission = optional_param($cap->name, null, PARAM_PERMISSION); |
---|
104 | if (is_null($permission)) { |
---|
105 | // A permission was not specified in submitted data. |
---|
106 | continue; |
---|
107 | } |
---|
108 | |
---|
109 | // If the permission has changed, update $this->permissions and |
---|
110 | // Record the fact there is data to save. |
---|
111 | if ($this->permissions[$cap->name] != $permission) { |
---|
112 | $this->permissions[$cap->name] = $permission; |
---|
113 | $this->changed[] = $cap->name; |
---|
114 | } |
---|
115 | } |
---|
116 | } |
---|
117 | |
---|
118 | /** |
---|
119 | * Save the new values of any permissions that have been changed. |
---|
120 | */ |
---|
121 | public function save_changes() { |
---|
122 | // Set the permissions. |
---|
123 | foreach ($this->changed as $changedcap) { |
---|
124 | assign_capability($changedcap, $this->permissions[$changedcap], |
---|
125 | $this->roleid, $this->context->id, true); |
---|
126 | } |
---|
127 | |
---|
128 | // Force accessinfo refresh for users visiting this context. |
---|
129 | $this->context->mark_dirty(); |
---|
130 | } |
---|
131 | |
---|
132 | public function display() { |
---|
133 | $this->load_parent_permissions(); |
---|
134 | foreach ($this->capabilities as $cap) { |
---|
135 | if (!isset($this->parentpermissions[$cap->name])) { |
---|
136 | $this->parentpermissions[$cap->name] = CAP_INHERIT; |
---|
137 | } |
---|
138 | } |
---|
139 | parent::display(); |
---|
140 | } |
---|
141 | |
---|
142 | protected function add_header_cells() { |
---|
143 | global $OUTPUT; |
---|
144 | echo '<th colspan="' . count($this->displaypermissions) . '" scope="col">' . |
---|
145 | get_string('permission', 'core_role') . ' ' . $OUTPUT->help_icon('permission', 'core_role') . '</th>'; |
---|
146 | echo '<th class="risk" colspan="' . count($this->allrisks) . '" scope="col">' . get_string('risks', 'core_role') . '</th>'; |
---|
147 | } |
---|
148 | |
---|
149 | protected function num_extra_columns() { |
---|
150 | return count($this->displaypermissions) + count($this->allrisks); |
---|
151 | } |
---|
152 | |
---|
153 | protected function get_row_classes($capability) { |
---|
154 | $rowclasses = array(); |
---|
155 | foreach ($this->allrisks as $riskname => $risk) { |
---|
156 | if ($risk & (int)$capability->riskbitmask) { |
---|
157 | $rowclasses[] = $riskname; |
---|
158 | } |
---|
159 | } |
---|
160 | return $rowclasses; |
---|
161 | } |
---|
162 | |
---|
163 | protected abstract function add_permission_cells($capability); |
---|
164 | |
---|
165 | protected function add_row_cells($capability) { |
---|
166 | $this->add_permission_cells($capability); |
---|
167 | // One cell for each possible risk. |
---|
168 | foreach ($this->allrisks as $riskname => $risk) { |
---|
169 | echo '<td class="risk ' . str_replace('risk', '', $riskname) . '">'; |
---|
170 | if ($risk & (int)$capability->riskbitmask) { |
---|
171 | echo $this->get_risk_icon($riskname); |
---|
172 | } |
---|
173 | echo '</td>'; |
---|
174 | } |
---|
175 | } |
---|
176 | |
---|
177 | /** |
---|
178 | * Print a risk icon, as a link to the Risks page on Moodle Docs. |
---|
179 | * |
---|
180 | * @param string $type the type of risk, will be one of the keys from the |
---|
181 | * get_all_risks array. Must start with 'risk'. |
---|
182 | */ |
---|
183 | public function get_risk_icon($type) { |
---|
184 | global $OUTPUT; |
---|
185 | if (!isset($this->riskicons[$type])) { |
---|
186 | $iconurl = $OUTPUT->pix_url('i/' . str_replace('risk', 'risk_', $type)); |
---|
187 | $text = '<img src="' . $iconurl . '" alt="' . get_string($type . 'short', 'admin') . '" />'; |
---|
188 | $action = new popup_action('click', $this->risksurl, 'docspopup'); |
---|
189 | $this->riskicons[$type] = $OUTPUT->action_link($this->risksurl, $text, $action, array('title'=>get_string($type, 'admin'))); |
---|
190 | } |
---|
191 | return $this->riskicons[$type]; |
---|
192 | } |
---|
193 | } |
---|