Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 686
0.00% covered (danger)
0.00%
0 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
acp_permissions
0.00% covered (danger)
0.00%
0 / 684
0.00% covered (danger)
0.00%
0 / 12
78680
0.00% covered (danger)
0.00%
0 / 1
 main
0.00% covered (danger)
0.00%
0 / 301
0.00% covered (danger)
0.00%
0 / 1
16512
 build_subforum_options
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
72
 build_permission_dropdown
0.00% covered (danger)
0.00%
0 / 9
0.00% covered (danger)
0.00%
0 / 1
20
 check_existence
0.00% covered (danger)
0.00%
0 / 24
0.00% covered (danger)
0.00%
0 / 1
56
 set_permissions
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 1
272
 set_all_permissions
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
210
 check_assigned_role
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
 remove_permissions
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
132
 log_action
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
156
 permission_trace
0.00% covered (danger)
0.00%
0 / 134
0.00% covered (danger)
0.00%
0 / 1
3306
 copy_forum_permissions
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 1
30
 retrieve_defined_user_groups
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 1
182
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*/
17if (!defined('IN_PHPBB'))
18{
19    exit;
20}
21
22class acp_permissions
23{
24    var $u_action;
25    var $permission_dropdown;
26
27    /**
28     * @var $phpbb_permissions \phpbb\permissions
29     */
30    protected $permissions;
31
32    function main($id, $mode)
33    {
34        global $db, $user, $auth, $template, $phpbb_container, $request;
35        global $config, $phpbb_root_path, $phpEx;
36
37        if (!function_exists('user_get_id_name'))
38        {
39            include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
40        }
41
42        if (!class_exists('auth_admin'))
43        {
44            include($phpbb_root_path . 'includes/acp/auth.' . $phpEx);
45        }
46
47        $auth_admin = new auth_admin();
48
49        $user->add_lang('acp/permissions');
50        add_permission_language();
51
52        $this->tpl_name = 'acp_permissions';
53
54        $this->permissions = $phpbb_container->get('acl.permissions');
55
56        // Trace has other vars
57        if ($mode == 'trace')
58        {
59            $user_id = $request->variable('u', 0);
60            $forum_id = $request->variable('f', 0);
61            $permission = $request->variable('auth', '');
62
63            $this->tpl_name = 'permission_trace';
64
65            if ($user_id && isset($auth_admin->acl_options['id'][$permission]) && $auth->acl_get('a_viewauth'))
66            {
67                $this->page_title = sprintf($user->lang['TRACE_PERMISSION'], $this->permissions->get_permission_lang($permission));
68                $this->permission_trace($user_id, $forum_id, $permission);
69                return;
70            }
71            trigger_error('NO_MODE', E_USER_ERROR);
72        }
73
74        // Copy forum permissions
75        if ($mode == 'setting_forum_copy')
76        {
77            $this->tpl_name = 'permission_forum_copy';
78
79            if ($auth->acl_get('a_fauth') && $auth->acl_get('a_authusers') && $auth->acl_get('a_authgroups') && $auth->acl_get('a_mauth'))
80            {
81                $this->page_title = 'ACP_FORUM_PERMISSIONS_COPY';
82                $this->copy_forum_permissions();
83                return;
84            }
85
86            trigger_error('NO_MODE', E_USER_ERROR);
87        }
88
89        // Set some vars
90        $action = $request->variable('action', array('' => 0));
91        $action = key($action);
92        $action = (isset($_POST['psubmit'])) ? 'apply_permissions' : $action;
93
94        $all_forums = $request->variable('all_forums', 0);
95        $subforum_id = $request->variable('subforum_id', 0);
96        $forum_id = $request->variable('forum_id', array(0));
97
98        $username = $request->variable('username', array(''), true);
99        $usernames = $request->variable('usernames', '', true);
100        $user_id = $request->variable('user_id', array(0));
101
102        $group_id = $request->variable('group_id', array(0));
103        $select_all_groups = $request->variable('select_all_groups', 0);
104
105        $form_name = 'acp_permissions';
106        add_form_key($form_name);
107
108        // If select all groups is set, we pre-build the group id array (this option is used for other screens to link to the permission settings screen)
109        if ($select_all_groups)
110        {
111            // Add default groups to selection
112            $sql_and = (!$config['coppa_enable']) ? " AND group_name <> 'REGISTERED_COPPA'" : '';
113
114            $sql = 'SELECT group_id
115                FROM ' . GROUPS_TABLE . '
116                WHERE group_type = ' . GROUP_SPECIAL . "
117                $sql_and";
118            $result = $db->sql_query($sql);
119
120            while ($row = $db->sql_fetchrow($result))
121            {
122                $group_id[] = $row['group_id'];
123            }
124            $db->sql_freeresult($result);
125        }
126
127        // Map usernames to ids and vice versa
128        if ($usernames)
129        {
130            $username = explode("\n", $usernames);
131        }
132        unset($usernames);
133
134        if (count($username) && !count($user_id))
135        {
136            user_get_id_name($user_id, $username);
137
138            if (!count($user_id))
139            {
140                trigger_error($user->lang['SELECTED_USER_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING);
141            }
142        }
143        unset($username);
144
145        // Build forum ids (of all forums are checked or subforum listing used)
146        if ($all_forums)
147        {
148            $sql = 'SELECT forum_id
149                FROM ' . FORUMS_TABLE . '
150                ORDER BY left_id';
151            $result = $db->sql_query($sql);
152
153            $forum_id = array();
154            while ($row = $db->sql_fetchrow($result))
155            {
156                $forum_id[] = (int) $row['forum_id'];
157            }
158            $db->sql_freeresult($result);
159        }
160        else if ($subforum_id)
161        {
162            $forum_id = array();
163            foreach (get_forum_branch($subforum_id, 'children') as $row)
164            {
165                $forum_id[] = (int) $row['forum_id'];
166            }
167        }
168
169        // Define some common variables for every mode
170        $permission_scope = (strpos($mode, '_global') !== false) ? 'global' : 'local';
171
172        // Showing introductionary page?
173        if ($mode == 'intro')
174        {
175            $this->page_title = 'ACP_PERMISSIONS';
176
177            $template->assign_vars(array(
178                'S_INTRO'        => true)
179            );
180
181            return;
182        }
183
184        switch ($mode)
185        {
186            case 'setting_user_global':
187            case 'setting_group_global':
188                $this->permission_dropdown = array('u_', 'm_', 'a_');
189                $permission_victim = ($mode == 'setting_user_global') ? array('user') : array('group');
190                $this->page_title = ($mode == 'setting_user_global') ? 'ACP_USERS_PERMISSIONS' : 'ACP_GROUPS_PERMISSIONS';
191            break;
192
193            case 'setting_user_local':
194            case 'setting_group_local':
195                $this->permission_dropdown = array('f_', 'm_');
196                $permission_victim = ($mode == 'setting_user_local') ? array('user', 'forums') : array('group', 'forums');
197                $this->page_title = ($mode == 'setting_user_local') ? 'ACP_USERS_FORUM_PERMISSIONS' : 'ACP_GROUPS_FORUM_PERMISSIONS';
198            break;
199
200            case 'setting_admin_global':
201            case 'setting_mod_global':
202                $this->permission_dropdown = (strpos($mode, '_admin_') !== false) ? array('a_') : array('m_');
203                $permission_victim = array('usergroup');
204                $this->page_title = ($mode == 'setting_admin_global') ? 'ACP_ADMINISTRATORS' : 'ACP_GLOBAL_MODERATORS';
205            break;
206
207            case 'setting_mod_local':
208            case 'setting_forum_local':
209                $this->permission_dropdown = ($mode == 'setting_mod_local') ? array('m_') : array('f_');
210                $permission_victim = array('forums', 'usergroup');
211                $this->page_title = ($mode == 'setting_mod_local') ? 'ACP_FORUM_MODERATORS' : 'ACP_FORUM_PERMISSIONS';
212            break;
213
214            case 'view_admin_global':
215            case 'view_user_global':
216            case 'view_mod_global':
217                $this->permission_dropdown = ($mode == 'view_admin_global') ? array('a_') : (($mode == 'view_user_global') ? array('u_') : array('m_'));
218                $permission_victim = array('usergroup_view');
219                $this->page_title = ($mode == 'view_admin_global') ? 'ACP_VIEW_ADMIN_PERMISSIONS' : (($mode == 'view_user_global') ? 'ACP_VIEW_USER_PERMISSIONS' : 'ACP_VIEW_GLOBAL_MOD_PERMISSIONS');
220            break;
221
222            case 'view_mod_local':
223            case 'view_forum_local':
224                $this->permission_dropdown = ($mode == 'view_mod_local') ? array('m_') : array('f_');
225                $permission_victim = array('forums', 'usergroup_view');
226                $this->page_title = ($mode == 'view_mod_local') ? 'ACP_VIEW_FORUM_MOD_PERMISSIONS' : 'ACP_VIEW_FORUM_PERMISSIONS';
227            break;
228
229            default:
230                trigger_error('NO_MODE', E_USER_ERROR);
231            break;
232        }
233
234        $template->assign_vars(array(
235            'L_TITLE'        => $user->lang[$this->page_title],
236            'L_EXPLAIN'        => $user->lang[$this->page_title . '_EXPLAIN'])
237        );
238
239        // Get permission type
240        $permission_type = $request->variable('type', $this->permission_dropdown[0]);
241
242        if (!in_array($permission_type, $this->permission_dropdown))
243        {
244            trigger_error($user->lang['WRONG_PERMISSION_TYPE'] . adm_back_link($this->u_action), E_USER_WARNING);
245        }
246
247        // Handle actions
248        if (strpos($mode, 'setting_') === 0 && $action)
249        {
250            switch ($action)
251            {
252                case 'delete':
253                    if (confirm_box(true))
254                    {
255                        // All users/groups selected?
256                        $all_users = (isset($_POST['all_users'])) ? true : false;
257                        $all_groups = (isset($_POST['all_groups'])) ? true : false;
258
259                        if ($all_users || $all_groups)
260                        {
261                            $items = $this->retrieve_defined_user_groups($permission_scope, $forum_id, $permission_type);
262
263                            if ($all_users && count($items['user_ids']))
264                            {
265                                $user_id = $items['user_ids'];
266                            }
267                            else if ($all_groups && count($items['group_ids']))
268                            {
269                                $group_id = $items['group_ids'];
270                            }
271                        }
272
273                        if (count($user_id) || count($group_id))
274                        {
275                            $this->remove_permissions($mode, $permission_type, $auth_admin, $user_id, $group_id, $forum_id);
276                        }
277                        else
278                        {
279                            trigger_error($user->lang['NO_USER_GROUP_SELECTED'] . adm_back_link($this->u_action), E_USER_WARNING);
280                        }
281                    }
282                    else
283                    {
284                        if (isset($_POST['cancel']))
285                        {
286                            $u_redirect = $this->u_action . '&amp;type=' . $permission_type;
287                            foreach ($forum_id as $fid)
288                            {
289                                $u_redirect .= '&amp;forum_id[]=' . $fid;
290                            }
291                            redirect($u_redirect);
292                        }
293
294                        $s_hidden_fields = array(
295                            'i'                => $id,
296                            'mode'            => $mode,
297                            'action'        => array($action => 1),
298                            'user_id'        => $user_id,
299                            'group_id'        => $group_id,
300                            'forum_id'        => $forum_id,
301                            'type'            => $permission_type,
302                        );
303                        if (isset($_POST['all_users']))
304                        {
305                            $s_hidden_fields['all_users'] = 1;
306                        }
307                        if (isset($_POST['all_groups']))
308                        {
309                            $s_hidden_fields['all_groups'] = 1;
310                        }
311                        confirm_box(false, $user->lang['CONFIRM_OPERATION'], build_hidden_fields($s_hidden_fields));
312                    }
313                break;
314
315                case 'apply_permissions':
316                    if (!isset($_POST['setting']))
317                    {
318                        send_status_line(403, 'Forbidden');
319                        trigger_error($user->lang['NO_AUTH_SETTING_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING);
320                    }
321                    if (!check_form_key($form_name))
322                    {
323                        trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING);
324                    }
325
326                    $this->set_permissions($mode, $permission_type, $auth_admin, $user_id, $group_id);
327                break;
328
329                case 'apply_all_permissions':
330                    if (!isset($_POST['setting']))
331                    {
332                        send_status_line(403, 'Forbidden');
333                        trigger_error($user->lang['NO_AUTH_SETTING_FOUND'] . adm_back_link($this->u_action), E_USER_WARNING);
334                    }
335                    if (!check_form_key($form_name))
336                    {
337                        trigger_error($user->lang['FORM_INVALID']. adm_back_link($this->u_action), E_USER_WARNING);
338                    }
339
340                    $this->set_all_permissions($mode, $permission_type, $auth_admin, $user_id, $group_id);
341                break;
342            }
343        }
344
345        // Go through the screens/options needed and present them in correct order
346        foreach ($permission_victim as $victim)
347        {
348            switch ($victim)
349            {
350                case 'forum_dropdown':
351
352                    if (count($forum_id))
353                    {
354                        $this->check_existence('forum', $forum_id);
355                        continue 2;
356                    }
357
358                    $template->assign_vars(array(
359                        'S_SELECT_FORUM'        => true,
360                        'S_FORUM_OPTIONS'        => make_forum_select(false, false, true, false, false))
361                    );
362
363                break;
364
365                case 'forums':
366
367                    if (count($forum_id))
368                    {
369                        $this->check_existence('forum', $forum_id);
370                        continue 2;
371                    }
372
373                    $forum_list = make_forum_select(false, false, true, false, false, false, true);
374
375                    // Build forum options
376                    $s_forum_options = '';
377                    foreach ($forum_list as $f_id => $f_row)
378                    {
379                        $s_forum_options .= '<option value="' . $f_id . '"' . (($f_row['selected']) ? ' selected="selected"' : '') . (($f_row['disabled']) ? ' disabled="disabled" class="disabled-option"' : '') . '>' . $f_row['padding'] . $f_row['forum_name'] . '</option>';
380                    }
381
382                    // Build subforum options
383                    $s_subforum_options = $this->build_subforum_options($forum_list);
384
385                    $template->assign_vars(array(
386                        'S_SELECT_FORUM'        => true,
387                        'S_FORUM_OPTIONS'        => $s_forum_options,
388                        'S_SUBFORUM_OPTIONS'    => $s_subforum_options,
389                        'S_FORUM_ALL'            => true,
390                        'S_FORUM_MULTIPLE'        => true)
391                    );
392
393                break;
394
395                case 'user':
396
397                    if (count($user_id))
398                    {
399                        $this->check_existence('user', $user_id);
400                        continue 2;
401                    }
402
403                    $template->assign_vars(array(
404                        'S_SELECT_USER'            => true,
405                        'U_FIND_USERNAME'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&amp;form=select_victim&amp;field=username&amp;select_single=true'),
406                    ));
407
408                break;
409
410                case 'group':
411
412                    if (count($group_id))
413                    {
414                        $this->check_existence('group', $group_id);
415                        continue 2;
416                    }
417
418                    $template->assign_vars(array(
419                        'S_SELECT_GROUP'        => true,
420                        'S_GROUP_OPTIONS'        => group_select_options(false, false, false), // Show all groups
421                    ));
422
423                break;
424
425                case 'usergroup':
426                case 'usergroup_view':
427
428                    $all_users = (isset($_POST['all_users'])) ? true : false;
429                    $all_groups = (isset($_POST['all_groups'])) ? true : false;
430
431                    if ((count($user_id) && !$all_users) || (count($group_id) && !$all_groups))
432                    {
433                        if (count($user_id))
434                        {
435                            $this->check_existence('user', $user_id);
436                        }
437
438                        if (count($group_id))
439                        {
440                            $this->check_existence('group', $group_id);
441                        }
442
443                        continue 2;
444                    }
445
446                    // Now we check the users... because the "all"-selection is different here (all defined users/groups)
447                    $items = $this->retrieve_defined_user_groups($permission_scope, $forum_id, $permission_type);
448
449                    if ($all_users && count($items['user_ids']))
450                    {
451                        $user_id = $items['user_ids'];
452                        continue 2;
453                    }
454
455                    if ($all_groups && count($items['group_ids']))
456                    {
457                        $group_id = $items['group_ids'];
458                        continue 2;
459                    }
460
461                    $template->assign_vars(array(
462                        'S_SELECT_USERGROUP'        => ($victim == 'usergroup') ? true : false,
463                        'S_SELECT_USERGROUP_VIEW'    => ($victim == 'usergroup_view') ? true : false,
464                        'S_DEFINED_USER_OPTIONS'    => $items['user_ids_options'],
465                        'S_DEFINED_GROUP_OPTIONS'    => $items['group_ids_options'],
466                        'S_ADD_GROUP_OPTIONS'        => group_select_options(false, $items['group_ids'], false),    // Show all groups
467                        'U_FIND_USERNAME'            => append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=searchuser&amp;form=add_user&amp;field=username&amp;select_single=true'),
468                    ));
469
470                break;
471            }
472
473            // The S_ALLOW_SELECT parameter below is a measure to lower memory usage.
474            // If there are more than 5 forums selected the admin is not able to select all users/groups too.
475            // We need to see if the number of forums can be increased or need to be decreased.
476
477            // Setting permissions screen
478            $s_hidden_fields = build_hidden_fields(array(
479                    'user_id'        => $user_id,
480                    'group_id'        => $group_id,
481                    'forum_id'        => $forum_id,
482                    'type'            => $permission_type,
483            ));
484
485            $template->assign_vars(array(
486                'U_ACTION'                => $this->u_action,
487                'ANONYMOUS_USER_ID'        => ANONYMOUS,
488
489                'S_SELECT_VICTIM'        => true,
490                'S_ALLOW_ALL_SELECT'    => (count($forum_id) > 5) ? false : true,
491                'S_CAN_SELECT_USER'        => ($auth->acl_get('a_authusers')) ? true : false,
492                'S_CAN_SELECT_GROUP'    => ($auth->acl_get('a_authgroups')) ? true : false,
493                'S_HIDDEN_FIELDS'        => $s_hidden_fields)
494            );
495
496            // Let the forum names being displayed
497            if (count($forum_id))
498            {
499                $sql = 'SELECT forum_name
500                    FROM ' . FORUMS_TABLE . '
501                    WHERE ' . $db->sql_in_set('forum_id', $forum_id) . '
502                    ORDER BY left_id ASC';
503                $result = $db->sql_query($sql);
504
505                $forum_names = array();
506                while ($row = $db->sql_fetchrow($result))
507                {
508                    $forum_names[] = $row['forum_name'];
509                }
510                $db->sql_freeresult($result);
511
512                $template->assign_vars(array(
513                    'S_FORUM_NAMES'        => (count($forum_names)) ? true : false,
514                    'FORUM_NAMES'        => implode($user->lang['COMMA_SEPARATOR'], $forum_names))
515                );
516            }
517
518            return;
519        }
520
521        // Setting permissions screen
522        $s_hidden_fields = build_hidden_fields(array(
523                'user_id'        => $user_id,
524                'group_id'        => $group_id,
525                'forum_id'        => $forum_id,
526                'type'            => $permission_type,
527        ));
528
529        // Do not allow forum_ids being set and no other setting defined (will bog down the server too much)
530        if (count($forum_id) && !count($user_id) && !count($group_id))
531        {
532            trigger_error($user->lang['ONLY_FORUM_DEFINED'] . adm_back_link($this->u_action), E_USER_WARNING);
533        }
534
535        $template->assign_vars(array(
536            'S_PERMISSION_DROPDOWN'        => (count($this->permission_dropdown) > 1) ? $this->build_permission_dropdown($this->permission_dropdown, $permission_type, $permission_scope) : false,
537            'L_PERMISSION_TYPE'            => $this->permissions->get_type_lang($permission_type),
538
539            'U_ACTION'                    => $this->u_action,
540            'S_HIDDEN_FIELDS'            => $s_hidden_fields)
541        );
542
543        if (strpos($mode, 'setting_') === 0)
544        {
545            $template->assign_vars(array(
546                'S_SETTING_PERMISSIONS'        => true)
547            );
548
549            $hold_ary = $auth_admin->get_mask('set', (count($user_id)) ? $user_id : false, (count($group_id)) ? $group_id : false, (count($forum_id)) ? $forum_id : false, $permission_type, $permission_scope, ACL_NO);
550            $auth_admin->display_mask('set', $permission_type, $hold_ary, ((count($user_id)) ? 'user' : 'group'), (($permission_scope == 'local') ? true : false));
551        }
552        else
553        {
554            $template->assign_vars(array(
555                'S_VIEWING_PERMISSIONS'        => true)
556            );
557
558            $hold_ary = $auth_admin->get_mask('view', (count($user_id)) ? $user_id : false, (count($group_id)) ? $group_id : false, (count($forum_id)) ? $forum_id : false, $permission_type, $permission_scope, ACL_NEVER);
559            $auth_admin->display_mask('view', $permission_type, $hold_ary, ((count($user_id)) ? 'user' : 'group'), (($permission_scope == 'local') ? true : false));
560        }
561    }
562
563    /**
564    * Build +subforum options
565    */
566    function build_subforum_options($forum_list)
567    {
568        global $user;
569
570        $s_options = '';
571
572        $forum_list = array_merge($forum_list);
573
574        foreach ($forum_list as $key => $row)
575        {
576            if ($row['disabled'])
577            {
578                continue;
579            }
580
581            $s_options .= '<option value="' . $row['forum_id'] . '"' . (($row['selected']) ? ' selected="selected"' : '') . '>' . $row['padding'] . $row['forum_name'];
582
583            // We check if a branch is there...
584            $branch_there = false;
585
586            foreach (array_slice($forum_list, $key + 1) as $temp_row)
587            {
588                if ($temp_row['left_id'] > $row['left_id'] && $temp_row['left_id'] < $row['right_id'])
589                {
590                    $branch_there = true;
591                    break;
592                }
593                continue;
594            }
595
596            if ($branch_there)
597            {
598                $s_options .= ' [' . $user->lang['PLUS_SUBFORUMS'] . ']';
599            }
600
601            $s_options .= '</option>';
602        }
603
604        return $s_options;
605    }
606
607    /**
608    * Build dropdown field for changing permission types
609    */
610    function build_permission_dropdown($options, $default_option, $permission_scope)
611    {
612        global $auth;
613
614        $s_dropdown_options = '';
615        foreach ($options as $setting)
616        {
617            if (!$auth->acl_get('a_' . str_replace('_', '', $setting) . 'auth'))
618            {
619                continue;
620            }
621
622            $selected = ($setting == $default_option) ? ' selected="selected"' : '';
623            $l_setting = $this->permissions->get_type_lang($setting, $permission_scope);
624            $s_dropdown_options .= '<option value="' . $setting . '"' . $selected . '>' . $l_setting . '</option>';
625        }
626
627        return $s_dropdown_options;
628    }
629
630    /**
631    * Check if selected items exist. Remove not found ids and if empty return error.
632    */
633    function check_existence($mode, &$ids)
634    {
635        global $db, $user;
636
637        switch ($mode)
638        {
639            case 'user':
640                $table = USERS_TABLE;
641                $sql_id = 'user_id';
642            break;
643
644            case 'group':
645                $table = GROUPS_TABLE;
646                $sql_id = 'group_id';
647            break;
648
649            case 'forum':
650                $table = FORUMS_TABLE;
651                $sql_id = 'forum_id';
652            break;
653        }
654
655        if (count($ids))
656        {
657            $sql = "SELECT $sql_id
658                FROM $table
659                WHERE " . $db->sql_in_set($sql_id, $ids);
660            $result = $db->sql_query($sql);
661
662            $ids = array();
663            while ($row = $db->sql_fetchrow($result))
664            {
665                $ids[] = (int) $row[$sql_id];
666            }
667            $db->sql_freeresult($result);
668        }
669
670        if (!count($ids))
671        {
672            trigger_error($user->lang['SELECTED_' . strtoupper($mode) . '_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING);
673        }
674    }
675
676    /**
677    * Apply permissions
678    */
679    function set_permissions($mode, $permission_type, $auth_admin, &$user_id, &$group_id)
680    {
681        global $db, $cache, $user, $auth;
682        global $request, $phpbb_container;
683
684        $psubmit = $request->variable('psubmit', array(0 => array(0 => 0)));
685
686        // User or group to be set?
687        $ug_type = (count($user_id)) ? 'user' : 'group';
688
689        // Check the permission setting again
690        if (!$auth->acl_get('a_' . str_replace('_', '', $permission_type) . 'auth') || !$auth->acl_get('a_auth' . $ug_type . 's'))
691        {
692            send_status_line(403, 'Forbidden');
693            trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
694        }
695
696        // We loop through the auth settings defined in our submit
697        $ug_id = key($psubmit);
698        $forum_id = key($psubmit[$ug_id]);
699
700        $settings = $request->variable('setting', array(0 => array(0 => array('' => 0))), false, \phpbb\request\request_interface::POST);
701        if (empty($settings) || empty($settings[$ug_id]) || empty($settings[$ug_id][$forum_id]))
702        {
703            trigger_error('WRONG_PERMISSION_SETTING_FORMAT', E_USER_WARNING);
704        }
705
706        $auth_settings = $settings[$ug_id][$forum_id];
707
708        // Do we have a role we want to set?
709        $roles = $request->variable('role', array(0 => array(0 => 0)), false, \phpbb\request\request_interface::POST);
710        $assigned_role = (isset($roles[$ug_id][$forum_id])) ? (int) $roles[$ug_id][$forum_id] : 0;
711
712        // Do the admin want to set these permissions to other items too?
713        $inherit = $request->variable('inherit', array(0 => array(0)));
714
715        $ug_id = array($ug_id);
716        $forum_id = array($forum_id);
717
718        if (count($inherit))
719        {
720            foreach ($inherit as $_ug_id => $forum_id_ary)
721            {
722                // Inherit users/groups?
723                if (!in_array($_ug_id, $ug_id))
724                {
725                    $ug_id[] = $_ug_id;
726                }
727
728                // Inherit forums?
729                $forum_id = array_merge($forum_id, array_keys($forum_id_ary));
730            }
731        }
732
733        $forum_id = array_unique($forum_id);
734
735        // If the auth settings differ from the assigned role, then do not set a role...
736        if ($assigned_role)
737        {
738            if (!$this->check_assigned_role($assigned_role, $auth_settings))
739            {
740                $assigned_role = 0;
741            }
742        }
743
744        // Update the permission set...
745        $auth_admin->acl_set($ug_type, $forum_id, $ug_id, $auth_settings, $assigned_role);
746
747        // Do we need to recache the moderator lists?
748        if ($permission_type == 'm_')
749        {
750            phpbb_cache_moderators($db, $phpbb_container->get('dbal.tools'), $cache, $auth);
751        }
752
753        // Remove users who are now moderators or admins from everyones foes list
754        if ($permission_type == 'm_' || $permission_type == 'a_')
755        {
756            phpbb_update_foes($db, $auth, $group_id, $user_id);
757        }
758
759        $this->log_action($mode, 'add', $permission_type, $ug_type, $ug_id, $forum_id);
760
761        meta_refresh(5, $this->u_action);
762        trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action));
763    }
764
765    /**
766    * Apply all permissions
767    */
768    function set_all_permissions($mode, $permission_type, $auth_admin, &$user_id, &$group_id)
769    {
770        global $db, $cache, $user, $auth;
771        global $request, $phpbb_container;
772
773        // User or group to be set?
774        $ug_type = (count($user_id)) ? 'user' : 'group';
775
776        // Check the permission setting again
777        if (!$auth->acl_get('a_' . str_replace('_', '', $permission_type) . 'auth') || !$auth->acl_get('a_auth' . $ug_type . 's'))
778        {
779            send_status_line(403, 'Forbidden');
780            trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
781        }
782
783        $auth_settings = $request->variable('setting', array(0 => array(0 => array('' => 0))), false, \phpbb\request\request_interface::POST);
784        $auth_roles = $request->variable('role', array(0 => array(0 => 0)), false, \phpbb\request\request_interface::POST);
785        $ug_ids = $forum_ids = array();
786
787        // We need to go through the auth settings
788        foreach ($auth_settings as $ug_id => $forum_auth_row)
789        {
790            $ug_id = (int) $ug_id;
791            $ug_ids[] = $ug_id;
792
793            foreach ($forum_auth_row as $forum_id => $auth_options)
794            {
795                $forum_id = (int) $forum_id;
796                $forum_ids[] = $forum_id;
797
798                // Check role...
799                $assigned_role = (isset($auth_roles[$ug_id][$forum_id])) ? (int) $auth_roles[$ug_id][$forum_id] : 0;
800
801                // If the auth settings differ from the assigned role, then do not set a role...
802                if ($assigned_role)
803                {
804                    if (!$this->check_assigned_role($assigned_role, $auth_options))
805                    {
806                        $assigned_role = 0;
807                    }
808                }
809
810                // Update the permission set...
811                $auth_admin->acl_set($ug_type, $forum_id, $ug_id, $auth_options, $assigned_role, false);
812            }
813        }
814
815        $auth_admin->acl_clear_prefetch();
816
817        // Do we need to recache the moderator lists?
818        if ($permission_type == 'm_')
819        {
820            phpbb_cache_moderators($db, $phpbb_container->get('dbal.tools'), $cache, $auth);
821        }
822
823        // Remove users who are now moderators or admins from everyones foes list
824        if ($permission_type == 'm_' || $permission_type == 'a_')
825        {
826            phpbb_update_foes($db, $auth, $group_id, $user_id);
827        }
828
829        $this->log_action($mode, 'add', $permission_type, $ug_type, $ug_ids, $forum_ids);
830
831        if ($mode == 'setting_forum_local' || $mode == 'setting_mod_local')
832        {
833            meta_refresh(5, $this->u_action . '&amp;forum_id[]=' . implode('&amp;forum_id[]=', $forum_ids));
834            trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action . '&amp;forum_id[]=' . implode('&amp;forum_id[]=', $forum_ids)));
835        }
836        else
837        {
838            meta_refresh(5, $this->u_action);
839            trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action));
840        }
841    }
842
843    /**
844    * Compare auth settings with auth settings from role
845    * returns false if they differ, true if they are equal
846    */
847    function check_assigned_role($role_id, &$auth_settings)
848    {
849        global $db;
850
851        $sql = 'SELECT o.auth_option, r.auth_setting
852            FROM ' . ACL_OPTIONS_TABLE . ' o, ' . ACL_ROLES_DATA_TABLE . ' r
853            WHERE o.auth_option_id = r.auth_option_id
854                AND r.role_id = ' . $role_id;
855        $result = $db->sql_query($sql);
856
857        $test_auth_settings = array();
858        while ($row = $db->sql_fetchrow($result))
859        {
860            $test_auth_settings[$row['auth_option']] = $row['auth_setting'];
861        }
862        $db->sql_freeresult($result);
863
864        // We need to add any ACL_NO setting from auth_settings to compare correctly
865        foreach ($auth_settings as $option => $setting)
866        {
867            if ($setting == ACL_NO)
868            {
869                $test_auth_settings[$option] = $setting;
870            }
871        }
872
873        if (count(array_diff_assoc($auth_settings, $test_auth_settings)))
874        {
875            return false;
876        }
877
878        return true;
879    }
880
881    /**
882    * Remove permissions
883    */
884    function remove_permissions($mode, $permission_type, $auth_admin, &$user_id, &$group_id, &$forum_id)
885    {
886        global $user, $db, $cache, $auth, $phpbb_container;
887
888        // User or group to be set?
889        $ug_type = (count($user_id)) ? 'user' : 'group';
890
891        // Check the permission setting again
892        if (!$auth->acl_get('a_' . str_replace('_', '', $permission_type) . 'auth') || !$auth->acl_get('a_auth' . $ug_type . 's'))
893        {
894            send_status_line(403, 'Forbidden');
895            trigger_error($user->lang['NO_AUTH_OPERATION'] . adm_back_link($this->u_action), E_USER_WARNING);
896        }
897
898        $auth_admin->acl_delete($ug_type, (($ug_type == 'user') ? $user_id : $group_id), (count($forum_id) ? $forum_id : false), $permission_type);
899
900        // Do we need to recache the moderator lists?
901        if ($permission_type == 'm_')
902        {
903            phpbb_cache_moderators($db, $phpbb_container->get('dbal.tools'), $cache, $auth);
904        }
905
906        $this->log_action($mode, 'del', $permission_type, $ug_type, (($ug_type == 'user') ? $user_id : $group_id), (count($forum_id) ? $forum_id : array(0 => 0)));
907
908        if ($mode == 'setting_forum_local' || $mode == 'setting_mod_local')
909        {
910            meta_refresh(5, $this->u_action . '&amp;forum_id[]=' . implode('&amp;forum_id[]=', $forum_id));
911            trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action . '&amp;forum_id[]=' . implode('&amp;forum_id[]=', $forum_id)));
912        }
913        else
914        {
915            meta_refresh(5, $this->u_action);
916            trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action));
917        }
918    }
919
920    /**
921    * Log permission changes
922    */
923    function log_action($mode, $action, $permission_type, $ug_type, $ug_id, $forum_id)
924    {
925        global $db, $user, $phpbb_log, $phpbb_container;
926
927        if (!is_array($ug_id))
928        {
929            $ug_id = array($ug_id);
930        }
931
932        if (!is_array($forum_id))
933        {
934            $forum_id = array($forum_id);
935        }
936
937        // Logging ... first grab user or groupnames ...
938        $sql = ($ug_type == 'group') ? 'SELECT group_name as name, group_type FROM ' . GROUPS_TABLE . ' WHERE ' : 'SELECT username as name FROM ' . USERS_TABLE . ' WHERE ';
939        $sql .= $db->sql_in_set(($ug_type == 'group') ? 'group_id' : 'user_id', array_map('intval', $ug_id));
940        $result = $db->sql_query($sql);
941
942        /** @var \phpbb\group\helper $group_helper */
943        $group_helper = $phpbb_container->get('group_helper');
944
945        $l_ug_list = '';
946        while ($row = $db->sql_fetchrow($result))
947        {
948            $group_name = $group_helper->get_name($row['name']);
949            $l_ug_list .= (($l_ug_list != '') ? ', ' : '') . ((isset($row['group_type']) && $row['group_type'] == GROUP_SPECIAL) ? '<span class="sep">' . $group_name . '</span>' : $group_name);
950        }
951        $db->sql_freeresult($result);
952
953        $mode = str_replace('setting_', '', $mode);
954
955        if ($forum_id[0] == 0)
956        {
957            $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ACL_' . strtoupper($action) . '_' . strtoupper($mode) . '_' . strtoupper($permission_type), false, array($l_ug_list));
958        }
959        else
960        {
961            // Grab the forum details if non-zero forum_id
962            $sql = 'SELECT forum_name
963                FROM ' . FORUMS_TABLE . '
964                WHERE ' . $db->sql_in_set('forum_id', $forum_id);
965            $result = $db->sql_query($sql);
966
967            $l_forum_list = '';
968            while ($row = $db->sql_fetchrow($result))
969            {
970                $l_forum_list .= (($l_forum_list != '') ? ', ' : '') . $row['forum_name'];
971            }
972            $db->sql_freeresult($result);
973
974            $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ACL_' . strtoupper($action) . '_' . strtoupper($mode) . '_' . strtoupper($permission_type), false, array($l_forum_list, $l_ug_list));
975        }
976    }
977
978    /**
979    * Display a complete trace tree for the selected permission to determine where settings are set/unset
980    */
981    function permission_trace($user_id, $forum_id, $permission)
982    {
983        global $db, $template, $user, $auth, $request, $phpbb_container;
984
985        if ($user_id != $user->data['user_id'])
986        {
987            $userdata = $auth->obtain_user_data($user_id);
988        }
989        else
990        {
991            $userdata = $user->data;
992        }
993
994        if (!$userdata)
995        {
996            trigger_error('NO_USERS', E_USER_ERROR);
997        }
998
999        /** @var \phpbb\group\helper $group_helper */
1000        $group_helper = $phpbb_container->get('group_helper');
1001
1002        $forum_name = false;
1003
1004        if ($forum_id)
1005        {
1006            $sql = 'SELECT forum_name
1007                FROM ' . FORUMS_TABLE . "
1008                WHERE forum_id = $forum_id";
1009            $result = $db->sql_query($sql, 3600);
1010            $forum_name = $db->sql_fetchfield('forum_name');
1011            $db->sql_freeresult($result);
1012        }
1013
1014        $back = $request->variable('back', 0);
1015
1016        $template->assign_vars(array(
1017            'PERMISSION'            => $this->permissions->get_permission_lang($permission),
1018            'PERMISSION_USERNAME'    => $userdata['username'],
1019            'FORUM_NAME'            => $forum_name,
1020
1021            'S_GLOBAL_TRACE'        => ($forum_id) ? false : true,
1022
1023            'U_BACK'                => ($back) ? build_url(array('f', 'back')) . "&amp;f=$back" : '')
1024        );
1025
1026        $template->assign_block_vars('trace', array(
1027            'WHO'            => $user->lang['DEFAULT'],
1028            'INFORMATION'    => $user->lang['TRACE_DEFAULT'],
1029
1030            'S_SETTING_NO'        => true,
1031            'S_TOTAL_NO'        => true)
1032        );
1033
1034        $sql = 'SELECT DISTINCT g.group_name, g.group_id, g.group_type
1035            FROM ' . GROUPS_TABLE . ' g
1036                LEFT JOIN ' . USER_GROUP_TABLE . ' ug ON (ug.group_id = g.group_id)
1037            WHERE ug.user_id = ' . $user_id . '
1038                AND ug.user_pending = 0
1039                AND NOT (ug.group_leader = 1 AND g.group_skip_auth = 1)
1040            ORDER BY g.group_type DESC, g.group_id DESC';
1041        $result = $db->sql_query($sql);
1042
1043        $groups = array();
1044        while ($row = $db->sql_fetchrow($result))
1045        {
1046            $groups[$row['group_id']] = array(
1047                'auth_setting'        => ACL_NO,
1048                'group_name'        => $group_helper->get_name($row['group_name']),
1049            );
1050        }
1051        $db->sql_freeresult($result);
1052
1053        $total = ACL_NO;
1054        $add_key = (($forum_id) ? '_LOCAL' : '');
1055
1056        if (count($groups))
1057        {
1058            // Get group auth settings
1059            $hold_ary = $auth->acl_group_raw_data(array_keys($groups), $permission, $forum_id);
1060
1061            foreach ($hold_ary as $group_id => $forum_ary)
1062            {
1063                $groups[$group_id]['auth_setting'] = $forum_ary[$forum_id][$permission];
1064            }
1065            unset($hold_ary);
1066
1067            foreach ($groups as $row)
1068            {
1069                switch ($row['auth_setting'])
1070                {
1071                    case ACL_NO:
1072                        $information = $user->lang['TRACE_GROUP_NO' . $add_key];
1073                    break;
1074
1075                    case ACL_YES:
1076                        $information = ($total == ACL_YES) ? $user->lang['TRACE_GROUP_YES_TOTAL_YES' . $add_key] : (($total == ACL_NEVER) ? $user->lang['TRACE_GROUP_YES_TOTAL_NEVER' . $add_key] : $user->lang['TRACE_GROUP_YES_TOTAL_NO' . $add_key]);
1077                        $total = ($total == ACL_NO) ? ACL_YES : $total;
1078                    break;
1079
1080                    case ACL_NEVER:
1081                        $information = ($total == ACL_YES) ? $user->lang['TRACE_GROUP_NEVER_TOTAL_YES' . $add_key] : (($total == ACL_NEVER) ? $user->lang['TRACE_GROUP_NEVER_TOTAL_NEVER' . $add_key] : $user->lang['TRACE_GROUP_NEVER_TOTAL_NO' . $add_key]);
1082                        $total = ACL_NEVER;
1083                    break;
1084                }
1085
1086                $template->assign_block_vars('trace', array(
1087                    'WHO'            => $row['group_name'],
1088                    'INFORMATION'    => $information,
1089
1090                    'S_SETTING_NO'        => ($row['auth_setting'] == ACL_NO) ? true : false,
1091                    'S_SETTING_YES'        => ($row['auth_setting'] == ACL_YES) ? true : false,
1092                    'S_SETTING_NEVER'    => ($row['auth_setting'] == ACL_NEVER) ? true : false,
1093                    'S_TOTAL_NO'        => ($total == ACL_NO) ? true : false,
1094                    'S_TOTAL_YES'        => ($total == ACL_YES) ? true : false,
1095                    'S_TOTAL_NEVER'        => ($total == ACL_NEVER) ? true : false)
1096                );
1097            }
1098        }
1099
1100        // Get user specific permission... globally or for this forum
1101        $hold_ary = $auth->acl_user_raw_data($user_id, $permission, $forum_id);
1102        $auth_setting = (!count($hold_ary)) ? ACL_NO : $hold_ary[$user_id][$forum_id][$permission];
1103
1104        switch ($auth_setting)
1105        {
1106            case ACL_NO:
1107                $information = ($total == ACL_NO) ? $user->lang['TRACE_USER_NO_TOTAL_NO' . $add_key] : $user->lang['TRACE_USER_KEPT' . $add_key];
1108                $total = ($total == ACL_NO) ? ACL_NEVER : $total;
1109            break;
1110
1111            case ACL_YES:
1112                $information = ($total == ACL_YES) ? $user->lang['TRACE_USER_YES_TOTAL_YES' . $add_key] : (($total == ACL_NEVER) ? $user->lang['TRACE_USER_YES_TOTAL_NEVER' . $add_key] : $user->lang['TRACE_USER_YES_TOTAL_NO' . $add_key]);
1113                $total = ($total == ACL_NO) ? ACL_YES : $total;
1114            break;
1115
1116            case ACL_NEVER:
1117                $information = ($total == ACL_YES) ? $user->lang['TRACE_USER_NEVER_TOTAL_YES' . $add_key] : (($total == ACL_NEVER) ? $user->lang['TRACE_USER_NEVER_TOTAL_NEVER' . $add_key] : $user->lang['TRACE_USER_NEVER_TOTAL_NO' . $add_key]);
1118                $total = ACL_NEVER;
1119            break;
1120        }
1121
1122        $template->assign_block_vars('trace', array(
1123            'WHO'            => $userdata['username'],
1124            'INFORMATION'    => $information,
1125
1126            'S_SETTING_NO'        => ($auth_setting == ACL_NO) ? true : false,
1127            'S_SETTING_YES'        => ($auth_setting == ACL_YES) ? true : false,
1128            'S_SETTING_NEVER'    => ($auth_setting == ACL_NEVER) ? true : false,
1129            'S_TOTAL_NO'        => false,
1130            'S_TOTAL_YES'        => ($total == ACL_YES) ? true : false,
1131            'S_TOTAL_NEVER'        => ($total == ACL_NEVER) ? true : false)
1132        );
1133
1134        if ($forum_id != 0 && isset($auth->acl_options['global'][$permission]))
1135        {
1136            if ($user_id != $user->data['user_id'])
1137            {
1138                $auth2 = new \phpbb\auth\auth();
1139                $auth2->acl($userdata);
1140                $auth_setting = $auth2->acl_get($permission);
1141            }
1142            else
1143            {
1144                $auth_setting = $auth->acl_get($permission);
1145            }
1146
1147            if ($auth_setting)
1148            {
1149                $information = ($total == ACL_YES) ? $user->lang['TRACE_USER_GLOBAL_YES_TOTAL_YES'] : $user->lang['TRACE_USER_GLOBAL_YES_TOTAL_NEVER'];
1150                $total = ACL_YES;
1151            }
1152            else
1153            {
1154                $information = $user->lang['TRACE_USER_GLOBAL_NEVER_TOTAL_KEPT'];
1155            }
1156
1157            // If there is no auth information we do not need to worry the user by showing non-relevant data.
1158            if ($auth_setting)
1159            {
1160                $template->assign_block_vars('trace', array(
1161                    'WHO'            => sprintf($user->lang['TRACE_GLOBAL_SETTING'], $userdata['username']),
1162                    'INFORMATION'    => sprintf($information, '<a href="' . $this->u_action . "&amp;u=$user_id&amp;f=0&amp;auth=$permission&amp;back=$forum_id\">", '</a>'),
1163
1164                    'S_SETTING_NO'        => false,
1165                    'S_SETTING_YES'        => $auth_setting,
1166                    'S_SETTING_NEVER'    => !$auth_setting,
1167                    'S_TOTAL_NO'        => false,
1168                    'S_TOTAL_YES'        => ($total == ACL_YES) ? true : false,
1169                    'S_TOTAL_NEVER'        => ($total == ACL_NEVER) ? true : false)
1170                );
1171            }
1172        }
1173
1174        // Take founder status into account, overwriting the default values
1175        if ($userdata['user_type'] == USER_FOUNDER && strpos($permission, 'a_') === 0)
1176        {
1177            $template->assign_block_vars('trace', array(
1178                'WHO'            => $userdata['username'],
1179                'INFORMATION'    => $user->lang['TRACE_USER_FOUNDER'],
1180
1181                'S_SETTING_NO'        => ($auth_setting == ACL_NO) ? true : false,
1182                'S_SETTING_YES'        => ($auth_setting == ACL_YES) ? true : false,
1183                'S_SETTING_NEVER'    => ($auth_setting == ACL_NEVER) ? true : false,
1184                'S_TOTAL_NO'        => false,
1185                'S_TOTAL_YES'        => true,
1186                'S_TOTAL_NEVER'        => false)
1187            );
1188
1189            $total = ACL_YES;
1190        }
1191
1192        // Total value...
1193        $template->assign_vars(array(
1194            'S_RESULT_NO'        => ($total == ACL_NO) ? true : false,
1195            'S_RESULT_YES'        => ($total == ACL_YES) ? true : false,
1196            'S_RESULT_NEVER'    => ($total == ACL_NEVER) ? true : false,
1197        ));
1198    }
1199
1200    /**
1201    * Handles copying permissions from one forum to others
1202    */
1203    function copy_forum_permissions()
1204    {
1205        global $db, $auth, $cache, $phpbb_container, $template, $user, $request;
1206
1207        $user->add_lang('acp/forums');
1208
1209        $submit = isset($_POST['submit']) ? true : false;
1210
1211        if ($submit)
1212        {
1213            $src = $request->variable('src_forum_id', 0);
1214            $dest = $request->variable('dest_forum_ids', array(0));
1215
1216            if (confirm_box(true))
1217            {
1218                if (copy_forum_permissions($src, $dest))
1219                {
1220                    phpbb_cache_moderators($db, $phpbb_container->get('dbal.tools'), $cache, $auth);
1221
1222                    $auth->acl_clear_prefetch();
1223                    $cache->destroy('sql', FORUMS_TABLE);
1224
1225                    trigger_error($user->lang['AUTH_UPDATED'] . adm_back_link($this->u_action));
1226                }
1227                else
1228                {
1229                    trigger_error($user->lang['SELECTED_FORUM_NOT_EXIST'] . adm_back_link($this->u_action), E_USER_WARNING);
1230                }
1231            }
1232            else
1233            {
1234                $s_hidden_fields = array(
1235                    'submit'            => $submit,
1236                    'src_forum_id'        => $src,
1237                    'dest_forum_ids'    => $dest,
1238                );
1239
1240                $s_hidden_fields = build_hidden_fields($s_hidden_fields);
1241
1242                confirm_box(false, $user->lang['COPY_PERMISSIONS_CONFIRM'], $s_hidden_fields);
1243            }
1244        }
1245
1246        $template->assign_vars(array(
1247            'S_FORUM_OPTIONS' => make_forum_select(false, false, false, false, false),
1248        ));
1249    }
1250
1251    /**
1252    * Get already assigned users/groups
1253    */
1254    function retrieve_defined_user_groups($permission_scope, $forum_id, $permission_type)
1255    {
1256        global $db, $phpbb_container;
1257
1258        /** @var \phpbb\group\helper $group_helper */
1259        $group_helper = $phpbb_container->get('group_helper');
1260
1261        $sql_forum_id = ($permission_scope == 'global') ? 'AND a.forum_id = 0' : ((count($forum_id)) ? 'AND ' . $db->sql_in_set('a.forum_id', $forum_id) : 'AND a.forum_id <> 0');
1262
1263        // Permission options are only able to be a permission set... therefore we will pre-fetch the possible options and also the possible roles
1264        $option_ids = $role_ids = array();
1265
1266        $sql = 'SELECT auth_option_id
1267            FROM ' . ACL_OPTIONS_TABLE . '
1268            WHERE auth_option ' . $db->sql_like_expression($permission_type . $db->get_any_char());
1269        $result = $db->sql_query($sql);
1270
1271        while ($row = $db->sql_fetchrow($result))
1272        {
1273            $option_ids[] = (int) $row['auth_option_id'];
1274        }
1275        $db->sql_freeresult($result);
1276
1277        if (count($option_ids))
1278        {
1279            $sql = 'SELECT DISTINCT role_id
1280                FROM ' . ACL_ROLES_DATA_TABLE . '
1281                WHERE ' . $db->sql_in_set('auth_option_id', $option_ids);
1282            $result = $db->sql_query($sql);
1283
1284            while ($row = $db->sql_fetchrow($result))
1285            {
1286                $role_ids[] = (int) $row['role_id'];
1287            }
1288            $db->sql_freeresult($result);
1289        }
1290
1291        if (count($option_ids) && count($role_ids))
1292        {
1293            $sql_where = 'AND (' . $db->sql_in_set('a.auth_option_id', $option_ids) . ' OR ' . $db->sql_in_set('a.auth_role_id', $role_ids) . ')';
1294        }
1295        else if (count($role_ids))
1296        {
1297            $sql_where = 'AND ' . $db->sql_in_set('a.auth_role_id', $role_ids);
1298        }
1299        else if (count($option_ids))
1300        {
1301            $sql_where = 'AND ' . $db->sql_in_set('a.auth_option_id', $option_ids);
1302        }
1303
1304        // Not ideal, due to the filesort, non-use of indexes, etc.
1305        $sql = 'SELECT DISTINCT u.user_id, u.username, u.username_clean, u.user_regdate
1306            FROM ' . USERS_TABLE . ' u, ' . ACL_USERS_TABLE . " a
1307            WHERE u.user_id = a.user_id
1308                $sql_forum_id
1309                $sql_where
1310            ORDER BY u.username_clean, u.user_regdate ASC";
1311        $result = $db->sql_query($sql);
1312
1313        $s_defined_user_options = '';
1314        $defined_user_ids = array();
1315        while ($row = $db->sql_fetchrow($result))
1316        {
1317            $s_defined_user_options .= '<option value="' . $row['user_id'] . '">' . $row['username'] . '</option>';
1318            $defined_user_ids[] = $row['user_id'];
1319        }
1320        $db->sql_freeresult($result);
1321
1322        $sql = 'SELECT DISTINCT g.group_type, g.group_name, g.group_id
1323            FROM ' . GROUPS_TABLE . ' g, ' . ACL_GROUPS_TABLE . " a
1324            WHERE g.group_id = a.group_id
1325                $sql_forum_id
1326                $sql_where
1327            ORDER BY g.group_type DESC, g.group_name ASC";
1328        $result = $db->sql_query($sql);
1329
1330        $s_defined_group_options = '';
1331        $defined_group_ids = array();
1332        while ($row = $db->sql_fetchrow($result))
1333        {
1334            $s_defined_group_options .= '<option' . (($row['group_type'] == GROUP_SPECIAL) ? ' class="sep"' : '') . ' value="' . $row['group_id'] . '">' . $group_helper->get_name($row['group_name']) . '</option>';
1335            $defined_group_ids[] = $row['group_id'];
1336        }
1337        $db->sql_freeresult($result);
1338
1339        return array(
1340            'group_ids'            => $defined_group_ids,
1341            'group_ids_options'    => $s_defined_group_options,
1342            'user_ids'            => $defined_user_ids,
1343            'user_ids_options'    => $s_defined_user_options
1344        );
1345    }
1346}