Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

auth.php

Zuletzt modifiziert: 09.10.2024, 12:52 - Dateigröße: 38.56 KiB


 0001  <?php
 0002  /**
 0003  *
 0004  * This file is part of the phpBB Forum Software package.
 0005  *
 0006  * @copyright (c) phpBB Limited <https://www.phpbb.com>
 0007  * @license GNU General Public License, version 2 (GPL-2.0)
 0008  *
 0009  * For full copyright and license information, please see
 0010  * the docs/CREDITS.txt file.
 0011  *
 0012  */
 0013   
 0014  /**
 0015  * @ignore
 0016  */
 0017  if (!defined('IN_PHPBB'))
 0018  {
 0019      exit;
 0020  }
 0021   
 0022  /**
 0023  * ACP Permission/Auth class
 0024  */
 0025  class auth_admin extends \phpbb\auth\auth
 0026  {
 0027      /**
 0028      * Init auth settings
 0029      */
 0030      function auth_admin()
 0031      {
 0032          global $db, $cache;
 0033   
 0034          if (($this->acl_options = $cache->get('_acl_options')) === false)
 0035          {
 0036              $sql = 'SELECT auth_option_id, auth_option, is_global, is_local
 0037                  FROM ' . ACL_OPTIONS_TABLE . '
 0038                  ORDER BY auth_option_id';
 0039              $result = $db->sql_query($sql);
 0040   
 0041              $global = $local = 0;
 0042              $this->acl_options = array();
 0043              while ($row = $db->sql_fetchrow($result))
 0044              {
 0045                  if ($row['is_global'])
 0046                  {
 0047                      $this->acl_options['global'][$row['auth_option']] = $global++;
 0048                  }
 0049   
 0050                  if ($row['is_local'])
 0051                  {
 0052                      $this->acl_options['local'][$row['auth_option']] = $local++;
 0053                  }
 0054   
 0055                  $this->acl_options['id'][$row['auth_option']] = (int) $row['auth_option_id'];
 0056                  $this->acl_options['option'][(int) $row['auth_option_id']] = $row['auth_option'];
 0057              }
 0058              $db->sql_freeresult($result);
 0059   
 0060              $cache->put('_acl_options', $this->acl_options);
 0061          }
 0062      }
 0063   
 0064      /**
 0065      * Get permission mask
 0066      * This function only supports getting permissions of one type (for example a_)
 0067      *
 0068      * @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
 0069      * @param mixed $user_id user ids to search for (a user_id or a group_id has to be specified at least)
 0070      * @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)
 0071      * @param mixed $forum_id forum_ids to search for. Defining a forum id also means getting local settings
 0072      * @param string $auth_option the auth_option defines the permission setting to look for (a_ for example)
 0073      * @param local|global $scope the scope defines the permission scope. If local, a forum_id is additionally required
 0074      * @param ACL_NEVER|ACL_NO|ACL_YES $acl_fill defines the mode those permissions not set are getting filled with
 0075      */
 0076      function get_mask($mode, $user_id = false, $group_id = false, $forum_id = false, $auth_option = false, $scope = false, $acl_fill = ACL_NEVER)
 0077      {
 0078          global $db, $user;
 0079   
 0080          $hold_ary = array();
 0081          $view_user_mask = ($mode == 'view' && $group_id === false) ? true : false;
 0082   
 0083          if ($auth_option === false || $scope === false)
 0084          {
 0085              return array();
 0086          }
 0087   
 0088          $acl_user_function = ($mode == 'set') ? 'acl_user_raw_data' : 'acl_raw_data';
 0089   
 0090          if (!$view_user_mask)
 0091          {
 0092              if ($forum_id !== false)
 0093              {
 0094                  $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);
 0095              }
 0096              else
 0097              {
 0098                  $hold_ary = ($group_id !== false) ? $this->acl_group_raw_data($group_id, $auth_option . '%', ($scope == 'global') ? 0 : false) : $this->$acl_user_function($user_id, $auth_option . '%', ($scope == 'global') ? 0 : false);
 0099              }
 0100          }
 0101   
 0102          // Make sure hold_ary is filled with every setting (prevents missing forums/users/groups)
 0103          $ug_id = ($group_id !== false) ? ((!is_array($group_id)) ? array($group_id) : $group_id) : ((!is_array($user_id)) ? array($user_id) : $user_id);
 0104          $forum_ids = ($forum_id !== false) ? ((!is_array($forum_id)) ? array($forum_id) : $forum_id) : (($scope == 'global') ? array(0) : array());
 0105   
 0106          // Only those options we need
 0107          $compare_options = array_diff(preg_replace('/^((?!' . $auth_option . ').+)|(' . $auth_option . ')$/', '', array_keys($this->acl_options[$scope])), array(''));
 0108   
 0109          // If forum_ids is false and the scope is local we actually want to have all forums within the array
 0110          if ($scope == 'local' && !sizeof($forum_ids))
 0111          {
 0112              $sql = 'SELECT forum_id
 0113                  FROM ' . FORUMS_TABLE;
 0114              $result = $db->sql_query($sql, 120);
 0115   
 0116              while ($row = $db->sql_fetchrow($result))
 0117              {
 0118                  $forum_ids[] = (int) $row['forum_id'];
 0119              }
 0120              $db->sql_freeresult($result);
 0121          }
 0122   
 0123          if ($view_user_mask)
 0124          {
 0125              $auth2 = null;
 0126   
 0127              $sql = 'SELECT user_id, user_permissions, user_type
 0128                  FROM ' . USERS_TABLE . '
 0129                  WHERE ' . $db->sql_in_set('user_id', $ug_id);
 0130              $result = $db->sql_query($sql);
 0131   
 0132              while ($userdata = $db->sql_fetchrow($result))
 0133              {
 0134                  if ($user->data['user_id'] != $userdata['user_id'])
 0135                  {
 0136                      $auth2 = new \phpbb\auth\auth();
 0137                      $auth2->acl($userdata);
 0138                  }
 0139                  else
 0140                  {
 0141                      global $auth;
 0142                      $auth2 = &$auth;
 0143                  }
 0144   
 0145                  $hold_ary[$userdata['user_id']] = array();
 0146                  foreach ($forum_ids as $f_id)
 0147                  {
 0148                      $hold_ary[$userdata['user_id']][$f_id] = array();
 0149                      foreach ($compare_options as $option)
 0150                      {
 0151                          $hold_ary[$userdata['user_id']][$f_id][$option] = $auth2->acl_get($option, $f_id);
 0152                      }
 0153                  }
 0154              }
 0155              $db->sql_freeresult($result);
 0156   
 0157              unset($userdata);
 0158              unset($auth2);
 0159          }
 0160   
 0161          foreach ($ug_id as $_id)
 0162          {
 0163              if (!isset($hold_ary[$_id]))
 0164              {
 0165                  $hold_ary[$_id] = array();
 0166              }
 0167   
 0168              foreach ($forum_ids as $f_id)
 0169              {
 0170                  if (!isset($hold_ary[$_id][$f_id]))
 0171                  {
 0172                      $hold_ary[$_id][$f_id] = array();
 0173                  }
 0174              }
 0175          }
 0176   
 0177          // Now, we need to fill the gaps with $acl_fill. ;)
 0178   
 0179          // Now switch back to keys
 0180          if (sizeof($compare_options))
 0181          {
 0182              $compare_options = array_combine($compare_options, array_fill(1, sizeof($compare_options), $acl_fill));
 0183          }
 0184   
 0185          // Defining the user-function here to save some memory
 0186          $return_acl_fill = function () use ($acl_fill)
 0187          {
 0188              return $acl_fill;
 0189          };
 0190   
 0191          // Actually fill the gaps
 0192          if (sizeof($hold_ary))
 0193          {
 0194              foreach ($hold_ary as $ug_id => $row)
 0195              {
 0196                  foreach ($row as $id => $options)
 0197                  {
 0198                      // Do not include the global auth_option
 0199                      unset($options[$auth_option]);
 0200   
 0201                      // Not a "fine" solution, but at all it's a 1-dimensional
 0202                      // array_diff_key function filling the resulting array values with zeros
 0203                      // The differences get merged into $hold_ary (all permissions having $acl_fill set)
 0204                      $hold_ary[$ug_id][$id] = array_merge($options,
 0205   
 0206                          array_map($return_acl_fill,
 0207                              array_flip(
 0208                                  array_diff(
 0209                                      array_keys($compare_options), array_keys($options)
 0210                                  )
 0211                              )
 0212                          )
 0213                      );
 0214                  }
 0215              }
 0216          }
 0217          else
 0218          {
 0219              $hold_ary[($group_id !== false) ? $group_id : $user_id][(int) $forum_id] = $compare_options;
 0220          }
 0221   
 0222          return $hold_ary;
 0223      }
 0224   
 0225      /**
 0226      * Get permission mask for roles
 0227      * This function only supports getting masks for one role
 0228      */
 0229      function get_role_mask($role_id)
 0230      {
 0231          global $db;
 0232   
 0233          $hold_ary = array();
 0234   
 0235          // Get users having this role set...
 0236          $sql = 'SELECT user_id, forum_id
 0237              FROM ' . ACL_USERS_TABLE . '
 0238              WHERE auth_role_id = ' . $role_id . '
 0239              ORDER BY forum_id';
 0240          $result = $db->sql_query($sql);
 0241   
 0242          while ($row = $db->sql_fetchrow($result))
 0243          {
 0244              $hold_ary[$row['forum_id']]['users'][] = $row['user_id'];
 0245          }
 0246          $db->sql_freeresult($result);
 0247   
 0248          // Now grab groups...
 0249          $sql = 'SELECT group_id, forum_id
 0250              FROM ' . ACL_GROUPS_TABLE . '
 0251              WHERE auth_role_id = ' . $role_id . '
 0252              ORDER BY forum_id';
 0253          $result = $db->sql_query($sql);
 0254   
 0255          while ($row = $db->sql_fetchrow($result))
 0256          {
 0257              $hold_ary[$row['forum_id']]['groups'][] = $row['group_id'];
 0258          }
 0259          $db->sql_freeresult($result);
 0260   
 0261          return $hold_ary;
 0262      }
 0263   
 0264      /**
 0265      * Display permission mask (assign to template)
 0266      */
 0267      function display_mask($mode, $permission_type, &$hold_ary, $user_mode = 'user', $local = false, $group_display = true)
 0268      {
 0269          global $template, $user, $db, $phpbb_container;
 0270   
 0271          /* @var $phpbb_permissions \phpbb\permissions */
 0272          $phpbb_permissions = $phpbb_container->get('acl.permissions');
 0273   
 0274          /** @var \phpbb\group\helper $group_helper */
 0275          $group_helper = $phpbb_container->get('group_helper');
 0276   
 0277          // Define names for template loops, might be able to be set
 0278          $tpl_pmask = 'p_mask';
 0279          $tpl_fmask = 'f_mask';
 0280          $tpl_category = 'category';
 0281          $tpl_mask = 'mask';
 0282   
 0283          $l_acl_type = $phpbb_permissions->get_type_lang($permission_type, (($local) ? 'local' : 'global'));
 0284   
 0285          // Allow trace for viewing permissions and in user mode
 0286          $show_trace = ($mode == 'view' && $user_mode == 'user') ? true : false;
 0287   
 0288          // Get names
 0289          if ($user_mode == 'user')
 0290          {
 0291              $sql = 'SELECT user_id as ug_id, username as ug_name
 0292                  FROM ' . USERS_TABLE . '
 0293                  WHERE ' . $db->sql_in_set('user_id', array_keys($hold_ary)) . '
 0294                  ORDER BY username_clean ASC';
 0295          }
 0296          else
 0297          {
 0298              $sql = 'SELECT group_id as ug_id, group_name as ug_name, group_type
 0299                  FROM ' . GROUPS_TABLE . '
 0300                  WHERE ' . $db->sql_in_set('group_id', array_keys($hold_ary)) . '
 0301                  ORDER BY group_type DESC, group_name ASC';
 0302          }
 0303          $result = $db->sql_query($sql);
 0304   
 0305          $ug_names_ary = array();
 0306          while ($row = $db->sql_fetchrow($result))
 0307          {
 0308              $ug_names_ary[$row['ug_id']] = ($user_mode == 'user') ? $row['ug_name'] : $group_helper->get_name($row['ug_name']);
 0309          }
 0310          $db->sql_freeresult($result);
 0311   
 0312          // Get used forums
 0313          $forum_ids = array();
 0314          foreach ($hold_ary as $ug_id => $row)
 0315          {
 0316              $forum_ids = array_merge($forum_ids, array_keys($row));
 0317          }
 0318          $forum_ids = array_unique($forum_ids);
 0319   
 0320          $forum_names_ary = array();
 0321          if ($local)
 0322          {
 0323              $forum_names_ary = make_forum_select(false, false, true, false, false, false, true);
 0324   
 0325              // Remove the disabled ones, since we do not create an option field here...
 0326              foreach ($forum_names_ary as $key => $value)
 0327              {
 0328                  if (!$value['disabled'])
 0329                  {
 0330                      continue;
 0331                  }
 0332                  unset($forum_names_ary[$key]);
 0333              }
 0334          }
 0335          else
 0336          {
 0337              $forum_names_ary[0] = $l_acl_type;
 0338          }
 0339   
 0340          // Get available roles
 0341          $sql = 'SELECT *
 0342              FROM ' . ACL_ROLES_TABLE . "
 0343              WHERE role_type = '" . $db->sql_escape($permission_type) . "'
 0344              ORDER BY role_order ASC";
 0345          $result = $db->sql_query($sql);
 0346   
 0347          $roles = array();
 0348          while ($row = $db->sql_fetchrow($result))
 0349          {
 0350              $roles[$row['role_id']] = $row;
 0351          }
 0352          $db->sql_freeresult($result);
 0353   
 0354          $cur_roles = $this->acl_role_data($user_mode, $permission_type, array_keys($hold_ary));
 0355   
 0356          // Build js roles array (role data assignments)
 0357          $s_role_js_array = '';
 0358   
 0359          if (sizeof($roles))
 0360          {
 0361              $s_role_js_array = array();
 0362   
 0363              // Make sure every role (even if empty) has its array defined
 0364              foreach ($roles as $_role_id => $null)
 0365              {
 0366                  $s_role_js_array[$_role_id] = "\n" . 'role_options[' . $_role_id . '] = new Array();' . "\n";
 0367              }
 0368   
 0369              $sql = 'SELECT r.role_id, o.auth_option, r.auth_setting
 0370                  FROM ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' o
 0371                  WHERE o.auth_option_id = r.auth_option_id
 0372                      AND ' . $db->sql_in_set('r.role_id', array_keys($roles));
 0373              $result = $db->sql_query($sql);
 0374   
 0375              while ($row = $db->sql_fetchrow($result))
 0376              {
 0377                  $flag = substr($row['auth_option'], 0, strpos($row['auth_option'], '_') + 1);
 0378                  if ($flag == $row['auth_option'])
 0379                  {
 0380                      continue;
 0381                  }
 0382   
 0383                  $s_role_js_array[$row['role_id']] .= 'role_options[' . $row['role_id'] . '][\'' . addslashes($row['auth_option']) . '\'] = ' . $row['auth_setting'] . '; ';
 0384              }
 0385              $db->sql_freeresult($result);
 0386   
 0387              $s_role_js_array = implode('', $s_role_js_array);
 0388          }
 0389   
 0390          $template->assign_var('S_ROLE_JS_ARRAY', $s_role_js_array);
 0391          unset($s_role_js_array);
 0392   
 0393          // Now obtain memberships
 0394          $user_groups_default = $user_groups_custom = array();
 0395          if ($user_mode == 'user' && $group_display)
 0396          {
 0397              $sql = 'SELECT group_id, group_name, group_type
 0398                  FROM ' . GROUPS_TABLE . '
 0399                  ORDER BY group_type DESC, group_name ASC';
 0400              $result = $db->sql_query($sql);
 0401   
 0402              $groups = array();
 0403              while ($row = $db->sql_fetchrow($result))
 0404              {
 0405                  $groups[$row['group_id']] = $row;
 0406              }
 0407              $db->sql_freeresult($result);
 0408   
 0409              $memberships = group_memberships(false, array_keys($hold_ary), false);
 0410   
 0411              // User is not a member of any group? Bad admin, bad bad admin...
 0412              if ($memberships)
 0413              {
 0414                  foreach ($memberships as $row)
 0415                  {
 0416                      $user_groups_default[$row['user_id']][] = $group_helper->get_name($groups[$row['group_id']]['group_name']);
 0417                  }
 0418              }
 0419              unset($memberships, $groups);
 0420          }
 0421   
 0422          // If we only have one forum id to display or being in local mode and more than one user/group to display,
 0423          // we switch the complete interface to group by user/usergroup instead of grouping by forum
 0424          // To achieve this, we need to switch the array a bit
 0425          if (sizeof($forum_ids) == 1 || ($local && sizeof($ug_names_ary) > 1))
 0426          {
 0427              $hold_ary_temp = $hold_ary;
 0428              $hold_ary = array();
 0429              foreach ($hold_ary_temp as $ug_id => $row)
 0430              {
 0431                  foreach ($forum_names_ary as $forum_id => $forum_row)
 0432                  {
 0433                      if (isset($row[$forum_id]))
 0434                      {
 0435                          $hold_ary[$forum_id][$ug_id] = $row[$forum_id];
 0436                      }
 0437                  }
 0438              }
 0439              unset($hold_ary_temp);
 0440   
 0441              foreach ($hold_ary as $forum_id => $forum_array)
 0442              {
 0443                  $content_array = $categories = array();
 0444                  $this->build_permission_array($hold_ary[$forum_id], $content_array, $categories, array_keys($ug_names_ary));
 0445   
 0446                  $template->assign_block_vars($tpl_pmask, array(
 0447                      'NAME'            => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'],
 0448                      'PADDING'        => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'],
 0449   
 0450                      'CATEGORIES'    => implode('</th><th>', $categories),
 0451   
 0452                      'L_ACL_TYPE'    => $l_acl_type,
 0453   
 0454                      'S_LOCAL'        => ($local) ? true : false,
 0455                      'S_GLOBAL'        => (!$local) ? true : false,
 0456                      'S_NUM_CATS'    => sizeof($categories),
 0457                      'S_VIEW'        => ($mode == 'view') ? true : false,
 0458                      'S_NUM_OBJECTS'    => sizeof($content_array),
 0459                      'S_USER_MODE'    => ($user_mode == 'user') ? true : false,
 0460                      'S_GROUP_MODE'    => ($user_mode == 'group') ? true : false)
 0461                  );
 0462   
 0463                  @reset($content_array);
 0464                  while (list($ug_id, $ug_array) = each($content_array))
 0465                  {
 0466                      // Build role dropdown options
 0467                      $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
 0468   
 0469                      $role_options = array();
 0470   
 0471                      $s_role_options = '';
 0472                      $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
 0473   
 0474                      @reset($roles);
 0475                      while (list($role_id, $role_row) = each($roles))
 0476                      {
 0477                          $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']);
 0478                          $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name'];
 0479   
 0480                          $title = ($role_description) ? ' title="' . $role_description . '"' : '';
 0481                          $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>';
 0482   
 0483                          $role_options[] = array(
 0484                              'ID'    => $role_id,
 0485                              'ROLE_NAME'    => $role_name,
 0486                              'TITLE'        => $role_description,
 0487                              'SELECTED'    => $role_id == $current_role_id,
 0488                          );
 0489                      }
 0490   
 0491                      if ($s_role_options)
 0492                      {
 0493                          $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options;
 0494                      }
 0495   
 0496                      if (!$current_role_id && $mode != 'view')
 0497                      {
 0498                          $s_custom_permissions = false;
 0499   
 0500                          foreach ($ug_array as $key => $value)
 0501                          {
 0502                              if ($value['S_NEVER'] || $value['S_YES'])
 0503                              {
 0504                                  $s_custom_permissions = true;
 0505                                  break;
 0506                              }
 0507                          }
 0508                      }
 0509                      else
 0510                      {
 0511                          $s_custom_permissions = false;
 0512                      }
 0513   
 0514                      $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array(
 0515                          'NAME'                => $ug_names_ary[$ug_id],
 0516                          'UG_ID'                => $ug_id,
 0517                          'S_ROLE_OPTIONS'    => $s_role_options,
 0518                          'S_CUSTOM'            => $s_custom_permissions,
 0519                          'FORUM_ID'            => $forum_id,
 0520                          'S_ROLE_ID'            => $current_role_id,
 0521                      ));
 0522   
 0523                      $template->assign_block_vars_array($tpl_pmask . '.' . $tpl_fmask . '.role_options', $role_options);
 0524   
 0525                      $this->assign_cat_array($ug_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace);
 0526   
 0527                      unset($content_array[$ug_id]);
 0528                  }
 0529   
 0530                  unset($hold_ary[$forum_id]);
 0531              }
 0532          }
 0533          else
 0534          {
 0535              foreach ($ug_names_ary as $ug_id => $ug_name)
 0536              {
 0537                  if (!isset($hold_ary[$ug_id]))
 0538                  {
 0539                      continue;
 0540                  }
 0541   
 0542                  $content_array = $categories = array();
 0543                  $this->build_permission_array($hold_ary[$ug_id], $content_array, $categories, array_keys($forum_names_ary));
 0544   
 0545                  $template->assign_block_vars($tpl_pmask, array(
 0546                      'NAME'            => $ug_name,
 0547                      'CATEGORIES'    => implode('</th><th>', $categories),
 0548   
 0549                      'USER_GROUPS_DEFAULT'    => ($user_mode == 'user' && isset($user_groups_default[$ug_id]) && sizeof($user_groups_default[$ug_id])) ? implode($user->lang['COMMA_SEPARATOR'], $user_groups_default[$ug_id]) : '',
 0550                      'USER_GROUPS_CUSTOM'    => ($user_mode == 'user' && isset($user_groups_custom[$ug_id]) && sizeof($user_groups_custom[$ug_id])) ? implode($user->lang['COMMA_SEPARATOR'], $user_groups_custom[$ug_id]) : '',
 0551                      'L_ACL_TYPE'            => $l_acl_type,
 0552   
 0553                      'S_LOCAL'        => ($local) ? true : false,
 0554                      'S_GLOBAL'        => (!$local) ? true : false,
 0555                      'S_NUM_CATS'    => sizeof($categories),
 0556                      'S_VIEW'        => ($mode == 'view') ? true : false,
 0557                      'S_NUM_OBJECTS'    => sizeof($content_array),
 0558                      'S_USER_MODE'    => ($user_mode == 'user') ? true : false,
 0559                      'S_GROUP_MODE'    => ($user_mode == 'group') ? true : false)
 0560                  );
 0561   
 0562                  @reset($content_array);
 0563                  while (list($forum_id, $forum_array) = each($content_array))
 0564                  {
 0565                      // Build role dropdown options
 0566                      $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
 0567   
 0568                      $role_options = array();
 0569   
 0570                      $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
 0571                      $s_role_options = '';
 0572   
 0573                      @reset($roles);
 0574                      while (list($role_id, $role_row) = each($roles))
 0575                      {
 0576                          $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']);
 0577                          $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name'];
 0578   
 0579                          $title = ($role_description) ? ' title="' . $role_description . '"' : '';
 0580                          $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>';
 0581   
 0582                          $role_options[] = array(
 0583                              'ID'    => $role_id,
 0584                              'ROLE_NAME'    => $role_name,
 0585                              'TITLE'        => $role_description,
 0586                              'SELECTED'    => $role_id == $current_role_id,
 0587                          );
 0588                      }
 0589   
 0590                      if ($s_role_options)
 0591                      {
 0592                          $s_role_options = '<option value="0"' . ((!$current_role_id) ? ' selected="selected"' : '') . ' title="' . htmlspecialchars($user->lang['NO_ROLE_ASSIGNED_EXPLAIN']) . '">' . $user->lang['NO_ROLE_ASSIGNED'] . '</option>' . $s_role_options;
 0593                      }
 0594   
 0595                      if (!$current_role_id && $mode != 'view')
 0596                      {
 0597                          $s_custom_permissions = false;
 0598   
 0599                          foreach ($forum_array as $key => $value)
 0600                          {
 0601                              if ($value['S_NEVER'] || $value['S_YES'])
 0602                              {
 0603                                  $s_custom_permissions = true;
 0604                                  break;
 0605                              }
 0606                          }
 0607                      }
 0608                      else
 0609                      {
 0610                          $s_custom_permissions = false;
 0611                      }
 0612   
 0613                      $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array(
 0614                          'NAME'                => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'],
 0615                          'PADDING'            => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'],
 0616                          'S_CUSTOM'            => $s_custom_permissions,
 0617                          'UG_ID'                => $ug_id,
 0618                          'S_ROLE_OPTIONS'    => $s_role_options,
 0619                          'FORUM_ID'            => $forum_id)
 0620                      );
 0621   
 0622                      $template->assign_block_vars_array($tpl_pmask . '.' . $tpl_fmask . '.role_options', $role_options);
 0623   
 0624                      $this->assign_cat_array($forum_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace);
 0625                  }
 0626   
 0627                  unset($hold_ary[$ug_id], $ug_names_ary[$ug_id]);
 0628              }
 0629          }
 0630      }
 0631   
 0632      /**
 0633      * Display permission mask for roles
 0634      */
 0635      function display_role_mask(&$hold_ary)
 0636      {
 0637          global $db, $template, $user, $phpbb_root_path, $phpEx;
 0638          global $phpbb_container;
 0639   
 0640          if (!sizeof($hold_ary))
 0641          {
 0642              return;
 0643          }
 0644   
 0645          /** @var \phpbb\group\helper $group_helper */
 0646          $group_helper = $phpbb_container->get('group_helper');
 0647   
 0648          // Get forum names
 0649          $sql = 'SELECT forum_id, forum_name
 0650              FROM ' . FORUMS_TABLE . '
 0651              WHERE ' . $db->sql_in_set('forum_id', array_keys($hold_ary)) . '
 0652              ORDER BY left_id';
 0653          $result = $db->sql_query($sql);
 0654   
 0655          // If the role is used globally, then reflect that
 0656          $forum_names = (isset($hold_ary[0])) ? array(0 => '') : array();
 0657          while ($row = $db->sql_fetchrow($result))
 0658          {
 0659              $forum_names[$row['forum_id']] = $row['forum_name'];
 0660          }
 0661          $db->sql_freeresult($result);
 0662   
 0663          foreach ($forum_names as $forum_id => $forum_name)
 0664          {
 0665              $auth_ary = $hold_ary[$forum_id];
 0666   
 0667              $template->assign_block_vars('role_mask', array(
 0668                  'NAME'                => ($forum_id == 0) ? $user->lang['GLOBAL_MASK'] : $forum_name,
 0669                  'FORUM_ID'            => $forum_id)
 0670              );
 0671   
 0672              if (isset($auth_ary['users']) && sizeof($auth_ary['users']))
 0673              {
 0674                  $sql = 'SELECT user_id, username
 0675                      FROM ' . USERS_TABLE . '
 0676                      WHERE ' . $db->sql_in_set('user_id', $auth_ary['users']) . '
 0677                      ORDER BY username_clean ASC';
 0678                  $result = $db->sql_query($sql);
 0679   
 0680                  while ($row = $db->sql_fetchrow($result))
 0681                  {
 0682                      $template->assign_block_vars('role_mask.users', array(
 0683                          'USER_ID'        => $row['user_id'],
 0684                          'USERNAME'        => get_username_string('username', $row['user_id'], $row['username']),
 0685                          'U_PROFILE'        => get_username_string('profile', $row['user_id'], $row['username']),
 0686                      ));
 0687                  }
 0688                  $db->sql_freeresult($result);
 0689              }
 0690   
 0691              if (isset($auth_ary['groups']) && sizeof($auth_ary['groups']))
 0692              {
 0693                  $sql = 'SELECT group_id, group_name, group_type
 0694                      FROM ' . GROUPS_TABLE . '
 0695                      WHERE ' . $db->sql_in_set('group_id', $auth_ary['groups']) . '
 0696                      ORDER BY group_type ASC, group_name';
 0697                  $result = $db->sql_query($sql);
 0698   
 0699                  while ($row = $db->sql_fetchrow($result))
 0700                  {
 0701                      $template->assign_block_vars('role_mask.groups', array(
 0702                          'GROUP_ID'        => $row['group_id'],
 0703                          'GROUP_NAME'    => $group_helper->get_name($row['group_name']),
 0704                          'U_PROFILE'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=group&amp;g={$row['group_id']}"))
 0705                      );
 0706                  }
 0707                  $db->sql_freeresult($result);
 0708              }
 0709          }
 0710      }
 0711   
 0712      /**
 0713      * NOTE: this function is not in use atm
 0714      * Add a new option to the list ... $options is a hash of form ->
 0715      * $options = array(
 0716      *    'local'        => array('option1', 'option2', ...),
 0717      *    'global'    => array('optionA', 'optionB', ...)
 0718      * );
 0719      */
 0720      function acl_add_option($options)
 0721      {
 0722          global $db, $cache;
 0723   
 0724          if (!is_array($options))
 0725          {
 0726              return false;
 0727          }
 0728   
 0729          $cur_options = array();
 0730   
 0731          // Determine current options
 0732          $sql = 'SELECT auth_option, is_global, is_local
 0733              FROM ' . ACL_OPTIONS_TABLE . '
 0734              ORDER BY auth_option_id';
 0735          $result = $db->sql_query($sql);
 0736   
 0737          while ($row = $db->sql_fetchrow($result))
 0738          {
 0739              $cur_options[$row['auth_option']] = ($row['is_global'] && $row['is_local']) ? 'both' : (($row['is_global']) ? 'global' : 'local');
 0740          }
 0741          $db->sql_freeresult($result);
 0742   
 0743          // Here we need to insert new options ... this requires discovering whether
 0744          // an options is global, local or both and whether we need to add an permission
 0745          // set flag (x_)
 0746          $new_options = array('local' => array(), 'global' => array());
 0747   
 0748          foreach ($options as $type => $option_ary)
 0749          {
 0750              $option_ary = array_unique($option_ary);
 0751   
 0752              foreach ($option_ary as $option_value)
 0753              {
 0754                  $new_options[$type][] = $option_value;
 0755   
 0756                  $flag = substr($option_value, 0, strpos($option_value, '_') + 1);
 0757   
 0758                  if (!in_array($flag, $new_options[$type]))
 0759                  {
 0760                      $new_options[$type][] = $flag;
 0761                  }
 0762              }
 0763          }
 0764          unset($options);
 0765   
 0766          $options = array();
 0767          $options['local'] = array_diff($new_options['local'], $new_options['global']);
 0768          $options['global'] = array_diff($new_options['global'], $new_options['local']);
 0769          $options['both'] = array_intersect($new_options['local'], $new_options['global']);
 0770   
 0771          // Now check which options to add/update
 0772          $add_options = $update_options = array();
 0773   
 0774          // First local ones...
 0775          foreach ($options as $type => $option_ary)
 0776          {
 0777              foreach ($option_ary as $option)
 0778              {
 0779                  if (!isset($cur_options[$option]))
 0780                  {
 0781                      $add_options[] = array(
 0782                          'auth_option'    => (string) $option,
 0783                          'is_global'        => ($type == 'global' || $type == 'both') ? 1 : 0,
 0784                          'is_local'        => ($type == 'local' || $type == 'both') ? 1 : 0
 0785                      );
 0786   
 0787                      continue;
 0788                  }
 0789   
 0790                  // Else, update existing entry if it is changed...
 0791                  if ($type === $cur_options[$option])
 0792                  {
 0793                      continue;
 0794                  }
 0795   
 0796                  // New type is always both:
 0797                  // If is now both, we set both.
 0798                  // If it was global the new one is local and we need to set it to both
 0799                  // If it was local the new one is global and we need to set it to both
 0800                  $update_options[] = $option;
 0801              }
 0802          }
 0803   
 0804          if (!empty($add_options))
 0805          {
 0806              $db->sql_multi_insert(ACL_OPTIONS_TABLE, $add_options);
 0807          }
 0808   
 0809          if (!empty($update_options))
 0810          {
 0811              $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . '
 0812                  SET is_global = 1, is_local = 1
 0813                  WHERE ' . $db->sql_in_set('auth_option', $update_options);
 0814              $db->sql_query($sql);
 0815          }
 0816   
 0817          $cache->destroy('_acl_options');
 0818          $this->acl_clear_prefetch();
 0819   
 0820          // Because we just changed the options and also purged the options cache, we instantly update/regenerate it for later calls to succeed.
 0821          $this->acl_options = array();
 0822          $this->auth_admin();
 0823   
 0824          return true;
 0825      }
 0826   
 0827      /**
 0828      * Set a user or group ACL record
 0829      */
 0830      function acl_set($ug_type, $forum_id, $ug_id, $auth, $role_id = 0, $clear_prefetch = true)
 0831      {
 0832          global $db;
 0833   
 0834          // One or more forums
 0835          if (!is_array($forum_id))
 0836          {
 0837              $forum_id = array($forum_id);
 0838          }
 0839   
 0840          // One or more users
 0841          if (!is_array($ug_id))
 0842          {
 0843              $ug_id = array($ug_id);
 0844          }
 0845   
 0846          $ug_id_sql = $db->sql_in_set($ug_type . '_id', array_map('intval', $ug_id));
 0847          $forum_sql = $db->sql_in_set('forum_id', array_map('intval', $forum_id));
 0848   
 0849          // Instead of updating, inserting, removing we just remove all current settings and re-set everything...
 0850          $table = ($ug_type == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE;
 0851          $id_field = $ug_type . '_id';
 0852   
 0853          // Get any flags as required
 0854          reset($auth);
 0855          $flag = key($auth);
 0856          $flag = substr($flag, 0, strpos($flag, '_') + 1);
 0857   
 0858          // This ID (the any-flag) is set if one or more permissions are true...
 0859          $any_option_id = (int) $this->acl_options['id'][$flag];
 0860   
 0861          // Remove any-flag from auth ary
 0862          if (isset($auth[$flag]))
 0863          {
 0864              unset($auth[$flag]);
 0865          }
 0866   
 0867          // Remove current auth options...
 0868          $auth_option_ids = array((int) $any_option_id);
 0869          foreach ($auth as $auth_option => $auth_setting)
 0870          {
 0871              $auth_option_ids[] = (int) $this->acl_options['id'][$auth_option];
 0872          }
 0873   
 0874          $sql = "DELETE FROM $table
 0875              WHERE $forum_sql
 0876                  AND $ug_id_sql
 0877                  AND " . $db->sql_in_set('auth_option_id', $auth_option_ids);
 0878          $db->sql_query($sql);
 0879   
 0880          // Remove those having a role assigned... the correct type of course...
 0881          $sql = 'SELECT role_id
 0882              FROM ' . ACL_ROLES_TABLE . "
 0883              WHERE role_type = '" . $db->sql_escape($flag) . "'";
 0884          $result = $db->sql_query($sql);
 0885   
 0886          $role_ids = array();
 0887          while ($row = $db->sql_fetchrow($result))
 0888          {
 0889              $role_ids[] = $row['role_id'];
 0890          }
 0891          $db->sql_freeresult($result);
 0892   
 0893          if (sizeof($role_ids))
 0894          {
 0895              $sql = "DELETE FROM $table
 0896                  WHERE $forum_sql
 0897                      AND $ug_id_sql
 0898                      AND auth_option_id = 0
 0899                      AND " . $db->sql_in_set('auth_role_id', $role_ids);
 0900              $db->sql_query($sql);
 0901          }
 0902   
 0903          // Ok, include the any-flag if one or more auth options are set to yes...
 0904          foreach ($auth as $auth_option => $setting)
 0905          {
 0906              if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER))
 0907              {
 0908                  $auth[$flag] = ACL_YES;
 0909              }
 0910          }
 0911   
 0912          $sql_ary = array();
 0913          foreach ($forum_id as $forum)
 0914          {
 0915              $forum = (int) $forum;
 0916   
 0917              if ($role_id)
 0918              {
 0919                  foreach ($ug_id as $id)
 0920                  {
 0921                      $sql_ary[] = array(
 0922                          $id_field            => (int) $id,
 0923                          'forum_id'            => (int) $forum,
 0924                          'auth_option_id'    => 0,
 0925                          'auth_setting'        => 0,
 0926                          'auth_role_id'        => (int) $role_id,
 0927                      );
 0928                  }
 0929              }
 0930              else
 0931              {
 0932                  foreach ($auth as $auth_option => $setting)
 0933                  {
 0934                      $auth_option_id = (int) $this->acl_options['id'][$auth_option];
 0935   
 0936                      if ($setting != ACL_NO)
 0937                      {
 0938                          foreach ($ug_id as $id)
 0939                          {
 0940                              $sql_ary[] = array(
 0941                                  $id_field            => (int) $id,
 0942                                  'forum_id'            => (int) $forum,
 0943                                  'auth_option_id'    => (int) $auth_option_id,
 0944                                  'auth_setting'        => (int) $setting
 0945                              );
 0946                          }
 0947                      }
 0948                  }
 0949              }
 0950          }
 0951   
 0952          $db->sql_multi_insert($table, $sql_ary);
 0953   
 0954          if ($clear_prefetch)
 0955          {
 0956              $this->acl_clear_prefetch();
 0957          }
 0958      }
 0959   
 0960      /**
 0961      * Set a role-specific ACL record
 0962      */
 0963      function acl_set_role($role_id, $auth)
 0964      {
 0965          global $db;
 0966   
 0967          // Get any-flag as required
 0968          reset($auth);
 0969          $flag = key($auth);
 0970          $flag = substr($flag, 0, strpos($flag, '_') + 1);
 0971   
 0972          // Remove any-flag from auth ary
 0973          if (isset($auth[$flag]))
 0974          {
 0975              unset($auth[$flag]);
 0976          }
 0977   
 0978          // Re-set any flag...
 0979          foreach ($auth as $auth_option => $setting)
 0980          {
 0981              if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER))
 0982              {
 0983                  $auth[$flag] = ACL_YES;
 0984              }
 0985          }
 0986   
 0987          $sql_ary = array();
 0988          foreach ($auth as $auth_option => $setting)
 0989          {
 0990              $auth_option_id = (int) $this->acl_options['id'][$auth_option];
 0991   
 0992              if ($setting != ACL_NO)
 0993              {
 0994                  $sql_ary[] = array(
 0995                      'role_id'            => (int) $role_id,
 0996                      'auth_option_id'    => (int) $auth_option_id,
 0997                      'auth_setting'        => (int) $setting
 0998                  );
 0999              }
 1000          }
 1001   
 1002          // If no data is there, we set the any-flag to ACL_NEVER...
 1003          if (!sizeof($sql_ary))
 1004          {
 1005              $sql_ary[] = array(
 1006                  'role_id'            => (int) $role_id,
 1007                  'auth_option_id'    => (int) $this->acl_options['id'][$flag],
 1008                  'auth_setting'        => ACL_NEVER
 1009              );
 1010          }
 1011   
 1012          // Remove current auth options...
 1013          $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . '
 1014              WHERE role_id = ' . $role_id;
 1015          $db->sql_query($sql);
 1016   
 1017          // Now insert the new values
 1018          $db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary);
 1019   
 1020          $this->acl_clear_prefetch();
 1021      }
 1022   
 1023      /**
 1024      * Remove local permission
 1025      */
 1026      function acl_delete($mode, $ug_id = false, $forum_id = false, $permission_type = false)
 1027      {
 1028          global $db;
 1029   
 1030          if ($ug_id === false && $forum_id === false)
 1031          {
 1032              return;
 1033          }
 1034   
 1035          $option_id_ary = array();
 1036          $table = ($mode == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE;
 1037          $id_field = $mode . '_id';
 1038   
 1039          $where_sql = array();
 1040   
 1041          if ($forum_id !== false)
 1042          {
 1043              $where_sql[] = (!is_array($forum_id)) ? 'forum_id = ' . (int) $forum_id : $db->sql_in_set('forum_id', array_map('intval', $forum_id));
 1044          }
 1045   
 1046          if ($ug_id !== false)
 1047          {
 1048              $where_sql[] = (!is_array($ug_id)) ? $id_field . ' = ' . (int) $ug_id : $db->sql_in_set($id_field, array_map('intval', $ug_id));
 1049          }
 1050   
 1051          // There seem to be auth options involved, therefore we need to go through the list and make sure we capture roles correctly
 1052          if ($permission_type !== false)
 1053          {
 1054              // Get permission type
 1055              $sql = 'SELECT auth_option, auth_option_id
 1056                  FROM ' . ACL_OPTIONS_TABLE . "
 1057                  WHERE auth_option " . $db->sql_like_expression($permission_type . $db->get_any_char());
 1058              $result = $db->sql_query($sql);
 1059   
 1060              $auth_id_ary = array();
 1061              while ($row = $db->sql_fetchrow($result))
 1062              {
 1063                  $option_id_ary[] = $row['auth_option_id'];
 1064                  $auth_id_ary[$row['auth_option']] = ACL_NO;
 1065              }
 1066              $db->sql_freeresult($result);
 1067   
 1068              // First of all, lets grab the items having roles with the specified auth options assigned
 1069              $sql = "SELECT auth_role_id, $id_field, forum_id
 1070                  FROM $table, " . ACL_ROLES_TABLE . " r
 1071                  WHERE auth_role_id <> 0
 1072                      AND auth_role_id = r.role_id
 1073                      AND r.role_type = '{$permission_type}'
 1074                      AND " . implode(' AND ', $where_sql) . '
 1075                  ORDER BY auth_role_id';
 1076              $result = $db->sql_query($sql);
 1077   
 1078              $cur_role_auth = array();
 1079              while ($row = $db->sql_fetchrow($result))
 1080              {
 1081                  $cur_role_auth[$row['auth_role_id']][$row['forum_id']][] = $row[$id_field];
 1082              }
 1083              $db->sql_freeresult($result);
 1084   
 1085              // Get role data for resetting data
 1086              if (sizeof($cur_role_auth))
 1087              {
 1088                  $sql = 'SELECT ao.auth_option, rd.role_id, rd.auth_setting
 1089                      FROM ' . ACL_OPTIONS_TABLE . ' ao, ' . ACL_ROLES_DATA_TABLE . ' rd
 1090                      WHERE ao.auth_option_id = rd.auth_option_id
 1091                          AND ' . $db->sql_in_set('rd.role_id', array_keys($cur_role_auth));
 1092                  $result = $db->sql_query($sql);
 1093   
 1094                  $auth_settings = array();
 1095                  while ($row = $db->sql_fetchrow($result))
 1096                  {
 1097                      // We need to fill all auth_options, else setting it will fail...
 1098                      if (!isset($auth_settings[$row['role_id']]))
 1099                      {
 1100                          $auth_settings[$row['role_id']] = $auth_id_ary;
 1101                      }
 1102                      $auth_settings[$row['role_id']][$row['auth_option']] = $row['auth_setting'];
 1103                  }
 1104                  $db->sql_freeresult($result);
 1105   
 1106                  // Set the options
 1107                  foreach ($cur_role_auth as $role_id => $auth_row)
 1108                  {
 1109                      foreach ($auth_row as $f_id => $ug_row)
 1110                      {
 1111                          $this->acl_set($mode, $f_id, $ug_row, $auth_settings[$role_id], 0, false);
 1112                      }
 1113                  }
 1114              }
 1115          }
 1116   
 1117          // Now, normally remove permissions...
 1118          if ($permission_type !== false)
 1119          {
 1120              $where_sql[] = $db->sql_in_set('auth_option_id', array_map('intval', $option_id_ary));
 1121          }
 1122   
 1123          $sql = "DELETE FROM $table
 1124              WHERE " . implode(' AND ', $where_sql);
 1125          $db->sql_query($sql);
 1126   
 1127          $this->acl_clear_prefetch();
 1128      }
 1129   
 1130      /**
 1131      * Assign category to template
 1132      * used by display_mask()
 1133      */
 1134      function assign_cat_array(&$category_array, $tpl_cat, $tpl_mask, $ug_id, $forum_id, $s_view, $show_trace = false)
 1135      {
 1136          global $template, $phpbb_admin_path, $phpEx, $phpbb_container;
 1137   
 1138          /* @var $phpbb_permissions \phpbb\permissions */
 1139          $phpbb_permissions = $phpbb_container->get('acl.permissions');
 1140   
 1141          @reset($category_array);
 1142          while (list($cat, $cat_array) = each($category_array))
 1143          {
 1144              if (!$phpbb_permissions->category_defined($cat))
 1145              {
 1146                  continue;
 1147              }
 1148   
 1149              $template->assign_block_vars($tpl_cat, array(
 1150                  'S_YES'        => ($cat_array['S_YES'] && !$cat_array['S_NEVER'] && !$cat_array['S_NO']) ? true : false,
 1151                  'S_NEVER'    => ($cat_array['S_NEVER'] && !$cat_array['S_YES'] && !$cat_array['S_NO']) ? true : false,
 1152                  'S_NO'        => ($cat_array['S_NO'] && !$cat_array['S_NEVER'] && !$cat_array['S_YES']) ? true : false,
 1153   
 1154                  'CAT_NAME'    => $phpbb_permissions->get_category_lang($cat),
 1155              ));
 1156   
 1157              /*    Sort permissions by name (more naturaly and user friendly than sorting by a primary key)
 1158              *    Commented out due to it's memory consumption and time needed
 1159              *
 1160              $key_array = array_intersect(array_keys($user->lang), array_map(create_function('$a', 'return "acl_" . $a;'), array_keys($cat_array['permissions'])));
 1161              $values_array = $cat_array['permissions'];
 1162   
 1163              $cat_array['permissions'] = array();
 1164   
 1165              foreach ($key_array as $key)
 1166              {
 1167                  $key = str_replace('acl_', '', $key);
 1168                  $cat_array['permissions'][$key] = $values_array[$key];
 1169              }
 1170              unset($key_array, $values_array);
 1171  */
 1172              @reset($cat_array['permissions']);
 1173              while (list($permission, $allowed) = each($cat_array['permissions']))
 1174              {
 1175                  if (!$phpbb_permissions->permission_defined($permission))
 1176                  {
 1177                      continue;
 1178                  }
 1179   
 1180                  if ($s_view)
 1181                  {
 1182                      $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array(
 1183                          'S_YES'        => ($allowed == ACL_YES) ? true : false,
 1184                          'S_NEVER'    => ($allowed == ACL_NEVER) ? 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&amp;mode=trace&amp;u=$ug_id&amp;f=$forum_id&amp;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                  else
 1198                  {
 1199                      $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array(
 1200                          'S_YES'        => ($allowed == ACL_YES) ? true : false,
 1201                          'S_NEVER'    => ($allowed == ACL_NEVER) ? true : false,
 1202                          'S_NO'        => ($allowed == ACL_NO) ? true : false,
 1203   
 1204                          'UG_ID'            => $ug_id,
 1205                          'FORUM_ID'        => $forum_id,
 1206                          'FIELD_NAME'    => $permission,
 1207                          'S_FIELD_NAME'    => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']',
 1208   
 1209                          'U_TRACE'        => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&amp;mode=trace&amp;u=$ug_id&amp;f=$forum_id&amp;auth=$permission") : '',
 1210                          'UA_TRACE'        => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission", false) : '',
 1211   
 1212                          'PERMISSION'    => $phpbb_permissions->get_permission_lang($permission),
 1213                      ));
 1214                  }
 1215              }
 1216          }
 1217      }
 1218   
 1219      /**
 1220      * Building content array from permission rows with explicit key ordering
 1221      * used by display_mask()
 1222      */
 1223      function build_permission_array(&$permission_row, &$content_array, &$categories, $key_sort_array)
 1224      {
 1225          global $phpbb_container;
 1226   
 1227          /* @var $phpbb_permissions \phpbb\permissions */
 1228          $phpbb_permissions = $phpbb_container->get('acl.permissions');
 1229   
 1230          foreach ($key_sort_array as $forum_id)
 1231          {
 1232              if (!isset($permission_row[$forum_id]))
 1233              {
 1234                  continue;
 1235              }
 1236   
 1237              $permissions = $permission_row[$forum_id];
 1238              ksort($permissions);
 1239   
 1240              @reset($permissions);
 1241              while (list($permission, $auth_setting) = each($permissions))
 1242              {
 1243                  $cat = $phpbb_permissions->get_permission_category($permission);
 1244   
 1245                  // Build our categories array
 1246                  if (!isset($categories[$cat]))
 1247                  {
 1248                      $categories[$cat] = $phpbb_permissions->get_category_lang($cat);
 1249                  }
 1250   
 1251                  // Build our content array
 1252                  if (!isset($content_array[$forum_id]))
 1253                  {
 1254                      $content_array[$forum_id] = array();
 1255                  }
 1256   
 1257                  if (!isset($content_array[$forum_id][$cat]))
 1258                  {
 1259                      $content_array[$forum_id][$cat] = array(
 1260                          'S_YES'            => false,
 1261                          'S_NEVER'        => false,
 1262                          'S_NO'            => false,
 1263                          'permissions'    => array(),
 1264                      );
 1265                  }
 1266   
 1267                  $content_array[$forum_id][$cat]['S_YES'] |= ($auth_setting == ACL_YES) ? true : false;
 1268                  $content_array[$forum_id][$cat]['S_NEVER'] |= ($auth_setting == ACL_NEVER) ? true : false;
 1269                  $content_array[$forum_id][$cat]['S_NO'] |= ($auth_setting == ACL_NO) ? true : false;
 1270   
 1271                  $content_array[$forum_id][$cat]['permissions'][$permission] = $auth_setting;
 1272              }
 1273          }
 1274      }
 1275   
 1276      /**
 1277      * Use permissions from another user. This transferes a permission set from one user to another.
 1278      * The other user is always able to revert back to his permission set.
 1279      * This function does not check for lower/higher permissions, it is possible for the user to gain
 1280      * "more" permissions by this.
 1281      * Admin permissions will not be copied.
 1282      */
 1283      function ghost_permissions($from_user_id, $to_user_id)
 1284      {
 1285          global $db;
 1286   
 1287          if ($to_user_id == ANONYMOUS)
 1288          {
 1289              return false;
 1290          }
 1291   
 1292          $hold_ary = $this->acl_raw_data_single_user($from_user_id);
 1293   
 1294          // Key 0 in $hold_ary are global options, all others are forum_ids
 1295   
 1296          // We disallow copying admin permissions
 1297          foreach ($this->acl_options['global'] as $opt => $id)
 1298          {
 1299              if (strpos($opt, 'a_') === 0)
 1300              {
 1301                  $hold_ary[0][$this->acl_options['id'][$opt]] = ACL_NEVER;
 1302              }
 1303          }
 1304   
 1305          // Force a_switchperm to be allowed
 1306          $hold_ary[0][$this->acl_options['id']['a_switchperm']] = ACL_YES;
 1307   
 1308          $user_permissions = $this->build_bitstring($hold_ary);
 1309   
 1310          if (!$user_permissions)
 1311          {
 1312              return false;
 1313          }
 1314   
 1315          $sql = 'UPDATE ' . USERS_TABLE . "
 1316              SET user_permissions = '" . $db->sql_escape($user_permissions) . "',
 1317                  user_perm_from = $from_user_id
 1318              WHERE user_id = " . $to_user_id;
 1319          $db->sql_query($sql);
 1320   
 1321          return true;
 1322      }
 1323  }
 1324