Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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: 37.49 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_root_path, $phpEx, $phpbb_container;
0270          $phpbb_permissions = $phpbb_container->get('acl.permissions');
0271   
0272          // Define names for template loops, might be able to be set
0273          $tpl_pmask = 'p_mask';
0274          $tpl_fmask = 'f_mask';
0275          $tpl_category = 'category';
0276          $tpl_mask = 'mask';
0277   
0278          $l_acl_type = $phpbb_permissions->get_type_lang($permission_type, (($local) ? 'local' : 'global'));
0279   
0280          // Allow trace for viewing permissions and in user mode
0281          $show_trace = ($mode == 'view' && $user_mode == 'user') ? true : false;
0282   
0283          // Get names
0284          if ($user_mode == 'user')
0285          {
0286              $sql = 'SELECT user_id as ug_id, username as ug_name
0287                  FROM ' . USERS_TABLE . '
0288                  WHERE ' . $db->sql_in_set('user_id', array_keys($hold_ary)) . '
0289                  ORDER BY username_clean ASC';
0290          }
0291          else
0292          {
0293              $sql = 'SELECT group_id as ug_id, group_name as ug_name, group_type
0294                  FROM ' . GROUPS_TABLE . '
0295                  WHERE ' . $db->sql_in_set('group_id', array_keys($hold_ary)) . '
0296                  ORDER BY group_type DESC, group_name ASC';
0297          }
0298          $result = $db->sql_query($sql);
0299   
0300          $ug_names_ary = array();
0301          while ($row = $db->sql_fetchrow($result))
0302          {
0303              $ug_names_ary[$row['ug_id']] = ($user_mode == 'user') ? $row['ug_name'] : (($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['ug_name']] : $row['ug_name']);
0304          }
0305          $db->sql_freeresult($result);
0306   
0307          // Get used forums
0308          $forum_ids = array();
0309          foreach ($hold_ary as $ug_id => $row)
0310          {
0311              $forum_ids = array_merge($forum_ids, array_keys($row));
0312          }
0313          $forum_ids = array_unique($forum_ids);
0314   
0315          $forum_names_ary = array();
0316          if ($local)
0317          {
0318              $forum_names_ary = make_forum_select(false, false, true, false, false, false, true);
0319   
0320              // Remove the disabled ones, since we do not create an option field here...
0321              foreach ($forum_names_ary as $key => $value)
0322              {
0323                  if (!$value['disabled'])
0324                  {
0325                      continue;
0326                  }
0327                  unset($forum_names_ary[$key]);
0328              }
0329          }
0330          else
0331          {
0332              $forum_names_ary[0] = $l_acl_type;
0333          }
0334   
0335          // Get available roles
0336          $sql = 'SELECT *
0337              FROM ' . ACL_ROLES_TABLE . "
0338              WHERE role_type = '" . $db->sql_escape($permission_type) . "'
0339              ORDER BY role_order ASC";
0340          $result = $db->sql_query($sql);
0341   
0342          $roles = array();
0343          while ($row = $db->sql_fetchrow($result))
0344          {
0345              $roles[$row['role_id']] = $row;
0346          }
0347          $db->sql_freeresult($result);
0348   
0349          $cur_roles = $this->acl_role_data($user_mode, $permission_type, array_keys($hold_ary));
0350   
0351          // Build js roles array (role data assignments)
0352          $s_role_js_array = '';
0353   
0354          if (sizeof($roles))
0355          {
0356              $s_role_js_array = array();
0357   
0358              // Make sure every role (even if empty) has its array defined
0359              foreach ($roles as $_role_id => $null)
0360              {
0361                  $s_role_js_array[$_role_id] = "\n" . 'role_options[' . $_role_id . '] = new Array();' . "\n";
0362              }
0363   
0364              $sql = 'SELECT r.role_id, o.auth_option, r.auth_setting
0365                  FROM ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' o
0366                  WHERE o.auth_option_id = r.auth_option_id
0367                      AND ' . $db->sql_in_set('r.role_id', array_keys($roles));
0368              $result = $db->sql_query($sql);
0369   
0370              while ($row = $db->sql_fetchrow($result))
0371              {
0372                  $flag = substr($row['auth_option'], 0, strpos($row['auth_option'], '_') + 1);
0373                  if ($flag == $row['auth_option'])
0374                  {
0375                      continue;
0376                  }
0377   
0378                  $s_role_js_array[$row['role_id']] .= 'role_options[' . $row['role_id'] . '][\'' . addslashes($row['auth_option']) . '\'] = ' . $row['auth_setting'] . '; ';
0379              }
0380              $db->sql_freeresult($result);
0381   
0382              $s_role_js_array = implode('', $s_role_js_array);
0383          }
0384   
0385          $template->assign_var('S_ROLE_JS_ARRAY', $s_role_js_array);
0386          unset($s_role_js_array);
0387   
0388          // Now obtain memberships
0389          $user_groups_default = $user_groups_custom = array();
0390          if ($user_mode == 'user' && $group_display)
0391          {
0392              $sql = 'SELECT group_id, group_name, group_type
0393                  FROM ' . GROUPS_TABLE . '
0394                  ORDER BY group_type DESC, group_name ASC';
0395              $result = $db->sql_query($sql);
0396   
0397              $groups = array();
0398              while ($row = $db->sql_fetchrow($result))
0399              {
0400                  $groups[$row['group_id']] = $row;
0401              }
0402              $db->sql_freeresult($result);
0403   
0404              $memberships = group_memberships(false, array_keys($hold_ary), false);
0405   
0406              // User is not a member of any group? Bad admin, bad bad admin...
0407              if ($memberships)
0408              {
0409                  foreach ($memberships as $row)
0410                  {
0411                      if ($groups[$row['group_id']]['group_type'] == GROUP_SPECIAL)
0412                      {
0413                          $user_groups_default[$row['user_id']][] = $user->lang['G_' . $groups[$row['group_id']]['group_name']];
0414                      }
0415                      else
0416                      {
0417                          $user_groups_custom[$row['user_id']][] = $groups[$row['group_id']]['group_name'];
0418                      }
0419                  }
0420              }
0421              unset($memberships, $groups);
0422          }
0423   
0424          // If we only have one forum id to display or being in local mode and more than one user/group to display,
0425          // we switch the complete interface to group by user/usergroup instead of grouping by forum
0426          // To achieve this, we need to switch the array a bit
0427          if (sizeof($forum_ids) == 1 || ($local && sizeof($ug_names_ary) > 1))
0428          {
0429              $hold_ary_temp = $hold_ary;
0430              $hold_ary = array();
0431              foreach ($hold_ary_temp as $ug_id => $row)
0432              {
0433                  foreach ($forum_names_ary as $forum_id => $forum_row)
0434                  {
0435                      if (isset($row[$forum_id]))
0436                      {
0437                          $hold_ary[$forum_id][$ug_id] = $row[$forum_id];
0438                      }
0439                  }
0440              }
0441              unset($hold_ary_temp);
0442   
0443              foreach ($hold_ary as $forum_id => $forum_array)
0444              {
0445                  $content_array = $categories = array();
0446                  $this->build_permission_array($hold_ary[$forum_id], $content_array, $categories, array_keys($ug_names_ary));
0447   
0448                  $template->assign_block_vars($tpl_pmask, array(
0449                      'NAME'            => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'],
0450                      'PADDING'        => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'],
0451   
0452                      'CATEGORIES'    => implode('</th><th>', $categories),
0453   
0454                      'L_ACL_TYPE'    => $l_acl_type,
0455   
0456                      'S_LOCAL'        => ($local) ? true : false,
0457                      'S_GLOBAL'        => (!$local) ? true : false,
0458                      'S_NUM_CATS'    => sizeof($categories),
0459                      'S_VIEW'        => ($mode == 'view') ? true : false,
0460                      'S_NUM_OBJECTS'    => sizeof($content_array),
0461                      'S_USER_MODE'    => ($user_mode == 'user') ? true : false,
0462                      'S_GROUP_MODE'    => ($user_mode == 'group') ? true : false)
0463                  );
0464   
0465                  @reset($content_array);
0466                  while (list($ug_id, $ug_array) = each($content_array))
0467                  {
0468                      // Build role dropdown options
0469                      $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
0470   
0471                      $s_role_options = '';
0472   
0473                      @reset($roles);
0474                      while (list($role_id, $role_row) = each($roles))
0475                      {
0476                          $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']);
0477                          $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name'];
0478   
0479                          $title = ($role_description) ? ' title="' . $role_description . '"' : '';
0480                          $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>';
0481                      }
0482   
0483                      if ($s_role_options)
0484                      {
0485                          $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;
0486                      }
0487   
0488                      if (!$current_role_id && $mode != 'view')
0489                      {
0490                          $s_custom_permissions = false;
0491   
0492                          foreach ($ug_array as $key => $value)
0493                          {
0494                              if ($value['S_NEVER'] || $value['S_YES'])
0495                              {
0496                                  $s_custom_permissions = true;
0497                                  break;
0498                              }
0499                          }
0500                      }
0501                      else
0502                      {
0503                          $s_custom_permissions = false;
0504                      }
0505   
0506                      $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array(
0507                          'NAME'                => $ug_names_ary[$ug_id],
0508                          'S_ROLE_OPTIONS'    => $s_role_options,
0509                          'UG_ID'                => $ug_id,
0510                          'S_CUSTOM'            => $s_custom_permissions,
0511                          'FORUM_ID'            => $forum_id)
0512                      );
0513   
0514                      $this->assign_cat_array($ug_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace);
0515   
0516                      unset($content_array[$ug_id]);
0517                  }
0518   
0519                  unset($hold_ary[$forum_id]);
0520              }
0521          }
0522          else
0523          {
0524              foreach ($ug_names_ary as $ug_id => $ug_name)
0525              {
0526                  if (!isset($hold_ary[$ug_id]))
0527                  {
0528                      continue;
0529                  }
0530   
0531                  $content_array = $categories = array();
0532                  $this->build_permission_array($hold_ary[$ug_id], $content_array, $categories, array_keys($forum_names_ary));
0533   
0534                  $template->assign_block_vars($tpl_pmask, array(
0535                      'NAME'            => $ug_name,
0536                      'CATEGORIES'    => implode('</th><th>', $categories),
0537   
0538                      '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]) : '',
0539                      '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]) : '',
0540                      'L_ACL_TYPE'            => $l_acl_type,
0541   
0542                      'S_LOCAL'        => ($local) ? true : false,
0543                      'S_GLOBAL'        => (!$local) ? true : false,
0544                      'S_NUM_CATS'    => sizeof($categories),
0545                      'S_VIEW'        => ($mode == 'view') ? true : false,
0546                      'S_NUM_OBJECTS'    => sizeof($content_array),
0547                      'S_USER_MODE'    => ($user_mode == 'user') ? true : false,
0548                      'S_GROUP_MODE'    => ($user_mode == 'group') ? true : false)
0549                  );
0550   
0551                  @reset($content_array);
0552                  while (list($forum_id, $forum_array) = each($content_array))
0553                  {
0554                      // Build role dropdown options
0555                      $current_role_id = (isset($cur_roles[$ug_id][$forum_id])) ? $cur_roles[$ug_id][$forum_id] : 0;
0556   
0557                      $s_role_options = '';
0558   
0559                      @reset($roles);
0560                      while (list($role_id, $role_row) = each($roles))
0561                      {
0562                          $role_description = (!empty($user->lang[$role_row['role_description']])) ? $user->lang[$role_row['role_description']] : nl2br($role_row['role_description']);
0563                          $role_name = (!empty($user->lang[$role_row['role_name']])) ? $user->lang[$role_row['role_name']] : $role_row['role_name'];
0564   
0565                          $title = ($role_description) ? ' title="' . $role_description . '"' : '';
0566                          $s_role_options .= '<option value="' . $role_id . '"' . (($role_id == $current_role_id) ? ' selected="selected"' : '') . $title . '>' . $role_name . '</option>';
0567                      }
0568   
0569                      if ($s_role_options)
0570                      {
0571                          $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;
0572                      }
0573   
0574                      if (!$current_role_id && $mode != 'view')
0575                      {
0576                          $s_custom_permissions = false;
0577   
0578                          foreach ($forum_array as $key => $value)
0579                          {
0580                              if ($value['S_NEVER'] || $value['S_YES'])
0581                              {
0582                                  $s_custom_permissions = true;
0583                                  break;
0584                              }
0585                          }
0586                      }
0587                      else
0588                      {
0589                          $s_custom_permissions = false;
0590                      }
0591   
0592                      $template->assign_block_vars($tpl_pmask . '.' . $tpl_fmask, array(
0593                          'NAME'                => ($forum_id == 0) ? $forum_names_ary[0] : $forum_names_ary[$forum_id]['forum_name'],
0594                          'PADDING'            => ($forum_id == 0) ? '' : $forum_names_ary[$forum_id]['padding'],
0595                          'S_ROLE_OPTIONS'    => $s_role_options,
0596                          'S_CUSTOM'            => $s_custom_permissions,
0597                          'UG_ID'                => $ug_id,
0598                          'FORUM_ID'            => $forum_id)
0599                      );
0600   
0601                      $this->assign_cat_array($forum_array, $tpl_pmask . '.' . $tpl_fmask . '.' . $tpl_category, $tpl_mask, $ug_id, $forum_id, ($mode == 'view'), $show_trace);
0602                  }
0603   
0604                  unset($hold_ary[$ug_id], $ug_names_ary[$ug_id]);
0605              }
0606          }
0607      }
0608   
0609      /**
0610      * Display permission mask for roles
0611      */
0612      function display_role_mask(&$hold_ary)
0613      {
0614          global $db, $template, $user, $phpbb_root_path, $phpbb_admin_path, $phpEx;
0615   
0616          if (!sizeof($hold_ary))
0617          {
0618              return;
0619          }
0620   
0621          // Get forum names
0622          $sql = 'SELECT forum_id, forum_name
0623              FROM ' . FORUMS_TABLE . '
0624              WHERE ' . $db->sql_in_set('forum_id', array_keys($hold_ary)) . '
0625              ORDER BY left_id';
0626          $result = $db->sql_query($sql);
0627   
0628          // If the role is used globally, then reflect that
0629          $forum_names = (isset($hold_ary[0])) ? array(0 => '') : array();
0630          while ($row = $db->sql_fetchrow($result))
0631          {
0632              $forum_names[$row['forum_id']] = $row['forum_name'];
0633          }
0634          $db->sql_freeresult($result);
0635   
0636          foreach ($forum_names as $forum_id => $forum_name)
0637          {
0638              $auth_ary = $hold_ary[$forum_id];
0639   
0640              $template->assign_block_vars('role_mask', array(
0641                  'NAME'                => ($forum_id == 0) ? $user->lang['GLOBAL_MASK'] : $forum_name,
0642                  'FORUM_ID'            => $forum_id)
0643              );
0644   
0645              if (isset($auth_ary['users']) && sizeof($auth_ary['users']))
0646              {
0647                  $sql = 'SELECT user_id, username
0648                      FROM ' . USERS_TABLE . '
0649                      WHERE ' . $db->sql_in_set('user_id', $auth_ary['users']) . '
0650                      ORDER BY username_clean ASC';
0651                  $result = $db->sql_query($sql);
0652   
0653                  while ($row = $db->sql_fetchrow($result))
0654                  {
0655                      $template->assign_block_vars('role_mask.users', array(
0656                          'USER_ID'        => $row['user_id'],
0657                          'USERNAME'        => get_username_string('username', $row['user_id'], $row['username']),
0658                          'U_PROFILE'        => get_username_string('profile', $row['user_id'], $row['username']),
0659                      ));
0660                  }
0661                  $db->sql_freeresult($result);
0662              }
0663   
0664              if (isset($auth_ary['groups']) && sizeof($auth_ary['groups']))
0665              {
0666                  $sql = 'SELECT group_id, group_name, group_type
0667                      FROM ' . GROUPS_TABLE . '
0668                      WHERE ' . $db->sql_in_set('group_id', $auth_ary['groups']) . '
0669                      ORDER BY group_type ASC, group_name';
0670                  $result = $db->sql_query($sql);
0671   
0672                  while ($row = $db->sql_fetchrow($result))
0673                  {
0674                      $template->assign_block_vars('role_mask.groups', array(
0675                          'GROUP_ID'        => $row['group_id'],
0676                          'GROUP_NAME'    => ($row['group_type'] == GROUP_SPECIAL) ? $user->lang['G_' . $row['group_name']] : $row['group_name'],
0677                          'U_PROFILE'        => append_sid("{$phpbb_root_path}memberlist.$phpEx", "mode=group&amp;g={$row['group_id']}"))
0678                      );
0679                  }
0680                  $db->sql_freeresult($result);
0681              }
0682          }
0683      }
0684   
0685      /**
0686      * NOTE: this function is not in use atm
0687      * Add a new option to the list ... $options is a hash of form ->
0688      * $options = array(
0689      *    'local'        => array('option1', 'option2', ...),
0690      *    'global'    => array('optionA', 'optionB', ...)
0691      * );
0692      */
0693      function acl_add_option($options)
0694      {
0695          global $db, $cache;
0696   
0697          if (!is_array($options))
0698          {
0699              return false;
0700          }
0701   
0702          $cur_options = array();
0703   
0704          // Determine current options
0705          $sql = 'SELECT auth_option, is_global, is_local
0706              FROM ' . ACL_OPTIONS_TABLE . '
0707              ORDER BY auth_option_id';
0708          $result = $db->sql_query($sql);
0709   
0710          while ($row = $db->sql_fetchrow($result))
0711          {
0712              $cur_options[$row['auth_option']] = ($row['is_global'] && $row['is_local']) ? 'both' : (($row['is_global']) ? 'global' : 'local');
0713          }
0714          $db->sql_freeresult($result);
0715   
0716          // Here we need to insert new options ... this requires discovering whether
0717          // an options is global, local or both and whether we need to add an permission
0718          // set flag (x_)
0719          $new_options = array('local' => array(), 'global' => array());
0720   
0721          foreach ($options as $type => $option_ary)
0722          {
0723              $option_ary = array_unique($option_ary);
0724   
0725              foreach ($option_ary as $option_value)
0726              {
0727                  $new_options[$type][] = $option_value;
0728   
0729                  $flag = substr($option_value, 0, strpos($option_value, '_') + 1);
0730   
0731                  if (!in_array($flag, $new_options[$type]))
0732                  {
0733                      $new_options[$type][] = $flag;
0734                  }
0735              }
0736          }
0737          unset($options);
0738   
0739          $options = array();
0740          $options['local'] = array_diff($new_options['local'], $new_options['global']);
0741          $options['global'] = array_diff($new_options['global'], $new_options['local']);
0742          $options['both'] = array_intersect($new_options['local'], $new_options['global']);
0743   
0744          // Now check which options to add/update
0745          $add_options = $update_options = array();
0746   
0747          // First local ones...
0748          foreach ($options as $type => $option_ary)
0749          {
0750              foreach ($option_ary as $option)
0751              {
0752                  if (!isset($cur_options[$option]))
0753                  {
0754                      $add_options[] = array(
0755                          'auth_option'    => (string) $option,
0756                          'is_global'        => ($type == 'global' || $type == 'both') ? 1 : 0,
0757                          'is_local'        => ($type == 'local' || $type == 'both') ? 1 : 0
0758                      );
0759   
0760                      continue;
0761                  }
0762   
0763                  // Else, update existing entry if it is changed...
0764                  if ($type === $cur_options[$option])
0765                  {
0766                      continue;
0767                  }
0768   
0769                  // New type is always both:
0770                  // If is now both, we set both.
0771                  // If it was global the new one is local and we need to set it to both
0772                  // If it was local the new one is global and we need to set it to both
0773                  $update_options[] = $option;
0774              }
0775          }
0776   
0777          if (!empty($add_options))
0778          {
0779              $db->sql_multi_insert(ACL_OPTIONS_TABLE, $add_options);
0780          }
0781   
0782          if (!empty($update_options))
0783          {
0784              $sql = 'UPDATE ' . ACL_OPTIONS_TABLE . '
0785                  SET is_global = 1, is_local = 1
0786                  WHERE ' . $db->sql_in_set('auth_option', $update_options);
0787              $db->sql_query($sql);
0788          }
0789   
0790          $cache->destroy('_acl_options');
0791          $this->acl_clear_prefetch();
0792   
0793          // Because we just changed the options and also purged the options cache, we instantly update/regenerate it for later calls to succeed.
0794          $this->acl_options = array();
0795          $this->auth_admin();
0796   
0797          return true;
0798      }
0799   
0800      /**
0801      * Set a user or group ACL record
0802      */
0803      function acl_set($ug_type, $forum_id, $ug_id, $auth, $role_id = 0, $clear_prefetch = true)
0804      {
0805          global $db;
0806   
0807          // One or more forums
0808          if (!is_array($forum_id))
0809          {
0810              $forum_id = array($forum_id);
0811          }
0812   
0813          // One or more users
0814          if (!is_array($ug_id))
0815          {
0816              $ug_id = array($ug_id);
0817          }
0818   
0819          $ug_id_sql = $db->sql_in_set($ug_type . '_id', array_map('intval', $ug_id));
0820          $forum_sql = $db->sql_in_set('forum_id', array_map('intval', $forum_id));
0821   
0822          // Instead of updating, inserting, removing we just remove all current settings and re-set everything...
0823          $table = ($ug_type == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE;
0824          $id_field = $ug_type . '_id';
0825   
0826          // Get any flags as required
0827          reset($auth);
0828          $flag = key($auth);
0829          $flag = substr($flag, 0, strpos($flag, '_') + 1);
0830   
0831          // This ID (the any-flag) is set if one or more permissions are true...
0832          $any_option_id = (int) $this->acl_options['id'][$flag];
0833   
0834          // Remove any-flag from auth ary
0835          if (isset($auth[$flag]))
0836          {
0837              unset($auth[$flag]);
0838          }
0839   
0840          // Remove current auth options...
0841          $auth_option_ids = array((int) $any_option_id);
0842          foreach ($auth as $auth_option => $auth_setting)
0843          {
0844              $auth_option_ids[] = (int) $this->acl_options['id'][$auth_option];
0845          }
0846   
0847          $sql = "DELETE FROM $table
0848              WHERE $forum_sql
0849                  AND $ug_id_sql
0850                  AND " . $db->sql_in_set('auth_option_id', $auth_option_ids);
0851          $db->sql_query($sql);
0852   
0853          // Remove those having a role assigned... the correct type of course...
0854          $sql = 'SELECT role_id
0855              FROM ' . ACL_ROLES_TABLE . "
0856              WHERE role_type = '" . $db->sql_escape($flag) . "'";
0857          $result = $db->sql_query($sql);
0858   
0859          $role_ids = array();
0860          while ($row = $db->sql_fetchrow($result))
0861          {
0862              $role_ids[] = $row['role_id'];
0863          }
0864          $db->sql_freeresult($result);
0865   
0866          if (sizeof($role_ids))
0867          {
0868              $sql = "DELETE FROM $table
0869                  WHERE $forum_sql
0870                      AND $ug_id_sql
0871                      AND auth_option_id = 0
0872                      AND " . $db->sql_in_set('auth_role_id', $role_ids);
0873              $db->sql_query($sql);
0874          }
0875   
0876          // Ok, include the any-flag if one or more auth options are set to yes...
0877          foreach ($auth as $auth_option => $setting)
0878          {
0879              if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER))
0880              {
0881                  $auth[$flag] = ACL_YES;
0882              }
0883          }
0884   
0885          $sql_ary = array();
0886          foreach ($forum_id as $forum)
0887          {
0888              $forum = (int) $forum;
0889   
0890              if ($role_id)
0891              {
0892                  foreach ($ug_id as $id)
0893                  {
0894                      $sql_ary[] = array(
0895                          $id_field            => (int) $id,
0896                          'forum_id'            => (int) $forum,
0897                          'auth_option_id'    => 0,
0898                          'auth_setting'        => 0,
0899                          'auth_role_id'        => (int) $role_id,
0900                      );
0901                  }
0902              }
0903              else
0904              {
0905                  foreach ($auth as $auth_option => $setting)
0906                  {
0907                      $auth_option_id = (int) $this->acl_options['id'][$auth_option];
0908   
0909                      if ($setting != ACL_NO)
0910                      {
0911                          foreach ($ug_id as $id)
0912                          {
0913                              $sql_ary[] = array(
0914                                  $id_field            => (int) $id,
0915                                  'forum_id'            => (int) $forum,
0916                                  'auth_option_id'    => (int) $auth_option_id,
0917                                  'auth_setting'        => (int) $setting
0918                              );
0919                          }
0920                      }
0921                  }
0922              }
0923          }
0924   
0925          $db->sql_multi_insert($table, $sql_ary);
0926   
0927          if ($clear_prefetch)
0928          {
0929              $this->acl_clear_prefetch();
0930          }
0931      }
0932   
0933      /**
0934      * Set a role-specific ACL record
0935      */
0936      function acl_set_role($role_id, $auth)
0937      {
0938          global $db;
0939   
0940          // Get any-flag as required
0941          reset($auth);
0942          $flag = key($auth);
0943          $flag = substr($flag, 0, strpos($flag, '_') + 1);
0944   
0945          // Remove any-flag from auth ary
0946          if (isset($auth[$flag]))
0947          {
0948              unset($auth[$flag]);
0949          }
0950   
0951          // Re-set any flag...
0952          foreach ($auth as $auth_option => $setting)
0953          {
0954              if ($setting == ACL_YES && (!isset($auth[$flag]) || $auth[$flag] == ACL_NEVER))
0955              {
0956                  $auth[$flag] = ACL_YES;
0957              }
0958          }
0959   
0960          $sql_ary = array();
0961          foreach ($auth as $auth_option => $setting)
0962          {
0963              $auth_option_id = (int) $this->acl_options['id'][$auth_option];
0964   
0965              if ($setting != ACL_NO)
0966              {
0967                  $sql_ary[] = array(
0968                      'role_id'            => (int) $role_id,
0969                      'auth_option_id'    => (int) $auth_option_id,
0970                      'auth_setting'        => (int) $setting
0971                  );
0972              }
0973          }
0974   
0975          // If no data is there, we set the any-flag to ACL_NEVER...
0976          if (!sizeof($sql_ary))
0977          {
0978              $sql_ary[] = array(
0979                  'role_id'            => (int) $role_id,
0980                  'auth_option_id'    => (int) $this->acl_options['id'][$flag],
0981                  'auth_setting'        => ACL_NEVER
0982              );
0983          }
0984   
0985          // Remove current auth options...
0986          $sql = 'DELETE FROM ' . ACL_ROLES_DATA_TABLE . '
0987              WHERE role_id = ' . $role_id;
0988          $db->sql_query($sql);
0989   
0990          // Now insert the new values
0991          $db->sql_multi_insert(ACL_ROLES_DATA_TABLE, $sql_ary);
0992   
0993          $this->acl_clear_prefetch();
0994      }
0995   
0996      /**
0997      * Remove local permission
0998      */
0999      function acl_delete($mode, $ug_id = false, $forum_id = false, $permission_type = false)
1000      {
1001          global $db;
1002   
1003          if ($ug_id === false && $forum_id === false)
1004          {
1005              return;
1006          }
1007   
1008          $option_id_ary = array();
1009          $table = ($mode == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE;
1010          $id_field = $mode . '_id';
1011   
1012          $where_sql = array();
1013   
1014          if ($forum_id !== false)
1015          {
1016              $where_sql[] = (!is_array($forum_id)) ? 'forum_id = ' . (int) $forum_id : $db->sql_in_set('forum_id', array_map('intval', $forum_id));
1017          }
1018   
1019          if ($ug_id !== false)
1020          {
1021              $where_sql[] = (!is_array($ug_id)) ? $id_field . ' = ' . (int) $ug_id : $db->sql_in_set($id_field, array_map('intval', $ug_id));
1022          }
1023   
1024          // There seem to be auth options involved, therefore we need to go through the list and make sure we capture roles correctly
1025          if ($permission_type !== false)
1026          {
1027              // Get permission type
1028              $sql = 'SELECT auth_option, auth_option_id
1029                  FROM ' . ACL_OPTIONS_TABLE . "
1030                  WHERE auth_option " . $db->sql_like_expression($permission_type . $db->get_any_char());
1031              $result = $db->sql_query($sql);
1032   
1033              $auth_id_ary = array();
1034              while ($row = $db->sql_fetchrow($result))
1035              {
1036                  $option_id_ary[] = $row['auth_option_id'];
1037                  $auth_id_ary[$row['auth_option']] = ACL_NO;
1038              }
1039              $db->sql_freeresult($result);
1040   
1041              // First of all, lets grab the items having roles with the specified auth options assigned
1042              $sql = "SELECT auth_role_id, $id_field, forum_id
1043                  FROM $table" . ACL_ROLES_TABLE . " r
1044                  WHERE auth_role_id <> 0
1045                      AND auth_role_id = r.role_id
1046                      AND r.role_type = '{$permission_type}'
1047                      AND " . implode(' AND ', $where_sql) . '
1048                  ORDER BY auth_role_id';
1049              $result = $db->sql_query($sql);
1050   
1051              $cur_role_auth = array();
1052              while ($row = $db->sql_fetchrow($result))
1053              {
1054                  $cur_role_auth[$row['auth_role_id']][$row['forum_id']][] = $row[$id_field];
1055              }
1056              $db->sql_freeresult($result);
1057   
1058              // Get role data for resetting data
1059              if (sizeof($cur_role_auth))
1060              {
1061                  $sql = 'SELECT ao.auth_option, rd.role_id, rd.auth_setting
1062                      FROM ' . ACL_OPTIONS_TABLE . ' ao, ' . ACL_ROLES_DATA_TABLE . ' rd
1063                      WHERE ao.auth_option_id = rd.auth_option_id
1064                          AND ' . $db->sql_in_set('rd.role_id', array_keys($cur_role_auth));
1065                  $result = $db->sql_query($sql);
1066   
1067                  $auth_settings = array();
1068                  while ($row = $db->sql_fetchrow($result))
1069                  {
1070                      // We need to fill all auth_options, else setting it will fail...
1071                      if (!isset($auth_settings[$row['role_id']]))
1072                      {
1073                          $auth_settings[$row['role_id']] = $auth_id_ary;
1074                      }
1075                      $auth_settings[$row['role_id']][$row['auth_option']] = $row['auth_setting'];
1076                  }
1077                  $db->sql_freeresult($result);
1078   
1079                  // Set the options
1080                  foreach ($cur_role_auth as $role_id => $auth_row)
1081                  {
1082                      foreach ($auth_row as $f_id => $ug_row)
1083                      {
1084                          $this->acl_set($mode, $f_id, $ug_row, $auth_settings[$role_id], 0, false);
1085                      }
1086                  }
1087              }
1088          }
1089   
1090          // Now, normally remove permissions...
1091          if ($permission_type !== false)
1092          {
1093              $where_sql[] = $db->sql_in_set('auth_option_id', array_map('intval', $option_id_ary));
1094          }
1095   
1096          $sql = "DELETE FROM $table
1097              WHERE " . implode(' AND ', $where_sql);
1098          $db->sql_query($sql);
1099   
1100          $this->acl_clear_prefetch();
1101      }
1102   
1103      /**
1104      * Assign category to template
1105      * used by display_mask()
1106      */
1107      function assign_cat_array(&$category_array, $tpl_cat, $tpl_mask, $ug_id, $forum_id, $s_view, $show_trace = false)
1108      {
1109          global $template, $user, $phpbb_admin_path, $phpEx, $phpbb_container;
1110   
1111          $phpbb_permissions = $phpbb_container->get('acl.permissions');
1112   
1113          @reset($category_array);
1114          while (list($cat, $cat_array) = each($category_array))
1115          {
1116              $template->assign_block_vars($tpl_cat, array(
1117                  'S_YES'        => ($cat_array['S_YES'] && !$cat_array['S_NEVER'] && !$cat_array['S_NO']) ? true : false,
1118                  'S_NEVER'    => ($cat_array['S_NEVER'] && !$cat_array['S_YES'] && !$cat_array['S_NO']) ? true : false,
1119                  'S_NO'        => ($cat_array['S_NO'] && !$cat_array['S_NEVER'] && !$cat_array['S_YES']) ? true : false,
1120   
1121                  'CAT_NAME'    => $phpbb_permissions->get_category_lang($cat),
1122              ));
1123   
1124              /*    Sort permissions by name (more naturaly and user friendly than sorting by a primary key)
1125              *    Commented out due to it's memory consumption and time needed
1126              *
1127              $key_array = array_intersect(array_keys($user->lang), array_map(create_function('$a', 'return "acl_" . $a;'), array_keys($cat_array['permissions'])));
1128              $values_array = $cat_array['permissions'];
1129   
1130              $cat_array['permissions'] = array();
1131   
1132              foreach ($key_array as $key)
1133              {
1134                  $key = str_replace('acl_', '', $key);
1135                  $cat_array['permissions'][$key] = $values_array[$key];
1136              }
1137              unset($key_array, $values_array);
1138  */
1139              @reset($cat_array['permissions']);
1140              while (list($permission, $allowed) = each($cat_array['permissions']))
1141              {
1142                  if ($s_view)
1143                  {
1144                      $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array(
1145                          'S_YES'        => ($allowed == ACL_YES) ? true : false,
1146                          'S_NEVER'    => ($allowed == ACL_NEVER) ? true : false,
1147   
1148                          'UG_ID'            => $ug_id,
1149                          'FORUM_ID'        => $forum_id,
1150                          'FIELD_NAME'    => $permission,
1151                          'S_FIELD_NAME'    => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']',
1152   
1153                          '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") : '',
1154                          'UA_TRACE'        => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission", false) : '',
1155   
1156                          'PERMISSION'    => $phpbb_permissions->get_permission_lang($permission),
1157                      ));
1158                  }
1159                  else
1160                  {
1161                      $template->assign_block_vars($tpl_cat . '.' . $tpl_mask, array(
1162                          'S_YES'        => ($allowed == ACL_YES) ? true : false,
1163                          'S_NEVER'    => ($allowed == ACL_NEVER) ? true : false,
1164                          'S_NO'        => ($allowed == ACL_NO) ? true : false,
1165   
1166                          'UG_ID'            => $ug_id,
1167                          'FORUM_ID'        => $forum_id,
1168                          'FIELD_NAME'    => $permission,
1169                          'S_FIELD_NAME'    => 'setting[' . $ug_id . '][' . $forum_id . '][' . $permission . ']',
1170   
1171                          '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") : '',
1172                          'UA_TRACE'        => ($show_trace) ? append_sid("{$phpbb_admin_path}index.$phpEx", "i=permissions&mode=trace&u=$ug_id&f=$forum_id&auth=$permission", false) : '',
1173   
1174                          'PERMISSION'    => $phpbb_permissions->get_permission_lang($permission),
1175                      ));
1176                  }
1177              }
1178          }
1179      }
1180   
1181      /**
1182      * Building content array from permission rows with explicit key ordering
1183      * used by display_mask()
1184      */
1185      function build_permission_array(&$permission_row, &$content_array, &$categories, $key_sort_array)
1186      {
1187          global $user, $phpbb_container;
1188   
1189          $phpbb_permissions = $phpbb_container->get('acl.permissions');
1190   
1191          foreach ($key_sort_array as $forum_id)
1192          {
1193              if (!isset($permission_row[$forum_id]))
1194              {
1195                  continue;
1196              }
1197   
1198              $permissions = $permission_row[$forum_id];
1199              ksort($permissions);
1200   
1201              @reset($permissions);
1202              while (list($permission, $auth_setting) = each($permissions))
1203              {
1204                  $cat = $phpbb_permissions->get_permission_category($permission);
1205   
1206                  // Build our categories array
1207                  if (!isset($categories[$cat]))
1208                  {
1209                      $categories[$cat] = $phpbb_permissions->get_category_lang($cat);
1210                  }
1211   
1212                  // Build our content array
1213                  if (!isset($content_array[$forum_id]))
1214                  {
1215                      $content_array[$forum_id] = array();
1216                  }
1217   
1218                  if (!isset($content_array[$forum_id][$cat]))
1219                  {
1220                      $content_array[$forum_id][$cat] = array(
1221                          'S_YES'            => false,
1222                          'S_NEVER'        => false,
1223                          'S_NO'            => false,
1224                          'permissions'    => array(),
1225                      );
1226                  }
1227   
1228                  $content_array[$forum_id][$cat]['S_YES'] |= ($auth_setting == ACL_YES) ? true : false;
1229                  $content_array[$forum_id][$cat]['S_NEVER'] |= ($auth_setting == ACL_NEVER) ? true : false;
1230                  $content_array[$forum_id][$cat]['S_NO'] |= ($auth_setting == ACL_NO) ? true : false;
1231   
1232                  $content_array[$forum_id][$cat]['permissions'][$permission] = $auth_setting;
1233              }
1234          }
1235      }
1236   
1237      /**
1238      * Use permissions from another user. This transferes a permission set from one user to another.
1239      * The other user is always able to revert back to his permission set.
1240      * This function does not check for lower/higher permissions, it is possible for the user to gain
1241      * "more" permissions by this.
1242      * Admin permissions will not be copied.
1243      */
1244      function ghost_permissions($from_user_id, $to_user_id)
1245      {
1246          global $db;
1247   
1248          if ($to_user_id == ANONYMOUS)
1249          {
1250              return false;
1251          }
1252   
1253          $hold_ary = $this->acl_raw_data_single_user($from_user_id);
1254   
1255          // Key 0 in $hold_ary are global options, all others are forum_ids
1256   
1257          // We disallow copying admin permissions
1258          foreach ($this->acl_options['global'] as $opt => $id)
1259          {
1260              if (strpos($opt, 'a_') === 0)
1261              {
1262                  $hold_ary[0][$this->acl_options['id'][$opt]] = ACL_NEVER;
1263              }
1264          }
1265   
1266          // Force a_switchperm to be allowed
1267          $hold_ary[0][$this->acl_options['id']['a_switchperm']] = ACL_YES;
1268   
1269          $user_permissions = $this->build_bitstring($hold_ary);
1270   
1271          if (!$user_permissions)
1272          {
1273              return false;
1274          }
1275   
1276          $sql = 'UPDATE ' . USERS_TABLE . "
1277              SET user_permissions = '" . $db->sql_escape($user_permissions) . "',
1278                  user_perm_from = $from_user_id
1279              WHERE user_id = " . $to_user_id;
1280          $db->sql_query($sql);
1281   
1282          return true;
1283      }
1284  }
1285