Verzeichnisstruktur phpBB-3.0.0


Veröffentlicht
12.12.2007

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:51 - Dateigröße: 36.76 KiB


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