1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* @package Joomla.Platform |
4
|
|
|
* @subpackage Form |
5
|
|
|
* |
6
|
|
|
* @copyright Copyright (C) 2008 - 2021 redWEB.dk. All rights reserved. |
7
|
|
|
* @license GNU General Public License version 2 or later, see LICENSE. |
8
|
|
|
*/ |
9
|
|
|
|
10
|
|
|
defined('JPATH_PLATFORM') or die; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Form Field class for the Joomla Platform. |
14
|
|
|
* Field for assigning permissions to groups for a given asset |
15
|
|
|
* |
16
|
|
|
* @package Joomla.Platform |
17
|
|
|
* @subpackage Form |
18
|
|
|
* @see JAccess |
19
|
|
|
* @since 11.1 |
20
|
|
|
*/ |
21
|
|
|
class JFormFieldRrules extends JFormField |
22
|
|
|
{ |
23
|
|
|
/** |
24
|
|
|
* The form field type. |
25
|
|
|
* |
26
|
|
|
* @var string |
27
|
|
|
* @since 11.1 |
28
|
|
|
*/ |
29
|
|
|
public $type = 'Rrules'; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* Method to get the field input markup for Access Control Lists. |
33
|
|
|
* Optionally can be associated with a specific component and section. |
34
|
|
|
* |
35
|
|
|
* TODO: Add access check. |
36
|
|
|
* |
37
|
|
|
* @return string The field input markup. |
38
|
|
|
* |
39
|
|
|
* @since 11.1 |
40
|
|
|
*/ |
41
|
|
|
protected function getInput() |
42
|
|
|
{ |
43
|
|
|
JHtml::_('rbootstrap.tooltip'); |
44
|
|
|
|
45
|
|
|
// Initialise some field attributes. |
46
|
|
|
$section = $this->element['section'] ? (string) $this->element['section'] : ''; |
47
|
|
|
$component = $this->element['component'] ? (string) $this->element['component'] : ''; |
48
|
|
|
$assetField = $this->element['asset_field'] ? (string) $this->element['asset_field'] : 'asset_id'; |
49
|
|
|
|
50
|
|
|
// Get the actions for the asset. |
51
|
|
|
$actions = JAccess::getActionsFromFile($component, $section) ?: array(); |
52
|
|
|
|
53
|
|
|
// Iterate over the children and add to the actions. |
54
|
|
|
foreach ($this->element->children() as $el) |
55
|
|
|
{ |
56
|
|
|
if ($el->getName() == 'action') |
57
|
|
|
{ |
58
|
|
|
$actions[] = (object) array('name' => (string) $el['name'], 'title' => (string) $el['title'], |
59
|
|
|
'description' => (string) $el['description']); |
60
|
|
|
} |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
// Get the explicit rules for this asset. |
64
|
|
|
if ($section == 'component') |
65
|
|
|
{ |
66
|
|
|
// Need to find the asset id by the name of the component. |
67
|
|
|
$db = JFactory::getDbo(); |
68
|
|
|
$query = $db->getQuery(true) |
69
|
|
|
->select($db->quoteName('id')) |
70
|
|
|
->from($db->quoteName('#__assets')) |
71
|
|
|
->where($db->quoteName('name') . ' = ' . $db->quote($component)); |
72
|
|
|
$db->setQuery($query); |
73
|
|
|
$assetId = (int) $db->loadResult(); |
74
|
|
|
} |
75
|
|
|
else |
76
|
|
|
{ |
77
|
|
|
// Find the asset id of the content. |
78
|
|
|
// Note that for global configuration, com_config injects asset_id = 1 into the form. |
79
|
|
|
$assetId = $this->form->getValue($assetField); |
80
|
|
|
} |
81
|
|
|
|
82
|
|
|
// Full width format. |
83
|
|
|
|
84
|
|
|
// Get the rules for just this asset (non-recursive). |
85
|
|
|
$assetRules = JAccess::getAssetRules($assetId, false, false); |
86
|
|
|
|
87
|
|
|
// Get the available user groups. |
88
|
|
|
$groups = $this->getUserGroups(); |
89
|
|
|
|
90
|
|
|
// Prepare output |
91
|
|
|
$html = array(); |
92
|
|
|
|
93
|
|
|
// Description |
94
|
|
|
$html[] = '<p class="rule-desc">' . JText::_('JLIB_RULES_SETTINGS_DESC') . '</p>'; |
95
|
|
|
|
96
|
|
|
// Begin tabs |
97
|
|
|
$html[] = '<div id="permissions-sliders" class="tabbable tabs-left">'; |
98
|
|
|
|
99
|
|
|
// Building tab nav |
100
|
|
|
$html[] = '<ul class="nav nav-tabs">'; |
101
|
|
|
|
102
|
|
|
foreach ($groups as $group) |
103
|
|
|
{ |
104
|
|
|
// Initial Active Tab |
105
|
|
|
$active = ""; |
106
|
|
|
|
107
|
|
|
if ($group->value == 1) |
108
|
|
|
{ |
109
|
|
|
$active = "active"; |
110
|
|
|
} |
111
|
|
|
|
112
|
|
|
$html[] = '<li class="' . $active . '">'; |
113
|
|
|
$html[] = '<a href="#permission-' . $group->value . '" data-toggle="tab">'; |
114
|
|
|
$html[] = str_repeat('<span class="level">–</span> ', $curLevel = $group->level) . $group->text; |
115
|
|
|
$html[] = '</a>'; |
116
|
|
|
$html[] = '</li>'; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
$html[] = '</ul>'; |
120
|
|
|
|
121
|
|
|
$html[] = '<div class="tab-content">'; |
122
|
|
|
|
123
|
|
|
// Start a row for each user group. |
124
|
|
|
foreach ($groups as $group) |
125
|
|
|
{ |
126
|
|
|
// Initial Active Pane |
127
|
|
|
$active = ""; |
128
|
|
|
|
129
|
|
|
if ($group->value == 1) |
130
|
|
|
{ |
131
|
|
|
$active = " active"; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
$html[] = '<div class="tab-pane' . $active . '" id="permission-' . $group->value . '">'; |
135
|
|
|
$html[] = '<table class="table table-striped">'; |
136
|
|
|
$html[] = '<thead>'; |
137
|
|
|
$html[] = '<tr>'; |
138
|
|
|
|
139
|
|
|
$html[] = '<th class="actions" id="actions-th' . $group->value . '">'; |
140
|
|
|
$html[] = '<span class="acl-action">' . JText::_('JLIB_RULES_ACTION') . '</span>'; |
141
|
|
|
$html[] = '</th>'; |
142
|
|
|
|
143
|
|
|
$html[] = '<th class="settings" id="settings-th' . $group->value . '">'; |
144
|
|
|
$html[] = '<span class="acl-action">' . JText::_('JLIB_RULES_SELECT_SETTING') . '</span>'; |
145
|
|
|
$html[] = '</th>'; |
146
|
|
|
|
147
|
|
|
// The calculated setting is not shown for the root group of global configuration. |
148
|
|
|
$canCalculateSettings = ($group->parent_id || !empty($component)); |
149
|
|
|
|
150
|
|
|
if ($canCalculateSettings) |
151
|
|
|
{ |
152
|
|
|
$html[] = '<th id="aclactionth' . $group->value . '">'; |
153
|
|
|
$html[] = '<span class="acl-action">' . JText::_('JLIB_RULES_CALCULATED_SETTING') . '</span>'; |
154
|
|
|
$html[] = '</th>'; |
155
|
|
|
} |
156
|
|
|
|
157
|
|
|
$html[] = '</tr>'; |
158
|
|
|
$html[] = '</thead>'; |
159
|
|
|
$html[] = '<tbody>'; |
160
|
|
|
|
161
|
|
|
foreach ($actions as $action) |
162
|
|
|
{ |
163
|
|
|
$html[] = '<tr>'; |
164
|
|
|
$html[] = '<td headers="actions-th' . $group->value . '">'; |
165
|
|
|
$html[] = '<label for="' . $this->id . '_' . $action->name . '_' . $group->value . '" class="hasTooltip" title="' |
166
|
|
|
. htmlspecialchars(JText::_($action->title) . ' ' . JText::_($action->description), ENT_COMPAT, 'UTF-8') . '">'; |
167
|
|
|
$html[] = JText::_($action->title); |
168
|
|
|
$html[] = '</label>'; |
169
|
|
|
$html[] = '</td>'; |
170
|
|
|
|
171
|
|
|
$html[] = '<td headers="settings-th' . $group->value . '">'; |
172
|
|
|
|
173
|
|
|
$html[] = '<select class="input-small input-sm" name="' . $this->name . '[' . $action->name . '][' . $group->value . ']" id="' |
174
|
|
|
. $this->id . '_' . $action->name |
175
|
|
|
. '_' . $group->value . '" title="' |
176
|
|
|
. JText::sprintf('JLIB_RULES_SELECT_ALLOW_DENY_GROUP', JText::_($action->title), trim($group->text)) . '">'; |
177
|
|
|
|
178
|
|
|
$inheritedRule = JAccess::checkGroup($group->value, $action->name, $assetId); |
179
|
|
|
|
180
|
|
|
// Get the actual setting for the action for this group. |
181
|
|
|
$assetRule = $assetRules->allow($action->name, $group->value); |
182
|
|
|
|
183
|
|
|
// Build the dropdowns for the permissions sliders |
184
|
|
|
|
185
|
|
|
// The parent group has "Not Set", all children can rightly "Inherit" from that. |
186
|
|
|
$html[] = '<option value=""' . ($assetRule === null ? ' selected="selected"' : '') . '>' |
187
|
|
|
. JText::_(empty($group->parent_id) && empty($component) ? 'JLIB_RULES_NOT_SET' : 'JLIB_RULES_INHERITED') . '</option>'; |
188
|
|
|
$html[] = '<option value="1"' . ($assetRule === true ? ' selected="selected"' : '') . '>' . JText::_('JLIB_RULES_ALLOWED') |
189
|
|
|
. '</option>'; |
190
|
|
|
$html[] = '<option value="0"' . ($assetRule === false ? ' selected="selected"' : '') . '>' . JText::_('JLIB_RULES_DENIED') |
191
|
|
|
. '</option>'; |
192
|
|
|
|
193
|
|
|
$html[] = '</select>  '; |
194
|
|
|
|
195
|
|
|
// If this asset's rule is allowed, but the inherited rule is deny, we have a conflict. |
196
|
|
|
if (($assetRule === true) && ($inheritedRule === false)) |
197
|
|
|
{ |
198
|
|
|
$html[] = JText::_('JLIB_RULES_CONFLICT'); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
$html[] = '</td>'; |
202
|
|
|
|
203
|
|
|
// Build the Calculated Settings column. |
204
|
|
|
// The inherited settings column is not displayed for the root group in global configuration. |
205
|
|
|
if ($canCalculateSettings) |
206
|
|
|
{ |
207
|
|
|
$html[] = '<td headers="aclactionth' . $group->value . '">'; |
208
|
|
|
|
209
|
|
|
// This is where we show the current effective settings considering currrent group, path and cascade. |
210
|
|
|
// Check whether this is a component or global. Change the text slightly. |
211
|
|
|
|
212
|
|
|
if (JAccess::checkGroup($group->value, 'core.admin', $assetId) !== true) |
213
|
|
|
{ |
214
|
|
|
if ($inheritedRule === null) |
215
|
|
|
{ |
216
|
|
|
$html[] = '<span class="label label-important label-danger">' . JText::_('JLIB_RULES_NOT_ALLOWED') . '</span>'; |
217
|
|
|
} |
218
|
|
|
elseif ($inheritedRule === true) |
219
|
|
|
{ |
220
|
|
|
$html[] = '<span class="label label-success">' . JText::_('JLIB_RULES_ALLOWED') . '</span>'; |
221
|
|
|
} |
222
|
|
|
elseif ($inheritedRule === false) |
223
|
|
|
{ |
224
|
|
|
if ($assetRule === false) |
225
|
|
|
{ |
226
|
|
|
$html[] = '<span class="label label-important label-danger">' . JText::_('JLIB_RULES_NOT_ALLOWED') . '</span>'; |
227
|
|
|
} |
228
|
|
|
else |
229
|
|
|
{ |
230
|
|
|
$html[] = '<span class="label label-default"><i class="icon-lock icon-white"></i> ' . JText::_('JLIB_RULES_NOT_ALLOWED_LOCKED') |
231
|
|
|
. '</span>'; |
232
|
|
|
} |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
elseif (!empty($component)) |
236
|
|
|
{ |
237
|
|
|
$html[] = '<span class="label label-success"><i class="icon-lock icon-white"></i> ' . JText::_('JLIB_RULES_ALLOWED_ADMIN') |
238
|
|
|
. '</span>'; |
239
|
|
|
} |
240
|
|
|
else |
241
|
|
|
{ |
242
|
|
|
// Special handling for groups that have global admin because they can't be denied. |
243
|
|
|
// The admin rights can be changed. |
244
|
|
|
if ($action->name === 'core.admin') |
245
|
|
|
{ |
246
|
|
|
$html[] = '<span class="label label-success">' . JText::_('JLIB_RULES_ALLOWED') . '</span>'; |
247
|
|
|
} |
248
|
|
|
elseif ($inheritedRule === false) |
249
|
|
|
{ |
250
|
|
|
// Other actions cannot be changed. |
251
|
|
|
$html[] = '<span class="label label-important label-danger"><i class="icon-lock icon-white"></i> ' |
252
|
|
|
. JText::_('JLIB_RULES_NOT_ALLOWED_ADMIN_CONFLICT') . '</span>'; |
253
|
|
|
} |
254
|
|
|
else |
255
|
|
|
{ |
256
|
|
|
$html[] = '<span class="label label-success"><i class="icon-lock icon-white"></i> ' . JText::_('JLIB_RULES_ALLOWED_ADMIN') |
257
|
|
|
. '</span>'; |
258
|
|
|
} |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
$html[] = '</td>'; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
$html[] = '</tr>'; |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
$html[] = '</tbody>'; |
268
|
|
|
$html[] = '</table></div>'; |
269
|
|
|
} |
270
|
|
|
|
271
|
|
|
$html[] = '</div></div>'; |
272
|
|
|
|
273
|
|
|
$html[] = '<div class="alert">'; |
274
|
|
|
|
275
|
|
|
if ($section == 'component' || $section == null) |
276
|
|
|
{ |
277
|
|
|
$html[] = JText::_('JLIB_RULES_SETTING_NOTES'); |
278
|
|
|
} |
279
|
|
|
else |
280
|
|
|
{ |
281
|
|
|
$html[] = JText::_('JLIB_RULES_SETTING_NOTES_ITEM'); |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
$html[] = '</div>'; |
285
|
|
|
|
286
|
|
|
return implode("\n", $html); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
/** |
290
|
|
|
* Get a list of the user groups. |
291
|
|
|
* |
292
|
|
|
* @return array |
293
|
|
|
* |
294
|
|
|
* @since 11.1 |
295
|
|
|
*/ |
296
|
|
|
protected function getUserGroups() |
297
|
|
|
{ |
298
|
|
|
if (class_exists('JHelperUsergroups')) |
299
|
|
|
{ |
300
|
|
|
$options = JHelperUsergroups::getInstance()->getAll(); |
301
|
|
|
|
302
|
|
|
foreach ($options as &$option) |
303
|
|
|
{ |
304
|
|
|
$option->value = $option->id; |
305
|
|
|
$option->text = $option->title; |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
return array_values($options); |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
$db = JFactory::getDbo(); |
312
|
|
|
$query = $db->getQuery(true) |
313
|
|
|
->select('a.id AS value, a.title AS text, COUNT(DISTINCT b.id) AS level, a.parent_id') |
314
|
|
|
->from('#__usergroups AS a') |
315
|
|
|
->join('LEFT', $db->quoteName('#__usergroups') . ' AS b ON a.lft > b.lft AND a.rgt < b.rgt') |
316
|
|
|
->group('a.id, a.title, a.lft, a.rgt, a.parent_id') |
317
|
|
|
->order('a.lft ASC'); |
318
|
|
|
$db->setQuery($query); |
319
|
|
|
$options = $db->loadObjectList(); |
320
|
|
|
|
321
|
|
|
return $options; |
322
|
|
|
} |
323
|
|
|
} |
324
|
|
|
|