Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
23.71% |
147 / 620 |
|
16.67% |
2 / 12 |
CRAP | |
0.00% |
0 / 1 |
auth_admin | |
23.62% |
146 / 618 |
|
16.67% |
2 / 12 |
25049.30 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
5 | |||
get_mask | |
0.00% |
0 / 64 |
|
0.00% |
0 / 1 |
1190 | |||
get_role_mask | |
94.74% |
18 / 19 |
|
0.00% |
0 / 1 |
3.00 | |||
display_mask | |
0.00% |
0 / 194 |
|
0.00% |
0 / 1 |
6480 | |||
display_role_mask | |
0.00% |
0 / 46 |
|
0.00% |
0 / 1 |
156 | |||
acl_add_option | |
95.83% |
46 / 48 |
|
0.00% |
0 / 1 |
19 | |||
acl_set | |
100.00% |
65 / 65 |
|
100.00% |
1 / 1 |
19 | |||
acl_set_role | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
90 | |||
acl_delete | |
0.00% |
0 / 51 |
|
0.00% |
0 / 1 |
306 | |||
assign_cat_array | |
0.00% |
0 / 41 |
|
0.00% |
0 / 1 |
552 | |||
build_permission_array | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
110 | |||
ghost_permissions | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
30 |
1 | <?php |
2 | /** |
3 | * |
4 | * This file is part of the phpBB Forum Software package. |
5 | * |
6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
7 | * @license GNU General Public License, version 2 (GPL-2.0) |
8 | * |
9 | * For full copyright and license information, please see |
10 | * the docs/CREDITS.txt file. |
11 | * |
12 | */ |
13 | |
14 | /** |
15 | * @ignore |
16 | */ |
17 | if (!defined('IN_PHPBB')) |
18 | { |
19 | exit; |
20 | } |
21 | |
22 | /** |
23 | * ACP Permission/Auth class |
24 | */ |
25 | class auth_admin extends \phpbb\auth\auth |
26 | { |
27 | /** |
28 | * Init auth settings |
29 | */ |
30 | function __construct() |
31 | { |
32 | global $db, $cache; |
33 | |
34 | if (($this->acl_options = $cache->get('_acl_options')) === false) |
35 | { |
36 | $sql = 'SELECT auth_option_id, auth_option, is_global, is_local |
37 | FROM ' . ACL_OPTIONS_TABLE . ' |
38 | ORDER BY auth_option_id'; |
39 | $result = $db->sql_query($sql); |
40 | |
41 | $global = $local = 0; |
42 | $this->acl_options = array(); |
43 | while ($row = $db->sql_fetchrow($result)) |
44 | { |
45 | if ($row['is_global']) |
46 | { |
47 | $this->acl_options['global'][$row['auth_option']] = $global++; |
48 | } |
49 | |
50 | if ($row['is_local']) |
51 | { |
52 | $this->acl_options['local'][$row['auth_option']] = $local++; |
53 | } |
54 | |
55 | $this->acl_options['id'][$row['auth_option']] = (int) $row['auth_option_id']; |
56 | $this->acl_options['option'][(int) $row['auth_option_id']] = $row['auth_option']; |
57 | } |
58 | $db->sql_freeresult($result); |
59 | |
60 | $cache->put('_acl_options', $this->acl_options); |
61 | } |
62 | } |
63 | |
64 | /** |
65 | * Get permission mask |
66 | * This function only supports getting permissions of one type (for example a_) |
67 | * |
68 | * @param set|view $mode defines the permissions we get, view gets effective permissions (checking user AND group permissions), set only gets the user or group permission set alone |
69 | * @param mixed $user_id user ids to search for (a user_id or a group_id has to be specified at least) |
70 | * @param mixed $group_id group ids to search for, return group related settings (a user_id or a group_id has to be specified at least) |
71 | * @param mixed $forum_id forum_ids to search for. Defining a forum id also means getting local settings |
72 | * @param string $auth_option the auth_option defines the permission setting to look for (a_ for example) |
73 | * @param local|global $scope the scope defines the permission scope. If local, a forum_id is additionally required |
74 | * @param ACL_NEVER|ACL_NO|ACL_YES $acl_fill defines the mode those permissions not set are getting filled with |
75 | */ |
76 | function get_mask($mode, $user_id = false, $group_id = false, $forum_id = false, $auth_option = false, $scope = false, $acl_fill = ACL_NEVER) |
77 | { |
78 | global $db, $user; |
79 | |
80 | $hold_ary = array(); |
81 | $view_user_mask = ($mode == 'view' && $group_id === false) ? true : false; |
82 | |
83 | if ($auth_option === false || $scope === false) |
84 | { |
85 | return array(); |
86 | } |
87 | |
88 | $acl_user_function = ($mode == 'set') ? 'acl_user_raw_data' : 'acl_raw_data'; |
89 | |
90 | if (!$view_user_mask) |
91 | { |
92 | if ($forum_id !== false) |
93 | { |
94 | $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%', $forum_id) : $this->$acl_user_function($user_id, $auth_option . '%', $forum_id); |
95 | } |
96 | else |
97 | { |
98 | $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%') : $this->$acl_user_function($user_id, $auth_option . '%', ($scope == 'global') ? 0 : false); |
99 | } |
100 | } |
101 | |
102 | // Make sure hold_ary is filled with every setting (prevents missing forums/users/groups) |
103 | $ug_id = ($group_id !== false) ? ((!is_array($group_id)) ? array($group_id) : $group_id) : ((!is_array($user_id)) ? array($user_id) : $user_id); |
104 | $forum_ids = ($forum_id !== false) ? ((!is_array($forum_id)) ? array($forum_id) : $forum_id) : (($scope == 'global') ? array(0) : array()); |
105 | |
106 | // Only those options we need |
107 | $compare_options = array_diff(preg_replace('/^((?!' . $auth_option . ').+)|(' . $auth_option . ')$/', '', array_keys($this->acl_options[$scope])), array('')); |
108 | |
109 | // If forum_ids is false and the scope is local we actually want to have all forums within the array |
110 | if ($scope == 'local' && !count($forum_ids)) |
111 | { |
112 | $sql = 'SELECT forum_id |
113 | FROM ' . FORUMS_TABLE; |
114 | $result = $db->sql_query($sql, 120); |
115 | |
116 | while ($row = $db->sql_fetchrow($result)) |
117 | { |
118 | $forum_ids[] = (int) $row['forum_id']; |
119 | } |
120 | $db->sql_freeresult($result); |
121 | } |
122 | |
123 | if ($view_user_mask) |
124 | { |
125 | $auth2 = null; |
126 | |
127 | $sql = 'SELECT user_id, user_permissions, user_type |
128 | FROM ' . USERS_TABLE . ' |
129 | WHERE ' . $db->sql_in_set('user_id', $ug_id); |
130 | $result = $db->sql_query($sql); |
131 | |
132 | while ($userdata = $db->sql_fetchrow($result)) |
133 | { |
134 | if ($user->data['user_id'] != $userdata['user_id']) |
135 | { |
136 | $auth2 = new \phpbb\auth\auth(); |
137 | $auth2->acl($userdata); |
138 | } |
139 | else |
140 | { |
141 | global $auth; |
142 | $auth2 = &$auth; |
143 | } |
144 | |
145 | $hold_ary[$userdata['user_id']] = array(); |
146 | foreach ($forum_ids as $f_id) |
147 | { |
148 | $hold_ary[$userdata['user_id']][$f_id] = array(); |
149 | foreach ($compare_options as $option) |
150 | { |
151 | $hold_ary[$userdata['user_id']][$f_id][$option] = $auth2->acl_get($option, $f_id); |
152 | } |
153 | } |
154 | } |
155 | $db->sql_freeresult($result); |
156 | |
157 | unset($userdata); |
158 | unset($auth2); |
159 | } |
160 | |
161 | foreach ($ug_id as $_id) |
162 | { |
163 | if (!isset($hold_ary[$_id])) |
164 | { |
165 | $hold_ary[$_id] = array(); |
166 | } |
167 | |
168 | foreach ($forum_ids as $f_id) |
169 | { |
170 | if (!isset($hold_ary[$_id][$f_id])) |
171 | { |
172 | $hold_ary[$_id][$f_id] = array(); |
173 | } |
174 | } |
175 | } |
176 | |
177 | // Now, we need to fill the gaps with $acl_fill. ;) |
178 | |
179 | // Now switch back to keys |
180 | if (count($compare_options)) |
181 | { |
182 | $compare_options = array_combine($compare_options, array_fill(1, count($compare_options), $acl_fill)); |
183 | } |
184 | |
185 | // Defining the user-function here to save some memory |
186 | $return_acl_fill = function () use ($acl_fill) |
187 | { |
188 | return $acl_fill; |
189 | }; |
190 | |
191 | // Actually fill the gaps |
192 | if (count($hold_ary)) |
193 | { |
194 | foreach ($hold_ary as $ug_id => $row) |
195 | { |
196 | foreach ($row as $id => $options) |
197 | { |
198 | // Do not include the global auth_option |
199 | unset($options[$auth_option]); |
200 | |
201 | // Not a "fine" solution, but at all it's a 1-dimensional |
202 | // array_diff_key function filling the resulting array values with zeros |
203 | // The differences get merged into $hold_ary (all permissions having $acl_fill set) |
204 | $hold_ary[$ug_id][$id] = array_merge($options, |
205 | |
206 | array_map($return_acl_fill, |
207 | array_flip( |
208 | array_diff( |
209 | array_keys($compare_options), array_keys($options) |
210 | ) |
211 | ) |
212 | ) |
213 | ); |
214 | } |
215 | } |
216 | } |
217 | else |
218 | { |
219 | $hold_ary[($group_id !== false) ? $group_id : $user_id][(int) $forum_id] = $compare_options; |
220 | } |
221 | |
222 | return $hold_ary; |
223 | } |
224 | |
225 | /** |
226 | * Get permission mask for roles |
227 | * This function only supports getting masks for one role |
228 | */ |
229 | function get_role_mask($role_id) |
230 | { |
231 | global $db; |
232 | |
233 | $hold_ary = array(); |
234 | |
235 | // Get users having this role set... |
236 | $sql = 'SELECT user_id, forum_id |
237 | FROM ' . ACL_USERS_TABLE . ' |
238 | WHERE auth_role_id = ' . $role_id . ' |
239 | ORDER BY forum_id'; |
240 | $result = $db->sql_query($sql); |
241 | |
242 | while ($row = $db->sql_fetchrow($result)) |
243 | { |
244 | $hold_ary[$row['forum_id']]['users'][] = $row['user_id']; |
245 | } |
246 | $db->sql_freeresult($result); |
247 | |
248 | // Now grab groups... |
249 | $sql = 'SELECT group_id, forum_id |
250 | FROM ' . ACL_GROUPS_TABLE . ' |
251 | WHERE auth_role_id = ' . $role_id . ' |
252 | ORDER BY forum_id'; |
253 | $result = $db->sql_query($sql); |
254 | |
255 | while ($row = $db->sql_fetchrow($result)) |
256 | { |
257 | $hold_ary[$row['forum_id']]['groups'][] = $row['group_id']; |
258 | } |
259 | $db->sql_freeresult($result); |
260 | |
261 | return $hold_ary; |
262 | } |
263 | |
264 | /** |
265 | * Display permission mask (assign to template) |
266 | */ |
267 | function display_mask($mode, $permission_type, &$hold_ary, $user_mode = 'user', $local = false, $group_display = true) |
268 | { |
269 | global $template, $user, $db, $phpbb_container; |
270 | |
271 | /* @var $phpbb_permissions \phpbb\permissions */ |
272 | $phpbb_permissions = $phpbb_container->get('acl.permissions'); |
273 | |
274 | /** @var \phpbb\group\helper $group_helper */ |
275 | $group_helper = $phpbb_container->get('group_helper'); |
276 | |
277 | // Define names for template loops, might be able to be set |
278 | $tpl_pmask = 'p_mask'; |
279 | $tpl_fmask = 'f_mask'; |
280 | $tpl_category = 'category'; |
281 | $tpl_mask = 'mask'; |
282 | |
283 | $l_acl_type = $phpbb_permissions->get_type_lang($permission_type, (($local) ? 'local' : 'global')); |
284 | |
285 | // Allow trace for viewing permissions and in user mode |
286 | $show_trace = ($mode == 'view' && $user_mode == 'user') ? true : false; |
287 | |
288 | // Get names |
289 | if ($user_mode == 'user') |
290 | { |
291 | $sql = 'SELECT user_id as ug_id, username as ug_name |
292 | FROM ' . USERS_TABLE . ' |
293 | WHERE ' . $db->sql_in_set('user_id', array_keys($hold_ary)) . ' |
294 | ORDER BY username_clean ASC'; |
295 | } |
296 | else |
297 | { |
298 | $sql = 'SELECT group_id as ug_id, group_name as ug_name, group_type |
299 | FROM ' . GROUPS_TABLE . ' |
300 | WHERE ' . $db->sql_in_set('group_id', array_keys($hold_ary)) . ' |
301 | ORDER BY group_type DESC, group_name ASC'; |
302 | } |
303 | $result = $db->sql_query($sql); |
304 | |
305 | $ug_names_ary = array(); |
306 | while ($row = $db->sql_fetchrow($result)) |
307 | { |
308 | $ug_names_ary[$row['ug_id']] = ($user_mode == 'user') ? $row['ug_name'] : $group_helper->get_name($row['ug_name']); |
309 | } |
310 | $db->sql_freeresult($result); |
311 | |
312 | // Get used forums |
313 | $forum_ids = array(); |
314 | foreach ($hold_ary as $ug_id => $row) |
315 | { |
316 | $forum_ids = array_merge($forum_ids, array_keys($row)); |
317 | } |
318 | $forum_ids = array_unique($forum_ids); |
319 | |
320 | $forum_names_ary = array(); |
321 | if ($local) |
322 | { |
323 | $forum_names_ary = make_forum_select(false, false, true, false, false, false, true); |
324 | |
325 | // Remove the disabled ones, since we do not create an option field here... |
326 | foreach ($forum_names_ary as $key => $value) |
327 | { |
328 | if (!$value['disabled']) |
329 | { |
330 | continue; |
331 | } |
332 | unset($forum_names_ary[$key]); |
333 | } |
334 | } |
335 | else |
336 | { |
337 | $forum_names_ary[0] = $l_acl_type; |
338 | } |
339 | |
340 | // Get available roles |
341 | $sql = 'SELECT * |
342 | FROM ' . ACL_ROLES_TABLE . " |
343 | WHERE role_type = '" . $db->sql_escape($permission_type) . "' |
344 | ORDER BY role_order ASC"; |
345 | $result = $db->sql_query($sql); |
346 | |
347 | $roles = array(); |
348 | while ($row = $db->sql_fetchrow($result)) |
349 | { |
350 | $roles[$row['role_id']] = $row; |
351 | } |
352 | $db->sql_freeresult($result); |
353 | |
354 | $cur_roles = $this->acl_role_data($user_mode, $permission_type, array_keys($hold_ary)); |
355 | |
356 | // Build js roles array (role data assignments) |
357 | $s_role_js_array = ''; |
358 | |
359 | if (count($roles)) |
360 | { |
361 | $s_role_js_array = array(); |
362 | |
363 | // Make sure every role (even if empty) has its array defined |
364 | foreach ($roles as $_role_id => $null) |
365 | { |
366 | $s_role_js_array[$_role_id] = "\n" . 'role_options[' . $_role_id . '] = new Array();' . "\n"; |
367 | } |
368 | |
369 | $sql = 'SELECT r.role_id, o.auth_option, r.auth_setting |
370 | FROM ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' o |
371 | WHERE o.auth_option_id = r.auth_option_id |
372 | AND ' . $db->sql_in_set('r.role_id', array_keys($roles)); |
373 | $result = $db->sql_query($sql); |
374 | |
375 | while ($row = $db->sql_fetchrow($result)) |
376 | { |
377 | $flag = substr($row['auth_option'], 0, strpos($row['auth_option'], '_') + 1); |
378 | if ($flag == $row['auth_option']) |
379 | { |
380 | continue; |
381 | } |
382 | |
383 | $s_role_js_array[$row['role_id']] .= 'role_options[' . $row['role_id'] . '][\'' . addslashes($row['auth_option']) . '\'] = ' . $row['auth_setting'] . '; '; |
384 | } |
385 | $db->sql_freeresult($result); |
386 | |
387 | $s_role_js_array = implode('', $s_role_js_array); |
388 | } |
389 | |
390 | $template->assign_var('S_ROLE_JS_ARRAY', $s_role_js_array); |
391 | unset($s_role_js_array); |
392 | |
393 | // Now obtain memberships |
394 | $user_groups_default = $user_groups_custom = array(); |
395 | if ($user_mode == 'user' && $group_display) |
396 | { |
397 | $sql = 'SELECT group_id, group_name, group_type |
398 | FROM ' . GROUPS_TABLE . ' |
399 | ORDER BY group_type DESC, group_name ASC'; |
400 | $result = $db->sql_query($sql); |
401 | |
402 | $groups = array(); |
403 | while ($row = $db->sql_fetchrow($result)) |
404 | { |
405 | $groups[$row['group_id']] = $row; |
406 | } |
407 | $db->sql_freeresult($result); |
408 | |
409 | $memberships = group_memberships(false, array_keys($hold_ary), false); |
410 | |
411 | // User is not a member of any group? Bad admin, bad bad admin... |
412 | if ($memberships) |
413 | { |
414 | foreach ($memberships as $row) |
415 | { |
416 | $user_groups_default[$row['user_id']][] = $group_helper->get_name($groups[$row['group_id']]['group_name']); |
417 | } |
418 | } |
419 | unset($memberships, $groups); |
420 | } |
421 | |
422 | // If we only have one forum id to display or being in local mode and more than one user/group to display, |
423 | // we switch the complete interface to group by user/usergroup instead of grouping by forum |
424 | // To achieve this, we need to switch the array a bit |
425 | if (count($forum_ids) == 1 || ($local && count($ug_names_ary) > 1)) |
426 | { |
427 | $hold_ary_temp = $hold_ary; |
428 | $hold_ary = array(); |
429 | foreach ($hold_ary_temp as $ug_id => $row) |
430 | { |
431 | foreach ($forum_names_ary as $forum_id => $forum_row) |
432 | { |
433 | if (isset($row[$forum_id])) |
434 | { |
435 | $hold_ary[$forum_id][$ug_id] = $row[$forum_id]; |
436 | } |
437 | } |
438 | } |
439 | unset($hold_ary_temp); |
440 | |
441 | foreach ($hold_ary as $forum_id => $forum_array) |
442 | { |
443 | $content_array = $categories = array(); |
444 | $this->build_permission_array($hold_ary[$forum_id], $content_array, $categories, array_keys($ug_names_ary)); |
445 | |
446 | $template->assign_block_vars($tpl_pmask, array( |
447 | 'NAME' => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'], |
448 | 'PADDING' => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'], |
449 | |
450 | 'CATEGORIES' => implode('</th><th>', $categories), |
451 | |
452 | 'L_ACL_TYPE' => $l_acl_type, |
453 | |
454 | 'S_LOCAL' => ($local) ? true : false, |
455 | 'S_GLOBAL' => (!$local) ? true : false, |
456 | 'S_NUM_CATS' => count($categories), |
457 | 'S_VIEW' => ($mode == 'view') ? true : false, |
458 | 'S_NUM_OBJECTS' => count($content_array), |
459 | 'S_USER_MODE' => ($user_mode == 'user') ? true : false, |
460 | 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false) |
461 | ); |
462 | |
463 | foreach ($content_array as $ug_id => $ug_array) |
464 | { |
465 | // Build role dropdown options |
466 | $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0; |
467 | |
468 | $role_options = array(); |
469 | |
470 | $s_role_options = ''; |
471 | $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0; |
472 | |
473 | foreach ($roles as $role_id => $role_row) |
474 | { |
475 | $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']); |
476 | $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name']; |
477 | |
478 | $title = ($role_description) ? ' title="' . $role_description . '"' : ''; |
479 | $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>'; |
480 | |
481 | $role_options[] = array( |
482 | 'ID' => $role_id, |
483 | 'ROLE_NAME' => $role_name, |
484 | 'TITLE' => $role_description, |
485 | 'SELECTED' => $role_id == $current_role_id, |
486 | ); |
487 | } |
488 | |
489 | if ($s_role_options) |
490 | { |
491 | $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN'], ENT_COMPAT) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options; |
492 | } |
493 | |
494 | if (!$current_role_id && $mode != 'view') |
495 | { |
496 | $s_custom_permissions = false; |
497 | |
498 | foreach ($ug_array as $key => $value) |
499 | { |
500 | if ($value['S_NEVER'] || $value['S_YES']) |
501 | { |
502 | $s_custom_permissions = true; |
503 | break; |
504 | } |
505 | } |
506 | } |
507 | else |
508 | { |
509 | $s_custom_permissions = false; |
510 | } |
511 | |
512 | $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array( |
513 | 'NAME' => $ug_names_ary[$ug_id], |
514 | 'UG_ID' => $ug_id, |
515 | 'S_ROLE_OPTIONS' => $s_role_options, |
516 | 'S_CUSTOM' => $s_custom_permissions, |
517 | 'FORUM_ID' => $forum_id, |
518 | 'S_ROLE_ID' => $current_role_id, |
519 | )); |
520 | |
521 | $template->assign_block_vars_array($tpl_pmask . '.' . $tpl_fmask . '.role_options', $role_options); |
522 | |
523 | $this->assign_cat_array($ug_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace); |
524 | |
525 | unset($content_array[$ug_id]); |
526 | } |
527 | |
528 | unset($hold_ary[$forum_id]); |
529 | } |
530 | } |
531 | else |
532 | { |
533 | foreach ($ug_names_ary as $ug_id => $ug_name) |
534 | { |
535 | if (!isset($hold_ary[$ug_id])) |
536 | { |
537 | continue; |
538 | } |
539 | |
540 | $content_array = $categories = array(); |
541 | $this->build_permission_array($hold_ary[$ug_id], $content_array, $categories, array_keys($forum_names_ary)); |
542 | |
543 | $template->assign_block_vars($tpl_pmask, array( |
544 | 'NAME' => $ug_name, |
545 | 'CATEGORIES' => implode('</th><th>', $categories), |
546 | |
547 | 'USER_GROUPS_DEFAULT' => ($user_mode == 'user' && isset($user_groups_default[$ug_id]) && count($user_groups_default[$ug_id])) ? implode($user->lang['COMMA_SEPARATOR'], $user_groups_default[$ug_id]) : '', |
548 | 'USER_GROUPS_CUSTOM' => ($user_mode == 'user' && isset($user_groups_custom[$ug_id]) && count($user_groups_custom[$ug_id])) ? implode($user->lang['COMMA_SEPARATOR'], $user_groups_custom[$ug_id]) : '', |
549 | 'L_ACL_TYPE' => $l_acl_type, |
550 | |
551 | 'S_LOCAL' => ($local) ? true : false, |
552 | 'S_GLOBAL' => (!$local) ? true : false, |
553 | 'S_NUM_CATS' => count($categories), |
554 | 'S_VIEW' => ($mode == 'view') ? true : false, |
555 | 'S_NUM_OBJECTS' => count($content_array), |
556 | 'S_USER_MODE' => ($user_mode == 'user') ? true : false, |
557 | 'S_GROUP_MODE' => ($user_mode == 'group') ? true : false) |
558 | ); |
559 | |
560 | foreach ($content_array as $forum_id => $forum_array) |
561 | { |
562 | // Build role dropdown options |
563 | $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0; |
564 | |
565 | $role_options = array(); |
566 | |
567 | $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0; |
568 | $s_role_options = ''; |
569 | |
570 | foreach ($roles as $role_id => $role_row) |
571 | { |
572 | $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']); |
573 | $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name']; |
574 | |
575 | $title = ($role_description) ? ' title="' . $role_description . '"' : ''; |
576 | $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>'; |
577 | |
578 | $role_options[] = array( |
579 | 'ID' => $role_id, |
580 | 'ROLE_NAME' => $role_name, |
581 | 'TITLE' => $role_description, |
582 | 'SELECTED' => $role_id == $current_role_id, |
583 | ); |
584 | } |
585 | |
586 | if ($s_role_options) |
587 | { |
588 | $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN'], ENT_COMPAT) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options; |
589 | } |
590 | |
591 | if (!$current_role_id && $mode != 'view') |
592 | { |
593 | $s_custom_permissions = false; |
594 | |
595 | foreach ($forum_array as $key => $value) |
596 | { |
597 | if ($value['S_NEVER'] || $value['S_YES']) |
598 | { |
599 | $s_custom_permissions = true; |
600 | break; |
601 | } |
602 | } |
603 | } |
604 | else |
605 | { |
606 | $s_custom_permissions = false; |
607 | } |
608 | |
609 | $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array( |
610 | 'NAME' => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'], |
611 | 'PADDING' => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'], |
612 | 'S_CUSTOM' => $s_custom_permissions, |
613 | 'UG_ID' => $ug_id, |
614 | 'S_ROLE_OPTIONS' => $s_role_options, |
615 | 'FORUM_ID' => $forum_id) |
616 | ); |
617 | |
618 | $template->assign_block_vars_array($tpl_pmask . '.' . $tpl_fmask . '.role_options', $role_options); |
619 | |
620 | $this->assign_cat_array($forum_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace); |
621 | } |
622 | |
623 | unset($hold_ary[$ug_id], $ug_names_ary[$ug_id]); |
624 | } |
625 | } |
626 | } |
627 | |
628 | /** |
629 | * Display permission mask for roles |
630 | */ |
631 | function display_role_mask(&$hold_ary) |
632 | { |
633 | global $db, $template, $user, $phpbb_root_path, $phpEx; |
634 | global $phpbb_container; |
635 | |
636 | if (!count($hold_ary)) |
637 | { |
638 | return; |
639 | } |
640 | |
641 | /** @var \phpbb\group\helper $group_helper */ |
642 | $group_helper = $phpbb_container->get('group_helper'); |
643 | |
644 | // Get forum names |
645 | $sql = 'SELECT forum_id, forum_name |
646 | FROM ' . FORUMS_TABLE . ' |
647 | WHERE ' . $db->sql_in_set('forum_id', array_keys($hold_ary)) . ' |
648 | ORDER BY left_id'; |
649 | $result = $db->sql_query($sql); |
650 | |
651 | // If the role is used globally, then reflect that |
652 | $forum_names = (isset($hold_ary[0])) ? array(0 => '') : array(); |
653 | while ($row = $db->sql_fetchrow($result)) |
654 | { |
655 | $forum_names[$row['forum_id']] = $row['forum_name']; |
656 | } |
657 | $db->sql_freeresult($result); |
658 | |
659 | foreach ($forum_names as $forum_id => $forum_name) |
660 | { |
661 | $auth_ary = $hold_ary[$forum_id]; |
662 | |
663 | $template->assign_block_vars('role_mask', array( |
664 | 'NAME' => ($forum_id == 0) ? $user->lang['GLOBAL_MASK'] : $forum_name, |
665 | 'FORUM_ID' => $forum_id) |
666 | ); |
667 | |
668 | if (isset($auth_ary['users']) && count($auth_ary['users'])) |
669 | { |
670 | $sql = 'SELECT user_id, username |
671 | FROM ' . USERS_TABLE . ' |
672 | WHERE ' . $db->sql_in_set('user_id', $auth_ary['users']) . ' |
673 | ORDER BY username_clean ASC'; |
674 | $result = $db->sql_query($sql); |
675 | |
676 | while ($row = $db->sql_fetchrow($result)) |
677 | { |
678 | $template->assign_block_vars('role_mask.users', array( |
679 | 'USER_ID' => $row['user_id'], |
680 | 'USERNAME' => get_username_string('username', $row['user_id'], $row['username']), |
681 | 'U_PROFILE' => get_username_string('profile', $row['user_id'], $row['username']), |
682 | )); |
683 | } |
684 | $db->sql_freeresult($result); |
685 | } |
686 | |
687 | if (isset($auth_ary['groups']) && count($auth_ary['groups'])) |
688 | { |
689 | $sql = 'SELECT group_id, group_name, group_type |
690 | FROM ' . GROUPS_TABLE . ' |
691 | WHERE ' . $db->sql_in_set('group_id', $auth_ary['groups']) . ' |
692 | ORDER BY group_type ASC, group_name'; |
693 | $result = $db->sql_query($sql); |
694 | |
695 | while ($row = $db->sql_fetchrow($result)) |
696 | { |
697 | $template->assign_block_vars('role_mask.groups', array( |
698 | 'GROUP_ID' => $row['group_id'], |
699 | 'GROUP_NAME' => $group_helper->get_name($row['group_name']), |
700 | 'U_PROFILE' => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=group&g={$row['group_id']}")) |
701 | ); |
702 | } |
703 | $db->sql_freeresult($result); |
704 | } |
705 | } |
706 | } |
707 | |
708 | /** |
709 | * NOTE: this function is not in use atm |
710 | * Add a new option to the list ... $options is a hash of form -> |
711 | * $options = array( |
712 | * 'local' => array('option1', 'option2', ...), |
713 | * 'global' => array('optionA', 'optionB', ...) |
714 | * ); |
715 | */ |
716 | function acl_add_option($options) |
717 | { |
718 | global $db, $cache; |
719 | |
720 | if (!is_array($options)) |
721 | { |
722 | return false; |
723 | } |
724 | |
725 | $cur_options = array(); |
726 | |
727 | // Determine current options |
728 | $sql = 'SELECT auth_option, is_global, is_local |
729 | FROM ' . ACL_OPTIONS_TABLE . ' |
730 | ORDER BY auth_option_id'; |
731 | $result = $db->sql_query($sql); |
732 | |
733 | while ($row = $db->sql_fetchrow($result)) |
734 | { |
735 | $cur_options[$row['auth_option']] = ($row['is_global'] && $row['is_local']) ? 'both' : (($row['is_global']) ? 'global' : 'local'); |
736 | } |
737 | $db->sql_freeresult($result); |
738 | |
739 | // Here we need to insert new options ... this requires discovering whether |
740 | // an options is global, local or both and whether we need to add an permission |
741 | // set flag (x_) |
742 | $new_options = array('local' => array(), 'global' => array()); |
743 | |
744 | foreach ($options as $type => $option_ary) |
745 | { |
746 | $option_ary = array_unique($option_ary); |
747 | |
748 | foreach ($option_ary as $option_value) |
749 | { |
750 | $new_options[$type][] = $option_value; |
751 | |
752 | $flag = substr($option_value, 0, strpos($option_value, '_') + 1); |
753 | |
754 | if (!in_array($flag, $new_options[$type])) |
755 | { |
756 | $new_options[$type][] = $flag; |
757 | } |
758 | } |
759 | } |
760 | unset($options); |
761 | |
762 | $options = array(); |
763 | $options['local'] = array_diff($new_options['local'], $new_options['global']); |
764 | $options['global'] = array_diff($new_options['global'], $new_options['local']); |
765 | $options['both'] = array_intersect($new_options['local'], $new_options['global']); |
766 | |
767 | // Now check which options to add/update |
768 | $add_options = $update_options = array(); |
769 | |
770 | // First local ones... |
771 | foreach ($options as $type => $option_ary) |
772 | { |
773 | foreach ($option_ary as $option) |
774 | { |
775 | if (!isset($cur_options[$option])) |
776 | { |
777 | $add_options[] = array( |
778 | 'auth_option' => (string) $option, |
779 | 'is_global' => ($type == 'global' || $type == 'both') ? 1 : 0, |
780 | 'is_local' => ($type == 'local' || $type == 'both') ? 1 : 0 |
781 | ); |
782 | |
783 | continue; |
784 | } |
785 | |
786 | // Else, update existing entry if it is changed... |
787 | if ($type === $cur_options[$option]) |
788 | { |
789 | continue; |
790 | } |
791 | |
792 | // New type is always both: |
793 | // If is now both, we set both. |
794 | // If it was global the new one is local and we need to set it to both |
795 | // If it was local the new one is global and we need to set it to both |
796 | $update_options[] = $option; |
797 | } |
798 | } |
799 | |
800 | if (!empty($add_options)) |
801 | { |
802 | $db->sql_multi_insert(ACL_OPTIONS_TABLE, $add_options); |
803 | } |
804 | |
805 | if (!empty($update_options)) |
806 | { |
807 | $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . ' |
808 | SET is_global = 1, is_local = 1 |
809 | WHERE ' . $db->sql_in_set('auth_option', $update_options); |
810 | $db->sql_query($sql); |
811 | } |
812 | |
813 | $cache->destroy('_acl_options'); |
814 | $this->acl_clear_prefetch(); |
815 | |
816 | // Because we just changed the options and also purged the options cache, we instantly update/regenerate it for later calls to succeed. |
817 | $this->acl_options = array(); |
818 | $this->__construct(); |
819 | |
820 | return true; |
821 | } |
822 | |
823 | /** |
824 | * Set a user or group ACL record |
825 | */ |
826 | function acl_set($ug_type, $forum_id, $ug_id, $auth, $role_id = 0, $clear_prefetch = true) |
827 | { |
828 | global $db; |
829 | |
830 | // One or more forums |
831 | if (!is_array($forum_id)) |
832 | { |
833 | $forum_id = array($forum_id); |
834 | } |
835 | |
836 | // One or more users |
837 | if (!is_array($ug_id)) |
838 | { |
839 | $ug_id = array($ug_id); |
840 | } |
841 | |
842 | $ug_id_sql = $db->sql_in_set($ug_type . '_id', array_map('intval', $ug_id)); |
843 | $forum_sql = $db->sql_in_set('forum_id', array_map('intval', $forum_id)); |
844 | |
845 | // Instead of updating, inserting, removing we just remove all current settings and re-set everything... |
846 | $table = ($ug_type == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE; |
847 | $id_field = $ug_type . '_id'; |
848 | |
849 | // Get any flags as required |
850 | reset($auth); |
851 | $flag = key($auth); |
852 | $flag = substr($flag, 0, strpos($flag, '_') + 1); |
853 | |
854 | // This ID (the any-flag) is set if one or more permissions are true... |
855 | $any_option_id = (int) $this->acl_options['id'][$flag]; |
856 | |
857 | // Remove any-flag from auth ary |
858 | if (isset($auth[$flag])) |
859 | { |
860 | unset($auth[$flag]); |
861 | } |
862 | |
863 | // Remove current auth options... |
864 | $auth_option_ids = array((int) $any_option_id); |
865 | foreach ($auth as $auth_option => $auth_setting) |
866 | { |
867 | $auth_option_ids[] = (int) $this->acl_options['id'][$auth_option]; |
868 | } |
869 | |
870 | $sql = "DELETE FROM $table |
871 | WHERE $forum_sql |
872 | AND $ug_id_sql |
873 | AND " . $db->sql_in_set('auth_option_id', $auth_option_ids); |
874 | $db->sql_query($sql); |
875 | |
876 | // Remove those having a role assigned... the correct type of course... |
877 | $sql = 'SELECT role_id |
878 | FROM ' . ACL_ROLES_TABLE . " |
879 | WHERE role_type = '" . $db->sql_escape($flag) . "'"; |
880 | $result = $db->sql_query($sql); |
881 | |
882 | $role_ids = array(); |
883 | while ($row = $db->sql_fetchrow($result)) |
884 | { |
885 | $role_ids[] = $row['role_id']; |
886 | } |
887 | $db->sql_freeresult($result); |
888 | |
889 | if (count($role_ids)) |
890 | { |
891 | $sql = "DELETE FROM $table |
892 | WHERE $forum_sql |
893 | AND $ug_id_sql |
894 | AND auth_option_id = 0 |
895 | AND " . $db->sql_in_set('auth_role_id', $role_ids); |
896 | $db->sql_query($sql); |
897 | } |
898 | |
899 | // Ok, include the any-flag if one or more auth options are set to yes... |
900 | foreach ($auth as $auth_option => $setting) |
901 | { |
902 | if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER)) |
903 | { |
904 | $auth[$flag] = ACL_YES; |
905 | } |
906 | } |
907 | |
908 | $sql_ary = array(); |
909 | foreach ($forum_id as $forum) |
910 | { |
911 | $forum = (int) $forum; |
912 | |
913 | if ($role_id) |
914 | { |
915 | foreach ($ug_id as $id) |
916 | { |
917 | $sql_ary[] = array( |
918 | $id_field => (int) $id, |
919 | 'forum_id' => (int) $forum, |
920 | 'auth_option_id' => 0, |
921 | 'auth_setting' => 0, |
922 | 'auth_role_id' => (int) $role_id, |
923 | ); |
924 | } |
925 | } |
926 | else |
927 | { |
928 | foreach ($auth as $auth_option => $setting) |
929 | { |
930 | $auth_option_id = (int) $this->acl_options['id'][$auth_option]; |
931 | |
932 | if ($setting != ACL_NO) |
933 | { |
934 | foreach ($ug_id as $id) |
935 | { |
936 | $sql_ary[] = array( |
937 | $id_field => (int) $id, |
938 | 'forum_id' => (int) $forum, |
939 | 'auth_option_id' => (int) $auth_option_id, |
940 | 'auth_setting' => (int) $setting |
941 | ); |
942 | } |
943 | } |
944 | } |
945 | } |
946 | } |
947 | |
948 | $db->sql_multi_insert($table, $sql_ary); |
949 | |
950 | if ($clear_prefetch) |
951 | { |
952 | $this->acl_clear_prefetch(); |
953 | } |
954 | } |
955 | |
956 | /** |
957 | * Set a role-specific ACL record |
958 | */ |
959 | function acl_set_role($role_id, $auth) |
960 | { |
961 | global $db; |
962 | |
963 | // Get any-flag as required |
964 | reset($auth); |
965 | $flag = key($auth); |
966 | $flag = substr($flag, 0, strpos($flag, '_') + 1); |
967 | |
968 | // Remove any-flag from auth ary |
969 | if (isset($auth[$flag])) |
970 | { |
971 | unset($auth[$flag]); |
972 | } |
973 | |
974 | // Re-set any flag... |
975 | foreach ($auth as $auth_option => $setting) |
976 | { |
977 | if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER)) |
978 | { |
979 | $auth[$flag] = ACL_YES; |
980 | } |
981 | } |
982 | |
983 | $sql_ary = array(); |
984 | foreach ($auth as $auth_option => $setting) |
985 | { |
986 | $auth_option_id = (int) $this->acl_options['id'][$auth_option]; |
987 | |
988 | if ($setting != ACL_NO) |
989 | { |
990 | $sql_ary[] = array( |
991 | 'role_id' => (int) $role_id, |
992 | 'auth_option_id' => (int) $auth_option_id, |
993 | 'auth_setting' => (int) $setting |
994 | ); |
995 | } |
996 | } |
997 | |
998 | // If no data is there, we set the any-flag to ACL_NEVER... |
999 | if (!count($sql_ary)) |
1000 | { |
1001 | $sql_ary[] = array( |
1002 | 'role_id' => (int) $role_id, |
1003 | 'auth_option_id' => (int) $this->acl_options['id'][$flag], |
1004 | 'auth_setting' => ACL_NEVER |
1005 | ); |
1006 | } |
1007 | |
1008 | // Remove current auth options... |
1009 | $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' |
1010 | WHERE role_id = ' . $role_id; |
1011 | $db->sql_query($sql); |
1012 | |
1013 | // Now insert the new values |
1014 | $db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary); |
1015 | |
1016 | $this->acl_clear_prefetch(); |
1017 | } |
1018 | |
1019 | /** |
1020 | * Remove local permission |
1021 | */ |
1022 | function acl_delete($mode, $ug_id = false, $forum_id = false, $permission_type = false) |
1023 | { |
1024 | global $db; |
1025 | |
1026 | if ($ug_id === false && $forum_id === false) |
1027 | { |
1028 | return; |
1029 | } |
1030 | |
1031 | $option_id_ary = array(); |
1032 | $table = ($mode == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE; |
1033 | $id_field = $mode . '_id'; |
1034 | |
1035 | $where_sql = array(); |
1036 | |
1037 | if ($forum_id !== false) |
1038 | { |
1039 | $where_sql[] = (!is_array($forum_id)) ? 'forum_id = ' . (int) $forum_id : $db->sql_in_set('forum_id', array_map('intval', $forum_id)); |
1040 | } |
1041 | |
1042 | if ($ug_id !== false) |
1043 | { |
1044 | $where_sql[] = (!is_array($ug_id)) ? $id_field . ' = ' . (int) $ug_id : $db->sql_in_set($id_field, array_map('intval', $ug_id)); |
1045 | } |
1046 | |
1047 | // There seem to be auth options involved, therefore we need to go through the list and make sure we capture roles correctly |
1048 | if ($permission_type !== false) |
1049 | { |
1050 | // Get permission type |
1051 | $sql = 'SELECT auth_option, auth_option_id |
1052 | FROM ' . ACL_OPTIONS_TABLE . " |
1053 | WHERE auth_option " . $db->sql_like_expression($permission_type . $db->get_any_char()); |
1054 | $result = $db->sql_query($sql); |
1055 | |
1056 | $auth_id_ary = array(); |
1057 | while ($row = $db->sql_fetchrow($result)) |
1058 | { |
1059 | $option_id_ary[] = $row['auth_option_id']; |
1060 | $auth_id_ary[$row['auth_option']] = ACL_NO; |
1061 | } |
1062 | $db->sql_freeresult($result); |
1063 | |
1064 | // First of all, lets grab the items having roles with the specified auth options assigned |
1065 | $sql = "SELECT auth_role_id, $id_field, forum_id |
1066 | FROM $table, " . ACL_ROLES_TABLE . " r |
1067 | WHERE auth_role_id <> 0 |
1068 | AND auth_role_id = r.role_id |
1069 | AND r.role_type = '{$permission_type}' |
1070 | AND " . implode(' AND ', $where_sql) . ' |
1071 | ORDER BY auth_role_id'; |
1072 | $result = $db->sql_query($sql); |
1073 | |
1074 | $cur_role_auth = array(); |
1075 | while ($row = $db->sql_fetchrow($result)) |
1076 | { |
1077 | $cur_role_auth[$row['auth_role_id']][$row['forum_id']][] = $row[$id_field]; |
1078 | } |
1079 | $db->sql_freeresult($result); |
1080 | |
1081 | // Get role data for resetting data |
1082 | if (count($cur_role_auth)) |
1083 | { |
1084 | $sql = 'SELECT ao.auth_option, rd.role_id, rd.auth_setting |
1085 | FROM ' . ACL_OPTIONS_TABLE . ' ao, ' . ACL_ROLES_DATA_TABLE . ' rd |
1086 | WHERE ao.auth_option_id = rd.auth_option_id |
1087 | AND ' . $db->sql_in_set('rd.role_id', array_keys($cur_role_auth)); |
1088 | $result = $db->sql_query($sql); |
1089 | |
1090 | $auth_settings = array(); |
1091 | while ($row = $db->sql_fetchrow($result)) |
1092 | { |
1093 | // We need to fill all auth_options, else setting it will fail... |
1094 | if (!isset($auth_settings[$row['role_id']])) |
1095 | { |
1096 | $auth_settings[$row['role_id']] = $auth_id_ary; |
1097 | } |
1098 | $auth_settings[$row['role_id']][$row['auth_option']] = $row['auth_setting']; |
1099 | } |
1100 | $db->sql_freeresult($result); |
1101 | |
1102 | // Set the options |
1103 | foreach ($cur_role_auth as $role_id => $auth_row) |
1104 | { |
1105 | foreach ($auth_row as $f_id => $ug_row) |
1106 | { |
1107 | $this->acl_set($mode, $f_id, $ug_row, $auth_settings[$role_id], 0, false); |
1108 | } |
1109 | } |
1110 | } |
1111 | } |
1112 | |
1113 | // Now, normally remove permissions... |
1114 | if ($permission_type !== false) |
1115 | { |
1116 | $where_sql[] = $db->sql_in_set('auth_option_id', array_map('intval', $option_id_ary)); |
1117 | } |
1118 | |
1119 | $sql = "DELETE FROM $table |
1120 | WHERE " . implode(' AND ', $where_sql); |
1121 | $db->sql_query($sql); |
1122 | |
1123 | $this->acl_clear_prefetch(); |
1124 | } |
1125 | |
1126 | /** |
1127 | * Assign category to template |
1128 | * used by display_mask() |
1129 | */ |
1130 | function assign_cat_array(&$category_array, $tpl_cat, $tpl_mask, $ug_id, $forum_id, $s_view, $show_trace = false) |
1131 | { |
1132 | global $template, $phpbb_admin_path, $phpEx, $phpbb_container; |
1133 | |
1134 | /** @var \phpbb\permissions $phpbb_permissions */ |
1135 | $phpbb_permissions = $phpbb_container->get('acl.permissions'); |
1136 | |
1137 | $order = array_flip(array_keys($phpbb_permissions->get_permissions())); |
1138 | |
1139 | foreach ($category_array as $cat => $cat_array) |
1140 | { |
1141 | if (!$phpbb_permissions->category_defined($cat)) |
1142 | { |
1143 | continue; |
1144 | } |
1145 | |
1146 | $template->assign_block_vars($tpl_cat, array( |
1147 | 'S_YES' => ($cat_array['S_YES'] && !$cat_array['S_NEVER'] && !$cat_array['S_NO']) ? true : false, |
1148 | 'S_NEVER' => ($cat_array['S_NEVER'] && !$cat_array['S_YES'] && !$cat_array['S_NO']) ? true : false, |
1149 | 'S_NO' => ($cat_array['S_NO'] && !$cat_array['S_NEVER'] && !$cat_array['S_YES']) ? true : false, |
1150 | |
1151 | 'CAT_NAME' => $phpbb_permissions->get_category_lang($cat), |
1152 | )); |
1153 | |
1154 | $permissions = array_filter($cat_array['permissions'], [$phpbb_permissions, 'permission_defined'], ARRAY_FILTER_USE_KEY); |
1155 | |
1156 | uksort($permissions, function($a, $b) use ($order) { |
1157 | return $order[$a] <=> $order[$b]; |
1158 | }); |
1159 | |
1160 | foreach ($permissions as $permission => $allowed) |
1161 | { |
1162 | if ($s_view) |
1163 | { |
1164 | $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array( |
1165 | 'S_YES' => ($allowed == ACL_YES) ? true : false, |
1166 | 'S_NEVER' => ($allowed == ACL_NEVER) ? true : false, |
1167 | |
1168 | 'UG_ID' => $ug_id, |
1169 | 'FORUM_ID' => $forum_id, |
1170 | 'FIELD_NAME' => $permission, |
1171 | 'S_FIELD_NAME' => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']', |
1172 | |
1173 | 'U_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission") : '', |
1174 | 'UA_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission", false) : '', |
1175 | |
1176 | 'PERMISSION' => $phpbb_permissions->get_permission_lang($permission), |
1177 | )); |
1178 | } |
1179 | else |
1180 | { |
1181 | $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array( |
1182 | 'S_YES' => ($allowed == ACL_YES) ? true : false, |
1183 | 'S_NEVER' => ($allowed == ACL_NEVER) ? true : false, |
1184 | 'S_NO' => ($allowed == ACL_NO) ? true : false, |
1185 | |
1186 | 'UG_ID' => $ug_id, |
1187 | 'FORUM_ID' => $forum_id, |
1188 | 'FIELD_NAME' => $permission, |
1189 | 'S_FIELD_NAME' => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']', |
1190 | |
1191 | 'U_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission") : '', |
1192 | 'UA_TRACE' => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission", false) : '', |
1193 | |
1194 | 'PERMISSION' => $phpbb_permissions->get_permission_lang($permission), |
1195 | )); |
1196 | } |
1197 | } |
1198 | } |
1199 | } |
1200 | |
1201 | /** |
1202 | * Building content array from permission rows with explicit key ordering |
1203 | * used by display_mask() |
1204 | */ |
1205 | function build_permission_array(&$permission_row, &$content_array, &$categories, $key_sort_array) |
1206 | { |
1207 | global $phpbb_container; |
1208 | |
1209 | /** @var \phpbb\permissions $phpbb_permissions */ |
1210 | $phpbb_permissions = $phpbb_container->get('acl.permissions'); |
1211 | |
1212 | $order = array_flip(array_keys($phpbb_permissions->get_permissions())); |
1213 | |
1214 | foreach ($key_sort_array as $forum_id) |
1215 | { |
1216 | if (!isset($permission_row[$forum_id])) |
1217 | { |
1218 | continue; |
1219 | } |
1220 | |
1221 | $permissions = array_filter($permission_row[$forum_id], [$phpbb_permissions, 'permission_defined'], ARRAY_FILTER_USE_KEY); |
1222 | |
1223 | uksort($permissions, function($a, $b) use ($order) { |
1224 | return $order[$a] <=> $order[$b]; |
1225 | }); |
1226 | |
1227 | foreach ($permissions as $permission => $auth_setting) |
1228 | { |
1229 | $cat = $phpbb_permissions->get_permission_category($permission); |
1230 | |
1231 | // Build our categories array |
1232 | if (!isset($categories[$cat])) |
1233 | { |
1234 | $categories[$cat] = $phpbb_permissions->get_category_lang($cat); |
1235 | } |
1236 | |
1237 | // Build our content array |
1238 | if (!isset($content_array[$forum_id])) |
1239 | { |
1240 | $content_array[$forum_id] = array(); |
1241 | } |
1242 | |
1243 | if (!isset($content_array[$forum_id][$cat])) |
1244 | { |
1245 | $content_array[$forum_id][$cat] = array( |
1246 | 'S_YES' => false, |
1247 | 'S_NEVER' => false, |
1248 | 'S_NO' => false, |
1249 | 'permissions' => array(), |
1250 | ); |
1251 | } |
1252 | |
1253 | $content_array[$forum_id][$cat]['S_YES'] |= ($auth_setting == ACL_YES) ? true : false; |
1254 | $content_array[$forum_id][$cat]['S_NEVER'] |= ($auth_setting == ACL_NEVER) ? true : false; |
1255 | $content_array[$forum_id][$cat]['S_NO'] |= ($auth_setting == ACL_NO) ? true : false; |
1256 | |
1257 | $content_array[$forum_id][$cat]['permissions'][$permission] = $auth_setting; |
1258 | } |
1259 | } |
1260 | } |
1261 | |
1262 | /** |
1263 | * Use permissions from another user. This transferes a permission set from one user to another. |
1264 | * The other user is always able to revert back to his permission set. |
1265 | * This function does not check for lower/higher permissions, it is possible for the user to gain |
1266 | * "more" permissions by this. |
1267 | * Admin permissions will not be copied. |
1268 | */ |
1269 | function ghost_permissions($from_user_id, $to_user_id) |
1270 | { |
1271 | global $db; |
1272 | |
1273 | if ($to_user_id == ANONYMOUS) |
1274 | { |
1275 | return false; |
1276 | } |
1277 | |
1278 | $hold_ary = $this->acl_raw_data_single_user($from_user_id); |
1279 | |
1280 | // Key 0 in $hold_ary are global options, all others are forum_ids |
1281 | |
1282 | // We disallow copying admin permissions |
1283 | foreach ($this->acl_options['global'] as $opt => $id) |
1284 | { |
1285 | if (strpos($opt, 'a_') === 0) |
1286 | { |
1287 | $hold_ary[0][$this->acl_options['id'][$opt]] = ACL_NEVER; |
1288 | } |
1289 | } |
1290 | |
1291 | // Force a_switchperm to be allowed |
1292 | $hold_ary[0][$this->acl_options['id']['a_switchperm']] = ACL_YES; |
1293 | |
1294 | $user_permissions = $this->build_bitstring($hold_ary); |
1295 | |
1296 | if (!$user_permissions) |
1297 | { |
1298 | return false; |
1299 | } |
1300 | |
1301 | $sql = 'UPDATE ' . USERS_TABLE . " |
1302 | SET user_permissions = '" . $db->sql_escape($user_permissions) . "', |
1303 | user_perm_from = $from_user_id |
1304 | WHERE user_id = " . $to_user_id; |
1305 | $db->sql_query($sql); |
1306 | |
1307 | return true; |
1308 | } |
1309 | } |