[ Index ]

PHP Cross Reference of phpBB 3.0 Beta 3

title

Body

[close]

/includes/acp/ -> auth.php (source)

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


Generated: Wed Nov 22 00:35:05 2006 Cross-referenced by PHPXref 0.6