aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/classes
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes/classes')
-rw-r--r--phpBB/includes/classes/acl.php946
-rw-r--r--phpBB/includes/classes/cache.php425
-rw-r--r--phpBB/includes/classes/session.php1289
-rw-r--r--phpBB/includes/classes/template.php531
-rw-r--r--phpBB/includes/classes/template_compile.php904
-rw-r--r--phpBB/includes/classes/user.php1124
6 files changed, 0 insertions, 5219 deletions
diff --git a/phpBB/includes/classes/acl.php b/phpBB/includes/classes/acl.php
deleted file mode 100644
index 049b0842e2..0000000000
--- a/phpBB/includes/classes/acl.php
+++ /dev/null
@@ -1,946 +0,0 @@
-<?php
-/**
-*
-* @package phpBB3
-* @version $Id$
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Permission/ACL class
-* @package phpBB3
-*/
-class phpbb_acl
-{
- public $phpbb_required = array('acm', 'db');
- public $phpbb_optional = array();
-
- public $acl_raw;
-
- private $acl = array();
- private $cache = array();
- public $acl_options = array();
- private $acl_element_ids = false;
- private $recache = false;
-
- public function __construct()
- {
- $this->acl = $this->cache = $this->acl_options = array();
- $this->acl_element_ids = false;
-
- if (($this->acl_options = phpbb::$acm->get('acl_options')) === false)
- {
- $sql = 'SELECT auth_option_id, auth_option, is_global, is_local
- FROM ' . ACL_OPTIONS_TABLE . '
- ORDER BY auth_option_id';
- $result = phpbb::$db->sql_query($sql);
-
- $global = $local = 0;
- $this->acl_options = array();
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- if ($row['is_global'])
- {
- $this->acl_options['global'][$row['auth_option']] = $global++;
- }
-
- if ($row['is_local'])
- {
- $this->acl_options['local'][$row['auth_option']] = $local++;
- }
-
- $this->acl_options['id'][$row['auth_option']] = (int) $row['auth_option_id'];
- $this->acl_options['option'][(int) $row['auth_option_id']] = $row['auth_option'];
- }
- phpbb::$db->sql_freeresult($result);
-
- phpbb::$acm->put('acl_options', $this->acl_options);
- $this->recache = true;
- }
-
- // Add raw data acl class
- $this->acl_raw = new phpbb_acl_raw_data();
- }
-
- /**
- * Init permissions
- */
- public function init(array &$userdata)
- {
- if (!trim($userdata['user_permissions']) || $this->recache)
- {
- $this->acl_cache($userdata);
- }
-
- // Fill ACL array
- $this->_fill_acl($userdata['user_permissions']);
-
- // Verify bitstring length with options provided...
- $renew = false;
- $global_length = sizeof($this->acl_options['global']);
- $local_length = sizeof($this->acl_options['local']);
-
- // Specify comparing length (bitstring is padded to 31 bits)
- $global_length = ($global_length % 31) ? ($global_length - ($global_length % 31) + 31) : $global_length;
- $local_length = ($local_length % 31) ? ($local_length - ($local_length % 31) + 31) : $local_length;
-
- // You thought we are finished now? Noooo... now compare them.
- foreach ($this->acl as $forum_id => $bitstring)
- {
- if (($forum_id && strlen($bitstring) != $local_length) || (!$forum_id && strlen($bitstring) != $global_length))
- {
- $renew = true;
- break;
- }
- }
-
- // If a bitstring within the list does not match the options, we have a user with incorrect permissions set and need to renew them
- if ($renew)
- {
- $this->acl_cache($userdata);
- $this->_fill_acl($userdata['user_permissions']);
- }
-
- return;
- }
-
- /**
- * Fill ACL array with relevant bitstrings from user_permissions column
- * @access private
- */
- private function _fill_acl($user_permissions)
- {
- $this->acl = array();
- $user_permissions = explode("\n", $user_permissions);
-
- foreach ($user_permissions as $f => $seq)
- {
- if ($seq)
- {
- $i = 0;
-
- if (!isset($this->acl[$f]))
- {
- $this->acl[$f] = '';
- }
-
- while ($subseq = substr($seq, $i, 6))
- {
- // We put the original bitstring into the acl array
- $this->acl[$f] .= str_pad(base_convert($subseq, 36, 2), 31, 0, STR_PAD_LEFT);
- $i += 6;
- }
- }
- }
- }
-
- /**
- * Look up an option
- * if the option is prefixed with !, then the result becomes negated
- *
- * If a forum id is specified the local option will be combined with a global option if one exist.
- * If a forum id is not specified, only the global option will be checked.
- */
- public function acl_get($opt, $f = 0)
- {
- $negate = false;
-
- if (strpos($opt, '!') === 0)
- {
- $negate = true;
- $opt = substr($opt, 1);
- }
-
- if (!isset($this->cache[$f][$opt]))
- {
- // We combine the global/local option with an OR because some options are global and local.
- // If the user has the global permission the local one is true too and vice versa
- $this->cache[$f][$opt] = false;
-
- // Is this option a global permission setting?
- if (isset($this->acl_options['global'][$opt]))
- {
- if (isset($this->acl[0]))
- {
- $this->cache[$f][$opt] = $this->acl[0][$this->acl_options['global'][$opt]];
- }
- }
-
- // Is this option a local permission setting?
- // But if we check for a global option only, we won't combine the options...
- if ($f != 0 && isset($this->acl_options['local'][$opt]))
- {
- if (isset($this->acl[$f]) && isset($this->acl[$f][$this->acl_options['local'][$opt]]))
- {
- $this->cache[$f][$opt] |= $this->acl[$f][$this->acl_options['local'][$opt]];
- }
- }
- }
-
- // Founder always has all global options set to true...
- return $negate xor $this->cache[$f][$opt];
- }
-
- /**
- * Get forums with the specified permission setting
- * if the option is prefixed with !, then the result becomes negated
- *
- * @param bool $clean set to true if only values needs to be returned which are set/unset
- */
- public function acl_getf($opt, $clean = false)
- {
- $acl_f = array();
- $negate = false;
-
- if (strpos($opt, '!') === 0)
- {
- $negate = true;
- $opt = substr($opt, 1);
- }
-
- // If we retrieve a list of forums not having permissions in, we need to get every forum_id
- if ($negate)
- {
- if ($this->acl_forum_ids === false)
- {
- $sql = 'SELECT forum_id
- FROM ' . FORUMS_TABLE;
-
- if (sizeof($this->acl))
- {
- $sql .= ' WHERE ' . phpbb::$db->sql_in_set('forum_id', array_keys($this->acl), true);
- }
- $result = phpbb::$db->sql_query($sql);
-
- $this->acl_forum_ids = array();
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $this->acl_forum_ids[] = $row['forum_id'];
- }
- phpbb::$db->sql_freeresult($result);
- }
- }
-
- if (isset($this->acl_options['local'][$opt]))
- {
- foreach ($this->acl as $f => $bitstring)
- {
- // Skip global settings
- if (!$f)
- {
- continue;
- }
-
- $allowed = (!isset($this->cache[$f][$opt])) ? $this->acl_get($opt, $f) : $this->cache[$f][$opt];
-
- if (!$clean)
- {
- $acl_f[$f][$opt] = $negate xor $allowed;
- }
- else if ($negate xor $allowed)
- {
- $acl_f[$f][$opt] = 1;
- }
- }
- }
-
- // If we get forum_ids not having this permission, we need to fill the remaining parts
- if ($negate && sizeof($this->acl_forum_ids))
- {
- foreach ($this->acl_forum_ids as $f)
- {
- $acl_f[$f][$opt] = 1;
- }
- }
-
- return $acl_f;
- }
-
- /**
- * Get local permission state for any forum.
- *
- * Returns true if user has the permission in one or more forums, false if in no forum.
- * If global option is checked it returns the global state (same as acl_get($opt))
- * Local option has precedence...
- */
- public function acl_getf_global($opt)
- {
- if (is_array($opt))
- {
- // evaluates to true as soon as acl_getf_global is true for one option
- foreach ($opt as $check_option)
- {
- if ($this->acl_getf_global($check_option))
- {
- return true;
- }
- }
-
- return false;
- }
-
- if (isset($this->acl_options['local'][$opt]))
- {
- foreach ($this->acl as $f => $bitstring)
- {
- // Skip global settings
- if (!$f)
- {
- continue;
- }
-
- // as soon as the user has any permission we're done so return true
- if ((!isset($this->cache[$f][$opt])) ? $this->acl_get($opt, $f) : $this->cache[$f][$opt])
- {
- return true;
- }
- }
- }
- else if (isset($this->acl_options['global'][$opt]))
- {
- return $this->acl_get($opt);
- }
-
- return false;
- }
-
- /**
- * Get permission settings (more than one)
- */
- public function acl_gets()
- {
- $args = func_get_args();
- $f = array_pop($args);
-
- if (!is_numeric($f))
- {
- $args[] = $f;
- $f = 0;
- }
-
- // alternate syntax: acl_gets(array('m_', 'a_'), $forum_id)
- if (is_array($args[0]))
- {
- $args = $args[0];
- }
-
- $acl = 0;
- foreach ($args as $opt)
- {
- $acl |= $this->acl_get($opt, $f);
- }
-
- return $acl;
- }
-
- /**
- * Get permission listing based on user_id/options/forum_ids
- */
- public function acl_get_list($user_id = false, $opts = false, $forum_id = false)
- {
- if ($user_id !== false && !is_array($user_id) && $opts === false && $forum_id === false)
- {
- $hold_ary = array($user_id => $this->acl_raw->single_user($user_id));
- }
- else
- {
- $hold_ary = $this->acl_raw->data($user_id, $opts, $forum_id);
- }
-
- $auth_ary = array();
- foreach ($hold_ary as $user_id => $forum_ary)
- {
- foreach ($forum_ary as $forum_id => $auth_option_ary)
- {
- foreach ($auth_option_ary as $auth_option => $auth_setting)
- {
- if ($auth_setting)
- {
- $auth_ary[$forum_id][$auth_option][] = $user_id;
- }
- }
- }
- }
-
- return $auth_ary;
- }
-
- /**
- * Cache data to user_permissions row
- */
- public function acl_cache(array &$userdata)
- {
- // Empty user_permissions
- $userdata['user_permissions'] = '';
-
- $hold_ary = $this->acl_raw->single_user($userdata['user_id']);
-
- // Key 0 in $hold_ary are global options, all others are forum_ids
-
- // If this user is founder we're going to force fill the admin options ...
- if ($userdata['user_type'] == phpbb::USER_FOUNDER)
- {
- foreach ($this->acl_options['global'] as $opt => $id)
- {
- if (strpos($opt, 'a_') === 0)
- {
- $hold_ary[0][$this->acl_options['id'][$opt]] = phpbb::ACL_YES;
- }
- }
- }
-
- $hold_str = $this->build_bitstring($hold_ary);
-
- if ($hold_str)
- {
- $userdata['user_permissions'] = $hold_str;
-
- $sql = 'UPDATE ' . USERS_TABLE . "
- SET user_permissions = '" . phpbb::$db->sql_escape($userdata['user_permissions']) . "',
- user_perm_from = 0
- WHERE user_id = " . $userdata['user_id'];
- phpbb::$db->sql_query($sql);
- }
-
- return;
- }
-
- /**
- * Build bitstring from permission set
- */
- protected function build_bitstring(&$hold_ary)
- {
- $hold_str = '';
-
- if (sizeof($hold_ary))
- {
- ksort($hold_ary);
-
- $last_f = 0;
-
- foreach ($hold_ary as $f => $auth_ary)
- {
- $ary_key = (!$f) ? 'global' : 'local';
-
- $bitstring = array();
- foreach ($this->acl_options[$ary_key] as $opt => $id)
- {
- if (isset($auth_ary[$this->acl_options['id'][$opt]]))
- {
- $bitstring[$id] = $auth_ary[$this->acl_options['id'][$opt]];
-
- $option_key = substr($opt, 0, strpos($opt, '_') + 1);
-
- // If one option is allowed, the global permission for this option has to be allowed too
- // example: if the user has the a_ permission this means he has one or more a_* permissions
- if ($auth_ary[$this->acl_options['id'][$opt]] == phpbb::ACL_YES && (!isset($bitstring[$this->acl_options[$ary_key][$option_key]]) || $bitstring[$this->acl_options[$ary_key][$option_key]] == phpbb::ACL_NEVER))
- {
- $bitstring[$this->acl_options[$ary_key][$option_key]] = phpbb::ACL_YES;
- }
- }
- else
- {
- $bitstring[$id] = phpbb::ACL_NEVER;
- }
- }
-
- // Now this bitstring defines the permission setting for the current forum $f (or global setting)
- $bitstring = implode('', $bitstring);
-
- // The line number indicates the id, therefore we have to add empty lines for those ids not present
- $hold_str .= str_repeat("\n", $f - $last_f);
-
- // Convert bitstring for storage - we do not use binary/bytes because PHP's string functions are not fully binary safe
- for ($i = 0, $bit_length = strlen($bitstring); $i < $bit_length; $i += 31)
- {
- $hold_str .= str_pad(base_convert(str_pad(substr($bitstring, $i, 31), 31, 0, STR_PAD_RIGHT), 2, 36), 6, 0, STR_PAD_LEFT);
- }
-
- $last_f = $f;
- }
- unset($bitstring);
-
- $hold_str = rtrim($hold_str);
- }
-
- return $hold_str;
- }
-
- /**
- * Clear one or all users cached permission settings
- */
- public function acl_clear_prefetch($user_id = false)
- {
- // Rebuild options cache
- phpbb::$acm->destroy('role_cache');
-
- $sql = 'SELECT *
- FROM ' . ACL_ROLES_DATA_TABLE . '
- ORDER BY role_id ASC';
- $result = phpbb::$db->sql_query($sql);
-
- $this->role_cache = array();
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $this->role_cache[$row['role_id']][$row['auth_option_id']] = (int) $row['auth_setting'];
- }
- phpbb::$db->sql_freeresult($result);
-
- foreach ($this->role_cache as $role_id => $role_options)
- {
- $this->role_cache[$role_id] = serialize($role_options);
- }
-
- phpbb::$acm->put('role_cache', $this->role_cache);
-
- // Now empty user permissions
- $where_sql = '';
-
- if ($user_id !== false)
- {
- $user_id = (!is_array($user_id)) ? $user_id = array((int) $user_id) : array_map('intval', $user_id);
- $where_sql = ' WHERE ' . phpbb::$db->sql_in_set('user_id', $user_id);
- }
-
- $sql = 'UPDATE ' . USERS_TABLE . "
- SET user_permissions = '',
- user_perm_from = 0
- $where_sql";
- phpbb::$db->sql_query($sql);
-
- return;
- }
-
-/**
-}
-
- * Role-specific methods/definitionis used by phpbb_acl
-class phpbb_acl_role
-{
- */
-
- /**
- * Get assigned roles
- * @todo: protected or public?
- */
- public function acl_role_data($user_type, $role_type, $ug_id = false, $forum_id = false)
- {
- $roles = array();
-
- $sql_id = ($user_type == 'user') ? 'user_id' : 'group_id';
-
- $sql_ug = ($ug_id !== false) ? ((!is_array($ug_id)) ? "AND a.$sql_id = $ug_id" : 'AND ' . phpbb::$db->sql_in_set("a.$sql_id", $ug_id)) : '';
- $sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? "AND a.forum_id = $forum_id" : 'AND ' . phpbb::$db->sql_in_set('a.forum_id', $forum_id)) : '';
-
- // Grab assigned roles...
- $sql = 'SELECT a.auth_role_id, a.' . $sql_id . ', a.forum_id
- FROM ' . (($user_type == 'user') ? ACL_USERS_TABLE : ACL_GROUPS_TABLE) . ' a, ' . ACL_ROLES_TABLE . " r
- WHERE a.auth_role_id = r.role_id
- AND r.role_type = '" . phpbb::$db->sql_escape($role_type) . "'
- $sql_ug
- $sql_forum
- ORDER BY r.role_order ASC";
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $roles[$row[$sql_id]][$row['forum_id']] = $row['auth_role_id'];
- }
- phpbb::$db->sql_freeresult($result);
-
- return $roles;
- }
-}
-
-/**
-* data-specific methods/definitionis used by phpbb_acl
-*/
-class phpbb_acl_raw_data
-{
- /**
- * Get raw acl data based on user/option/forum
- * @todo: protected or public?
- */
- public function data($user_id = false, $opts = false, $forum_id = false)
- {
- $sql_user = ($user_id !== false) ? ((!is_array($user_id)) ? 'user_id = ' . (int) $user_id : phpbb::$db->sql_in_set('user_id', array_map('intval', $user_id))) : '';
- $sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? 'AND a.forum_id = ' . (int) $forum_id : 'AND ' . phpbb::$db->sql_in_set('a.forum_id', array_map('intval', $forum_id))) : '';
-
- $sql_opts = $sql_opts_select = $sql_opts_from = '';
- $hold_ary = array();
-
- if ($opts !== false)
- {
- $sql_opts_select = ', ao.auth_option';
- $sql_opts_from = ', ' . ACL_OPTIONS_TABLE . ' ao';
- $this->build_auth_option_statement('ao.auth_option', $opts, $sql_opts);
- }
-
- $sql_ary = array();
-
- // Grab non-role settings - user-specific
- $sql_ary[] = 'SELECT a.user_id, a.forum_id, a.auth_setting, a.auth_option_id' . $sql_opts_select . '
- FROM ' . ACL_USERS_TABLE . ' a' . $sql_opts_from . '
- WHERE a.auth_role_id = 0 ' .
- (($sql_opts_from) ? 'AND a.auth_option_id = ao.auth_option_id ' : '') .
- (($sql_user) ? 'AND a.' . $sql_user : '') . "
- $sql_forum
- $sql_opts";
-
- // Now the role settings - user-specific
- $sql_ary[] = 'SELECT a.user_id, a.forum_id, r.auth_option_id, r.auth_setting, r.auth_option_id' . $sql_opts_select . '
- FROM ' . ACL_USERS_TABLE . ' a, ' . ACL_ROLES_DATA_TABLE . ' r' . $sql_opts_from . '
- WHERE a.auth_role_id = r.role_id ' .
- (($sql_opts_from) ? 'AND r.auth_option_id = ao.auth_option_id ' : '') .
- (($sql_user) ? 'AND a.' . $sql_user : '') . "
- $sql_forum
- $sql_opts";
-
- foreach ($sql_ary as $sql)
- {
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $option = ($sql_opts_select) ? $row['auth_option'] : $this->acl_options['option'][$row['auth_option_id']];
- $hold_ary[$row['user_id']][$row['forum_id']][$option] = $row['auth_setting'];
- }
- phpbb::$db->sql_freeresult($result);
- }
-
- $sql_ary = array();
-
- // Now grab group settings - non-role specific...
- $sql_ary[] = 'SELECT ug.user_id, a.forum_id, a.auth_setting, a.auth_option_id' . $sql_opts_select . '
- FROM ' . ACL_GROUPS_TABLE . ' a, ' . USER_GROUP_TABLE . ' ug' . $sql_opts_from . '
- WHERE a.auth_role_id = 0 ' .
- (($sql_opts_from) ? 'AND a.auth_option_id = ao.auth_option_id ' : '') . '
- AND a.group_id = ug.group_id
- AND ug.user_pending = 0
- ' . (($sql_user) ? 'AND ug.' . $sql_user : '') . "
- $sql_forum
- $sql_opts";
-
- // Now grab group settings - role specific...
- $sql_ary[] = 'SELECT ug.user_id, a.forum_id, r.auth_setting, r.auth_option_id' . $sql_opts_select . '
- FROM ' . ACL_GROUPS_TABLE . ' a, ' . USER_GROUP_TABLE . ' ug, ' . ACL_ROLES_DATA_TABLE . ' r' . $sql_opts_from . '
- WHERE a.auth_role_id = r.role_id ' .
- (($sql_opts_from) ? 'AND r.auth_option_id = ao.auth_option_id ' : '') . '
- AND a.group_id = ug.group_id
- AND ug.user_pending = 0
- ' . (($sql_user) ? 'AND ug.' . $sql_user : '') . "
- $sql_forum
- $sql_opts";
-
- foreach ($sql_ary as $sql)
- {
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $option = ($sql_opts_select) ? $row['auth_option'] : $this->acl_options['option'][$row['auth_option_id']];
-
- // @todo: use the ref technique to reduce opcode generation
- if (!isset($hold_ary[$row['user_id']][$row['forum_id']][$option]) || (isset($hold_ary[$row['user_id']][$row['forum_id']][$option]) && $hold_ary[$row['user_id']][$row['forum_id']][$option] != phpbb::ACL_NEVER))
- {
- $hold_ary[$row['user_id']][$row['forum_id']][$option] = $row['auth_setting'];
-
- // If we detect phpbb::ACL_NEVER, we will unset the flag option (within building the bitstring it is correctly set again)
- if ($row['auth_setting'] == phpbb::ACL_NEVER)
- {
- $flag = substr($option, 0, strpos($option, '_') + 1);
-
- if (isset($hold_ary[$row['user_id']][$row['forum_id']][$flag]) && $hold_ary[$row['user_id']][$row['forum_id']][$flag] == phpbb::ACL_YES)
- {
- unset($hold_ary[$row['user_id']][$row['forum_id']][$flag]);
-
-/* if (in_array(phpbb::ACL_YES, $hold_ary[$row['user_id']][$row['forum_id']]))
- {
- $hold_ary[$row['user_id']][$row['forum_id']][$flag] = phpbb::ACL_YES;
- }
-*/
- }
- }
- }
- }
- phpbb::$db->sql_freeresult($result);
- }
-
- return $hold_ary;
- }
-
- /**
- * Get raw user based permission settings
- */
- public function user($user_id = false, $opts = false, $forum_id = false)
- {
- $sql_user = ($user_id !== false) ? ((!is_array($user_id)) ? 'user_id = ' . (int) $user_id : phpbb::$db->sql_in_set('user_id', array_map('intval', $user_id))) : '';
- $sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? 'AND a.forum_id = ' . (int) $forum_id : 'AND ' . phpbb::$db->sql_in_set('a.forum_id', array_map('intval', $forum_id))) : '';
-
- $sql_opts = '';
- $hold_ary = $sql_ary = array();
-
- if ($opts !== false)
- {
- $this->build_auth_option_statement('ao.auth_option', $opts, $sql_opts);
- }
-
- // Grab user settings - non-role specific...
- $sql_ary[] = 'SELECT a.user_id, a.forum_id, a.auth_setting, a.auth_option_id, ao.auth_option
- FROM ' . ACL_USERS_TABLE . ' a, ' . ACL_OPTIONS_TABLE . ' ao
- WHERE a.auth_role_id = 0
- AND a.auth_option_id = ao.auth_option_id ' .
- (($sql_user) ? 'AND a.' . $sql_user : '') . "
- $sql_forum
- $sql_opts
- ORDER BY a.forum_id, ao.auth_option";
-
- // Now the role settings - user-specific
- $sql_ary[] = 'SELECT a.user_id, a.forum_id, r.auth_option_id, r.auth_setting, r.auth_option_id, ao.auth_option
- FROM ' . ACL_USERS_TABLE . ' a, ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' ao
- WHERE a.auth_role_id = r.role_id
- AND r.auth_option_id = ao.auth_option_id ' .
- (($sql_user) ? 'AND a.' . $sql_user : '') . "
- $sql_forum
- $sql_opts
- ORDER BY a.forum_id, ao.auth_option";
-
- foreach ($sql_ary as $sql)
- {
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $hold_ary[$row['user_id']][$row['forum_id']][$row['auth_option']] = $row['auth_setting'];
- }
- phpbb::$db->sql_freeresult($result);
- }
-
- return $hold_ary;
- }
-
- /**
- * Get raw group based permission settings
- */
- public function group($group_id = false, $opts = false, $forum_id = false)
- {
- $sql_group = ($group_id !== false) ? ((!is_array($group_id)) ? 'group_id = ' . (int) $group_id : phpbb::$db->sql_in_set('group_id', array_map('intval', $group_id))) : '';
- $sql_forum = ($forum_id !== false) ? ((!is_array($forum_id)) ? 'AND a.forum_id = ' . (int) $forum_id : 'AND ' . phpbb::$db->sql_in_set('a.forum_id', array_map('intval', $forum_id))) : '';
-
- $sql_opts = '';
- $hold_ary = $sql_ary = array();
-
- if ($opts !== false)
- {
- $this->build_auth_option_statement('ao.auth_option', $opts, $sql_opts);
- }
-
- // Grab group settings - non-role specific...
- $sql_ary[] = 'SELECT a.group_id, a.forum_id, a.auth_setting, a.auth_option_id, ao.auth_option
- FROM ' . ACL_GROUPS_TABLE . ' a, ' . ACL_OPTIONS_TABLE . ' ao
- WHERE a.auth_role_id = 0
- AND a.auth_option_id = ao.auth_option_id ' .
- (($sql_group) ? 'AND a.' . $sql_group : '') . "
- $sql_forum
- $sql_opts
- ORDER BY a.forum_id, ao.auth_option";
-
- // Now grab group settings - role specific...
- $sql_ary[] = 'SELECT a.group_id, a.forum_id, r.auth_setting, r.auth_option_id, ao.auth_option
- FROM ' . ACL_GROUPS_TABLE . ' a, ' . ACL_ROLES_DATA_TABLE . ' r, ' . ACL_OPTIONS_TABLE . ' ao
- WHERE a.auth_role_id = r.role_id
- AND r.auth_option_id = ao.auth_option_id ' .
- (($sql_group) ? 'AND a.' . $sql_group : '') . "
- $sql_forum
- $sql_opts
- ORDER BY a.forum_id, ao.auth_option";
-
- foreach ($sql_ary as $sql)
- {
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $hold_ary[$row['group_id']][$row['forum_id']][$row['auth_option']] = $row['auth_setting'];
- }
- phpbb::$db->sql_freeresult($result);
- }
-
- return $hold_ary;
- }
-
- /**
- * Get raw acl data based on user for caching user_permissions
- * This function returns the same data as data(), but without the user id as the first key within the array.
- */
- public function single_user($user_id)
- {
- // Check if the role-cache is there
- if (($this->role_cache = phpbb::$acm->get('role_cache')) === false)
- {
- $this->role_cache = array();
-
- // We pre-fetch roles
- $sql = 'SELECT *
- FROM ' . ACL_ROLES_DATA_TABLE . '
- ORDER BY role_id ASC';
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $this->role_cache[$row['role_id']][$row['auth_option_id']] = (int) $row['auth_setting'];
- }
- phpbb::$db->sql_freeresult($result);
-
- foreach ($this->role_cache as $role_id => $role_options)
- {
- $this->role_cache[$role_id] = serialize($role_options);
- }
-
- phpbb::$acm->put('role_cache', $this->role_cache);
- }
-
- $hold_ary = array();
-
- // Grab user-specific permission settings
- $sql = 'SELECT forum_id, auth_option_id, auth_role_id, auth_setting
- FROM ' . ACL_USERS_TABLE . '
- WHERE user_id = ' . $user_id;
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- // If a role is assigned, assign all options included within this role. Else, only set this one option.
- if ($row['auth_role_id'])
- {
- $hold_ary[$row['forum_id']] = (empty($hold_ary[$row['forum_id']])) ? unserialize($this->role_cache[$row['auth_role_id']]) : $hold_ary[$row['forum_id']] + unserialize($this->role_cache[$row['auth_role_id']]);
- }
- else
- {
- $hold_ary[$row['forum_id']][$row['auth_option_id']] = $row['auth_setting'];
- }
- }
- phpbb::$db->sql_freeresult($result);
-
- // Now grab group-specific permission settings
- $sql = 'SELECT a.forum_id, a.auth_option_id, a.auth_role_id, a.auth_setting
- FROM ' . ACL_GROUPS_TABLE . ' a, ' . USER_GROUP_TABLE . ' ug
- WHERE a.group_id = ug.group_id
- AND ug.user_pending = 0
- AND ug.user_id = ' . $user_id;
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- if (!$row['auth_role_id'])
- {
- $this->_set_group_hold_ary($hold_ary[$row['forum_id']], $row['auth_option_id'], $row['auth_setting']);
- }
- else if (!empty($this->role_cache[$row['auth_role_id']]))
- {
- foreach (unserialize($this->role_cache[$row['auth_role_id']]) as $option_id => $setting)
- {
- $this->_set_group_hold_ary($hold_ary[$row['forum_id']], $option_id, $setting);
- }
- }
- }
- phpbb::$db->sql_freeresult($result);
-
- return $hold_ary;
- }
-
- /**
- * Private function snippet for setting a specific piece of the hold_ary
- */
- private function _set_group_hold_ary(&$hold_ary, $option_id, $setting)
- {
- if (!isset($hold_ary[$option_id]) || (isset($hold_ary[$option_id]) && $hold_ary[$option_id] != phpbb::ACL_NEVER))
- {
- $hold_ary[$option_id] = $setting;
-
- // If we detect phpbb::ACL_NEVER, we will unset the flag option (within building the bitstring it is correctly set again)
- if ($setting == phpbb::ACL_NEVER)
- {
- $flag = substr($this->acl_options['option'][$option_id], 0, strpos($this->acl_options['option'][$option_id], '_') + 1);
- $flag = (int) $this->acl_options['id'][$flag];
-
- if (isset($hold_ary[$flag]) && $hold_ary[$flag] == phpbb::ACL_YES)
- {
- unset($hold_ary[$flag]);
-
-/* This is uncommented, because i suspect this being slightly wrong due to mixed permission classes being possible
- if (in_array(phpbb::ACL_YES, $hold_ary))
- {
- $hold_ary[$flag] = phpbb::ACL_YES;
- }*/
- }
- }
- }
- }
-
- /**
- * Fill auth_option statement for later querying based on the supplied options
- */
- private function build_auth_option_statement($key, $auth_options, &$sql_opts)
- {
- if (!is_array($auth_options))
- {
- if (strpos($auth_options, '%') !== false)
- {
- $sql_opts = "AND $key " . phpbb::$db->sql_like_expression(str_replace('%', phpbb::$db->any_char, $auth_options));
- }
- else
- {
- $sql_opts = "AND $key = '" . phpbb::$db->sql_escape($auth_options) . "'";
- }
- }
- else
- {
- $is_like_expression = false;
-
- foreach ($auth_options as $option)
- {
- if (strpos($option, '%') !== false)
- {
- $is_like_expression = true;
- }
- }
-
- if (!$is_like_expression)
- {
- $sql_opts = 'AND ' . phpbb::$db->sql_in_set($key, $auth_options);
- }
- else
- {
- $sql = array();
-
- foreach ($auth_options as $option)
- {
- if (strpos($option, '%') !== false)
- {
- $sql[] = $key . ' ' . phpbb::$db->sql_like_expression(str_replace('%', phpbb::$db->any_char, $option));
- }
- else
- {
- $sql[] = $key . " = '" . phpbb::$db->sql_escape($option) . "'";
- }
- }
-
- $sql_opts = 'AND (' . implode(' OR ', $sql) . ')';
- }
- }
- }
-}
-
-?> \ No newline at end of file
diff --git a/phpBB/includes/classes/cache.php b/phpBB/includes/classes/cache.php
deleted file mode 100644
index eeeae58989..0000000000
--- a/phpBB/includes/classes/cache.php
+++ /dev/null
@@ -1,425 +0,0 @@
-<?php
-/**
-*
-* @package acm
-* @version $Id$
-* @copyright (c) 2005, 2008 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Class for obtaining cached entries, for example censor word list, configuration...
-* @package acm
-*/
-class phpbb_cache
-{
- /**
- * We do not want this object instantiable
- */
- private function ___construct() { }
-
- /**
- * Required phpBB objects
- */
- public $phpbb_required = array('config', 'acm', 'db');
-
- /**
- * Optional phpBB objects
- */
- public $phpbb_optional = array();
-
- /**
- * Get config values
- *
- * @return array configuration
- * @access public
- */
- public static function obtain_config()
- {
- if ((phpbb::$config = phpbb::$acm->get('#config')) !== false)
- {
- $sql = 'SELECT config_name, config_value
- FROM ' . CONFIG_TABLE . '
- WHERE is_dynamic = 1';
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- phpbb::$config[$row['config_name']] = $row['config_value'];
- }
- phpbb::$db->sql_freeresult($result);
- }
- else
- {
- phpbb::$config = $cached_config = array();
-
- $sql = 'SELECT config_name, config_value, is_dynamic
- FROM ' . CONFIG_TABLE;
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- if (!$row['is_dynamic'])
- {
- $cached_config[$row['config_name']] = $row['config_value'];
- }
-
- phpbb::$config[$row['config_name']] = $row['config_value'];
- }
- phpbb::$db->sql_freeresult($result);
-
- phpbb::$acm->put('#config', $cached_config);
- }
-
- return phpbb::$config;
- }
-
- /**
- * Obtain list of naughty words and build preg style replacement arrays for use by the calling script
- *
- * @return array Censored words
- * @access public
- */
- public static function obtain_word_list()
- {
- if (($censors = phpbb::$acm->get('word_censors')) === false)
- {
- $sql = 'SELECT word, replacement
- FROM ' . WORDS_TABLE;
- $result = phpbb::$db->sql_query($sql);
-
- $censors = array();
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $censors['match'][] = '#(?<!\w)(' . str_replace('\*', '\w*?', preg_quote($row['word'], '#')) . ')(?!\w)#i';
- $censors['replace'][] = $row['replacement'];
- }
- phpbb::$db->sql_freeresult($result);
-
- phpbb::$acm->put('word_censors', $censors);
- }
-
- return $censors;
- }
-
- /**
- * Obtain currently listed icons
- *
- * @return array Icons
- * @access public
- */
- public static function obtain_icons()
- {
- if (($icons = phpbb::$acm->get('icons')) === false)
- {
- // Topic icons
- $sql = 'SELECT *
- FROM ' . ICONS_TABLE . '
- ORDER BY icons_order';
- $result = phpbb::$db->sql_query($sql);
-
- $icons = array();
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $icons[$row['icons_id']]['img'] = $row['icons_url'];
- $icons[$row['icons_id']]['width'] = (int) $row['icons_width'];
- $icons[$row['icons_id']]['height'] = (int) $row['icons_height'];
- $icons[$row['icons_id']]['display'] = (bool) $row['display_on_posting'];
- }
- phpbb::$db->sql_freeresult($result);
-
- phpbb::$acm->put('icons', $icons);
- }
-
- return $icons;
- }
-
- /**
- * Obtain ranks
- *
- * @return Ranks
- * @access public
- */
- public static function obtain_ranks()
- {
- if (($ranks = phpbb::$acm->get('ranks')) === false)
- {
- $sql = 'SELECT *
- FROM ' . RANKS_TABLE . '
- ORDER BY rank_min DESC';
- $result = phpbb::$db->sql_query($sql);
-
- $ranks = array();
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- if ($row['rank_special'])
- {
- $ranks['special'][$row['rank_id']] = array(
- 'rank_title' => $row['rank_title'],
- 'rank_image' => $row['rank_image']
- );
- }
- else
- {
- $ranks['normal'][] = array(
- 'rank_title' => $row['rank_title'],
- 'rank_min' => $row['rank_min'],
- 'rank_image' => $row['rank_image']
- );
- }
- }
- phpbb::$db->sql_freeresult($result);
-
- phpbb::$acm->put('ranks', $ranks);
- }
-
- return $ranks;
- }
-
- /**
- * Put attachment extensions data into cache
- *
- * @return array Cached extensions
- * @access private
- */
- private static function cache_extensions()
- {
- $extensions = array(
- '_allowed_post' => array(),
- '_allowed_pm' => array(),
- );
-
- // The rule is to only allow those extensions defined. ;)
- $sql = 'SELECT e.extension, g.*
- FROM ' . EXTENSIONS_TABLE . ' e, ' . EXTENSION_GROUPS_TABLE . ' g
- WHERE e.group_id = g.group_id
- AND (g.allow_group = 1 OR g.allow_in_pm = 1)';
- $result = phpbb::$db->sql_query($sql);
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $extension = strtolower(trim($row['extension']));
-
- $extensions[$extension] = array(
- 'display_cat' => (int) $row['cat_id'],
- 'download_mode' => (int) $row['download_mode'],
- 'upload_icon' => trim($row['upload_icon']),
- 'max_filesize' => (int) $row['max_filesize'],
- 'allow_group' => $row['allow_group'],
- 'allow_in_pm' => $row['allow_in_pm'],
- );
-
- $allowed_forums = ($row['allowed_forums']) ? unserialize(trim($row['allowed_forums'])) : array();
-
- // Store allowed extensions forum wise
- if ($row['allow_group'])
- {
- $extensions['_allowed_post'][$extension] = (!sizeof($allowed_forums)) ? 0 : $allowed_forums;
- }
-
- if ($row['allow_in_pm'])
- {
- $extensions['_allowed_pm'][$extension] = 0;
- }
- }
- phpbb::$db->sql_freeresult($result);
-
- phpbb::$acm->put('extensions', $extensions);
- return $extensions;
- }
-
- /**
- * Obtain allowed attachment extensions in private messages
- *
- * @return array Allowed extensions
- * @access public
- */
- public static function obtain_extensions_pm()
- {
- if (($extensions = phpbb::$acm->get('extensions')) === false)
- {
- $extensions = self::cache_extensions();
- }
-
- // We are checking for private messages, therefore we only need to get the pm extensions...
- $result = array('_allowed_' => array());
-
- foreach ($extensions['_allowed_pm'] as $extension => $check)
- {
- $result['_allowed_'][$extension] = 0;
- $result[$extension] = $extensions[$extension];
- }
-
- return $result;
- }
-
- /**
- * Obtain allowed attachment extensions in specific forum
- *
- * @param int $forum_id The forum id
- * @return array Allowed extensions within the specified forum
- * @access public
- */
- public static function obtain_extensions_forum($forum_id)
- {
- if (($extensions = phpbb::$acm->get('extensions')) === false)
- {
- $extensions = self::cache_extensions();
- }
-
- $forum_id = (int) $forum_id;
- $result = array('_allowed_' => array());
-
- foreach ($extensions['_allowed_post'] as $extension => $check)
- {
- // Check for allowed forums
- if (is_array($check))
- {
- $allowed = (!in_array($forum_id, $check)) ? false : true;
- }
- else
- {
- $allowed = true;
- }
-
- if ($allowed)
- {
- $result['_allowed_'][$extension] = 0;
- $result[$extension] = $extensions[$extension];
- }
- }
-
- if (!isset($result['_allowed_']))
- {
- $result['_allowed_'] = array();
- }
-
- return $result;
- }
-
- /**
- * Obtain general attachment extension information
- *
- * @return array Cached extension information
- * @access public
- */
- public static function obtain_extensions()
- {
- if (($extensions = phpbb::$acm->get('extensions')) === false)
- {
- $extensions = self::cache_extensions();
- }
-
- return $extensions;
- }
-
- /**
- * Obtain active bots
- *
- * @return array Active bots
- * @access public
- */
- public static function obtain_bots()
- {
- if (($bots = phpbb::$acm->get('bots')) === false)
- {
- // @todo We order by last visit date. This way we are able to safe some cycles by checking the most active ones first.
- $sql = 'SELECT user_id, bot_agent, bot_ip
- FROM ' . BOTS_TABLE . '
- WHERE bot_active = 1
- ORDER BY ' . phpbb::$db->sql_function('length_varchar', 'bot_agent') . 'DESC';
- $result = phpbb::$db->sql_query($sql);
-
- $bots = array();
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $bots[] = $row;
- }
- phpbb::$db->sql_freeresult($result);
-
- phpbb::$acm->put('bots', $bots);
- }
-
- return $bots;
- }
-
- /**
- * Obtain Styles .cfg file data
- *
- * @param array $theme An array containing the path to the items
- * @param string $item The specific item to get: 'theme', 'template', or 'imageset'
- * @return array The configuration
- * @access public
- */
- public static function obtain_cfg_item($theme, $item = 'theme')
- {
- $parsed_array = phpbb::$acm->get('cfg_' . $item . '_' . $theme[$item . '_path']);
-
- if ($parsed_array === false)
- {
- $parsed_array = array();
- }
-
- $reparse = false;
- $filename = PHPBB_ROOT_PATH . 'styles/' . $theme[$item . '_path'] . '/' . $item . '/' . $item . '.cfg';
-
- if (!file_exists($filename))
- {
- return $parsed_array;
- }
-
- if (!isset($parsed_array['filetime']) || ((phpbb::$config['load_tplcompile'] && @filemtime($filename) > $parsed_array['filetime'])))
- {
- $reparse = true;
- }
-
- // Re-parse cfg file
- if ($reparse)
- {
- $parsed_array = parse_cfg_file($filename);
- $parsed_array['filetime'] = @filemtime($filename);
-
- phpbb::$acm->put('cfg_' . $item . '_' . $theme[$item . '_path'], $parsed_array);
- }
-
- return $parsed_array;
- }
-
- /**
- * Obtain disallowed usernames
- *
- * @return array Disallowed usernames
- * @access public
- */
- public static function obtain_disallowed_usernames()
- {
- if (($usernames = phpbb::$acm->get('disallowed_usernames')) === false)
- {
- $sql = 'SELECT disallow_username
- FROM ' . DISALLOW_TABLE;
- $result = phpbb::$db->sql_query($sql);
-
- $usernames = array();
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $usernames[] = str_replace('%', '.*?', preg_quote(utf8_clean_string($row['disallow_username']), '#'));
- }
- phpbb::$db->sql_freeresult($result);
-
- phpbb::$acm->put('disallowed_usernames', $usernames);
- }
-
- return $usernames;
- }
-}
-
-?> \ No newline at end of file
diff --git a/phpBB/includes/classes/session.php b/phpBB/includes/classes/session.php
deleted file mode 100644
index ca54bae552..0000000000
--- a/phpBB/includes/classes/session.php
+++ /dev/null
@@ -1,1289 +0,0 @@
-<?php
-/**
-*
-* @package phpBB3
-* @version $Id$
-* @copyright (c) 2005, 2008 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Session class
-* @package phpBB3
-*/
-abstract class phpbb_session
-{
- /**
- * @var array Cookie informations
- */
- private $cookie_data = array();
-
- /**
- * @var array User data
- */
- public $data = array();
-
- /**
- * @var string Session id
- */
- public $session_id = '';
-
- /**
- * @var int Current time
- */
- public $time_now = 0;
-
- /**
- * @var bool True if the current page is updated within the sessions table
- */
- public $update_session_page = true;
-
- /**
- * @var mixed Reference to authentication system.
- */
- public $auth = NULL;
-
- /**
- * @var mixed Reference to system array for obtaining server/system information
- */
- public $system = NULL;
-
- /**
- * @var array Extra url parameter to append to every URL in phpBB
- */
- public $extra_url = array();
-
- /**
- * @var bool If this is true then the session id (?sid=[session_id]) is required
- */
- public $need_sid = false;
-
- /**
- * @var array Information about current page
- */
- public $page = array();
-
- /**
- * @var string The users IP
- */
- public $ip = '127.0.0.1';
-
- /**
- * Init session. Empties the user data and assigns the system object (phpbb::$instances['system'])
- * @access public
- */
- public function __construct()
- {
- // Reset data array ;)
- $this->data = array();
-
- // Set auth to false (only valid for an user object)
- $this->auth = false;
-
- // Some system/server variables, directly generated by phpbb_system_info methods. Used like an array.
- // We use the phpbb:: one, because it could've been modified and being a completely different class
- $this->system =& phpbb::$instances['server-vars'];
- }
-
- /**
- * Specifiy the need for a session id within the URL
- *
- * @param bool $need_sid Specify if the session id is needed or not. Default is false.
- * @access public
- */
- public function need_sid($need_sid = false)
- {
- $this->need_sid = $need_sid;
- }
-
- /**
- * Start session management
- *
- * This is where all session activity begins. We gather various pieces of
- * information from the client and server. We test to see if a session already
- * exists. If it does, fine and dandy. If it doesn't we'll go on to create a
- * new one ... pretty logical heh? We also examine the system load (if we're
- * running on a system which makes such information readily available) and
- * halt if it's above an admin definable limit.
- *
- * @param bool $update_session_page If true the session page gets updated.
- * This can be set to false to circumvent certain scripts to update the users last visited page.
- *
- * @return bool True if the session exist or has been created, else False.
- * @access public
- */
- public function session_begin($update_session_page = true)
- {
- // Give us some basic information
- $this->time_now = time();
- $this->cookie_data = array('u' => 0, 'k' => '');
- $this->update_session_page = $update_session_page;
- $this->page = $this->system['page'];
- $this->ip = $this->system['ip'];
-
- if (phpbb_request::is_set(phpbb::$config['cookie_name'] . '_sid', phpbb_request::COOKIE) || phpbb_request::is_set(phpbb::$config['cookie_name'] . '_u', phpbb_request::COOKIE))
- {
- $this->cookie_data['u'] = request_var(phpbb::$config['cookie_name'] . '_u', 0, false, true);
- $this->cookie_data['k'] = request_var(phpbb::$config['cookie_name'] . '_k', '', false, true);
- $this->session_id = request_var(phpbb::$config['cookie_name'] . '_sid', '', false, true);
-
- if (empty($this->session_id))
- {
- $this->session_id = request_var('sid', '');
- $this->cookie_data = array('u' => 0, 'k' => '');
- $this->need_sid = true;
- }
- }
- else
- {
- $this->session_id = request_var('sid', '');
- $this->need_sid = true;
- }
-
- $this->extra_url = array();
-
- // Now check for an existing session
- if ($this->session_exist())
- {
- return true;
- }
-
- // If we reach here then no (valid) session exists. So we'll create a new one
- return $this->session_create();
- }
-
- /**
- * Create a new session
- *
- * If upon trying to start a session we discover there is nothing existing we
- * jump here. Additionally this method is called directly during login to regenerate
- * the session for the specific user. In this method we carry out a number of tasks;
- * garbage collection, (search)bot checking, banned user comparison. Basically
- * though this method will result in a new session for a specific user.
- *
- * @param int $user_id The user id to create the session for.
- * @param bool $set_admin Set the users admin field to identify him/her as an admin?
- * @param bool $persist_login Allow persistent login
- * @param bool $viewonline If false then the user will be logged in as hidden
- *
- * @return bool True if session got created successfully.
- * @access public
- */
- public function session_create($user_id = false, $set_admin = false, $persist_login = false, $viewonline = true)
- {
- // There is one case where we need to add a "failsafe" user... when we are not able to query the database
- if (!phpbb::registered('db'))
- {
- $this->data = $this->default_data();
- return true;
- }
-
- // If the data array is filled, chances are high that there was a different session active
- if (sizeof($this->data))
- {
- // Kill the session and do not create a new one
- $this->session_kill(false);
- }
-
- $this->data = array();
-
- // Do we allow autologin on this board? No? Then override anything
- // that may be requested here
- if (!phpbb::$config['allow_autologin'])
- {
- $this->cookie_data['k'] = $persist_login = false;
- }
-
- // Check for autologin key. ;)
- if ($this->auth !== false && method_exists($this->auth, 'autologin'))
- {
- $this->data = $this->auth->autologin();
-
- if (sizeof($this->data))
- {
- $this->cookie_data['k'] = '';
- $this->cookie_data['u'] = $this->data['user_id'];
- }
- }
-
- // NULL indicates we need to check for a bot later. Sometimes it is apparant that it is not a bot. ;) No need to always check this.
- $bot = NULL;
-
- // If we're presented with an autologin key we'll join against it.
- // Else if we've been passed a user_id we'll grab data based on that
- if (isset($this->cookie_data['k']) && $this->cookie_data['k'] && $this->cookie_data['u'] && !sizeof($this->data))
- {
- $sql = 'SELECT u.*
- FROM ' . USERS_TABLE . ' u, ' . SESSIONS_KEYS_TABLE . ' k
- WHERE u.user_id = ' . (int) $this->cookie_data['u'] . '
- AND u.user_type IN (' . phpbb::USER_NORMAL . ', ' . phpbb::USER_FOUNDER . ")
- AND k.user_id = u.user_id
- AND k.key_id = '" . phpbb::$db->sql_escape(md5($this->cookie_data['k'])) . "'";
- $result = phpbb::$db->sql_query($sql);
- $this->data = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
-
- $bot = false;
- }
- else if ($user_id !== false && !sizeof($this->data))
- {
- $this->cookie_data['k'] = '';
- $this->cookie_data['u'] = $user_id;
-
- $sql = 'SELECT *
- FROM ' . USERS_TABLE . '
- WHERE user_id = ' . (int) $this->cookie_data['u'] . '
- AND user_type IN (' . phpbb::USER_NORMAL . ', ' . phpbb::USER_FOUNDER . ')';
- $result = phpbb::$db->sql_query($sql);
- $this->data = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
-
- $bot = false;
- }
-
- if ($bot === NULL)
- {
- $bot = $this->check_bot();
- }
-
- // If no data was returned one or more of the following occurred:
- // Key didn't match one in the DB
- // User does not exist
- // User is inactive
- // User is bot
- if (!sizeof($this->data) || !is_array($this->data))
- {
- $this->cookie_data['k'] = '';
- $this->cookie_data['u'] = ($bot) ? $bot : ANONYMOUS;
-
- if (!$bot)
- {
- $sql = 'SELECT *
- FROM ' . USERS_TABLE . '
- WHERE user_id = ' . (int) $this->cookie_data['u'];
- }
- else
- {
- // We give bots always the same session if it is not yet expired.
- $sql = 'SELECT u.*, s.*
- FROM ' . USERS_TABLE . ' u
- LEFT JOIN ' . SESSIONS_TABLE . ' s ON (s.session_user_id = u.user_id)
- WHERE u.user_id = ' . (int) $bot;
- }
-
- $result = phpbb::$db->sql_query($sql);
- $this->data = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
-
- $this->is_registered = false;
- }
- else
- {
- $this->is_registered = true;
- $this->is_guest = false;
- $this->is_founder = $this->data['user_type'] == phpbb::USER_FOUNDER;
- }
-
- // Force user id to be integer...
- $this->data['user_id'] = (int) $this->data['user_id'];
-
- // Code for ANONYMOUS user, INACTIVE user and BOTS
- if (!$this->is_registered)
- {
- // Set last visit date to 'now'
- $this->data['session_last_visit'] = $this->time_now;
- $this->is_bot = ($bot) ? true : false;
-
- // If our friend is a bot, we re-assign a previously assigned session
- if ($this->is_bot && $bot == $this->data['user_id'] && $this->data['session_id'])
- {
- if ($this->session_valid(false))
- {
- $this->session_id = $this->data['session_id'];
-
- // Only update session DB a minute or so after last update or if page changes
- if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->system['page']['page']))
- {
- $this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now;
- $sql_ary = array('session_time' => $this->time_now, 'session_last_visit' => $this->time_now, 'session_admin' => 0);
-
- if ($this->update_session_page)
- {
- $sql_ary['session_page'] = substr($this->system['page']['page'], 0, 199);
- }
-
- $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . phpbb::$db->sql_build_array('UPDATE', $sql_ary) . "
- WHERE session_id = '" . phpbb::$db->sql_escape($this->session_id) . "'";
- phpbb::$db->sql_query($sql);
-
- // Update the last visit time
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_lastvisit = ' . (int) $this->data['session_time'] . '
- WHERE user_id = ' . (int) $this->data['user_id'];
- phpbb::$db->sql_query($sql);
- }
-
- $this->session_id = '';
-
- return true;
- }
- else
- {
- // If the ip and browser does not match make sure we only have one bot assigned to one session
- phpbb::$db->sql_query('DELETE FROM ' . SESSIONS_TABLE . ' WHERE session_user_id = ' . $this->data['user_id']);
- }
- }
- }
- else
- {
- // Code for registered users
- $this->data['session_last_visit'] = (!empty($this->data['session_time'])) ? $this->data['session_time'] : (($this->data['user_lastvisit']) ? $this->data['user_lastvisit'] : $this->time_now);
- $this->is_bot = false;
- }
-
- // At this stage we should have a filled data array, defined cookie u and k data.
- // data array should contain recent session info if we're a real user and a recent
- // session exists in which case session_id will also be set
-
- // Is user banned? Are they excluded? Won't return on ban, exists within method
- if ($this->data['user_type'] != phpbb::USER_FOUNDER)
- {
- if (!phpbb::$config['forwarded_for_check'])
- {
- $this->check_ban($this->data['user_id'], $this->system['ip']);
- }
- else
- {
- $ips = explode(', ', $this->forwarded_for);
- $ips[] = $this->system['ip'];
- $this->check_ban($this->data['user_id'], $ips);
- }
- }
-
- $session_autologin = (($this->cookie_data['k'] || $persist_login) && $this->is_registered) ? true : false;
- $set_admin = ($set_admin && $this->is_registered) ? true : false;
-
- // Create or update the session
- $sql_ary = array(
- 'session_user_id' => (int) $this->data['user_id'],
- 'session_start' => (int) $this->time_now,
- 'session_last_visit' => (int) $this->data['session_last_visit'],
- 'session_time' => (int) $this->time_now,
- 'session_browser' => (string) trim(substr($this->system['browser'], 0, 149)),
- 'session_forwarded_for' => (string) $this->system['forwarded_for'],
- 'session_ip' => (string) $this->system['ip'],
- 'session_autologin' => ($session_autologin) ? 1 : 0,
- 'session_admin' => ($set_admin) ? 1 : 0,
- 'session_viewonline' => ($viewonline) ? 1 : 0,
- );
-
- if ($this->update_session_page)
- {
- $sql_ary['session_page'] = (string) substr($this->system['page']['page'], 0, 199);
- }
-
- phpbb::$db->sql_return_on_error(true);
-
- // Delete old session, if user id now different from anonymous
- if (!defined('IN_ERROR_HANDLER'))
- {
- // We do not care about the user id, because we assign a new session later
- $sql = 'DELETE
- FROM ' . SESSIONS_TABLE . "
- WHERE session_id = '" . phpbb::$db->sql_escape($this->session_id) . "'";
- $result = phpbb::$db->sql_query($sql);
-
- // If there were no sessions or the session id empty (then the affected rows will be empty too), then we have a brand new session and can check the active sessions limit
- if ((!$result || !phpbb::$db->sql_affectedrows()) && (empty($this->data['session_time']) && phpbb::$config['active_sessions']))
- {
- $sql = 'SELECT COUNT(session_id) AS sessions
- FROM ' . SESSIONS_TABLE . '
- WHERE session_time >= ' . ($this->time_now - 60);
- $result = phpbb::$db->sql_query($sql);
- $row = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
-
- if ((int) $row['sessions'] > (int) phpbb::$config['active_sessions'])
- {
- header('HTTP/1.1 503 Service Unavailable');
- trigger_error('BOARD_UNAVAILABLE');
- }
- }
- }
-
- // Something quite important: session_page always holds the *last* page visited, except for the *first* visit.
- // We are not able to simply have an empty session_page btw, therefore we need to tell phpBB how to detect this special case.
- // If the session id is empty, we have a completely new one and will set an "identifier" here. This identifier is able to be checked later.
- if (empty($this->data['session_id']))
- {
- // This is a temporary variable, only set for the very first visit
- $this->data['session_created'] = true;
- }
-
- $this->session_id = $this->data['session_id'] = md5(phpbb::$security->unique_id());
-
- $sql_ary['session_id'] = (string) $this->session_id;
-
- $sql = 'INSERT INTO ' . SESSIONS_TABLE . ' ' . phpbb::$db->sql_build_array('INSERT', $sql_ary);
- phpbb::$db->sql_query($sql);
-
- phpbb::$db->sql_return_on_error(false);
-
- // Regenerate autologin/persistent login key
- if ($session_autologin)
- {
- $this->set_login_key();
- }
-
- // refresh data
- $this->data = array_merge($this->data, $sql_ary);
-
- if (!$bot)
- {
- $cookie_expire = $this->time_now + ((phpbb::$config['max_autologin_time']) ? 86400 * (int) phpbb::$config['max_autologin_time'] : 31536000);
-
- $this->set_cookie('u', $this->cookie_data['u'], $cookie_expire);
- $this->set_cookie('k', $this->cookie_data['k'], $cookie_expire);
- $this->set_cookie('sid', $this->session_id, $cookie_expire);
-
- unset($cookie_expire);
-
- // Only one session entry present...
- $sql = 'SELECT COUNT(session_id) AS sessions
- FROM ' . SESSIONS_TABLE . '
- WHERE session_user_id = ' . (int) $this->data['user_id'] . '
- AND session_time >= ' . (int) ($this->time_now - (max(phpbb::$config['session_length'], phpbb::$config['form_token_lifetime'])));
- $result = phpbb::$db->sql_query($sql);
- $row = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
-
- if ((int) $row['sessions'] <= 1 || empty($this->data['user_form_salt']))
- {
- $this->data['user_form_salt'] = phpbb::$security->unique_id();
-
- // Update the form key
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_form_salt = \'' . phpbb::$db->sql_escape($this->data['user_form_salt']) . '\'
- WHERE user_id = ' . (int) $this->data['user_id'];
- phpbb::$db->sql_query($sql);
- }
- }
- else
- {
- $this->data['session_time'] = $this->data['session_last_visit'] = $this->time_now;
-
- // Update the last visit time
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_lastvisit = ' . (int) $this->data['session_time'] . '
- WHERE user_id = ' . (int) $this->data['user_id'];
- phpbb::$db->sql_query($sql);
-
- $this->session_id = '';
- }
-
- return true;
- }
-
- /**
- * Kills a session
- *
- * This method does what it says on the tin. It will delete a pre-existing session.
- * It resets cookie information (destroying any autologin key within that cookie data)
- * and update the users information from the relevant session data. It will then
- * grab guest user information.
- *
- * @param bool $new_session If true a new session will be generated after the original one got killed.
- * @access public
- */
- public function session_kill($new_session = true)
- {
- $sql = 'DELETE FROM ' . SESSIONS_TABLE . "
- WHERE session_id = '" . phpbb::$db->sql_escape($this->session_id) . "'
- AND session_user_id = " . (int) $this->data['user_id'];
- phpbb::$db->sql_query($sql);
-
- // Allow connecting logout with external auth method logout
- if ($this->auth !== false && method_exists($this->auth, 'logout'))
- {
- $this->auth->logout($this, $new_session);
- }
-
- if ($this->data['user_id'] != ANONYMOUS)
- {
- // Delete existing session, update last visit info first!
- if (!isset($this->data['session_time']))
- {
- $this->data['session_time'] = time();
- }
-
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_lastvisit = ' . (int) $this->data['session_time'] . '
- WHERE user_id = ' . (int) $this->data['user_id'];
- phpbb::$db->sql_query($sql);
-
- if ($this->cookie_data['k'])
- {
- $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
- WHERE user_id = ' . (int) $this->data['user_id'] . "
- AND key_id = '" . phpbb::$db->sql_escape(md5($this->cookie_data['k'])) . "'";
- phpbb::$db->sql_query($sql);
- }
-
- // Reset the data array
- $this->data = array();
-
- $sql = 'SELECT *
- FROM ' . USERS_TABLE . '
- WHERE user_id = ' . ANONYMOUS;
- $result = phpbb::$db->sql_query($sql);
- $this->data = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
- }
-
- $cookie_expire = $this->time_now - 31536000;
- $this->set_cookie('u', '', $cookie_expire);
- $this->set_cookie('k', '', $cookie_expire);
- $this->set_cookie('sid', '', $cookie_expire);
- unset($cookie_expire);
-
- $this->session_id = '';
-
- // To make sure a valid session is created we create one for the anonymous user
- if ($new_session)
- {
- $this->session_create(ANONYMOUS);
- }
- }
-
- /**
- * Session garbage collection
- *
- * This looks a lot more complex than it really is. Effectively we are
- * deleting any sessions older than an admin definable limit. Due to the
- * way in which we maintain session data we have to ensure we update user
- * data before those sessions are destroyed. In addition this method
- * removes autologin key information that is older than an admin defined
- * limit.
- *
- * @access public
- */
- public function session_gc()
- {
- $batch_size = 10;
-
- if (!$this->time_now)
- {
- $this->time_now = time();
- }
-
- // Firstly, delete guest sessions
- $sql = 'DELETE FROM ' . SESSIONS_TABLE . '
- WHERE session_user_id = ' . ANONYMOUS . '
- AND session_time < ' . (int) ($this->time_now - phpbb::$config['session_length']);
- phpbb::$db->sql_query($sql);
-
- // Get expired sessions, only most recent for each user
- $sql = 'SELECT session_user_id, session_page, MAX(session_time) AS recent_time
- FROM ' . SESSIONS_TABLE . '
- WHERE session_time < ' . ($this->time_now - phpbb::$config['session_length']) . '
- GROUP BY session_user_id, session_page';
- $result = phpbb::$db->sql_query_limit($sql, $batch_size);
-
- $del_user_id = array();
- $del_sessions = 0;
-
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- $sql = 'UPDATE ' . USERS_TABLE . '
- SET user_lastvisit = ' . (int) $row['recent_time'] . ", user_lastpage = '" . phpbb::$db->sql_escape($row['session_page']) . "'
- WHERE user_id = " . (int) $row['session_user_id'];
- phpbb::$db->sql_query($sql);
-
- $del_user_id[] = (int) $row['session_user_id'];
- $del_sessions++;
- }
- phpbb::$db->sql_freeresult($result);
-
- if (sizeof($del_user_id))
- {
- // Delete expired sessions
- $sql = 'DELETE FROM ' . SESSIONS_TABLE . '
- WHERE ' . phpbb::$db->sql_in_set('session_user_id', $del_user_id) . '
- AND session_time < ' . ($this->time_now - phpbb::$config['session_length']);
- phpbb::$db->sql_query($sql);
- }
-
- if ($del_sessions < $batch_size)
- {
- // Less than 10 users, update gc timer ... else we want gc
- // called again to delete other sessions
- set_config('session_last_gc', $this->time_now, true);
-
- if (phpbb::$config['max_autologin_time'])
- {
- $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
- WHERE last_login < ' . (time() - (86400 * (int) phpbb::$config['max_autologin_time']));
- phpbb::$db->sql_query($sql);
- }
-
- // only called from CRON; should be a safe workaround until the infrastructure gets going
- if (!class_exists('captcha_factory'))
- {
- include(PHPBB_ROOT_PATH . "includes/captcha/captcha_factory." . PHP_EXT);
- }
- captcha_factory::garbage_collect(phpbb::$config['captcha_plugin']);
- }
-
- return;
- }
-
-
- /**
- * Sets a cookie of the given name with the specified data for the given length of time. If no time is specified, a session cookie will be set.
- *
- * @param string $name Name of the cookie, will be automatically prefixed with the phpBB cookie name. Track becomes [cookie_name]_track then.
- * @param string $cookiedata The data to hold within the cookie
- * @param int $cookietime The expiration time as UNIX timestamp. If 0 is provided, a session cookie is set.
- *
- * @access public
- */
- public function set_cookie($name, $cookiedata, $cookietime)
- {
- $name_data = rawurlencode(phpbb::$config['cookie_name'] . '_' . $name) . '=' . rawurlencode($cookiedata);
- $expire = gmdate('D, d-M-Y H:i:s \\G\\M\\T', $cookietime);
- $domain = (!phpbb::$config['cookie_domain'] || phpbb::$config['cookie_domain'] == 'localhost' || phpbb::$config['cookie_domain'] == '127.0.0.1') ? '' : '; domain=' . phpbb::$config['cookie_domain'];
-
- header('Set-Cookie: ' . $name_data . (($cookietime) ? '; expires=' . $expire : '') . '; path=' . phpbb::$config['cookie_path'] . $domain . ((!phpbb::$config['cookie_secure']) ? '' : '; secure') . '; HttpOnly', false);
- }
-
- /**
- * Check for banned user
- *
- * Checks whether the supplied user is banned by id, ip or email. If no parameters
- * are passed to the method pre-existing session data is used. If $return is false
- * this routine does not return on finding a banned user, it outputs a relevant
- * message and stops execution.
- *
- * @param int $user_id The user id to check. If false then do not check user ids
- * @param string|array $user_ips Can contain a string with one IP or an array of multiple IPs. If false then no ips are checked.
- * @param int $user_email The email address to check
- * @param bool $return If false then the banned message is displayed and script halted
- *
- * @return bool|string True if banned and no reason given.
- * False if not banned. A ban reason if banned and ban reason given. Check for !== false.
- * @access public
- */
- public function check_ban($user_id = false, $user_ips = false, $user_email = false, $return = false)
- {
- if (defined('IN_CHECK_BAN'))
- {
- return;
- }
-
- $banned = false;
- $cache_ttl = 3600;
- $where_sql = array();
-
- $sql = 'SELECT ban_ip, ban_userid, ban_email, ban_exclude, ban_give_reason, ban_end
- FROM ' . BANLIST_TABLE . '
- WHERE ';
-
- // Determine which entries to check, only return those
- if ($user_email === false)
- {
- $where_sql[] = "ban_email = ''";
- }
-
- if ($user_ips === false)
- {
- $where_sql[] = "(ban_ip = '' OR ban_exclude = 1)";
- }
-
- if ($user_id === false)
- {
- $where_sql[] = '(ban_userid = 0 OR ban_exclude = 1)';
- }
- else
- {
- $cache_ttl = ($user_id == ANONYMOUS) ? 3600 : 0;
- $_sql = '(ban_userid = ' . $user_id;
-
- if ($user_email !== false)
- {
- $_sql .= " OR ban_email <> ''";
- }
-
- if ($user_ips !== false)
- {
- $_sql .= " OR ban_ip <> ''";
- }
-
- $_sql .= ')';
-
- $where_sql[] = $_sql;
- }
-
- $sql .= (sizeof($where_sql)) ? implode(' AND ', $where_sql) : '';
- $result = phpbb::$db->sql_query($sql, $cache_ttl);
-
- $ban_triggered_by = 'user';
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- if ($row['ban_end'] && $row['ban_end'] < time())
- {
- continue;
- }
-
- $ip_banned = false;
- if (!empty($row['ban_ip']))
- {
- if (!is_array($user_ips))
- {
- $ip_banned = preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_ip'], '#')) . '$#i', $user_ips);
- }
- else
- {
- foreach ($user_ips as $user_ip)
- {
- if (preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_ip'], '#')) . '$#i', $user_ip))
- {
- $ip_banned = true;
- break;
- }
- }
- }
- }
-
- if ((!empty($row['ban_userid']) && intval($row['ban_userid']) == $user_id) ||
- $ip_banned ||
- (!empty($row['ban_email']) && preg_match('#^' . str_replace('\*', '.*?', preg_quote($row['ban_email'], '#')) . '$#i', $user_email)))
- {
- if (!empty($row['ban_exclude']))
- {
- $banned = false;
- break;
- }
- else
- {
- $banned = true;
- $ban_row = $row;
-
- if (!empty($row['ban_userid']) && intval($row['ban_userid']) == $user_id)
- {
- $ban_triggered_by = 'user';
- }
- else if ($ip_banned)
- {
- $ban_triggered_by = 'ip';
- }
- else
- {
- $ban_triggered_by = 'email';
- }
-
- // Don't break. Check if there is an exclude rule for this user
- }
- }
- }
- phpbb::$db->sql_freeresult($result);
-
- if ($banned && !$return)
- {
- // If the session is empty we need to create a valid one...
- if (empty($this->session_id))
- {
- // This seems to be no longer needed? - #14971
-// $this->session_create(ANONYMOUS);
- }
-
- // Initiate environment ... since it won't be set at this stage
- $this->setup();
-
- // Logout the user, banned users are unable to use the normal 'logout' link
- if ($this->data['user_id'] != ANONYMOUS)
- {
- $this->session_kill();
- }
-
- // We show a login box here to allow founders accessing the board if banned by IP
- if (defined('IN_LOGIN') && $this->data['user_id'] == ANONYMOUS)
- {
- $this->setup('ucp');
- $this->is_registered = $this->is_bot = $this->is_founder = false;
- $this->is_guest = true;
-
- // Set as a precaution to allow login_box() handling this case correctly as well as this function not being executed again.
- define('IN_CHECK_BAN', 1);
-
- login_box('index.' . PHP_EXT);
-
- // The false here is needed, else the user is able to circumvent the ban.
- $this->session_kill(false);
- }
-
- // Ok, we catch the case of an empty session id for the anonymous user...
- // This can happen if the user is logging in, banned by username and the login_box() being called "again".
- if (empty($this->session_id) && defined('IN_CHECK_BAN'))
- {
- $this->session_create(ANONYMOUS);
- }
-
-
- // Determine which message to output
- $till_date = ($ban_row['ban_end']) ? $this->format_date($ban_row['ban_end']) : '';
- $message = ($ban_row['ban_end']) ? 'BOARD_BAN_TIME' : 'BOARD_BAN_PERM';
-
- $message = sprintf($this->lang[$message], $till_date, '<a href="mailto:' . phpbb::$config['board_contact'] . '">', '</a>');
- $message .= ($ban_row['ban_give_reason']) ? '<br /><br />' . sprintf($this->lang['BOARD_BAN_REASON'], $ban_row['ban_give_reason']) : '';
- $message .= '<br /><br /><em>' . $this->lang['BAN_TRIGGERED_BY_' . strtoupper($ban_triggered_by)] . '</em>';
-
- // To circumvent session_begin returning a valid value and the check_ban() not called on second page view, we kill the session again
- $this->session_kill(false);
-
- // A very special case... we are within the cron script which is not supposed to print out the ban message... show blank page
- if (defined('IN_CRON'))
- {
- garbage_collection();
- exit_handler();
- exit;
- }
-
- trigger_error($message);
- }
-
- return ($banned && $ban_row['ban_give_reason']) ? $ban_row['ban_give_reason'] : $banned;
- }
-
- /**
- * Check if ip is blacklisted
- * This should be called only where absolutly necessary
- *
- * Only IPv4 (rbldns does not support AAAA records/IPv6 lookups)
- *
- * @param string $mode Possible modes are: register and post
- * spamhaus.org is used for both modes. Spamcop.net is additionally used for register.
- * @param string $ip The ip to check. If false then the current IP is used
- *
- * @return bool|array False if ip is not blacklisted, else an array([checked server], [lookup])
- * @author satmd (from the php manual)
- * @access public
- */
- public function check_dnsbl($mode, $ip = false)
- {
- if ($ip === false)
- {
- $ip = $this->system['ip'];
- }
-
- $dnsbl_check = array(
- 'sbl-xbl.spamhaus.org' => 'http://www.spamhaus.org/query/bl?ip=',
- );
-
- if ($mode == 'register')
- {
- $dnsbl_check['bl.spamcop.net'] = 'http://spamcop.net/bl.shtml?';
- }
-
- if ($ip)
- {
- $quads = explode('.', $ip);
- $reverse_ip = $quads[3] . '.' . $quads[2] . '.' . $quads[1] . '.' . $quads[0];
-
- // Need to be listed on all servers...
- $listed = true;
- $info = array();
-
- foreach ($dnsbl_check as $dnsbl => $lookup)
- {
- if (phpbb_checkdnsrr($reverse_ip . '.' . $dnsbl . '.', 'A') === true)
- {
- $info = array($dnsbl, $lookup . $ip);
- }
- else
- {
- $listed = false;
- }
- }
-
- if ($listed)
- {
- return $info;
- }
- }
-
- return false;
- }
-
- /**
- * Set/Update a persistent login key
- *
- * This method creates or updates a persistent session key. When a user makes
- * use of persistent (formerly auto-) logins a key is generated and stored in the
- * DB. When they revisit with the same key it's automatically updated in both the
- * DB and cookie. Multiple keys may exist for each user representing different
- * browsers or locations. As with _any_ non-secure-socket no passphrase login this
- * remains vulnerable to exploit.
- *
- * @param int $user_id The user id. If false the current users user id will be used
- * @param string $key A login key. If false then the current users login key stored within the cookie will be used
- * @param string $user_ip The users ip. If false, then the current users IP will be used
- * @access public
- */
- public function set_login_key($user_id = false, $key = false, $user_ip = false)
- {
- $user_id = ($user_id === false) ? $this->data['user_id'] : $user_id;
- $user_ip = ($user_ip === false) ? $this->system['ip'] : $user_ip;
- $key = ($key === false) ? (($this->cookie_data['k']) ? $this->cookie_data['k'] : false) : $key;
-
- $key_id = phpbb::$security->unique_id(hexdec(substr($this->session_id, 0, 8)));
-
- $sql_ary = array(
- 'key_id' => (string) md5($key_id),
- 'last_ip' => (string) $this->system['ip'],
- 'last_login' => (int) $this->time_now,
- );
-
- if (!$key)
- {
- $sql_ary += array(
- 'user_id' => (int) $user_id
- );
- }
-
- if ($key)
- {
- $sql = 'UPDATE ' . SESSIONS_KEYS_TABLE . '
- SET ' . phpbb::$db->sql_build_array('UPDATE', $sql_ary) . '
- WHERE user_id = ' . (int) $user_id . "
- AND key_id = '" . phpbb::$db->sql_escape(md5($key)) . "'";
- }
- else
- {
- $sql = 'INSERT INTO ' . SESSIONS_KEYS_TABLE . ' ' . phpbb::$db->sql_build_array('INSERT', $sql_ary);
- }
- phpbb::$db->sql_query($sql);
-
- $this->cookie_data['k'] = $key_id;
- }
-
- /**
- * Reset all login keys for the specified user
- *
- * This method removes all current login keys for a specified (or the current)
- * user. It will be called on password change to render old keys unusable
- *
- * @param int $user_id The user id. If false then the current users user id is used.
- * @access public
- */
- public function reset_login_keys($user_id = false)
- {
- $user_id = ($user_id === false) ? $this->data['user_id'] : $user_id;
-
- $sql = 'DELETE FROM ' . SESSIONS_KEYS_TABLE . '
- WHERE user_id = ' . (int) $user_id;
- phpbb::$db->sql_query($sql);
-
- // Let's also clear any current sessions for the specified user_id
- // If it's the current user then we'll leave this session intact
- $sql_where = 'session_user_id = ' . (int) $user_id;
- $sql_where .= ($user_id === $this->data['user_id']) ? " AND session_id <> '" . phpbb::$db->sql_escape($this->session_id) . "'" : '';
-
- $sql = 'DELETE FROM ' . SESSIONS_TABLE . "
- WHERE $sql_where";
- phpbb::$db->sql_query($sql);
-
- // We're changing the password of the current user and they have a key
- // Lets regenerate it to be safe
- if ($user_id === $this->data['user_id'] && $this->cookie_data['k'])
- {
- $this->set_login_key($user_id);
- }
- }
-
- /**
- * Reset all admin sessions
- *
- * @access public
- */
- public function unset_admin()
- {
- $sql = 'UPDATE ' . SESSIONS_TABLE . "
- SET session_admin = 0
- WHERE session_id = '" . phpbb::$db->sql_escape($this->session_id) . "'";
- phpbb::$db->sql_query($sql);
- }
-
- /**
- * Check if a valid, non-expired session exist. Also make sure it errors out correctly if we do not have a db-setup yet. ;)
- *
- * @return bool True if a valid, non-expired session exist
- * @access private
- */
- private function session_exist()
- {
- // If session is empty or does not match the session within the URL (if required - set by NEED_SID), then we need a new session
- if (empty($this->session_id) || ($this->need_sid && $this->session_id !== phpbb_request::variable('sid', '', false, phpbb_request::GET)))
- {
- return false;
- }
-
- // If the db is not initialized/registered, then we also need a new session (we are not able to go forward then...
- if (!phpbb::registered('db'))
- {
- return false;
- }
-
- // Now finally check the db for our provided session
- $sql = 'SELECT u.*, s.*
- FROM ' . SESSIONS_TABLE . ' s, ' . USERS_TABLE . " u
- WHERE s.session_id = '" . phpbb::$db->sql_escape($this->session_id) . "'
- AND u.user_id = s.session_user_id";
- $result = phpbb::$db->sql_query($sql);
- $row = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
-
- // Also new session if it has not been found. ;)
- if (!$row)
- {
- return false;
- }
-
- $this->data = $row;
-
- // Now check the ip, the browser, forwarded for and referer
- if (!$this->session_valid())
- {
- return false;
- }
-
- // Ok, we are not finished yet. We need to know if the session is expired
-
- // Check whether the session is still valid if we have one
- if ($this->auth !== false && method_exists($this->auth, 'validate_session'))
- {
- if (!$this->auth->validate_session($this))
- {
- return false;
- }
- }
-
- // Check the session length timeframe if autologin is not enabled.
- // Else check the autologin length... and also removing those having autologin enabled but no longer allowed board-wide.
- if (!$this->data['session_autologin'])
- {
- if ($this->data['session_time'] < $this->time_now - (phpbb::$config['session_length'] + 60))
- {
- return false;
- }
- }
- else if (!phpbb::$config['allow_autologin'] || (phpbb::$config['max_autologin_time'] && $this->data['session_time'] < $this->time_now - (86400 * (int) phpbb::$config['max_autologin_time']) + 60))
- {
- return false;
- }
-
- // Only update session DB a minute or so after last update or if page changes
- if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->system['page']['page']))
- {
- $sql_ary = array('session_time' => $this->time_now);
-
- if ($this->update_session_page)
- {
- $sql_ary['session_page'] = substr($this->system['page']['page'], 0, 199);
- $sql_ary['session_forum_id'] = $this->system['page']['forum'];
- }
-
- $sql = 'UPDATE ' . SESSIONS_TABLE . ' SET ' . phpbb::$db->sql_build_array('UPDATE', $sql_ary) . "
- WHERE session_id = '" . phpbb::$db->sql_escape($this->session_id) . "'";
- phpbb::$db->sql_query($sql);
- }
-
- $this->is_registered = ($this->data['user_id'] != ANONYMOUS && ($this->data['user_type'] == phpbb::USER_NORMAL || $this->data['user_type'] == phpbb::USER_FOUNDER)) ? true : false;
- $this->is_bot = (!$this->is_registered && $this->data['user_id'] != ANONYMOUS) ? true : false;
- $this->is_founder = $this->data['user_type'] == phpbb::USER_FOUNDER;
- $this->is_guest = (!$this->is_registered && $this->data['user_id'] == ANONYMOUS) ? true : false;
- $this->data['user_lang'] = basename($this->data['user_lang']);
-
- return true;
- }
-
- /**
- * Check if the request originated from the same page.
- *
- * @param bool $check_script_path If true, the path will be checked as well
- *
- * @return bool True if the referer is valid
- * @access private
- */
- private function validate_referer($check_script_path = false)
- {
- // no referer - nothing to validate, user's fault for turning it off (we only check on POST; so meta can't be the reason)
- if (empty($this->system['referer']) || empty($this->system['host']))
- {
- return true;
- }
-
- // Specialchar host, because it's the only one not specialchared
- $host = htmlspecialchars($this->system['host']);
- $ref = substr($this->system['referer'], strpos($this->system['referer'], '://') + 3);
-
- if (!(stripos($ref, $host) === 0))
- {
- return false;
- }
- else if ($check_script_path && rtrim($this->system['page']['root_script_path'], '/') !== '')
- {
- $ref = substr($ref, strlen($host));
- $server_port = $this->system['port'];
-
- if ($server_port !== 80 && $server_port !== 443 && stripos($ref, ":$server_port") === 0)
- {
- $ref = substr($ref, strlen(":$server_port"));
- }
-
- if (!(stripos(rtrim($ref, '/'), rtrim($this->system['page']['root_script_path'], '/')) === 0))
- {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Fill data array with a "faked" user account
- *
- * @return array Default user data array
- * @access private
- */
- private function default_data()
- {
- return array(
- 'user_id' => ANONYMOUS,
- );
- }
-
- /**
- * Check for a bot by comparing user agent and ip
- *
- * Here we do a bot check, oh er saucy! No, not that kind of bot
- * check. We loop through the list of bots defined by the admin and
- * see if we have any useragent and/or IP matches. If we do, this is a
- * bot, act accordingly
- *
- * @return bool True if it is a bot.
- * @access private
- */
- private function check_bot()
- {
- $bot = false;
-
- foreach (phpbb_cache::obtain_bots() as $row)
- {
- if ($row['bot_agent'] && preg_match('#' . str_replace('\*', '.*?', preg_quote($row['bot_agent'], '#')) . '#i', $this->system['browser']))
- {
- $bot = $row['user_id'];
- }
-
- // If ip is supplied, we will make sure the ip is matching too...
- if ($row['bot_ip'] && ($bot || !$row['bot_agent']))
- {
- // Set bot to false, then we only have to set it to true if it is matching
- $bot = false;
-
- foreach (explode(',', $row['bot_ip']) as $bot_ip)
- {
- if (!trim($bot_ip))
- {
- continue;
- }
-
- if (strpos($this->system['ip'], $bot_ip) === 0)
- {
- $bot = (int) $row['user_id'];
- break;
- }
- }
- }
-
- if ($bot)
- {
- break;
- }
- }
-
- return $bot;
- }
-
- /**
- * Check if session is valid by comparing ip, forwarded for, browser and referer
- *
- * @param bool $log_failure If true then a non-match will be logged. Can cause huge logs.
- *
- * @return bool True if the session is valid
- * @access private
- */
- private function session_valid($log_failure = true)
- {
- // Validate IP length according to admin ... enforces an IP
- // check on bots if admin requires this
-// $quadcheck = (phpbb::$config['ip_check_bot'] && $this->data['user_type'] & USER_BOT) ? 4 : phpbb::$config['ip_check'];
-
- if (strpos($this->system['ip'], ':') !== false && strpos($this->data['session_ip'], ':') !== false)
- {
- $session_ip = short_ipv6($this->data['session_ip'], phpbb::$config['ip_check']);
- $user_ip = short_ipv6($this->system['ip'], phpbb::$config['ip_check']);
- }
- else
- {
- $session_ip = implode('.', array_slice(explode('.', $this->data['session_ip']), 0, phpbb::$config['ip_check']));
- $user_ip = implode('.', array_slice(explode('.', $this->system['ip']), 0, phpbb::$config['ip_check']));
- }
-
- $session_browser = (phpbb::$config['browser_check']) ? trim(strtolower(substr($this->data['session_browser'], 0, 149))) : '';
- $user_browser = (phpbb::$config['browser_check']) ? trim(strtolower(substr($this->system['browser'], 0, 149))) : '';
-
- $session_forwarded_for = (phpbb::$config['forwarded_for_check']) ? substr($this->data['session_forwarded_for'], 0, 254) : '';
- $user_forwarded_for = (phpbb::$config['forwarded_for_check']) ? substr($this->system['forwarded_for'], 0, 254) : '';
-
- // referer checks
- $check_referer_path = phpbb::$config['referer_validation'] == REFERER_VALIDATE_PATH;
- $referer_valid = true;
-
- // we assume HEAD and TRACE to be foul play and thus only whitelist GET
- if (phpbb::$config['referer_validation'] && $this->system['request_method'])
- {
- $referer_valid = $this->validate_referer($check_referer_path);
- }
-
- if ($user_ip !== $session_ip || $user_browser !== $session_browser || $user_forwarded_for !== $session_forwarded_for || !$referer_valid)
- {
- // Added logging temporarly to help debug bugs...
- if (phpbb::$base_config['debug_extra'] && $this->data['user_id'] != ANONYMOUS && $log_failure)
- {
- if ($referer_valid)
- {
- add_log('critical', 'LOG_IP_BROWSER_FORWARDED_CHECK', $user_ip, $session_ip, $user_browser, $session_browser, htmlspecialchars($user_forwarded_for), htmlspecialchars($session_forwarded_for));
- }
- else
- {
- add_log('critical', 'LOG_REFERER_INVALID', $this->system['referer']);
- }
- }
-
- return false;
- }
-
- return true;
- }
-}
-
-?> \ No newline at end of file
diff --git a/phpBB/includes/classes/template.php b/phpBB/includes/classes/template.php
deleted file mode 100644
index 1ef29545d2..0000000000
--- a/phpBB/includes/classes/template.php
+++ /dev/null
@@ -1,531 +0,0 @@
-<?php
-/**
-*
-* @package phpBB3
-* @version $Id$
-* @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* @todo
-* IMG_ for image substitution?
-* {IMG_[key]:[alt]:[type]}
-* {IMG_ICON_CONTACT:CONTACT:full} -> phpbb::$user->img('icon_contact', 'CONTACT', 'full');
-*
-* More in-depth...
-* yadayada
-*/
-
-/**
-* Base Template class.
-* @package phpBB3
-*/
-class phpbb_template
-{
- public $phpbb_required = array('user', 'config');
- public $phpbb_optional = array();
-
- /**
- * variable that holds all the data we'll be substituting into
- * the compiled templates. Takes form:
- * --> $this->_tpldata[block][iteration#][child][iteration#][child2][iteration#][variablename] == value
- * if it's a root-level variable, it'll be like this:
- * --> $this->_tpldata[.][0][varname] == value
- * @var array
- */
- private $_tpldata = array('.' => array(0 => array()));
-
- /**
- * @var array Reference to template->_tpldata['.'][0]
- */
- private $_rootref;
-
- /**
- * @var string Root dir for template.
- */
- private $root = '';
-
- /**
- * @var string Path of the cache directory for the template
- */
- public $cachepath = '';
-
- /**
- * @var array Hash of handle => file path pairs
- */
- public $files = array();
-
- /**
- * @var array Hash of handle => filename pairs
- */
- public $filename = array();
-
- /**
- * Set template location
- * @access public
- */
- public function set_template()
- {
- if (file_exists(PHPBB_ROOT_PATH . 'styles/' . phpbb::$user->theme['template_path'] . '/template'))
- {
- $this->root = PHPBB_ROOT_PATH . 'styles/' . phpbb::$user->theme['template_path'] . '/template';
- $this->cachepath = PHPBB_ROOT_PATH . 'cache/tpl_' . phpbb::$user->theme['template_path'] . '_';
- }
- else
- {
- trigger_error('Template path could not be found: styles/' . phpbb::$user->theme['template_path'] . '/template', E_USER_ERROR);
- }
-
- $this->_rootref = &$this->_tpldata['.'][0];
- }
-
- /**
- * Set custom template location (able to use directory outside of phpBB)
- * @access public
- * @param string $template_path Path to template directory
- * @param string $template_name Name of template
- */
- public function set_custom_template($template_path, $template_name)
- {
- $this->root = $template_path;
- $this->cachepath = PHPBB_ROOT_PATH . 'cache/ctpl_' . str_replace('_', '-', $template_name) . '_';
- }
-
- /**
- * Sets the template filenames for handles. $filename_array
- * @access public
- * @param array $filname_array Should be a hash of handle => filename pairs.
- */
- public function set_filenames(array $filename_array)
- {
- foreach ($filename_array as $handle => $filename)
- {
- if (empty($filename))
- {
- trigger_error("template->set_filenames: Empty filename specified for $handle", E_USER_ERROR);
- }
-
- $this->filename[$handle] = $filename;
- $this->files[$handle] = $this->root . '/' . $filename;
- }
-
- return true;
- }
-
- /**
- * Destroy template data set
- * @access public
- */
- public function __destruct()
- {
- $this->_tpldata = array('.' => array(0 => array()));
- }
-
- /**
- * Reset/empty complete block
- * @access public
- * @param string $blockname Name of block to destroy
- */
- public function destroy_block_vars($blockname)
- {
- if (strpos($blockname, '.') !== false)
- {
- // Nested block.
- $blocks = explode('.', $blockname);
- $blockcount = sizeof($blocks) - 1;
-
- $str = &$this->_tpldata;
- for ($i = 0; $i < $blockcount; $i++)
- {
- $str = &$str[$blocks[$i]];
- $str = &$str[sizeof($str) - 1];
- }
-
- unset($str[$blocks[$blockcount]]);
- }
- else
- {
- // Top-level block.
- unset($this->_tpldata[$blockname]);
- }
- }
-
- /**
- * Display handle
- * @access public
- * @param string $handle Handle to display
- * @param bool $include_once Allow multiple inclusions
- * @return bool True on success, false on failure
- */
- public function display($handle, $include_once = true)
- {
-/*
- if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, __FUNCTION__), $handle, $include_once))
- {
- if ($phpbb_hook->hook_return(array(__CLASS__, __FUNCTION__)))
- {
- return $phpbb_hook->hook_return_result(array(__CLASS__, __FUNCTION__));
- }
- }
-*/
-/* if (defined('IN_ERROR_HANDLER'))
- {
- if ((E_NOTICE & error_reporting()) == E_NOTICE)
- {
- //error_reporting(error_reporting() ^ E_NOTICE);
- }
- }*/
-
- $_tpldata = &$this->_tpldata;
- $_rootref = &$this->_rootref;
- $_lang = &phpbb::$user->lang;
-
- if (($filename = $this->_tpl_load($handle)) !== false)
- {
- ($include_once) ? include_once($filename) : include($filename);
- }
- else if (($code = $this->_tpl_eval($handle)) !== false)
- {
- $code = ' ?> ' . $code . ' <?php ';
- eval($code);
- }
- else
- {
- // if we could not eval AND the file exists, something horrific has occured
- return false;
- }
-
- return true;
- }
-
- /**
- * Display the handle and assign the output to a template variable or return the compiled result.
- * @access public
- * @param string $handle Handle to operate on
- * @param string $template_var Template variable to assign compiled handle to
- * @param bool $return_content If true return compiled handle, otherwise assign to $template_var
- * @param bool $include_once Allow multiple inclusions of the file
- * @return bool|string If $return_content is true return string of the compiled handle, otherwise return true
- */
- public function assign_display($handle, $template_var = '', $return_content = true, $include_once = false)
- {
- ob_start();
- $this->display($handle, $include_once);
- $contents = ob_get_clean();
-
- if ($return_content)
- {
- return $contents;
- }
-
- $this->assign_var($template_var, $contents);
-
- return true;
- }
-
- /**
- * Load a compiled template if possible, if not, recompile it
- * @access private
- * @param string $handle Handle of the template to load
- * @return string|bool Return filename on success otherwise false
- * @uses template_compile is used to compile uncached templates
- */
- private function _tpl_load($handle)
- {
- if (!isset($this->filename[$handle]))
- {
- trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR);
- }
-
- $filename = $this->cachepath . str_replace('/', '.', $this->filename[$handle]) . '.' . PHP_EXT;
-
- $recompile = (!file_exists($filename) || @filesize($filename) === 0 || (phpbb::$config['load_tplcompile'] && @filemtime($filename) < filemtime($this->files[$handle]))) ? true : false;
-
- if (phpbb::$base_config['debug_extra'])
- {
- $recompile = true;
- }
-
- // Recompile page if the original template is newer, otherwise load the compiled version
- if ($recompile)
- {
- $compile = new phpbb_template_compile($this);
-
- // If we don't have a file assigned to this handle, die.
- if (!isset($this->files[$handle]))
- {
- trigger_error("template->_tpl_load(): No file specified for handle $handle", E_USER_ERROR);
- }
-
- if ($compile->_tpl_load_file($handle) === false)
- {
- return false;
- }
- }
-
- return $filename;
- }
-
- /**
- * This code should only run when some high level error prevents us from writing to the cache.
- * @access private
- * @param string $handle Template handle to compile
- * @return string|bool Return compiled code on success otherwise false
- * @uses template_compile is used to compile template
- */
- private function _tpl_eval($handle)
- {
- $compile = new phpbb_template_compile($this);
-
- // If we don't have a file assigned to this handle, die.
- if (!isset($this->files[$handle]))
- {
- trigger_error("template->_tpl_eval(): No file specified for handle $handle", E_USER_ERROR);
- }
-
- if (($code = $compile->_tpl_gen_src($handle)) === false)
- {
- return false;
- }
-
- return $code;
- }
-
- /**
- * Assign key variable pairs from an array
- * @access public
- * @param array $vararray A hash of variable name => value pairs
- */
- public function assign_vars(array $vararray)
- {
- foreach ($vararray as $key => $val)
- {
- $this->_rootref[$key] = $val;
- }
- }
-
- /**
- * Assign a single variable to a single key
- * @access public
- * @param string $varname Variable name
- * @param string $varval Value to assign to variable
- */
- public function assign_var($varname, $varval)
- {
- $this->_rootref[$varname] = $varval;
- }
-
- /**
- * Assign key variable pairs from an array to a specified block
- * @access public
- * @param string $blockname Name of block to assign $vararray to
- * @param array $vararray A hash of variable name => value pairs
- */
- public function assign_block_vars($blockname, array $vararray)
- {
- if (strpos($blockname, '.') !== false)
- {
- // Nested block.
- $blocks = explode('.', $blockname);
- $blockcount = sizeof($blocks) - 1;
-
- $str = &$this->_tpldata;
- for ($i = 0; $i < $blockcount; $i++)
- {
- $str = &$str[$blocks[$i]];
- $str = &$str[sizeof($str) - 1];
- }
-
- // Now we add the block that we're actually assigning to.
- // We're adding a new iteration to this block with the given
- // variable assignments.
- $str[$blocks[$blockcount]][] = $vararray;
- }
- else
- {
- // Top-level block.
-
- // Add a new iteration to this block with the variable assignments we were given.
- $this->_tpldata[$blockname][] = $vararray;
- }
- }
-
- /**
- * Change already assigned key variable pair (one-dimensional - single loop entry)
- *
- * An example of how to use this function:
- *
- * @param string $blockname the blockname, for example 'loop'
- * @param array $vararray the var array to insert/add or merge
- * @param mixed $key Key to search for
- *
- * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position]
- *
- * int: Position [the position to change or insert at directly given]
- *
- * If key is false the position is set to 0
- * If key is true the position is set to the last entry
- *
- * @param string $mode Mode to execute (valid modes are 'insert' and 'change')
- *
- * If insert, the vararray is inserted at the given position (position counting from zero).
- * If change, the current block gets merged with the vararray (resulting in new key/value pairs be added and existing keys be replaced by the new value).
- *
- * Since counting begins by zero, inserting at the last position will result in this array: array(vararray, last positioned array)
- * and inserting at position 1 will result in this array: array(first positioned array, vararray, following vars)
- *
- * @return bool false on error, true on success
- * @access public
- */
- public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert')
- {
- if (strpos($blockname, '.') !== false)
- {
- // Nested block.
- $blocks = explode('.', $blockname);
- $blockcount = sizeof($blocks) - 1;
-
- $block = &$this->_tpldata;
- for ($i = 0; $i < $blockcount; $i++)
- {
- if (($pos = strpos($blocks[$i], '[')) !== false)
- {
- $name = substr($blocks[$i], 0, $pos);
-
- if (strpos($blocks[$i], '[]') === $pos)
- {
- $index = sizeof($block[$name]) - 1;
- }
- else
- {
- $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1);
- }
- }
- else
- {
- $name = $blocks[$i];
- $index = sizeof($block[$name]) - 1;
- }
- $block = &$block[$name];
- $block = &$block[$index];
- }
-
- $block = &$block[$blocks[$i]]; // Traverse the last block
- }
- else
- {
- // Top-level block.
- $block = &$this->_tpldata[$blockname];
- }
-
- // Change key to zero (change first position) if false and to last position if true
- if ($key === false || $key === true)
- {
- $key = ($key === false) ? 0 : sizeof($block);
- }
-
- // Get correct position if array given
- if (is_array($key))
- {
- // Search array to get correct position
- list($search_key, $search_value) = @each($key);
-
- $key = NULL;
- foreach ($block as $i => $val_ary)
- {
- if ($val_ary[$search_key] === $search_value)
- {
- $key = $i;
- break;
- }
- }
-
- // key/value pair not found
- if ($key === NULL)
- {
- return false;
- }
- }
-
- // Insert Block
- if ($mode == 'insert')
- {
- // Re-position template blocks
- for ($i = sizeof($block); $i > $key; $i--)
- {
- $block[$i] = $block[$i-1];
- }
-
- // Insert vararray at given position
- $block[$key] = $vararray;
-
- return true;
- }
-
- // Which block to change?
- if ($mode == 'change')
- {
- if ($key == sizeof($block))
- {
- $key--;
- }
-
- $block[$key] = array_merge($block[$key], $vararray);
-
- return true;
- }
-
- return false;
- }
-
- /**
- * Include a separate template
- * @access private
- * @param string $filename Template filename to include
- * @param bool $include True to include the file, false to just load it
- * @uses template_compile is used to compile uncached templates
- */
- private function _tpl_include($filename, $include = true)
- {
- $handle = $filename;
- $this->filename[$handle] = $filename;
- $this->files[$handle] = $this->root . '/' . $filename;
-
- $filename = $this->_tpl_load($handle);
-
- if ($include)
- {
- $_tpldata = &$this->_tpldata;
- $_rootref = &$this->_rootref;
- $_lang = &phpbb::$user->lang;
-
- if ($filename)
- {
- include($filename);
- return;
- }
- else
- {
- $compile = new phpbb_template_compile($this);
-
- if (($code = $compile->_tpl_gen_src($handle)) !== false)
- {
- $code = ' ?> ' . $code . ' <?php ';
- eval($code);
- }
- }
- }
- }
-}
-
-?> \ No newline at end of file
diff --git a/phpBB/includes/classes/template_compile.php b/phpBB/includes/classes/template_compile.php
deleted file mode 100644
index 7880babc51..0000000000
--- a/phpBB/includes/classes/template_compile.php
+++ /dev/null
@@ -1,904 +0,0 @@
-<?php
-/**
-*
-* @package phpBB3
-* @version $Id$
-* @copyright (c) 2005 phpBB Group, sections (c) 2001 ispi of Lincoln Inc
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* The template filter that does the actual compilation
-* @see template_compile
-* @package phpBB3
-*/
-class phpbb_template_filter extends php_user_filter
-{
- const REGEX_NS = '[a-z][a-z_0-9]+';
-
- const REGEX_VAR = '[A-Z][A-Z_0-9]+';
-
- const REGEX_TAG = '<!-- ([A-Z][A-Z_0-9]+)(?: (.*?) ?)?-->';
-
- const REGEX_TOKENS = '~<!-- ([A-Z][A-Z_0-9]+)(?: (.*?) ?)?-->|{((?:[a-z][a-z_0-9]+\.)*\\$?[A-Z][A-Z_0-9]+)}~';
-
- /**
- * @var array
- */
- private $block_names = array();
-
- /**
- * @var array
- */
- private $block_else_level = array();
-
- /**
- * @var string
- */
- private $chunk;
-
- public function filter($in, $out, &$consumed, $closing)
- {
- $written = false;
-
- while ($bucket = stream_bucket_make_writeable($in))
- {
- $consumed += $bucket->datalen;
-
- $data = $this->chunk . $bucket->data;
- $last_nl = strrpos($data, "\n");
- $this->chunk = substr($data, $last_nl);
- $data = substr($data, 0, $last_nl);
-
- if (!strlen($data))
- {
- continue;
- }
-
- $written = true;
-
- $bucket->data = $this->compile($data);
- $bucket->datalen = strlen($bucket->data);
- stream_bucket_append($out, $bucket);
- }
-
- if ($closing && strlen($this->chunk))
- {
- $written = true;
- $bucket = stream_bucket_new($this->stream, $this->compile($this->chunk));
- stream_bucket_append($out, $bucket);
- }
-
- return $written ? PSFS_PASS_ON : PSFS_FEED_ME;
- }
-
- public function onCreate()
- {
- $this->chunk = '';
- return true;
- }
-
- private function compile($data)
- {
- $data = preg_replace('#<(?:[\\?%]|script)#s', '<?php echo\'\\0\';?>', $data);
- return str_replace('?><?php', '', preg_replace_callback(self::REGEX_TOKENS, array($this, 'replace'), $data));
- }
-
- private function replace($matches)
- {
- if (isset($matches[3]))
- {
- return $this->compile_var_tags($matches[0]);
- }
-
- switch ($matches[1])
- {
- case 'BEGIN':
- $this->block_else_level[] = false;
- return '<?php ' . $this->compile_tag_block($matches[2]) . ' ?>';
- break;
-
- case 'BEGINELSE':
- $this->block_else_level[sizeof($this->block_else_level) - 1] = true;
- return '<?php }} else { ?>';
- break;
-
- case 'END':
- array_pop($this->block_names);
- return '<?php ' . ((array_pop($this->block_else_level)) ? '}' : '}}') . ' ?>';
- break;
-
- case 'IF':
- return '<?php ' . $this->compile_tag_if($matches[2], false) . ' ?>';
- break;
-
- case 'ELSE':
- return '<?php } else { ?>';
- break;
-
- case 'ELSEIF':
- return '<?php ' . $this->compile_tag_if($matches[2], true) . ' ?>';
- break;
-
- case 'ENDIF':
- return '<?php } ?>';
- break;
-
- case 'DEFINE':
- return '<?php ' . $this->compile_tag_define($matches[2], true) . ' ?>';
- break;
-
- case 'UNDEFINE':
- return '<?php ' . $this->compile_tag_define($matches[2], false) . ' ?>';
- break;
-
- case 'INCLUDE':
- return '<?php ' . $this->compile_tag_include($matches[2]) . ' ?>';
- break;
-
- case 'INCLUDEPHP':
- return (phpbb::$config['tpl_allow_php']) ? '<?php ' . $this->compile_tag_include_php($matches[2]) . ' ?>' : '';
- break;
-
- case 'PHP':
- return (phpbb::$config['tpl_allow_php']) ? '<?php ' : '<!-- ';
- break;
-
- case 'ENDPHP':
- return (phpbb::$config['tpl_allow_php']) ? ' ?>' : ' -->';
- break;
-
- default:
- return $matches[0];
- break;
-
- }
- return '';
- }
-
- /**
- * Compile variables
- * @access private
- */
- private function compile_var_tags(&$text_blocks)
- {
- // change template varrefs into PHP varrefs
- $varrefs = array();
-
- // This one will handle varrefs WITH namespaces
- preg_match_all('#\{((?:' . self::REGEX_NS . '\.)+)(\$)?(' . self::REGEX_VAR . ')\}#', $text_blocks, $varrefs, PREG_SET_ORDER);
-
- foreach ($varrefs as $var_val)
- {
- $namespace = $var_val[1];
- $varname = $var_val[3];
- $new = $this->generate_block_varref($namespace, $varname, true, $var_val[2]);
-
- $text_blocks = str_replace($var_val[0], $new, $text_blocks);
- }
-
- // Handle special language tags L_ and LA_
- $this->compile_language_tags($text_blocks);
-
- // This will handle the remaining root-level varrefs
- $text_blocks = preg_replace('#\{(' . self::REGEX_VAR . ')\}#', "<?php echo (isset(\$_rootref['\\1'])) ? \$_rootref['\\1'] : ''; ?>", $text_blocks);
- $text_blocks = preg_replace('#\{\$(' . self::REGEX_VAR . ')\}#', "<?php echo (isset(\$_tpldata['DEFINE']['.']['\\1'])) ? \$_tpldata['DEFINE']['.']['\\1'] : ''; ?>", $text_blocks);
-
- return $text_blocks;
- }
-
- /**
- * Handles special language tags L_ and LA_
- */
- private function compile_language_tags(&$text_blocks)
- {
- // transform vars prefixed by L_ into their language variable pendant if nothing is set within the tpldata array
- if (strpos($text_blocks, '{L_') !== false)
- {
- $text_blocks = preg_replace('#\{L_(' . self::REGEX_VAR . ')\}#', "<?php echo ((isset(\$_rootref['L_\\1'])) ? \$_rootref['L_\\1'] : ((isset(\$_lang['\\1'])) ? \$_lang['\\1'] : '{ \\1 }')); ?>", $text_blocks);
- }
-
- // Handle addslashed language variables prefixed with LA_
- // If a template variable already exist, it will be used in favor of it...
- if (strpos($text_blocks, '{LA_') !== false)
- {
- $text_blocks = preg_replace('#\{LA_(' . self::REGEX_VAR . '+)\}#', "<?php echo ((isset(\$_rootref['LA_\\1'])) ? \$_rootref['LA_\\1'] : ((isset(\$_rootref['L_\\1'])) ? addslashes(\$_rootref['L_\\1']) : ((isset(\$_lang['\\1'])) ? addslashes(\$_lang['\\1']) : '{ \\1 }'))); ?>", $text_blocks);
- }
- }
-
- /**
- * Compile blocks
- * @access private
- */
- private function compile_tag_block($tag_args)
- {
- $no_nesting = false;
-
- // Is the designer wanting to call another loop in a loop?
- // <!-- BEGIN loop -->
- // <!-- BEGIN !loop2 -->
- // <!-- END !loop2 -->
- // <!-- END loop -->
- // 'loop2' is actually on the same nesting level as 'loop' you assign
- // variables to it with template->assign_block_vars('loop2', array(...))
- if (strpos($tag_args, '!') === 0)
- {
- // Count the number if ! occurrences (not allowed in vars)
- $no_nesting = substr_count($tag_args, '!');
- $tag_args = substr($tag_args, $no_nesting);
- }
-
- // Allow for control of looping (indexes start from zero):
- // foo(2) : Will start the loop on the 3rd entry
- // foo(-2) : Will start the loop two entries from the end
- // foo(3,4) : Will start the loop on the fourth entry and end it on the fifth
- // foo(3,-4) : Will start the loop on the fourth entry and end it four from last
- $match = array();
-
- if (preg_match('#^([^()]*)\(([\-\d]+)(?:,([\-\d]+))?\)$#', $tag_args, $match))
- {
- $tag_args = $match[1];
-
- if ($match[2] < 0)
- {
- $loop_start = '($_' . $tag_args . '_count ' . $match[2] . ' < 0 ? 0 : $_' . $tag_args . '_count ' . $match[2] . ')';
- }
- else
- {
- $loop_start = '($_' . $tag_args . '_count < ' . $match[2] . ' ? $_' . $tag_args . '_count : ' . $match[2] . ')';
- }
-
- if (!isset($match[3]) || strlen($match[3]) < 1 || $match[3] == -1)
- {
- $loop_end = '$_' . $tag_args . '_count';
- }
- else if ($match[3] >= 0)
- {
- $loop_end = '(' . ($match[3] + 1) . ' > $_' . $tag_args . '_count ? $_' . $tag_args . '_count : ' . ($match[3] + 1) . ')';
- }
- else //if ($match[3] < -1)
- {
- $loop_end = '$_' . $tag_args . '_count' . ($match[3] + 1);
- }
- }
- else
- {
- $loop_start = 0;
- $loop_end = '$_' . $tag_args . '_count';
- }
-
- $tag_template_php = '';
- array_push($this->block_names, $tag_args);
-
- if ($no_nesting !== false)
- {
- // We need to implode $no_nesting times from the end...
- $block = array_slice($this->block_names, -$no_nesting);
- }
- else
- {
- $block = $this->block_names;
- }
-
- if (sizeof($block) < 2)
- {
- // Block is not nested.
- $tag_template_php = '$_' . $tag_args . "_count = (isset(\$_tpldata['$tag_args'])) ? sizeof(\$_tpldata['$tag_args']) : 0;";
- $varref = "\$_tpldata['$tag_args']";
- }
- else
- {
- // This block is nested.
- // Generate a namespace string for this block.
- $namespace = implode('.', $block);
-
- // Get a reference to the data array for this block that depends on the
- // current indices of all parent blocks.
- $varref = $this->generate_block_data_ref($namespace, false);
-
- // Create the for loop code to iterate over this block.
- $tag_template_php = '$_' . $tag_args . '_count = (isset(' . $varref . ')) ? sizeof(' . $varref . ') : 0;';
- }
-
- $tag_template_php .= 'if ($_' . $tag_args . '_count) {';
-
- /**
- * The following uses foreach for iteration instead of a for loop, foreach is faster but requires PHP to make a copy of the contents of the array which uses more memory
- * <code>
- * if (!$offset)
- * {
- * $tag_template_php .= 'foreach (' . $varref . ' as $_' . $tag_args . '_i => $_' . $tag_args . '_val){';
- * }
- * </code>
- */
-
- $tag_template_php .= 'for ($_' . $tag_args . '_i = ' . $loop_start . '; $_' . $tag_args . '_i < ' . $loop_end . '; ++$_' . $tag_args . '_i){';
- $tag_template_php .= '$_' . $tag_args . '_val = &' . $varref . '[$_' . $tag_args . '_i];';
-
- return $tag_template_php;
- }
-
- /**
- * Compile a general expression - much of this is from Smarty with
- * some adaptions for our block level methods
- * @access private
- */
- private function compile_expression($tag_args, &$vars = array())
- {
- $match = array();
- preg_match_all('/(?:
- "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" |
- \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' |
- [(),] |
- [^\s(),]+)/x', $tag_args, $match);
-
- $tokens = $match[0];
- $is_arg_stack = array();
-
- for ($i = 0, $size = sizeof($tokens); $i < $size; $i++)
- {
- $token = &$tokens[$i];
-
- switch ($token)
- {
- case '!==':
- case '===':
- case '<<':
- case '>>':
- case '|':
- case '^':
- case '&':
- case '~':
- case ')':
- case ',':
- case '+':
- case '-':
- case '*':
- case '/':
- case '@':
- break;
-
- case '==':
- case 'eq':
- $token = '==';
- break;
-
- case '!=':
- case '<>':
- case 'ne':
- case 'neq':
- $token = '!=';
- break;
-
- case '<':
- case 'lt':
- $token = '<';
- break;
-
- case '<=':
- case 'le':
- case 'lte':
- $token = '<=';
- break;
-
- case '>':
- case 'gt':
- $token = '>';
- break;
-
- case '>=':
- case 'ge':
- case 'gte':
- $token = '>=';
- break;
-
- case '&&':
- case 'and':
- $token = '&&';
- break;
-
- case '||':
- case 'or':
- $token = '||';
- break;
-
- case '!':
- case 'not':
- $token = '!';
- break;
-
- case '%':
- case 'mod':
- $token = '%';
- break;
-
- case '(':
- array_push($is_arg_stack, $i);
- break;
-
- case 'is':
- $is_arg_start = ($tokens[$i-1] == ')') ? array_pop($is_arg_stack) : $i-1;
- $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
-
- $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
-
- array_splice($tokens, $is_arg_start, sizeof($tokens), $new_tokens);
-
- $i = $is_arg_start;
-
- // no break
-
- default:
- $varrefs = array();
- if (preg_match('#^((?:' . self::REGEX_NS . '\.)+)?(\$)?(?=[A-Z])([A-Z0-9\-_]+)#s', $token, $varrefs))
- {
- if (!empty($varrefs[1]))
- {
- $namespace = substr($varrefs[1], 0, -1);
- $namespace = (strpos($namespace, '.') === false) ? $namespace : strrchr($namespace, '.');
-
- // S_ROW_COUNT is deceptive, it returns the current row number now the number of rows
- // hence S_ROW_COUNT is deprecated in favour of S_ROW_NUM
- switch ($varrefs[3])
- {
- case 'S_ROW_NUM':
- case 'S_ROW_COUNT':
- $token = "\$_${namespace}_i";
- break;
-
- case 'S_NUM_ROWS':
- $token = "\$_${namespace}_count";
- break;
-
- case 'S_FIRST_ROW':
- $token = "(\$_${namespace}_i == 0)";
- break;
-
- case 'S_LAST_ROW':
- $token = "(\$_${namespace}_i == \$_${namespace}_count - 1)";
- break;
-
- case 'S_BLOCK_NAME':
- $token = "'$namespace'";
- break;
-
- default:
- $token = $this->generate_block_data_ref(substr($varrefs[1], 0, -1), true, $varrefs[2]) . '[\'' . $varrefs[3] . '\']';
- $vars[$token] = true;
- break;
- }
- }
- else
- {
- $token = ($varrefs[2]) ? '$_tpldata[\'DEFINE\'][\'.\'][\'' . $varrefs[3] . '\']' : '$_rootref[\'' . $varrefs[3] . '\']';
- $vars[$token] = true;
- }
-
- }
- else if (preg_match('#^\.((?:' . self::REGEX_NS . '\.?)+)$#s', $token, $varrefs))
- {
- // Allow checking if loops are set with .loopname
- // It is also possible to check the loop count by doing <!-- IF .loopname > 1 --> for example
- $blocks = explode('.', $varrefs[1]);
-
- // If the block is nested, we have a reference that we can grab.
- // If the block is not nested, we just go and grab the block from _tpldata
- if (sizeof($blocks) > 1)
- {
- $block = array_pop($blocks);
- $namespace = implode('.', $blocks);
- $varref = $this->generate_block_data_ref($namespace, true);
-
- // Add the block reference for the last child.
- $varref .= "['" . $block . "']";
- }
- else
- {
- $varref = '$_tpldata';
-
- // Add the block reference for the last child.
- $varref .= "['" . $blocks[0] . "']";
- }
- $token = "isset($varref) && sizeof($varref)";
- }
-
- break;
- }
- }
-
- return $tokens;
- }
-
-
- private function compile_tag_if($tag_args, $elseif)
- {
- $vars = array();
-
- $tokens = $this->compile_expression($tag_args, $vars);
-
- $tpl = ($elseif) ? '} else if (' : 'if (';
-
- if (!empty($vars))
- {
- $tpl .= '(isset(' . implode(') && isset(', array_keys($vars)) . ')) && ';
- }
-
- $tpl .= implode(' ', $tokens);
- $tpl .= ') { ';
-
- return $tpl;
- }
-
- /**
- * Compile DEFINE tags
- * @access private
- */
- private function compile_tag_define($tag_args, $op)
- {
- $match = array();
- preg_match('#^((?:' . self::REGEX_NS . '\.)+)?\$(?=[A-Z])([A-Z0-9_\-]*)(?: = (.*?))?$#', $tag_args, $match);
-
- if (empty($match[2]) || (!isset($match[3]) && $op))
- {
- return '';
- }
-
- if (!$op)
- {
- return 'unset(' . (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ');';
- }
-
- $parsed_statement = implode(' ', $this->compile_expression($match[3]));
-
- return (($match[1]) ? $this->generate_block_data_ref(substr($match[1], 0, -1), true, true) . '[\'' . $match[2] . '\']' : '$_tpldata[\'DEFINE\'][\'.\'][\'' . $match[2] . '\']') . ' = ' . $parsed_statement . ';';
- }
-
- /**
- * Compile INCLUDE tag
- * @access private
- */
- private function compile_tag_include($tag_args)
- {
- return "\$this->_tpl_include('$tag_args');";
- }
-
- /**
- * Compile INCLUDE_PHP tag
- * @access private
- */
- private function compile_tag_include_php($tag_args)
- {
- return "include('$tag_args');";
- }
-
- /**
- * parse expression
- * This is from Smarty
- * @access private
- */
- private function _parse_is_expr($is_arg, $tokens)
- {
- $expr_end = 0;
- $negate_expr = false;
-
- if (($first_token = array_shift($tokens)) == 'not')
- {
- $negate_expr = true;
- $expr_type = array_shift($tokens);
- }
- else
- {
- $expr_type = $first_token;
- }
-
- switch ($expr_type)
- {
- case 'even':
- if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by')
- {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!(($is_arg / $expr_arg) & 1)";
- }
- else
- {
- $expr = "!($is_arg & 1)";
- }
- break;
-
- case 'odd':
- if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by')
- {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "(($is_arg / $expr_arg) & 1)";
- }
- else
- {
- $expr = "($is_arg & 1)";
- }
- break;
-
- case 'div':
- if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by')
- {
- $expr_end++;
- $expr_arg = $tokens[$expr_end++];
- $expr = "!($is_arg % $expr_arg)";
- }
- break;
- }
-
- if ($negate_expr)
- {
- if ($expr[0] == '!')
- {
- // Negated expression, de-negate it.
- $expr = substr($expr, 1);
- }
- else
- {
- $expr = "!($expr)";
- }
- }
-
- array_splice($tokens, 0, $expr_end, $expr);
-
- return $tokens;
- }
-
- /**
- * Generates a reference to the given variable inside the given (possibly nested)
- * block namespace. This is a string of the form:
- * ' . $_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['varname'] . '
- * It's ready to be inserted into an "echo" line in one of the templates.
- *
- * @access private
- * @param string $namespace Namespace to access (expects a trailing "." on the namespace)
- * @param string $varname Variable name to use
- * @param bool $echo If true return an echo statement, otherwise a reference to the internal variable
- * @param bool $defop If true this is a variable created with the DEFINE construct, otherwise template variable
- * @return string Code to access variable or echo it if $echo is true
- */
- private function generate_block_varref($namespace, $varname, $echo = true, $defop = false)
- {
- // Strip the trailing period.
- $namespace = substr($namespace, 0, -1);
-
- $expr = true;
- $isset = false;
-
- // S_ROW_COUNT is deceptive, it returns the current row number now the number of rows
- // hence S_ROW_COUNT is deprecated in favour of S_ROW_NUM
- switch ($varname)
- {
- case 'S_ROW_NUM':
- case 'S_ROW_COUNT':
- $varref = "\$_${namespace}_i";
- break;
-
- case 'S_NUM_ROWS':
- $varref = "\$_${namespace}_count";
- break;
-
- case 'S_FIRST_ROW':
- $varref = "(\$_${namespace}_i == 0)";
- break;
-
- case 'S_LAST_ROW':
- $varref = "(\$_${namespace}_i == \$_${namespace}_count - 1)";
- break;
-
- case 'S_BLOCK_NAME':
- $varref = "'$namespace'";
- break;
-
- default:
- // Get a reference to the data block for this namespace.
- $varref = $this->generate_block_data_ref($namespace, true, $defop);
- // Prepend the necessary code to stick this in an echo line.
-
- // Append the variable reference.
- $varref .= "['$varname']";
-
- $expr = false;
- $isset = true;
- break;
- }
- // @todo Test the !$expr more
- $varref = ($echo) ? '<?php echo ' . ($isset ? "isset($varref) ? $varref : ''" : $varref) . '; ?>' : (($expr || isset($varref)) ? $varref : '');
-
- return $varref;
- }
-
- /**
- * Generates a reference to the array of data values for the given
- * (possibly nested) block namespace. This is a string of the form:
- * $_tpldata['parent'][$_parent_i]['$child1'][$_child1_i]['$child2'][$_child2_i]...['$childN']
- *
- * @access private
- * @param string $blockname Block to access (does not expect a trailing "." on the blockname)
- * @param bool $include_last_iterator If $include_last_iterator is true, then [$_childN_i] will be appended to the form shown above.
- * @param bool $defop If true this is a variable created with the DEFINE construct, otherwise template variable
- * @return string Code to access variable
- */
- private function generate_block_data_ref($blockname, $include_last_iterator, $defop = false)
- {
- // Get an array of the blocks involved.
- $blocks = explode('.', $blockname);
- $blockcount = sizeof($blocks) - 1;
-
- // DEFINE is not an element of any referenced variable, we must use _tpldata to access it
- if ($defop)
- {
- $varref = '$_tpldata[\'DEFINE\']';
- // Build up the string with everything but the last child.
- for ($i = 0; $i < $blockcount; $i++)
- {
- $varref .= "['" . $blocks[$i] . "'][\$_" . $blocks[$i] . '_i]';
- }
- // Add the block reference for the last child.
- $varref .= "['" . $blocks[$blockcount] . "']";
- // Add the iterator for the last child if requried.
- if ($include_last_iterator)
- {
- $varref .= '[$_' . $blocks[$blockcount] . '_i]';
- }
- return $varref;
- }
- else if ($include_last_iterator)
- {
- return '$_'. $blocks[$blockcount] . '_val';
- }
- else
- {
- return '$_'. $blocks[$blockcount - 1] . '_val[\''. $blocks[$blockcount]. '\']';
- }
- }
-}
-
-stream_filter_register('phpbb_template', 'phpbb_template_filter');
-
-/**
-* Extension of template class - Functions needed for compiling templates only.
-*
-* psoTFX, phpBB Development Team - Completion of file caching, decompilation
-* routines and implementation of conditionals/keywords and associated changes
-*
-* The interface was inspired by PHPLib templates, and the template file (formats are
-* quite similar)
-*
-* The keyword/conditional implementation is currently based on sections of code from
-* the Smarty templating engine (c) 2001 ispi of Lincoln, Inc. which is released
-* (on its own and in whole) under the LGPL. Section 3 of the LGPL states that any code
-* derived from an LGPL application may be relicenced under the GPL, this applies
-* to this source
-*
-* DEFINE directive inspired by a request by Cyberalien
-*
-* @package phpBB3
-* @uses template_filter As a PHP stream filter to perform compilation of templates
-*/
-class phpbb_template_compile
-{
- /**
- * @var phpbb_template Reference to the {@link phpbb_template template} object performing compilation
- */
- private $template;
-
- /**
- * Constructor
- * @param phpbb_template $template {@link phpbb_template Template} object performing compilation
- */
- public function __construct(phpbb_template $template)
- {
- $this->template = $template;
- }
-
- /**
- * Load template source from file
- * @access public
- * @param string $handle Template handle we wish to load
- * @return bool Return true on success otherwise false
- */
- public function _tpl_load_file($handle)
- {
- // Try and open template for read
- if (!file_exists($this->template->files[$handle]))
- {
- trigger_error("template->_tpl_load_file(): File {$this->template->files[$handle]} does not exist or is empty", E_USER_ERROR);
- }
-
- // Actually compile the code now.
- return $this->compile_write($handle, $this->template->files[$handle]);
- }
-
- /**
- * Load template source from file
- * @access public
- * @param string $handle Template handle we wish to compile
- * @return string|bool Return compiled code on successful compilation otherwise false
- */
- public function _tpl_gen_src($handle)
- {
- // Try and open template for read
- if (!file_exists($this->template->files[$handle]))
- {
- trigger_error("template->_tpl_load_file(): File {$this->template->files[$handle]} does not exist or is empty", E_USER_ERROR);
- }
-
- // Actually compile the code now.
- return $this->compile_gen($this->template->files[$handle]);
- }
-
- /**
- * Write compiled file to cache directory
- * @access private
- * @param string $handle Template handle to compile
- * @param string $source_file Source template file
- * @return bool Return true on success otherwise false
- */
- private function compile_write($handle, $source_file)
- {
- $filename = $this->template->cachepath . str_replace('/', '.', $this->template->filename[$handle]) . '.' . PHP_EXT;
-
- $source_handle = @fopen($source_file, 'rb');
- $destination_handle = @fopen($filename, 'wb');
-
- if (!$source_handle || !$destination_handle)
- {
- return false;
- }
-
- @flock($destination_handle, LOCK_EX);
-
- stream_filter_append($source_handle, 'phpbb_template');
- stream_copy_to_stream($source_handle, $destination_handle);
-
- @fclose($source_handle);
- @flock($destination_handle, LOCK_UN);
- @fclose($destination_handle);
-
- phpbb::$system->chmod($filename, phpbb::CHMOD_READ | phpbb::CHMOD_WRITE);
-
- clearstatcache();
-
- return true;
- }
-
- /**
- * Generate source for eval()
- * @access private
- * @param string $source_file Source template file
- * @return string|bool Return compiled code on successful compilation otherwise false
- */
- private function compile_gen($source_file)
- {
- $source_handle = @fopen($source_file, 'rb');
- $destination_handle = @fopen('php://temp' ,'r+b');
-
- if (!$source_handle || !$destination_handle)
- {
- return false;
- }
-
- stream_filter_append($source_handle, 'phpbb_template');
- stream_copy_to_stream($source_handle, $destination_handle);
-
- @fclose($source_handle);
-
- rewind($destination_handle);
- return stream_get_contents($destination_handle);
- }
-}
-
-?> \ No newline at end of file
diff --git a/phpBB/includes/classes/user.php b/phpBB/includes/classes/user.php
deleted file mode 100644
index 83e8fce4eb..0000000000
--- a/phpBB/includes/classes/user.php
+++ /dev/null
@@ -1,1124 +0,0 @@
-<?php
-/**
-*
-* @package phpBB3
-* @version $Id$
-* @copyright (c) 2005, 2008 phpBB Group
-* @license http://opensource.org/licenses/gpl-license.php GNU Public License
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* Base user class
-*
-* This is the overarching class which contains (through session extend)
-* all methods utilised for user functionality during a session.
-*
-* @package phpBB3
-*/
-class phpbb_user extends phpbb_session
-{
- /**
- * @var array required phpBB objects
- */
- public $phpbb_required = array('config', 'acl', 'db', 'template', 'security', 'server-vars', 'acm', 'api:user');
-
- /**
- * @var array Optional phpBB objects
- */
- public $phpbb_optional = array();
-
- /**
- * @var array language entries
- */
- public $lang = array();
-
- /**
- * @var array help entries
- */
- public $help = array();
-
- /**
- * @var array theme entries
- */
- public $theme = array();
-
- /**
- * @var string users date format
- */
- public $date_format;
-
- /**
- * @var double users time zone
- */
- public $timezone;
-
- /**
- * @var int users summer time setting. 0 if not in DST, else DST offset.
- */
- public $dst;
-
- /**
- * @var string language name, for example 'en'
- */
- public $lang_name = false;
-
- /**
- * @var int the language id for the specified language name
- */
- public $lang_id = false;
-
- /**
- * @var string the language path phpBB can find installed languages
- */
- public $lang_path;
-
- /**
- * @var string Imageset language name. If no fallback happens it is the same as {@link lang_name lang_name}.
- */
- public $img_lang;
-
- /**
- * @var array Holds information about the imageset to build {@link img() images}.
- */
- public $img_array = array();
-
- /**
- * @var bool Is true if the user is a logged in registered user
- */
- public $is_registered = false;
-
- /**
- * @var bool Is true if the user is logged in and a search engine/bot
- */
- public $is_bot = false;
-
- /**
- * @var bool Is true if user is founder
- */
- public $is_founder = false;
-
- /**
- * @var bool Is true if user is anonymous/guest
- */
- public $is_guest = true;
-
- /**
- * Ablility to add new option (id 7). Enabled user options is stored in $data['user_options'].
- * @var array user options defining their possibilities to view flash, images, etc. User options only supports set/unset (true/false)
- */
- public $keyoptions = array('viewimg' => 0, 'viewflash' => 1, 'viewsmilies' => 2, 'viewsigs' => 3, 'viewavatars' => 4, 'viewcensors' => 5, 'attachsig' => 6, 'bbcode' => 8, 'smilies' => 9, 'popuppm' => 10);
-
- /**
- * @var array The respective true/false values for the {@link keyoptions keyoptions}.
- */
- public $keyvalues = array();
-
- /**
- * Constructor to set the lang path. Calls parrent::__construct()
- *
- * @param string $auth_method The authentication method to use, for example 'db'
- * @param string $lang_path Language pack path
- * @access public
- */
- public function __construct($auth_method, $lang_path)
- {
- parent::__construct();
-
- // Init auth object
- $method = basename(trim($auth_method));
- $class = 'phpbb_auth_' . $method;
-
- if (class_exists($class))
- {
- $this->auth = new $class();
- }
-
- // Set language path
- $this->lang_path = $lang_path;
-
- // Make sure last character is a directory separator
- if (substr($this->lang_path, -1) != '/')
- {
- $this->lang_path .= '/';
- }
- }
-
- /**
- * Determine and set language
- */
- public function set_language($lang_name = '')
- {
- // Try to determine language from browser
- if (!$lang_name && !empty($_SERVER['HTTP_ACCEPT_LANGUAGE']))
- {
- $accept_lang_ary = explode(',', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']));
-
- foreach ($accept_lang_ary as $accept_lang)
- {
- // Set correct format ... guess full xx_yy form
- $accept_lang = substr($accept_lang, 0, 2) . '_' . substr($accept_lang, 3, 2);
-
- if (file_exists($this->lang_path . basename($accept_lang)))
- {
- $lang_name = $accept_lang;
- break;
- }
- else
- {
- // No match on xx_yy so try xx
- $accept_lang = substr($accept_lang, 0, 2);
- if (file_exists($this->lang_path . basename($accept_lang)))
- {
- $lang_name = $accept_lang;
- break;
- }
- }
- }
- }
-
- // Still no luck?
- $lang_name = (!$lang_name && isset(phpbb::$config['default_lang'])) ? phpbb::$config['default_lang'] : basename($lang_name);
-
- // No appropriate language found ... so let's use the first one in the language
- // dir, this may or may not be English
- if (!$lang_name)
- {
- $dir = @opendir($this->lang_path);
-
- if (!$dir)
- {
- trigger_error('Unable to access the language directory', E_USER_ERROR);
- }
-
- while (($file = readdir($dir)) !== false)
- {
- $path = $this->lang_path . $file;
-
- if (!is_file($path) && !is_link($path) && file_exists($path . '/iso.txt'))
- {
- $lang_name = $file;
- break;
- }
- }
- closedir($dir);
- }
-
- // Update language name if changed
- if ($this->lang_name !== $lang_name)
- {
- $this->lang_name = $lang_name;
- }
-
- // Set data language in case we have a user where this is not set
- if (empty($this->data['user_lang']))
- {
- $this->data['user_lang'] = $this->lang_name;
- }
-
- // We include common language file here to not load it every time a custom language file is included
- $lang = &$this->lang;
-
- if ((include $this->lang_path . $this->lang_name . "/common." . PHP_EXT) === false)
- {
- die('Language file ' . $this->lang_path . $this->lang_name . "/common." . PHP_EXT . " couldn't be opened.");
- }
- }
-
- /**
- * Setup basic user-specific items (style, language, ...)
- *
- * @param string|array $lang_set Language set to setup.
- * Can be a string or an array of language files without a path and extension.
- * Format must match {@link add_lang() add_lang}.
- * @param int $style If not set to false this specifies the style id to use.
- * The page will then use the specified style id instead of the default one.
- * @access public
- */
- public function setup($lang_set = false, $style = false)
- {
- // Check if there is a valid session
- if (empty($this->data))
- {
- $this->session_begin();
-
- if (phpbb::registered('acl'))
- {
- phpbb::$acl->init($this->data);
- }
- }
-
- if ($this->data['user_id'] != ANONYMOUS)
- {
- $this->lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . "/common." . PHP_EXT)) ? $this->data['user_lang'] : basename(phpbb::$config['default_lang']);
- $this->date_format = $this->data['user_dateformat'];
- $this->timezone = $this->data['user_timezone'] * 3600;
- $this->dst = $this->data['user_dst'] * 3600;
- }
- else
- {
- $this->lang_name = basename(phpbb::$config['default_lang']);
- $this->date_format = phpbb::$config['default_dateformat'];
- $this->timezone = phpbb::$config['board_timezone'] * 3600;
- $this->dst = phpbb::$config['board_dst'] * 3600;
- }
-
- $this->set_language($this->lang_name);
-
- $this->add_lang($lang_set);
- unset($lang_set);
-
- if (phpbb_request::variable('style', false, false, phpbb_request::GET) && phpbb::$acl->acl_get('a_styles'))
- {
- $style = request_var('style', 0);
- $this->extra_url = array('style=' . $style);
- }
- else
- {
- // Set up style
- $style = ($style) ? $style : ((!phpbb::$config['override_user_style']) ? $this->data['user_style'] : phpbb::$config['default_style']);
- }
-
- $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name
- FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i
- WHERE s.style_id = $style
- AND t.template_id = s.template_id
- AND c.theme_id = s.theme_id
- AND i.imageset_id = s.imageset_id";
- $result = phpbb::$db->sql_query($sql, 3600);
- $this->theme = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
-
- // User has wrong style
- if (!$this->theme && $style == $this->data['user_style'])
- {
- $style = $this->data['user_style'] = phpbb::$config['default_style'];
-
- $sql = 'UPDATE ' . USERS_TABLE . "
- SET user_style = $style
- WHERE user_id = {$this->data['user_id']}";
- phpbb::$db->sql_query($sql);
-
- $sql = 'SELECT s.style_id, t.template_path, t.template_id, t.bbcode_bitfield, c.theme_path, c.theme_name, c.theme_storedb, c.theme_id, i.imageset_path, i.imageset_id, i.imageset_name
- FROM ' . STYLES_TABLE . ' s, ' . STYLES_TEMPLATE_TABLE . ' t, ' . STYLES_THEME_TABLE . ' c, ' . STYLES_IMAGESET_TABLE . " i
- WHERE s.style_id = $style
- AND t.template_id = s.template_id
- AND c.theme_id = s.theme_id
- AND i.imageset_id = s.imageset_id";
- $result = phpbb::$db->sql_query($sql, 3600);
- $this->theme = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
- }
-
- if (!$this->theme)
- {
- trigger_error('Could not get style data', E_USER_ERROR);
- }
-
- // Now parse the cfg file and cache it,
- // we are only interested in the theme configuration for now
- $parsed_items = phpbb_cache::obtain_cfg_item($this->theme, 'theme');
-
- $check_for = array(
- 'parse_css_file' => (int) 0,
- 'pagination_sep' => (string) ', ',
- );
-
- foreach ($check_for as $key => $default_value)
- {
- $this->theme[$key] = (isset($parsed_items[$key])) ? $parsed_items[$key] : $default_value;
- settype($this->theme[$key], gettype($default_value));
-
- if (is_string($default_value))
- {
- $this->theme[$key] = htmlspecialchars($this->theme[$key]);
- }
- }
-
- // If the style author specified the theme needs to be cached
- // (because of the used paths and variables) than make sure it is the case.
- // For example, if the theme uses language-specific images it needs to be stored in db.
- if (!$this->theme['theme_storedb'] && $this->theme['parse_css_file'])
- {
- $this->theme['theme_storedb'] = 1;
-
- $stylesheet = file_get_contents(PHPBB_ROOT_PATH . "styles/{$this->theme['theme_path']}/theme/stylesheet.css");
- // Match CSS imports
- $matches = array();
- preg_match_all('/@import url\(["\'](.*)["\']\);/i', $stylesheet, $matches);
-
- if (sizeof($matches))
- {
- $content = '';
- foreach ($matches[0] as $idx => $match)
- {
- if ($content = @file_get_contents(PHPBB_ROOT_PATH . "styles/{$this->theme['theme_path']}/theme/" . $matches[1][$idx]))
- {
- $content = trim($content);
- }
- else
- {
- $content = '';
- }
- $stylesheet = str_replace($match, $content, $stylesheet);
- }
- unset($content);
- }
-
- $stylesheet = str_replace('./', 'styles/' . $this->theme['theme_path'] . '/theme/', $stylesheet);
-
- $sql_ary = array(
- 'theme_data' => $stylesheet,
- 'theme_mtime' => time(),
- 'theme_storedb' => 1
- );
-
- phpbb::$db->sql_query('UPDATE ' . STYLES_THEME_TABLE . ' SET ' . phpbb::$db->sql_build_array('UPDATE', $sql_ary) . ' WHERE theme_id = ' . $this->theme['theme_id']);
- unset($sql_ary);
- }
-
- phpbb::$template->set_template();
-
- $this->img_lang = (file_exists(PHPBB_ROOT_PATH . 'styles/' . $this->theme['imageset_path'] . '/imageset/' . $this->lang_name)) ? $this->lang_name : phpbb::$config['default_lang'];
-
- $sql = 'SELECT image_name, image_filename, image_lang, image_height, image_width
- FROM ' . STYLES_IMAGESET_DATA_TABLE . '
- WHERE imageset_id = ' . $this->theme['imageset_id'] . "
- AND image_filename <> ''
- AND image_lang IN ('" . phpbb::$db->sql_escape($this->img_lang) . "', '')";
- $result = phpbb::$db->sql_query($sql, 3600);
-
- $localised_images = false;
- while ($row = phpbb::$db->sql_fetchrow($result))
- {
- if ($row['image_lang'])
- {
- $localised_images = true;
- }
-
- $row['image_filename'] = rawurlencode($row['image_filename']);
- $this->img_array[$row['image_name']] = $row;
- }
- phpbb::$db->sql_freeresult($result);
-
- // there were no localised images, try to refresh the localised imageset for the user's language
- if (!$localised_images)
- {
- // Attention: this code ignores the image definition list from acp_styles and just takes everything
- // that the config file contains
- $sql_ary = array();
-
- phpbb::$db->sql_transaction('begin');
-
- $sql = 'DELETE FROM ' . STYLES_IMAGESET_DATA_TABLE . '
- WHERE imageset_id = ' . $this->theme['imageset_id'] . '
- AND image_lang = \'' . phpbb::$db->sql_escape($this->img_lang) . '\'';
- $result = phpbb::$db->sql_query($sql);
-
- if (@file_exists(PHPBB_ROOT_PATH . "styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg"))
- {
- $cfg_data_imageset_data = parse_cfg_file(PHPBB_ROOT_PATH . "styles/{$this->theme['imageset_path']}/imageset/{$this->img_lang}/imageset.cfg");
- foreach ($cfg_data_imageset_data as $image_name => $value)
- {
- if (strpos($value, '*') !== false)
- {
- if (substr($value, -1, 1) === '*')
- {
- list($image_filename, $image_height) = explode('*', $value);
- $image_width = 0;
- }
- else
- {
- list($image_filename, $image_height, $image_width) = explode('*', $value);
- }
- }
- else
- {
- $image_filename = $value;
- $image_height = $image_width = 0;
- }
-
- if (strpos($image_name, 'img_') === 0 && $image_filename)
- {
- $image_name = substr($image_name, 4);
- $sql_ary[] = array(
- 'image_name' => (string) $image_name,
- 'image_filename' => (string) $image_filename,
- 'image_height' => (int) $image_height,
- 'image_width' => (int) $image_width,
- 'imageset_id' => (int) $this->theme['imageset_id'],
- 'image_lang' => (string) $this->img_lang,
- );
- }
- }
- }
-
- if (sizeof($sql_ary))
- {
- phpbb::$db->sql_multi_insert(STYLES_IMAGESET_DATA_TABLE, $sql_ary);
- phpbb::$db->sql_transaction('commit');
- phpbb::$acm->destroy_sql(STYLES_IMAGESET_DATA_TABLE);
-
- add_log('admin', 'LOG_IMAGESET_LANG_REFRESHED', $this->theme['imageset_name'], $this->img_lang);
- }
- else
- {
- phpbb::$db->sql_transaction('commit');
- add_log('admin', 'LOG_IMAGESET_LANG_MISSING', $this->theme['imageset_name'], $this->img_lang);
- }
- }
-
- // Call phpbb_user_session_handler() in case external application want to "bend" some variables or replace classes...
- // After calling it we continue script execution...
- // phpbb_user_session_handler();
-
- // If this function got called from the error handler we are finished here.
- if (defined('IN_ERROR_HANDLER'))
- {
- return;
- }
-
- // Disable board if the install/ directory is still present
- // For the brave development army we do not care about this, else we need to comment out this everytime we develop locally
- if (!phpbb::$base_config['debug_extra'] && !defined('ADMIN_START') && !defined('IN_INSTALL') && !defined('IN_LOGIN') && file_exists(PHPBB_ROOT_PATH . 'install'))
- {
- // Adjust the message slightly according to the permissions
- if (phpbb::$acl->acl_gets('a_', 'm_') || phpbb::$acl->acl_getf_global('m_'))
- {
- $message = 'REMOVE_INSTALL';
- }
- else
- {
- $message = (!empty(phpbb::$config['board_disable_msg'])) ? phpbb::$config['board_disable_msg'] : 'BOARD_DISABLE';
- }
- trigger_error($message);
- }
-
- // Is board disabled and user not an admin or moderator?
- if (phpbb::$config['board_disable'] && !defined('IN_LOGIN') && !phpbb::$acl->acl_gets('a_', 'm_') && !phpbb::$acl->acl_getf_global('m_'))
- {
- header('HTTP/1.1 503 Service Unavailable');
-
- $message = (!empty(phpbb::$config['board_disable_msg'])) ? phpbb::$config['board_disable_msg'] : 'BOARD_DISABLE';
- trigger_error($message);
- }
-
- // Is load exceeded?
- if (phpbb::$config['limit_load'] && $this->load !== false)
- {
- if ($this->load > floatval(phpbb::$config['limit_load']) && !defined('IN_LOGIN'))
- {
- // Set board disabled to true to let the admins/mods get the proper notification
- phpbb::$config['board_disable'] = '1';
-
- if (!phpbb::$acl->acl_gets('a_', 'm_') && !phpbb::$acl->acl_getf_global('m_'))
- {
- header('HTTP/1.1 503 Service Unavailable');
- trigger_error('BOARD_UNAVAILABLE');
- }
- }
- }
-
- if (isset($this->data['session_viewonline']))
- {
- // Make sure the user is able to hide his session
- if (!$this->data['session_viewonline'])
- {
- // Reset online status if not allowed to hide the session...
- if (!phpbb::$acl->acl_get('u_hideonline'))
- {
- $sql = 'UPDATE ' . SESSIONS_TABLE . '
- SET session_viewonline = 1
- WHERE session_user_id = ' . $this->data['user_id'];
- phpbb::$db->sql_query($sql);
- $this->data['session_viewonline'] = 1;
- }
- }
- else if (!$this->data['user_allow_viewonline'])
- {
- // the user wants to hide and is allowed to -> cloaking device on.
- if (phpbb::$acl->acl_get('u_hideonline'))
- {
- $sql = 'UPDATE ' . SESSIONS_TABLE . '
- SET session_viewonline = 0
- WHERE session_user_id = ' . $this->data['user_id'];
- phpbb::$db->sql_query($sql);
- $this->data['session_viewonline'] = 0;
- }
- }
- }
-
-
- // Does the user need to change their password? If so, redirect to the
- // ucp profile reg_details page ... of course do not redirect if we're already in the ucp
- if (!defined('IN_ADMIN') && !defined('ADMIN_START') && phpbb::$config['chg_passforce'] && $this->is_registered && phpbb::$acl->acl_get('u_chgpasswd') && $this->data['user_passchg'] < time() - (phpbb::$config['chg_passforce'] * 86400))
- {
- if (strpos($this->page['query_string'], 'mode=reg_details') === false && $this->page['page_name'] != 'ucp.' . PHP_EXT)
- {
- redirect(append_sid('ucp', 'i=profile&amp;mode=reg_details'));
- }
- }
-
- return;
- }
-
- /**
- * More advanced language substitution
- *
- * Function to mimic sprintf() with the possibility of using phpBB's language system to substitute nullar/singular/plural forms.
- * Params are the language key and the parameters to be substituted.
- * This function/functionality was inspired by SHS` and Ashe.
- *
- * For example:
- * <code>
- * phpbb::$user->lang('NUM_POSTS_IN_QUEUE', 1);
- * </code>
- *
- * @param string $key The language key to use
- * @param mixed $parameter,... An unlimited number of parameter to apply.
- *
- * @return string Substituted language string
- * @see sprintf()
- * @access public
- */
- public function lang()
- {
- $args = func_get_args();
- $key = $args[0];
-
- if (is_array($key))
- {
- $lang = &$this->lang[array_shift($key)];
-
- foreach ($key as $_key)
- {
- $lang = &$lang[$_key];
- }
- }
- else
- {
- $lang = &$this->lang[$key];
- }
-
- // Return if language string does not exist
- if (!isset($lang) || (!is_string($lang) && !is_array($lang)))
- {
- return $key;
- }
-
- // If the language entry is a string, we simply mimic sprintf() behaviour
- if (is_string($lang))
- {
- if (sizeof($args) == 1)
- {
- return $lang;
- }
-
- // Replace key with language entry and simply pass along...
- $args[0] = $lang;
- return call_user_func_array('sprintf', $args);
- }
-
- // It is an array... now handle different nullar/singular/plural forms
- $key_found = false;
-
- // We now get the first number passed and will select the key based upon this number
- for ($i = 1, $num_args = sizeof($args); $i < $num_args; $i++)
- {
- if (is_int($args[$i]))
- {
- $numbers = array_keys($lang);
-
- foreach ($numbers as $num)
- {
- if ($num > $args[$i])
- {
- break;
- }
-
- $key_found = $num;
- }
- }
- }
-
- // Ok, let's check if the key was found, else use the last entry (because it is mostly the plural form)
- if ($key_found === false)
- {
- $numbers = array_keys($lang);
- $key_found = end($numbers);
- }
-
- // Use the language string we determined and pass it to sprintf()
- $args[0] = $lang[$key_found];
- return call_user_func_array('sprintf', $args);
- }
-
- /**
- * Add Language Items - use_db and use_help are assigned where needed (only use them to force inclusion)
- *
- * Examples:
- * <code>
- * $lang_set = array('posting', 'help' => 'faq');
- * $lang_set = array('posting', 'viewtopic', 'help' => array('bbcode', 'faq'))
- * $lang_set = array(array('posting', 'viewtopic'), 'help' => array('bbcode', 'faq'))
- * $lang_set = 'posting'
- * $lang_set = array('help' => 'faq', 'db' => array('help:faq', 'posting'))
- * </code>
- *
- * @param mixed $lang_set specifies the language entries to include
- * @param bool $use_db internal variable for recursion, do not use
- * @param bool $use_help internal variable for recursion, do not use
- * @access public
- */
- public function add_lang($lang_set, $use_db = false, $use_help = false)
- {
- if (is_array($lang_set))
- {
- foreach ($lang_set as $key => $lang_file)
- {
- // Please do not delete this line.
- // We have to force the type here, else [array] language inclusion will not work
- $key = (string) $key;
-
- if ($key == 'db')
- {
- $this->add_lang($lang_file, true, $use_help);
- }
- else if ($key == 'help')
- {
- $this->add_lang($lang_file, $use_db, true);
- }
- else if (!is_array($lang_file))
- {
- $this->set_lang($this->lang, $this->help, $lang_file, $use_db, $use_help);
- }
- else
- {
- $this->add_lang($lang_file, $use_db, $use_help);
- }
- }
- unset($lang_set);
- }
- else if ($lang_set)
- {
- $this->set_lang($this->lang, $this->help, $lang_set, $use_db, $use_help);
- }
- }
-
- /**
- * Set language entry (called by {@link add_lang() add_lang})
- *
- * @param array &$lang A reference to the language array phpbb::$user->lang
- * @param array &$help A reference to the language help array phpbb::$user->help
- * @param string $lang_file Language filename
- * @param bool $use_db True if the database is used for obtaining the information
- * @param bool $use_help True if we fetch help entries instead of language entries
- * @access private
- */
- private function set_lang(&$lang, &$help, $lang_file, $use_db = false, $use_help = false)
- {
- // Make sure the language name is set (if the user setup did not happen it is not set)
- if (!$this->lang_name)
- {
- $this->lang_name = basename(phpbb::$config['default_lang']);
- }
-
- // $lang == $this->lang
- // $help == $this->help
- // - add appropriate variables here, name them as they are used within the language file...
- if (!$use_db)
- {
- if ($use_help && strpos($lang_file, '/') !== false)
- {
- $language_filename = $this->lang_path . $this->lang_name . '/' . substr($lang_file, 0, stripos($lang_file, '/') + 1) . 'help_' . substr($lang_file, stripos($lang_file, '/') + 1) . '.' . PHP_EXT;
- }
- else
- {
- $language_filename = $this->lang_path . $this->lang_name . '/' . (($use_help) ? 'help_' : '') . $lang_file . '.' . PHP_EXT;
- }
-
- if (!file_exists($language_filename))
- {
- if ($this->lang_name == 'en')
- {
- // The user's selected language is missing the file, the board default's language is missing the file, and the file doesn't exist in /en.
- $language_filename = str_replace($this->lang_path . 'en', $this->lang_path . $this->data['user_lang'], $language_filename);
- trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
- }
- else if ($this->lang_name == basename(phpbb::$config['default_lang']))
- {
- // Fall back to the English Language
- $this->lang_name = 'en';
- $this->set_lang($lang, $help, $lang_file, $use_db, $use_help);
- }
- else if (file_exists($this->lang_path . $this->data['user_lang'] . '/common.' . PHP_EXT))
- {
- // Fall back to the board default language
- $this->lang_name = basename(phpbb::$config['default_lang']);
- $this->set_lang($lang, $help, $lang_file, $use_db, $use_help);
- }
-
- // Reset the lang name
- $this->lang_name = (file_exists($this->lang_path . $this->data['user_lang'] . '/common.' . PHP_EXT)) ? $this->data['user_lang'] : basename(phpbb::$config['default_lang']);
- return;
- }
-
- if ((include $language_filename) === false)
- {
- trigger_error('Language file ' . $language_filename . ' couldn\'t be opened.', E_USER_ERROR);
- }
- }
- else if ($use_db)
- {
- // Get Database Language Strings
- // Put them into $lang if nothing is prefixed, put them into $help if help: is prefixed
- // For example: help:faq, posting
- }
- }
-
- /**
- * Format user date
- *
- * @param int $gmepoch Unix timestamp to format
- * @param string $format Date format in date() notation.
- * The character | used to indicate relative dates, for example |d m Y|, h:i is translated to Today, h:i.
- * @param bool $forcedate Force non-relative date format.
- *
- * @staticvar int $midnight Midnight time offset
- * @staticvar array $date_cache Array to cache commonly needed structures within this function
- *
- * @return mixed translated date
- * @access public
- */
- public function format_date($gmepoch, $format = false, $forcedate = false)
- {
- static $midnight;
- static $date_cache;
-
- $format = (!$format) ? $this->date_format : $format;
- $now = time();
- $delta = $now - $gmepoch;
-
- if (!isset($date_cache[$format]))
- {
- // Is the user requesting a friendly date format (i.e. 'Today 12:42')?
- $date_cache[$format] = array(
- 'is_short' => strpos($format, '|'),
- 'format_short' => substr($format, 0, strpos($format, '|')) . '||' . substr(strrchr($format, '|'), 1),
- 'format_long' => str_replace('|', '', $format),
- 'lang' => $this->lang['datetime'],
- );
-
- // Short representation of month in format? Some languages use different terms for the long and short format of May
- if ((strpos($format, '\M') === false && strpos($format, 'M') !== false) || (strpos($format, '\r') === false && strpos($format, 'r') !== false))
- {
- $date_cache[$format]['lang']['May'] = $this->lang['datetime']['May_short'];
- }
- }
-
- // Zone offset
- $zone_offset = $this->timezone + $this->dst;
-
- // Show date <= 1 hour ago as 'xx min ago'
- // A small tolerence is given for times in the future and times in the future but in the same minute are displayed as '< than a minute ago'
- if ($delta <= 3600 && ($delta >= -5 || (($now / 60) % 60) == (($gmepoch / 60) % 60)) && $date_cache[$format]['is_short'] !== false && !$forcedate && isset($this->lang['datetime']['AGO']))
- {
- return $this->lang(array('datetime', 'AGO'), max(0, (int) floor($delta / 60)));
- }
-
- if (!$midnight)
- {
- list($d, $m, $y) = explode(' ', gmdate('j n Y', time() + $zone_offset));
- $midnight = gmmktime(0, 0, 0, $m, $d, $y) - $zone_offset;
- }
-
- if ($date_cache[$format]['is_short'] !== false && !$forcedate && !($gmepoch < $midnight - 86400 || $gmepoch > $midnight + 172800))
- {
- $day = false;
-
- if ($gmepoch > $midnight + 86400)
- {
- $day = 'TOMORROW';
- }
- else if ($gmepoch > $midnight)
- {
- $day = 'TODAY';
- }
- else if ($gmepoch > $midnight - 86400)
- {
- $day = 'YESTERDAY';
- }
-
- if ($day !== false)
- {
- return str_replace('||', $this->lang['datetime'][$day], strtr(@gmdate($date_cache[$format]['format_short'], $gmepoch + $zone_offset), $date_cache[$format]['lang']));
- }
- }
-
- return strtr(@gmdate($date_cache[$format]['format_long'], $gmepoch + $zone_offset), $date_cache[$format]['lang']);
- }
-
- /**
- * Get language id currently used by the user
- *
- * @return int language id
- * @access public
- */
- public function get_iso_lang_id()
- {
- if (!empty($this->lang_id))
- {
- return $this->lang_id;
- }
-
- if (!$this->lang_name)
- {
- $this->lang_name = phpbb::$config['default_lang'];
- }
-
- $sql = 'SELECT lang_id
- FROM ' . LANG_TABLE . "
- WHERE lang_iso = '" . phpbb::$db->sql_escape($this->lang_name) . "'";
- $result = phpbb::$db->sql_query($sql);
- $this->lang_id = (int) phpbb::$db->sql_fetchfield('lang_id');
- phpbb::$db->sql_freeresult($result);
-
- return $this->lang_id;
- }
-
- /**
- * Get users profile fields
- *
- * @param int $user_id User id. If not specified the current users profile fields are grabbed.
- *
- * @return array Profile fields. If the current user then they are also stored as property $profile_fields.
- * @access public
- */
- public function get_profile_fields($user_id = false)
- {
- $user_id = ($user_id === false) ? $this->data['user_id'] : $user_id;
-
- if (isset($this->profile_fields) && $user_id === $this->data['user_id'])
- {
- return $this->profile_fields;
- }
-
- $sql = 'SELECT *
- FROM ' . PROFILE_FIELDS_DATA_TABLE . "
- WHERE user_id = $user_id";
- $result = phpbb::$db->sql_query_limit($sql, 1);
- $row = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
-
- if ($user_id === $this->data['user_id'])
- {
- $this->profile_fields = (!$row) ? array() : $row;
- }
-
- return $row;
- }
-
- /**
- * Specify/Get image from style imageset
- *
- * @param string $img The imageset image key name
- * @param string $alt An optional alternative image attribute.
- * If a corresponding language key exist it will be used: phpbb::$user->lang[$alt]
- * @param string $type The preferred type to return. Allowed types are: full_tag, src, width, height
- * @param int $width Set image width
- *
- * @return mixed returns the preferred type from $type
- * @access public
- */
- public function img($img, $alt = '', $type = 'full_tag', $width = false)
- {
- static $imgs;
-
- $img_data = &$imgs[$img];
-
- if (empty($img_data))
- {
- if (!isset($this->img_array[$img]))
- {
- // Do not fill the image to let designers decide what to do if the image is empty
- $img_data = '';
- return $img_data;
- }
-
- $img_data['src'] = PHPBB_ROOT_PATH . 'styles/' . rawurlencode($this->theme['imageset_path']) . '/imageset/' . ($this->img_array[$img]['image_lang'] ? $this->img_array[$img]['image_lang'] .'/' : '') . $this->img_array[$img]['image_filename'];
- $img_data['width'] = $this->img_array[$img]['image_width'];
- $img_data['height'] = $this->img_array[$img]['image_height'];
- }
-
- $alt = (!empty($this->lang[$alt])) ? $this->lang[$alt] : $alt;
-
- switch ($type)
- {
- case 'src':
- return $img_data['src'];
- break;
-
- case 'width':
- return ($width === false) ? $img_data['width'] : $width;
- break;
-
- case 'height':
- return $img_data['height'];
- break;
-
- default:
- $use_width = ($width === false) ? $img_data['width'] : $width;
-
- return '<img src="' . $img_data['src'] . '"' . (($use_width) ? ' width="' . $use_width . '"' : '') . (($img_data['height']) ? ' height="' . $img_data['height'] . '"' : '') . ' alt="' . $alt . '" title="' . $alt . '" />';
- break;
- }
- }
-
- /**
- * Get option bit field from user options.
- *
- * @param string $key The option key from {@link $keyoptions keyoptions}
- * @param int $data Optional user options bitfield.
- * If not specified then {@link $data $data['user_options']} is used.
- *
- * @return bool Corresponding option value returned. Is the option enabled or disabled.
- * @access public
- */
- public function optionget($key, $data = false)
- {
- if ($data !== false)
- {
- return $data & 1 << $this->keyoptions[$key];
- }
-
- if (!isset($this->keyvalues[$key]))
- {
- $this->keyvalues[$key] = $this->data['user_options'] & 1 << $this->keyoptions[$key];
- }
-
- return $this->keyvalues[$key];
- }
-
- /**
- * Set option bit field for user options.
- *
- * @param string $key The option key from {@link $keyoptions keyoptions}
- * @param bool $value True to enable the option, false to disable it
- * @param int $data Optional user options bitfield.
- * If not specified then {@link $data $data['user_options']} is used.
- *
- * @return bool The new user options bitfield is returned if $data is specified.
- * Else: false is returned if user options not changed, true if changed.
- * @access public
- */
- public function optionset($key, $value, $data = false)
- {
- $var = ($data) ? $data : $this->data['user_options'];
-
- if ($value && !($var & 1 << $this->keyoptions[$key]))
- {
- $var += 1 << $this->keyoptions[$key];
- }
- else if (!$value && ($var & 1 << $this->keyoptions[$key]))
- {
- $var -= 1 << $this->keyoptions[$key];
- }
- else
- {
- return ($data) ? $var : false;
- }
-
- if (!$data)
- {
- $this->data['user_options'] = $this->keyvalues[$key] = $var;
- return true;
- }
-
- return $var;
- }
-
- /**
- * User login. Log the user in.
- *
- * @param string $username The specified user name
- * @param string $password The specified password
- * @param bool $autologin Enable/disable persistent login
- * @param bool $viewonline If false then the user will be logged in as hidden
- * @param bool $admin If true the user requests an admin login
- *
- * @return array Login result array. This array returns results to the login script to show errors, notices, confirmations.
- * @access public
- */
- public function login($username, $password, $autologin = false, $viewonline = 1, $admin = 0)
- {
- if ($this->auth === false || !method_exists($this->auth, 'login'))
- {
- trigger_error('Authentication method not found', E_USER_ERROR);
- }
-
- $login = $this->auth->login($username, $password);
-
- // If the auth module wants us to create an empty profile do so and then treat the status as LOGIN_SUCCESS
- if ($login['status'] == LOGIN_SUCCESS_CREATE_PROFILE)
- {
- phpbb::$api->user->add($login['user_row'], (isset($login['cp_data'])) ? $login['cp_data'] : false);
-
- $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type
- FROM ' . USERS_TABLE . "
- WHERE username_clean = '" . phpbb::$db->sql_escape(utf8_clean_string($username)) . "'";
- $result = phpbb::$db->sql_query($sql);
- $row = phpbb::$db->sql_fetchrow($result);
- phpbb::$db->sql_freeresult($result);
-
- if (!$row)
- {
- return array(
- 'status' => LOGIN_ERROR_EXTERNAL_AUTH,
- 'error_msg' => 'AUTH_NO_PROFILE_CREATED',
- 'user_row' => array('user_id' => ANONYMOUS),
- );
- }
-
- $login = array(
- 'status' => LOGIN_SUCCESS,
- 'error_msg' => false,
- 'user_row' => $row,
- );
- }
-
- // If login succeeded, we will log the user in... else we pass the login array through...
- if ($login['status'] == LOGIN_SUCCESS)
- {
- // We create a new session. The session creation makes sure the old session is killed if there was one.
- $result = $this->session_create($login['user_row']['user_id'], $admin, $autologin, $viewonline);
-
- // Successful session creation
- if ($result === true)
- {
- return array(
- 'status' => LOGIN_SUCCESS,
- 'error_msg' => false,
- 'user_row' => $login['user_row'],
- );
- }
-
- return array(
- 'status' => LOGIN_BREAK,
- 'error_msg' => $result,
- 'user_row' => $login['user_row'],
- );
- }
-
- return $login;
- }
-}
-
-?> \ No newline at end of file