diff options
Diffstat (limited to 'phpBB/includes/classes')
-rw-r--r-- | phpBB/includes/classes/acl.php | 946 | ||||
-rw-r--r-- | phpBB/includes/classes/cache.php | 425 | ||||
-rw-r--r-- | phpBB/includes/classes/session.php | 1289 | ||||
-rw-r--r-- | phpBB/includes/classes/template.php | 531 | ||||
-rw-r--r-- | phpBB/includes/classes/template_compile.php | 904 | ||||
-rw-r--r-- | phpBB/includes/classes/user.php | 1124 |
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&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 |