|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @package phpBB3
|
|
|
4c79b5 |
* @version $Id: functions.php 9153 2008-12-02 17:02:56Z acydburn $
|
|
|
4c79b5 |
* @copyright (c) 2005 phpBB Group
|
|
|
4c79b5 |
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* @ignore
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
if (!defined('IN_PHPBB'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
exit;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Common global functions
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* set_var
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Set variable, used by {@link request_var the request_var function}
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @access private
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function set_var(&$result, $var, $type, $multibyte = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
settype($var, $type);
|
|
|
4c79b5 |
$result = $var;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($type == 'string')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$result = trim(htmlspecialchars(str_replace(array("\r\n", "\r", "\0"), array("\n", "\n", ''), $result), ENT_COMPAT, 'UTF-8'));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!empty($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Make sure multibyte characters are wellformed
|
|
|
4c79b5 |
if ($multibyte)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (!preg_match('/^./u', $result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$result = '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// no multibyte, allow only ASCII (0-127)
|
|
|
4c79b5 |
$result = preg_replace('/[\x80-\xFF]/', '?', $result);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$result = (STRIP) ? stripslashes($result) : $result;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* request_var
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Used to get passed variable
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function request_var($var_name, $default, $multibyte = false, $cookie = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (!$cookie && isset($_COOKIE[$var_name]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (!isset($_GET[$var_name]) && !isset($_POST[$var_name]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return (is_array($default)) ? array() : $default;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$_REQUEST[$var_name] = isset($_POST[$var_name]) ? $_POST[$var_name] : $_GET[$var_name];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!isset($_REQUEST[$var_name]) || (is_array($_REQUEST[$var_name]) && !is_array($default)) || (is_array($default) && !is_array($_REQUEST[$var_name])))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return (is_array($default)) ? array() : $default;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$var = $_REQUEST[$var_name];
|
|
|
4c79b5 |
if (!is_array($default))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$type = gettype($default);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
list($key_type, $type) = each($default);
|
|
|
4c79b5 |
$type = gettype($type);
|
|
|
4c79b5 |
$key_type = gettype($key_type);
|
|
|
4c79b5 |
if ($type == 'array')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
reset($default);
|
|
|
4c79b5 |
$default = current($default);
|
|
|
4c79b5 |
list($sub_key_type, $sub_type) = each($default);
|
|
|
4c79b5 |
$sub_type = gettype($sub_type);
|
|
|
4c79b5 |
$sub_type = ($sub_type == 'array') ? 'NULL' : $sub_type;
|
|
|
4c79b5 |
$sub_key_type = gettype($sub_key_type);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (is_array($var))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$_var = $var;
|
|
|
4c79b5 |
$var = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($_var as $k => $v)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
set_var($k, $k, $key_type);
|
|
|
4c79b5 |
if ($type == 'array' && is_array($v))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
foreach ($v as $_k => $_v)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (is_array($_v))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$_v = null;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
set_var($_k, $_k, $sub_key_type);
|
|
|
4c79b5 |
set_var($var[$k][$_k], $_v, $sub_type, $multibyte);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($type == 'array' || is_array($v))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$v = null;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
set_var($var[$k], $v, $type, $multibyte);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
set_var($var, $var, $type, $multibyte);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $var;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Set config value. Creates missing config entry.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function set_config($config_name, $config_value, $is_dynamic = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $cache, $config;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql = 'UPDATE ' . CONFIG_TABLE . "
|
|
|
4c79b5 |
SET config_value = '" . $db->sql_escape($config_value) . "'
|
|
|
4c79b5 |
WHERE config_name = '" . $db->sql_escape($config_name) . "'";
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$db->sql_affectedrows() && !isset($config[$config_name]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'INSERT INTO ' . CONFIG_TABLE . ' ' . $db->sql_build_array('INSERT', array(
|
|
|
4c79b5 |
'config_name' => $config_name,
|
|
|
4c79b5 |
'config_value' => $config_value,
|
|
|
4c79b5 |
'is_dynamic' => ($is_dynamic) ? 1 : 0));
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$config[$config_name] = $config_value;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$is_dynamic)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$cache->destroy('config');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Generates an alphanumeric random string of given length
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function gen_rand_string($num_chars = 8)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$rand_str = unique_id();
|
|
|
4c79b5 |
$rand_str = str_replace('0', 'Z', strtoupper(base_convert($rand_str, 16, 35)));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return substr($rand_str, 0, $num_chars);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Return unique id
|
|
|
4c79b5 |
* @param string $extra additional entropy
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function unique_id($extra = 'c')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
static $dss_seeded = false;
|
|
|
4c79b5 |
global $config;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$val = $config['rand_seed'] . microtime();
|
|
|
4c79b5 |
$val = md5($val);
|
|
|
4c79b5 |
$config['rand_seed'] = md5($config['rand_seed'] . $val . $extra);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($dss_seeded !== true && ($config['rand_seed_last_update'] < time() - rand(1,10)))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
set_config('rand_seed', $config['rand_seed'], true);
|
|
|
4c79b5 |
set_config('rand_seed_last_update', time(), true);
|
|
|
4c79b5 |
$dss_seeded = true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return substr($val, 4, 16);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Return formatted string for filesizes
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function get_formatted_filesize($bytes, $add_size_lang = true)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($bytes >= pow(2, 20))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return ($add_size_lang) ? round($bytes / 1024 / 1024, 2) . ' ' . $user->lang['MIB'] : round($bytes / 1024 / 1024, 2);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($bytes >= pow(2, 10))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return ($add_size_lang) ? round($bytes / 1024, 2) . ' ' . $user->lang['KIB'] : round($bytes / 1024, 2);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return ($add_size_lang) ? ($bytes) . ' ' . $user->lang['BYTES'] : ($bytes);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Determine whether we are approaching the maximum execution time. Should be called once
|
|
|
4c79b5 |
* at the beginning of the script in which it's used.
|
|
|
4c79b5 |
* @return bool Either true if the maximum execution time is nearly reached, or false
|
|
|
4c79b5 |
* if some time is still left.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function still_on_time($extra_time = 15)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
static $max_execution_time, $start_time;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$time = explode(' ', microtime());
|
|
|
4c79b5 |
$current_time = $time[0] + $time[1];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (empty($max_execution_time))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$max_execution_time = (function_exists('ini_get')) ? (int) @ini_get('max_execution_time') : (int) @get_cfg_var('max_execution_time');
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// If zero, then set to something higher to not let the user catch the ten seconds barrier.
|
|
|
4c79b5 |
if ($max_execution_time === 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$max_execution_time = 50 + $extra_time;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$max_execution_time = min(max(10, ($max_execution_time - $extra_time)), 50);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// For debugging purposes
|
|
|
4c79b5 |
// $max_execution_time = 10;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
global $starttime;
|
|
|
4c79b5 |
$start_time = (empty($starttime)) ? $current_time : $starttime;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return (ceil($current_time - $start_time) < $max_execution_time) ? true : false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @version Version 0.1 / slightly modified for phpBB 3.0.x (using $H$ as hash type identifier)
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Portable PHP password hashing framework.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Written by Solar Designer <solar at openwall.com> in 2004-2006 and placed in
|
|
|
4c79b5 |
* the public domain.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* There's absolutely no warranty.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* The homepage URL for this framework is:
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* http://www.openwall.com/phpass/
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Please be sure to update the Version line if you edit this file in any way.
|
|
|
4c79b5 |
* It is suggested that you leave the main version number intact, but indicate
|
|
|
4c79b5 |
* your project name (after the slash) and add your own revision information.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Please do not change the "private" password hashing method implemented in
|
|
|
4c79b5 |
* here, thereby making your hashes incompatible. However, if you must, please
|
|
|
4c79b5 |
* change the hash type identifier (the "$P$") to something different.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Obviously, since this code is in the public domain, the above are not
|
|
|
4c79b5 |
* requirements (there can be none), but merely suggestions.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Hash the password
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function phpbb_hash($password)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$random_state = unique_id();
|
|
|
4c79b5 |
$random = '';
|
|
|
4c79b5 |
$count = 6;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (($fh = @fopen('/dev/urandom', 'rb')))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$random = fread($fh, $count);
|
|
|
4c79b5 |
fclose($fh);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (strlen($random) < $count)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$random = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
for ($i = 0; $i < $count; $i += 16)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$random_state = md5(unique_id() . $random_state);
|
|
|
4c79b5 |
$random .= pack('H*', md5($random_state));
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$random = substr($random, 0, $count);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$hash = _hash_crypt_private($password, _hash_gensalt_private($random, $itoa64), $itoa64);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (strlen($hash) == 34)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $hash;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return md5($password);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Check for correct password
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param string $password The password in plain text
|
|
|
4c79b5 |
* @param string $hash The stored password hash
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @return bool Returns true if the password is correct, false if not.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function phpbb_check_hash($password, $hash)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
|
4c79b5 |
if (strlen($hash) == 34)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return (_hash_crypt_private($password, $hash, $itoa64) === $hash) ? true : false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return (md5($password) === $hash) ? true : false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Generate salt for hash generation
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function _hash_gensalt_private($input, &$itoa64, $iteration_count_log2 = 6)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($iteration_count_log2 < 4 || $iteration_count_log2 > 31)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$iteration_count_log2 = 8;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$output = '$H$';
|
|
|
4c79b5 |
$output .= $itoa64[min($iteration_count_log2 + ((PHP_VERSION >= 5) ? 5 : 3), 30)];
|
|
|
4c79b5 |
$output .= _hash_encode64($input, 6, $itoa64);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $output;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Encode hash
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function _hash_encode64($input, $count, &$itoa64)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$output = '';
|
|
|
4c79b5 |
$i = 0;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
do
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$value = ord($input[$i++]);
|
|
|
4c79b5 |
$output .= $itoa64[$value & 0x3f];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($i < $count)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$value |= ord($input[$i]) << 8;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$output .= $itoa64[($value >> 6) & 0x3f];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($i++ >= $count)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($i < $count)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$value |= ord($input[$i]) << 16;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$output .= $itoa64[($value >> 12) & 0x3f];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($i++ >= $count)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$output .= $itoa64[($value >> 18) & 0x3f];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
while ($i < $count);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $output;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* The crypt function/replacement
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function _hash_crypt_private($password, $setting, &$itoa64)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$output = '*';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Check for correct hash
|
|
|
4c79b5 |
if (substr($setting, 0, 3) != '$H$')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $output;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$count_log2 = strpos($itoa64, $setting[3]);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($count_log2 < 7 || $count_log2 > 30)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $output;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$count = 1 << $count_log2;
|
|
|
4c79b5 |
$salt = substr($setting, 4, 8);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (strlen($salt) != 8)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $output;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* We're kind of forced to use MD5 here since it's the only
|
|
|
4c79b5 |
* cryptographic primitive available in all versions of PHP
|
|
|
4c79b5 |
* currently in use. To implement our own low-level crypto
|
|
|
4c79b5 |
* in PHP would result in much worse performance and
|
|
|
4c79b5 |
* consequently in lower iteration counts and hashes that are
|
|
|
4c79b5 |
* quicker to crack (by non-PHP code).
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
if (PHP_VERSION >= 5)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$hash = md5($salt . $password, true);
|
|
|
4c79b5 |
do
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$hash = md5($hash . $password, true);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
while (--$count);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$hash = pack('H*', md5($salt . $password));
|
|
|
4c79b5 |
do
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$hash = pack('H*', md5($hash . $password));
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
while (--$count);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$output = substr($setting, 0, 12);
|
|
|
4c79b5 |
$output .= _hash_encode64($hash, 16, $itoa64);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $output;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Global function for chmodding directories and files for internal use
|
|
|
4c79b5 |
* This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions.
|
|
|
4c79b5 |
* The function determines owner and group from common.php file and sets the same to the provided file. Permissions are mapped to the group, user always has rw(x) permission.
|
|
|
4c79b5 |
* The function uses bit fields to build the permissions.
|
|
|
4c79b5 |
* The function sets the appropiate execute bit on directories.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Supported constants representing bit fields are:
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* CHMOD_ALL - all permissions (7)
|
|
|
4c79b5 |
* CHMOD_READ - read permission (4)
|
|
|
4c79b5 |
* CHMOD_WRITE - write permission (2)
|
|
|
4c79b5 |
* CHMOD_EXECUTE - execute permission (1)
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* NOTE: The function uses POSIX extension and fileowner()/filegroup() functions. If any of them is disabled, this function tries to build proper permissions, by calling is_readable() and is_writable() functions.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param $filename The file/directory to be chmodded
|
|
|
4c79b5 |
* @param $perms Permissions to set
|
|
|
4c79b5 |
* @return true on success, otherwise false
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @author faw, phpBB Group
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function phpbb_chmod($filename, $perms = CHMOD_READ)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Return if the file no longer exists.
|
|
|
4c79b5 |
if (!file_exists($filename))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!function_exists('fileowner') || !function_exists('filegroup'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$file_uid = $file_gid = false;
|
|
|
4c79b5 |
$common_php_owner = $common_php_group = false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $phpbb_root_path, $phpEx;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Determine owner/group of common.php file and the filename we want to change here
|
|
|
4c79b5 |
$common_php_owner = fileowner($phpbb_root_path . 'common.' . $phpEx);
|
|
|
4c79b5 |
$common_php_group = filegroup($phpbb_root_path . 'common.' . $phpEx);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$file_uid = fileowner($filename);
|
|
|
4c79b5 |
$file_gid = filegroup($filename);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Try to set the owner to the same common.php has
|
|
|
4c79b5 |
if ($common_php_owner !== $file_uid && $common_php_owner !== false && $file_uid !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Will most likely not work
|
|
|
4c79b5 |
if (@chown($filename, $common_php_owner));
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
clearstatcache();
|
|
|
4c79b5 |
$file_uid = fileowner($filename);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Try to set the group to the same common.php has
|
|
|
4c79b5 |
if ($common_php_group !== $file_gid && $common_php_group !== false && $file_gid !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (@chgrp($filename, $common_php_group));
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
clearstatcache();
|
|
|
4c79b5 |
$file_gid = filegroup($filename);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// And the owner and the groups PHP is running under.
|
|
|
4c79b5 |
$php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false;
|
|
|
4c79b5 |
$php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Who is PHP?
|
|
|
4c79b5 |
if ($file_uid === false || $file_gid === false || $php_uid === false || $php_gids === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$php = NULL;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($file_uid == $php_uid /* && $common_php_owner !== false && $common_php_owner === $file_uid*/)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$php = 'owner';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (in_array($file_gid, $php_gids))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$php = 'group';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$php = 'other';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Owner always has read/write permission
|
|
|
4c79b5 |
$owner = CHMOD_READ | CHMOD_WRITE;
|
|
|
4c79b5 |
if (is_dir($filename))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$owner |= CHMOD_EXECUTE;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Only add execute bit to the permission if the dir needs to be readable
|
|
|
4c79b5 |
if ($perms & CHMOD_READ)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$perms |= CHMOD_EXECUTE;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
switch ($php)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case null:
|
|
|
4c79b5 |
case 'owner':
|
|
|
4c79b5 |
/* ATTENTION: if php is owner or NULL we set it to group here. This is the most failsafe combination for the vast majority of server setups.
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
clearstatcache();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!is_null($php) || (is_readable($filename) && is_writable($filename)))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'group':
|
|
|
4c79b5 |
$result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
clearstatcache();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'other':
|
|
|
4c79b5 |
$result = @chmod($filename, ($owner << 6) + ($perms << 3) + ($perms << 0));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
clearstatcache();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!is_null($php) || ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || is_writable($filename))))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
default:
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $result;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Compatibility functions
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!function_exists('array_combine'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* A wrapper for the PHP5 function array_combine()
|
|
|
4c79b5 |
* @param array $keys contains keys for the resulting array
|
|
|
4c79b5 |
* @param array $values contains values for the resulting array
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @return Returns an array by using the values from the keys array as keys and the
|
|
|
4c79b5 |
* values from the values array as the corresponding values. Returns false if the
|
|
|
4c79b5 |
* number of elements for each array isn't equal or if the arrays are empty.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function array_combine($keys, $values)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$keys = array_values($keys);
|
|
|
4c79b5 |
$values = array_values($values);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$n = sizeof($keys);
|
|
|
4c79b5 |
$m = sizeof($values);
|
|
|
4c79b5 |
if (!$n || !$m || ($n != $m))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$combined = array();
|
|
|
4c79b5 |
for ($i = 0; $i < $n; $i++)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$combined[$keys[$i]] = $values[$i];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
return $combined;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!function_exists('str_split'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* A wrapper for the PHP5 function str_split()
|
|
|
4c79b5 |
* @param array $string contains the string to be converted
|
|
|
4c79b5 |
* @param array $split_length contains the length of each chunk
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @return Converts a string to an array. If the optional split_length parameter is specified,
|
|
|
4c79b5 |
* the returned array will be broken down into chunks with each being split_length in length,
|
|
|
4c79b5 |
* otherwise each chunk will be one character in length. FALSE is returned if split_length is
|
|
|
4c79b5 |
* less than 1. If the split_length length exceeds the length of string, the entire string is
|
|
|
4c79b5 |
* returned as the first (and only) array element.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function str_split($string, $split_length = 1)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($split_length < 1)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($split_length >= strlen($string))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return array($string);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
preg_match_all('#.{1,' . $split_length . '}#s', $string, $matches);
|
|
|
4c79b5 |
return $matches[0];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!function_exists('stripos'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* A wrapper for the PHP5 function stripos
|
|
|
4c79b5 |
* Find position of first occurrence of a case-insensitive string
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param string $haystack is the string to search in
|
|
|
4c79b5 |
* @param string $needle is the string to search for
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @return mixed Returns the numeric position of the first occurrence of needle in the haystack string. Unlike strpos(), stripos() is case-insensitive.
|
|
|
4c79b5 |
* Note that the needle may be a string of one or more characters.
|
|
|
4c79b5 |
* If needle is not found, stripos() will return boolean FALSE.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function stripos($haystack, $needle)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (preg_match('#' . preg_quote($needle, '#') . '#i', $haystack, $m))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return strpos($haystack, $m[0]);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Checks if a path ($path) is absolute or relative
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param string $path Path to check absoluteness of
|
|
|
4c79b5 |
* @return boolean
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function is_absolute($path)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return ($path[0] == '/' || (DIRECTORY_SEPARATOR == '\\' && preg_match('#^[a-z]:/#i', $path))) ? true : false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* @author Chris Smith <chris@project-minerva.org>
|
|
|
4c79b5 |
* @copyright 2006 Project Minerva Team
|
|
|
4c79b5 |
* @param string $path The path which we should attempt to resolve.
|
|
|
4c79b5 |
* @return mixed
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function phpbb_own_realpath($path)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Now to perform funky shizzle
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Switch to use UNIX slashes
|
|
|
4c79b5 |
$path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
|
|
|
4c79b5 |
$path_prefix = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Determine what sort of path we have
|
|
|
4c79b5 |
if (is_absolute($path))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$absolute = true;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($path[0] == '/')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Absolute path, *NIX style
|
|
|
4c79b5 |
$path_prefix = '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Absolute path, Windows style
|
|
|
4c79b5 |
// Remove the drive letter and colon
|
|
|
4c79b5 |
$path_prefix = $path[0] . ':';
|
|
|
4c79b5 |
$path = substr($path, 2);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Relative Path
|
|
|
4c79b5 |
// Prepend the current working directory
|
|
|
4c79b5 |
if (function_exists('getcwd'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// This is the best method, hopefully it is enabled!
|
|
|
4c79b5 |
$path = str_replace(DIRECTORY_SEPARATOR, '/', getcwd()) . '/' . $path;
|
|
|
4c79b5 |
$absolute = true;
|
|
|
4c79b5 |
if (preg_match('#^[a-z]:#i', $path))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$path_prefix = $path[0] . ':';
|
|
|
4c79b5 |
$path = substr($path, 2);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$path_prefix = '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (isset($_SERVER['SCRIPT_FILENAME']) && !empty($_SERVER['SCRIPT_FILENAME']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Warning: If chdir() has been used this will lie!
|
|
|
4c79b5 |
// Warning: This has some problems sometime (CLI can create them easily)
|
|
|
4c79b5 |
$path = str_replace(DIRECTORY_SEPARATOR, '/', dirname($_SERVER['SCRIPT_FILENAME'])) . '/' . $path;
|
|
|
4c79b5 |
$absolute = true;
|
|
|
4c79b5 |
$path_prefix = '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// We have no way of getting the absolute path, just run on using relative ones.
|
|
|
4c79b5 |
$absolute = false;
|
|
|
4c79b5 |
$path_prefix = '.';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Remove any repeated slashes
|
|
|
4c79b5 |
$path = preg_replace('#/{2,}#', '/', $path);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Remove the slashes from the start and end of the path
|
|
|
4c79b5 |
$path = trim($path, '/');
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Break the string into little bits for us to nibble on
|
|
|
4c79b5 |
$bits = explode('/', $path);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Remove any . in the path, renumber array for the loop below
|
|
|
4c79b5 |
$bits = array_values(array_diff($bits, array('.')));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Lets get looping, run over and resolve any .. (up directory)
|
|
|
4c79b5 |
for ($i = 0, $max = sizeof($bits); $i < $max; $i++)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// @todo Optimise
|
|
|
4c79b5 |
if ($bits[$i] == '..' )
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (isset($bits[$i - 1]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($bits[$i - 1] != '..')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// We found a .. and we are able to traverse upwards, lets do it!
|
|
|
4c79b5 |
unset($bits[$i]);
|
|
|
4c79b5 |
unset($bits[$i - 1]);
|
|
|
4c79b5 |
$i -= 2;
|
|
|
4c79b5 |
$max -= 2;
|
|
|
4c79b5 |
$bits = array_values($bits);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($absolute) // ie. !isset($bits[$i - 1]) && $absolute
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// We have an absolute path trying to descend above the root of the filesystem
|
|
|
4c79b5 |
// ... Error!
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Prepend the path prefix
|
|
|
4c79b5 |
array_unshift($bits, $path_prefix);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$resolved = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$max = sizeof($bits) - 1;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Check if we are able to resolve symlinks, Windows cannot.
|
|
|
4c79b5 |
$symlink_resolve = (function_exists('readlink')) ? true : false;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($bits as $i => $bit)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (@is_dir("$resolved/$bit") || ($i == $max && @is_file("$resolved/$bit")))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Path Exists
|
|
|
4c79b5 |
if ($symlink_resolve && is_link("$resolved/$bit") && ($link = readlink("$resolved/$bit")))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Resolved a symlink.
|
|
|
4c79b5 |
$resolved = $link . (($i == $max) ? '' : '/');
|
|
|
4c79b5 |
continue;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Something doesn't exist here!
|
|
|
4c79b5 |
// This is correct realpath() behaviour but sadly open_basedir and safe_mode make this problematic
|
|
|
4c79b5 |
// return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$resolved .= $bit . (($i == $max) ? '' : '/');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// @todo If the file exists fine and open_basedir only has one path we should be able to prepend it
|
|
|
4c79b5 |
// because we must be inside that basedir, the question is where...
|
|
|
4c79b5 |
// @internal The slash in is_dir() gets around an open_basedir restriction
|
|
|
4c79b5 |
if (!@file_exists($resolved) || (!is_dir($resolved . '/') && !is_file($resolved)))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Put the slashes back to the native operating systems slashes
|
|
|
4c79b5 |
$resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Check for DIRECTORY_SEPARATOR at the end (and remove it!)
|
|
|
4c79b5 |
if (substr($resolved, -1) == DIRECTORY_SEPARATOR)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return substr($resolved, 0, -1);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $resolved; // We got here, in the end!
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!function_exists('realpath'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* A wrapper for realpath
|
|
|
4c79b5 |
* @ignore
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function phpbb_realpath($path)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return phpbb_own_realpath($path);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* A wrapper for realpath
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function phpbb_realpath($path)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$realpath = realpath($path);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Strangely there are provider not disabling realpath but returning strange values. :o
|
|
|
4c79b5 |
// We at least try to cope with them.
|
|
|
4c79b5 |
if ($realpath === $path || $realpath === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return phpbb_own_realpath($path);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Check for DIRECTORY_SEPARATOR at the end (and remove it!)
|
|
|
4c79b5 |
if (substr($realpath, -1) == DIRECTORY_SEPARATOR)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$realpath = substr($realpath, 0, -1);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $realpath;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!function_exists('htmlspecialchars_decode'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* A wrapper for htmlspecialchars_decode
|
|
|
4c79b5 |
* @ignore
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function htmlspecialchars_decode($string, $quote_style = ENT_COMPAT)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return strtr($string, array_flip(get_html_translation_table(HTML_SPECIALCHARS, $quote_style)));
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// functions used for building option fields
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Pick a language, any language ...
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function language_select($default = '')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql = 'SELECT lang_iso, lang_local_name
|
|
|
4c79b5 |
FROM ' . LANG_TABLE . '
|
|
|
4c79b5 |
ORDER BY lang_english_name';
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$lang_options = '';
|
|
|
4c79b5 |
while ($row = $db->sql_fetchrow($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$selected = ($row['lang_iso'] == $default) ? ' selected="selected"' : '';
|
|
|
4c79b5 |
$lang_options .= '<option value="' . $row['lang_iso'] . '"' . $selected . '>' . $row['lang_local_name'] . '</option>';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $lang_options;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Pick a template/theme combo,
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function style_select($default = '', $all = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql_where = (!$all) ? 'WHERE style_active = 1 ' : '';
|
|
|
4c79b5 |
$sql = 'SELECT style_id, style_name
|
|
|
4c79b5 |
FROM ' . STYLES_TABLE . "
|
|
|
4c79b5 |
$sql_where
|
|
|
4c79b5 |
ORDER BY style_name";
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$style_options = '';
|
|
|
4c79b5 |
while ($row = $db->sql_fetchrow($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$selected = ($row['style_id'] == $default) ? ' selected="selected"' : '';
|
|
|
4c79b5 |
$style_options .= '<option value="' . $row['style_id'] . '"' . $selected . '>' . $row['style_name'] . '</option>';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $style_options;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Pick a timezone
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function tz_select($default = '', $truncate = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$tz_select = '';
|
|
|
4c79b5 |
foreach ($user->lang['tz_zones'] as $offset => $zone)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($truncate)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$zone_trunc = truncate_string($zone, 50, 255, false, '...');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$zone_trunc = $zone;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (is_numeric($offset))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$selected = ($offset == $default) ? ' selected="selected"' : '';
|
|
|
4c79b5 |
$tz_select .= '<option title="'.$zone.'" value="' . $offset . '"' . $selected . '>' . $zone_trunc . '</option>';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $tz_select;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Functions handling topic/post tracking/marking
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Marks a topic/forum as read
|
|
|
4c79b5 |
* Marks a topic as posted to
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param int $user_id can only be used with $mode == 'post'
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $user_id = 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $user, $config;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($mode == 'all')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($forum_id === false || !sizeof($forum_id))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($config['load_db_lastread'] && $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Mark all forums read (index page)
|
|
|
4c79b5 |
$db->sql_query('DELETE FROM ' . TOPICS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']}");
|
|
|
4c79b5 |
$db->sql_query('DELETE FROM ' . FORUMS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']}");
|
|
|
4c79b5 |
$db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_lastmark = ' . time() . " WHERE user_id = {$user->data['user_id']}");
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($config['load_anon_lastread'] || $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$tracking_topics = (isset($_COOKIE[$config['cookie_name'] . '_track'])) ? ((STRIP) ? stripslashes($_COOKIE[$config['cookie_name'] . '_track']) : $_COOKIE[$config['cookie_name'] . '_track']) : '';
|
|
|
4c79b5 |
$tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
unset($tracking_topics['tf']);
|
|
|
4c79b5 |
unset($tracking_topics['t']);
|
|
|
4c79b5 |
unset($tracking_topics['f']);
|
|
|
4c79b5 |
$tracking_topics['l'] = base_convert(time() - $config['board_startdate'], 10, 36);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$user->set_cookie('track', tracking_serialize($tracking_topics), time() + 31536000);
|
|
|
4c79b5 |
$_COOKIE[$config['cookie_name'] . '_track'] = (STRIP) ? addslashes(tracking_serialize($tracking_topics)) : tracking_serialize($tracking_topics);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
unset($tracking_topics);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_lastmark = ' . time() . " WHERE user_id = {$user->data['user_id']}");
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($mode == 'topics')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Mark all topics in forums read
|
|
|
4c79b5 |
if (!is_array($forum_id))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$forum_id = array($forum_id);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Add 0 to forums array to mark global announcements correctly
|
|
|
4c79b5 |
$forum_id[] = 0;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($config['load_db_lastread'] && $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'DELETE FROM ' . TOPICS_TRACK_TABLE . "
|
|
|
4c79b5 |
WHERE user_id = {$user->data['user_id']}
|
|
|
4c79b5 |
AND " . $db->sql_in_set('forum_id', $forum_id);
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql = 'SELECT forum_id
|
|
|
4c79b5 |
FROM ' . FORUMS_TRACK_TABLE . "
|
|
|
4c79b5 |
WHERE user_id = {$user->data['user_id']}
|
|
|
4c79b5 |
AND " . $db->sql_in_set('forum_id', $forum_id);
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql_update = array();
|
|
|
4c79b5 |
while ($row = $db->sql_fetchrow($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql_update[] = $row['forum_id'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (sizeof($sql_update))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'UPDATE ' . FORUMS_TRACK_TABLE . '
|
|
|
4c79b5 |
SET mark_time = ' . time() . "
|
|
|
4c79b5 |
WHERE user_id = {$user->data['user_id']}
|
|
|
4c79b5 |
AND " . $db->sql_in_set('forum_id', $sql_update);
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($sql_insert = array_diff($forum_id, $sql_update))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql_ary = array();
|
|
|
4c79b5 |
foreach ($sql_insert as $f_id)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql_ary[] = array(
|
|
|
4c79b5 |
'user_id' => (int) $user->data['user_id'],
|
|
|
4c79b5 |
'forum_id' => (int) $f_id,
|
|
|
4c79b5 |
'mark_time' => time()
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$db->sql_multi_insert(FORUMS_TRACK_TABLE, $sql_ary);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($config['load_anon_lastread'] || $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$tracking = (isset($_COOKIE[$config['cookie_name'] . '_track'])) ? ((STRIP) ? stripslashes($_COOKIE[$config['cookie_name'] . '_track']) : $_COOKIE[$config['cookie_name'] . '_track']) : '';
|
|
|
4c79b5 |
$tracking = ($tracking) ? tracking_unserialize($tracking) : array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($forum_id as $f_id)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$topic_ids36 = (isset($tracking['tf'][$f_id])) ? $tracking['tf'][$f_id] : array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (isset($tracking['tf'][$f_id]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
unset($tracking['tf'][$f_id]);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($topic_ids36 as $topic_id36)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
unset($tracking['t'][$topic_id36]);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (isset($tracking['f'][$f_id]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
unset($tracking['f'][$f_id]);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$tracking['f'][$f_id] = base_convert(time() - $config['board_startdate'], 10, 36);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (isset($tracking['tf']) && empty($tracking['tf']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
unset($tracking['tf']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$user->set_cookie('track', tracking_serialize($tracking), time() + 31536000);
|
|
|
4c79b5 |
$_COOKIE[$config['cookie_name'] . '_track'] = (STRIP) ? addslashes(tracking_serialize($tracking)) : tracking_serialize($tracking);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
unset($tracking);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($mode == 'topic')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($topic_id === false || $forum_id === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($config['load_db_lastread'] && $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'UPDATE ' . TOPICS_TRACK_TABLE . '
|
|
|
4c79b5 |
SET mark_time = ' . (($post_time) ? $post_time : time()) . "
|
|
|
4c79b5 |
WHERE user_id = {$user->data['user_id']}
|
|
|
4c79b5 |
AND topic_id = $topic_id";
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// insert row
|
|
|
4c79b5 |
if (!$db->sql_affectedrows())
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$db->sql_return_on_error(true);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql_ary = array(
|
|
|
4c79b5 |
'user_id' => (int) $user->data['user_id'],
|
|
|
4c79b5 |
'topic_id' => (int) $topic_id,
|
|
|
4c79b5 |
'forum_id' => (int) $forum_id,
|
|
|
4c79b5 |
'mark_time' => ($post_time) ? (int) $post_time : time(),
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$db->sql_query('INSERT INTO ' . TOPICS_TRACK_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$db->sql_return_on_error(false);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($config['load_anon_lastread'] || $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$tracking = (isset($_COOKIE[$config['cookie_name'] . '_track'])) ? ((STRIP) ? stripslashes($_COOKIE[$config['cookie_name'] . '_track']) : $_COOKIE[$config['cookie_name'] . '_track']) : '';
|
|
|
4c79b5 |
$tracking = ($tracking) ? tracking_unserialize($tracking) : array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$topic_id36 = base_convert($topic_id, 10, 36);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!isset($tracking['t'][$topic_id36]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$tracking['tf'][$forum_id][$topic_id36] = true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$post_time = ($post_time) ? $post_time : time();
|
|
|
4c79b5 |
$tracking['t'][$topic_id36] = base_convert($post_time - $config['board_startdate'], 10, 36);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// If the cookie grows larger than 10000 characters we will remove the smallest value
|
|
|
4c79b5 |
// This can result in old topics being unread - but most of the time it should be accurate...
|
|
|
4c79b5 |
if (isset($_COOKIE[$config['cookie_name'] . '_track']) && strlen($_COOKIE[$config['cookie_name'] . '_track']) > 10000)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
//echo 'Cookie grown too large' . print_r($tracking, true);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// We get the ten most minimum stored time offsets and its associated topic ids
|
|
|
4c79b5 |
$time_keys = array();
|
|
|
4c79b5 |
for ($i = 0; $i < 10 && sizeof($tracking['t']); $i++)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$min_value = min($tracking['t']);
|
|
|
4c79b5 |
$m_tkey = array_search($min_value, $tracking['t']);
|
|
|
4c79b5 |
unset($tracking['t'][$m_tkey]);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$time_keys[$m_tkey] = $min_value;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Now remove the topic ids from the array...
|
|
|
4c79b5 |
foreach ($tracking['tf'] as $f_id => $topic_id_ary)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
foreach ($time_keys as $m_tkey => $min_value)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (isset($topic_id_ary[$m_tkey]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$tracking['f'][$f_id] = $min_value;
|
|
|
4c79b5 |
unset($tracking['tf'][$f_id][$m_tkey]);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user->data['user_lastmark'] = intval(base_convert(max($time_keys) + $config['board_startdate'], 36, 10));
|
|
|
4c79b5 |
$db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_lastmark = ' . $user->data['user_lastmark'] . " WHERE user_id = {$user->data['user_id']}");
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$tracking['l'] = max($time_keys);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$user->set_cookie('track', tracking_serialize($tracking), time() + 31536000);
|
|
|
4c79b5 |
$_COOKIE[$config['cookie_name'] . '_track'] = (STRIP) ? addslashes(tracking_serialize($tracking)) : tracking_serialize($tracking);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($mode == 'post')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($topic_id === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$use_user_id = (!$user_id) ? $user->data['user_id'] : $user_id;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($config['load_db_track'] && $use_user_id != ANONYMOUS)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$db->sql_return_on_error(true);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql_ary = array(
|
|
|
4c79b5 |
'user_id' => (int) $use_user_id,
|
|
|
4c79b5 |
'topic_id' => (int) $topic_id,
|
|
|
4c79b5 |
'topic_posted' => 1
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$db->sql_query('INSERT INTO ' . TOPICS_POSTED_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$db->sql_return_on_error(false);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Get topic tracking info by using already fetched info
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function get_topic_tracking($forum_id, $topic_ids, &$rowset, $forum_mark_time, $global_announce_list = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $config, $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$last_read = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!is_array($topic_ids))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$topic_ids = array($topic_ids);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($topic_ids as $topic_id)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (!empty($rowset[$topic_id]['mark_time']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$last_read[$topic_id] = $rowset[$topic_id]['mark_time'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$topic_ids = array_diff($topic_ids, array_keys($last_read));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (sizeof($topic_ids))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mark_time = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Get global announcement info
|
|
|
4c79b5 |
if ($global_announce_list && sizeof($global_announce_list))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (!isset($forum_mark_time[0]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql = 'SELECT mark_time
|
|
|
4c79b5 |
FROM ' . FORUMS_TRACK_TABLE . "
|
|
|
4c79b5 |
WHERE user_id = {$user->data['user_id']}
|
|
|
4c79b5 |
AND forum_id = 0";
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
$row = $db->sql_fetchrow($result);
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($row)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mark_time[0] = $row['mark_time'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($forum_mark_time[0] !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mark_time[0] = $forum_mark_time[0];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!empty($forum_mark_time[$forum_id]) && $forum_mark_time[$forum_id] !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mark_time[$forum_id] = $forum_mark_time[$forum_id];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$user_lastmark = (isset($mark_time[$forum_id])) ? $mark_time[$forum_id] : $user->data['user_lastmark'];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($topic_ids as $topic_id)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($global_announce_list && isset($global_announce_list[$topic_id]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$last_read[$topic_id] = (isset($mark_time[0])) ? $mark_time[0] : $user_lastmark;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$last_read[$topic_id] = $user_lastmark;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $last_read;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Get topic tracking info from db (for cookie based tracking only this function is used)
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function get_complete_topic_tracking($forum_id, $topic_ids, $global_announce_list = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $config, $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$last_read = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!is_array($topic_ids))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$topic_ids = array($topic_ids);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($config['load_db_lastread'] && $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql = 'SELECT topic_id, mark_time
|
|
|
4c79b5 |
FROM ' . TOPICS_TRACK_TABLE . "
|
|
|
4c79b5 |
WHERE user_id = {$user->data['user_id']}
|
|
|
4c79b5 |
AND " . $db->sql_in_set('topic_id', $topic_ids);
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
while ($row = $db->sql_fetchrow($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$last_read[$row['topic_id']] = $row['mark_time'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$topic_ids = array_diff($topic_ids, array_keys($last_read));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (sizeof($topic_ids))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'SELECT forum_id, mark_time
|
|
|
4c79b5 |
FROM ' . FORUMS_TRACK_TABLE . "
|
|
|
4c79b5 |
WHERE user_id = {$user->data['user_id']}
|
|
|
4c79b5 |
AND forum_id " .
|
|
|
4c79b5 |
(($global_announce_list && sizeof($global_announce_list)) ? "IN (0, $forum_id)" : "= $forum_id");
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$mark_time = array();
|
|
|
4c79b5 |
while ($row = $db->sql_fetchrow($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mark_time[$row['forum_id']] = $row['mark_time'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$user_lastmark = (isset($mark_time[$forum_id])) ? $mark_time[$forum_id] : $user->data['user_lastmark'];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($topic_ids as $topic_id)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($global_announce_list && isset($global_announce_list[$topic_id]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$last_read[$topic_id] = (isset($mark_time[0])) ? $mark_time[0] : $user_lastmark;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$last_read[$topic_id] = $user_lastmark;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($config['load_anon_lastread'] || $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $tracking_topics;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!isset($tracking_topics) || !sizeof($tracking_topics))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$tracking_topics = (isset($_COOKIE[$config['cookie_name'] . '_track'])) ? ((STRIP) ? stripslashes($_COOKIE[$config['cookie_name'] . '_track']) : $_COOKIE[$config['cookie_name'] . '_track']) : '';
|
|
|
4c79b5 |
$tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user_lastmark = (isset($tracking_topics['l'])) ? base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate'] : 0;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user_lastmark = $user->data['user_lastmark'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($topic_ids as $topic_id)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$topic_id36 = base_convert($topic_id, 10, 36);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (isset($tracking_topics['t'][$topic_id36]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$last_read[$topic_id] = base_convert($tracking_topics['t'][$topic_id36], 36, 10) + $config['board_startdate'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$topic_ids = array_diff($topic_ids, array_keys($last_read));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (sizeof($topic_ids))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mark_time = array();
|
|
|
4c79b5 |
if ($global_announce_list && sizeof($global_announce_list))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (isset($tracking_topics['f'][0]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mark_time[0] = base_convert($tracking_topics['f'][0], 36, 10) + $config['board_startdate'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (isset($tracking_topics['f'][$forum_id]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mark_time[$forum_id] = base_convert($tracking_topics['f'][$forum_id], 36, 10) + $config['board_startdate'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$user_lastmark = (isset($mark_time[$forum_id])) ? $mark_time[$forum_id] : $user_lastmark;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($topic_ids as $topic_id)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($global_announce_list && isset($global_announce_list[$topic_id]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$last_read[$topic_id] = (isset($mark_time[0])) ? $mark_time[0] : $user_lastmark;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$last_read[$topic_id] = $user_lastmark;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $last_read;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Check for read forums and update topic tracking info accordingly
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param int $forum_id the forum id to check
|
|
|
4c79b5 |
* @param int $forum_last_post_time the forums last post time
|
|
|
4c79b5 |
* @param int $f_mark_time the forums last mark time if user is registered and load_db_lastread enabled
|
|
|
4c79b5 |
* @param int $mark_time_forum false if the mark time needs to be obtained, else the last users forum mark time
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @return true if complete forum got marked read, else false.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_time = false, $mark_time_forum = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $tracking_topics, $user, $config;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Determine the users last forum mark time if not given.
|
|
|
4c79b5 |
if ($mark_time_forum === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($config['load_db_lastread'] && $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mark_time_forum = (!empty($f_mark_time)) ? $f_mark_time : $user->data['user_lastmark'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($config['load_anon_lastread'] || $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$tracking_topics = (isset($_COOKIE[$config['cookie_name'] . '_track'])) ? ((STRIP) ? stripslashes($_COOKIE[$config['cookie_name'] . '_track']) : $_COOKIE[$config['cookie_name'] . '_track']) : '';
|
|
|
4c79b5 |
$tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user->data['user_lastmark'] = (isset($tracking_topics['l'])) ? (int) (base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate']) : 0;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$mark_time_forum = (isset($tracking_topics['f'][$forum_id])) ? (int) (base_convert($tracking_topics['f'][$forum_id], 36, 10) + $config['board_startdate']) : $user->data['user_lastmark'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Check the forum for any left unread topics.
|
|
|
4c79b5 |
// If there are none, we mark the forum as read.
|
|
|
4c79b5 |
if ($config['load_db_lastread'] && $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($mark_time_forum >= $forum_last_post_time)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// We do not need to mark read, this happened before. Therefore setting this to true
|
|
|
4c79b5 |
$row = true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'SELECT t.forum_id FROM ' . TOPICS_TABLE . ' t
|
|
|
4c79b5 |
LEFT JOIN ' . TOPICS_TRACK_TABLE . ' tt ON (tt.topic_id = t.topic_id AND tt.user_id = ' . $user->data['user_id'] . ')
|
|
|
4c79b5 |
WHERE t.forum_id = ' . $forum_id . '
|
|
|
4c79b5 |
AND t.topic_last_post_time > ' . $mark_time_forum . '
|
|
|
4c79b5 |
AND t.topic_moved_id = 0
|
|
|
4c79b5 |
AND (tt.topic_id IS NULL OR tt.mark_time < t.topic_last_post_time)
|
|
|
4c79b5 |
GROUP BY t.forum_id';
|
|
|
4c79b5 |
$result = $db->sql_query_limit($sql, 1);
|
|
|
4c79b5 |
$row = $db->sql_fetchrow($result);
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($config['load_anon_lastread'] || $user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Get information from cookie
|
|
|
4c79b5 |
$row = false;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!isset($tracking_topics['tf'][$forum_id]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// We do not need to mark read, this happened before. Therefore setting this to true
|
|
|
4c79b5 |
$row = true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'SELECT topic_id
|
|
|
4c79b5 |
FROM ' . TOPICS_TABLE . '
|
|
|
4c79b5 |
WHERE forum_id = ' . $forum_id . '
|
|
|
4c79b5 |
AND topic_last_post_time > ' . $mark_time_forum . '
|
|
|
4c79b5 |
AND topic_moved_id = 0';
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$check_forum = $tracking_topics['tf'][$forum_id];
|
|
|
4c79b5 |
$unread = false;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
while ($row = $db->sql_fetchrow($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (!isset($check_forum[base_convert($row['topic_id'], 10, 36)]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$unread = true;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$row = $unread;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$row = true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$row)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
markread('topics', $forum_id);
|
|
|
4c79b5 |
return true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Transform an array into a serialized format
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function tracking_serialize($input)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$out = '';
|
|
|
4c79b5 |
foreach ($input as $key => $value)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (is_array($value))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$out .= $key . ':(' . tracking_serialize($value) . ');';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$out .= $key . ':' . $value . ';';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
return $out;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Transform a serialized array into an actual array
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function tracking_unserialize($string, $max_depth = 3)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$n = strlen($string);
|
|
|
4c79b5 |
if ($n > 10010)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
die('Invalid data supplied');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$data = $stack = array();
|
|
|
4c79b5 |
$key = '';
|
|
|
4c79b5 |
$mode = 0;
|
|
|
4c79b5 |
$level = &$data;
|
|
|
4c79b5 |
for ($i = 0; $i < $n; ++$i)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
switch ($mode)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case 0:
|
|
|
4c79b5 |
switch ($string[$i])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case ':':
|
|
|
4c79b5 |
$level[$key] = 0;
|
|
|
4c79b5 |
$mode = 1;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
case ')':
|
|
|
4c79b5 |
unset($level);
|
|
|
4c79b5 |
$level = array_pop($stack);
|
|
|
4c79b5 |
$mode = 3;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
default:
|
|
|
4c79b5 |
$key .= $string[$i];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 1:
|
|
|
4c79b5 |
switch ($string[$i])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case '(':
|
|
|
4c79b5 |
if (sizeof($stack) >= $max_depth)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
die('Invalid data supplied');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$stack[] = &$level;
|
|
|
4c79b5 |
$level[$key] = array();
|
|
|
4c79b5 |
$level = &$level[$key];
|
|
|
4c79b5 |
$key = '';
|
|
|
4c79b5 |
$mode = 0;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
default:
|
|
|
4c79b5 |
$level[$key] = $string[$i];
|
|
|
4c79b5 |
$mode = 2;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 2:
|
|
|
4c79b5 |
switch ($string[$i])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case ')':
|
|
|
4c79b5 |
unset($level);
|
|
|
4c79b5 |
$level = array_pop($stack);
|
|
|
4c79b5 |
$mode = 3;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
case ';':
|
|
|
4c79b5 |
$key = '';
|
|
|
4c79b5 |
$mode = 0;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
default:
|
|
|
4c79b5 |
$level[$key] .= $string[$i];
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 3:
|
|
|
4c79b5 |
switch ($string[$i])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case ')':
|
|
|
4c79b5 |
unset($level);
|
|
|
4c79b5 |
$level = array_pop($stack);
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
case ';':
|
|
|
4c79b5 |
$key = '';
|
|
|
4c79b5 |
$mode = 0;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
default:
|
|
|
4c79b5 |
die('Invalid data supplied');
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (sizeof($stack) != 0 || ($mode != 0 && $mode != 3))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
die('Invalid data supplied');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $level;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Pagination functions
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Pagination routine, generates page number sequence
|
|
|
4c79b5 |
* tpl_prefix is for using different pagination blocks at one page
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function generate_pagination($base_url, $num_items, $per_page, $start_item, $add_prevnext_text = false, $tpl_prefix = '')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $template, $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Make sure $per_page is a valid value
|
|
|
4c79b5 |
$per_page = ($per_page <= 0) ? 1 : $per_page;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$seperator = '' . $user->lang['COMMA_SEPARATOR'] . '';
|
|
|
4c79b5 |
$total_pages = ceil($num_items / $per_page);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($total_pages == 1 || !$num_items)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$on_page = floor($start_item / $per_page) + 1;
|
|
|
4c79b5 |
$url_delim = (strpos($base_url, '?') === false) ? '?' : '&';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$page_string = ($on_page == 1) ? '1' : '1';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($total_pages > 5)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$start_cnt = min(max(1, $on_page - 4), $total_pages - 5);
|
|
|
4c79b5 |
$end_cnt = max(min($total_pages, $on_page + 4), 6);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$page_string .= ($start_cnt > 1) ? ' ... ' : $seperator;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
for ($i = $start_cnt + 1; $i < $end_cnt; $i++)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$page_string .= ($i == $on_page) ? '' . $i . '' : '' . $i . '';
|
|
|
4c79b5 |
if ($i < $end_cnt - 1)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$page_string .= $seperator;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$page_string .= ($end_cnt < $total_pages) ? ' ... ' : $seperator;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$page_string .= $seperator;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
for ($i = 2; $i < $total_pages; $i++)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$page_string .= ($i == $on_page) ? '' . $i . '' : '' . $i . '';
|
|
|
4c79b5 |
if ($i < $total_pages)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$page_string .= $seperator;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$page_string .= ($on_page == $total_pages) ? '' . $total_pages . '' : '' . $total_pages . '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($add_prevnext_text)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($on_page != 1)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$page_string = '' . $user->lang['PREVIOUS'] . ' ' . $page_string;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($on_page != $total_pages)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$page_string .= ' ' . $user->lang['NEXT'] . '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
$tpl_prefix . 'BASE_URL' => $base_url,
|
|
|
4c79b5 |
'A_' . $tpl_prefix . 'BASE_URL' => addslashes($base_url),
|
|
|
4c79b5 |
$tpl_prefix . 'PER_PAGE' => $per_page,
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$tpl_prefix . 'PREVIOUS_PAGE' => ($on_page == 1) ? '' : $base_url . "{$url_delim}start=" . (($on_page - 2) * $per_page),
|
|
|
4c79b5 |
$tpl_prefix . 'NEXT_PAGE' => ($on_page == $total_pages) ? '' : $base_url . "{$url_delim}start=" . ($on_page * $per_page),
|
|
|
4c79b5 |
$tpl_prefix . 'TOTAL_PAGES' => $total_pages,
|
|
|
4c79b5 |
));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $page_string;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Return current page (pagination)
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function on_page($num_items, $per_page, $start)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $template, $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Make sure $per_page is a valid value
|
|
|
4c79b5 |
$per_page = ($per_page <= 0) ? 1 : $per_page;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$on_page = floor($start / $per_page) + 1;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'ON_PAGE' => $on_page)
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return sprintf($user->lang['PAGE_OF'], $on_page, max(ceil($num_items / $per_page), 1));
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Server functions (building urls, redirecting...)
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Append session id to url.
|
|
|
4c79b5 |
* This function supports hooks.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param string $url The url the session id needs to be appended to (can have params)
|
|
|
4c79b5 |
* @param mixed $params String or array of additional url parameters
|
|
|
4c79b5 |
* @param bool $is_amp Is url using & (true) or & (false)
|
|
|
4c79b5 |
* @param string $session_id Possibility to use a custom session id instead of the global one
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Examples:
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* append_sid("{$phpbb_root_path}viewtopic.$phpEx?t=1&f=2");
|
|
|
4c79b5 |
* append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=1&f=2');
|
|
|
4c79b5 |
* append_sid("{$phpbb_root_path}viewtopic.$phpEx", 't=1&f=2', false);
|
|
|
4c79b5 |
* append_sid("{$phpbb_root_path}viewtopic.$phpEx", array('t' => 1, 'f' => 2));
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function append_sid($url, $params = false, $is_amp = true, $session_id = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $_SID, $_EXTRA_URL, $phpbb_hook;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Developers using the hook function need to globalise the $_SID and $_EXTRA_URL on their own and also handle it appropiatly.
|
|
|
4c79b5 |
// They could mimick most of what is within this function
|
|
|
4c79b5 |
if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__, $url, $params, $is_amp, $session_id))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($phpbb_hook->hook_return(__FUNCTION__))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $phpbb_hook->hook_return_result(__FUNCTION__);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$params_is_array = is_array($params);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Get anchor
|
|
|
4c79b5 |
$anchor = '';
|
|
|
4c79b5 |
if (strpos($url, '#') !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
list($url, $anchor) = explode('#', $url, 2);
|
|
|
4c79b5 |
$anchor = '#' . $anchor;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (!$params_is_array && strpos($params, '#') !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
list($params, $anchor) = explode('#', $params, 2);
|
|
|
4c79b5 |
$anchor = '#' . $anchor;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Handle really simple cases quickly
|
|
|
4c79b5 |
if ($_SID == '' && $session_id === false && empty($_EXTRA_URL) && !$params_is_array && !$anchor)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($params === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $url;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$url_delim = (strpos($url, '?') === false) ? '?' : (($is_amp) ? '&' : '&';;
|
|
|
4c79b5 |
return $url . ($params !== false ? $url_delim. $params : '');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Assign sid if session id is not specified
|
|
|
4c79b5 |
if ($session_id === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$session_id = $_SID;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$amp_delim = ($is_amp) ? '&' : '&';
|
|
|
4c79b5 |
$url_delim = (strpos($url, '?') === false) ? '?' : $amp_delim;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Appending custom url parameter?
|
|
|
4c79b5 |
$append_url = (!empty($_EXTRA_URL)) ? implode($amp_delim, $_EXTRA_URL) : '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Use the short variant if possible ;)
|
|
|
4c79b5 |
if ($params === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Append session id
|
|
|
4c79b5 |
if (!$session_id)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $url . (($append_url) ? $url_delim . $append_url : '') . $anchor;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $url . (($append_url) ? $url_delim . $append_url . $amp_delim : $url_delim) . 'sid=' . $session_id . $anchor;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Build string if parameters are specified as array
|
|
|
4c79b5 |
if (is_array($params))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$output = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($params as $key => $item)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($item === NULL)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
continue;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($key == '#')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$anchor = '#' . $item;
|
|
|
4c79b5 |
continue;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$output[] = $key . '=' . $item;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$params = implode($amp_delim, $output);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Append session id and parameters (even if they are empty)
|
|
|
4c79b5 |
// If parameters are empty, the developer can still append his/her parameters without caring about the delimiter
|
|
|
4c79b5 |
return $url . (($append_url) ? $url_delim . $append_url . $amp_delim : $url_delim) . $params . ((!$session_id) ? '' : $amp_delim . 'sid=' . $session_id) . $anchor;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Generate board url (example: http://www.example.com/phpBB)
|
|
|
4c79b5 |
* @param bool $without_script_path if set to true the script path gets not appended (example: http://www.example.com)
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function generate_board_url($without_script_path = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $config, $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$server_name = $user->host;
|
|
|
4c79b5 |
$server_port = (!empty($_SERVER['SERVER_PORT'])) ? (int) $_SERVER['SERVER_PORT'] : (int) getenv('SERVER_PORT');
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Forcing server vars is the only way to specify/override the protocol
|
|
|
4c79b5 |
if ($config['force_server_vars'] || !$server_name)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$server_protocol = ($config['server_protocol']) ? $config['server_protocol'] : (($config['cookie_secure']) ? 'https://' : 'http://');
|
|
|
4c79b5 |
$server_name = $config['server_name'];
|
|
|
4c79b5 |
$server_port = (int) $config['server_port'];
|
|
|
4c79b5 |
$script_path = $config['script_path'];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$url = $server_protocol . $server_name;
|
|
|
4c79b5 |
$cookie_secure = $config['cookie_secure'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Do not rely on cookie_secure, users seem to think that it means a secured cookie instead of an encrypted connection
|
|
|
4c79b5 |
$cookie_secure = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 1 : 0;
|
|
|
4c79b5 |
$url = (($cookie_secure) ? 'https://' : 'http://') . $server_name;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$script_path = $user->page['root_script_path'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($server_port && (($cookie_secure && $server_port <> 443) || (!$cookie_secure && $server_port <> 80)))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// HTTP HOST can carry a port number (we fetch $user->host, but for old versions this may be true)
|
|
|
4c79b5 |
if (strpos($server_name, ':') === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url .= ':' . $server_port;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$without_script_path)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url .= $script_path;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Strip / from the end
|
|
|
4c79b5 |
if (substr($url, -1, 1) == '/')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = substr($url, 0, -1);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $url;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Redirects the user to another page then exits the script nicely
|
|
|
4c79b5 |
* This function is intended for urls within the board. It's not meant to redirect to cross-domains.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param string $url The url to redirect to
|
|
|
4c79b5 |
* @param bool $return If true, do not redirect but return the sanitized URL. Default is no return.
|
|
|
4c79b5 |
* @param bool $disable_cd_check If true, redirect() will redirect to an external domain. If false, the redirect point to the boards url if it does not match the current domain. Default is false.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function redirect($url, $return = false, $disable_cd_check = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $cache, $config, $user, $phpbb_root_path;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (empty($user->lang))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user->add_lang('common');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$return)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
garbage_collection();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Make sure no &'s are in, this will break the redirect
|
|
|
4c79b5 |
$url = str_replace('&', '&', $url);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Determine which type of redirect we need to handle...
|
|
|
4c79b5 |
$url_parts = parse_url($url);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($url_parts === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Malformed url, redirect to current page...
|
|
|
4c79b5 |
$url = generate_board_url() . '/' . $user->page['page'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (!empty($url_parts['scheme']) && !empty($url_parts['host']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Attention: only able to redirect within the same domain if $disable_cd_check is false (yourdomain.com -> www.yourdomain.com will not work)
|
|
|
4c79b5 |
if (!$disable_cd_check && $url_parts['host'] !== $user->host)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = generate_board_url();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($url[0] == '/')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Absolute uri, prepend direct url...
|
|
|
4c79b5 |
$url = generate_board_url(true) . $url;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Relative uri
|
|
|
4c79b5 |
$pathinfo = pathinfo($url);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Is the uri pointing to the current directory?
|
|
|
4c79b5 |
if ($pathinfo['dirname'] == '.')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = str_replace('./', '', $url);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Strip / from the beginning
|
|
|
4c79b5 |
if ($url && substr($url, 0, 1) == '/')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = substr($url, 1);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($user->page['page_dir'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = generate_board_url() . '/' . $user->page['page_dir'] . '/' . $url;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = generate_board_url() . '/' . $url;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Used ./ before, but $phpbb_root_path is working better with urls within another root path
|
|
|
4c79b5 |
$root_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($phpbb_root_path)));
|
|
|
4c79b5 |
$page_dirs = explode('/', str_replace('\\', '/', phpbb_realpath($pathinfo['dirname'])));
|
|
|
4c79b5 |
$intersection = array_intersect_assoc($root_dirs, $page_dirs);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$root_dirs = array_diff_assoc($root_dirs, $intersection);
|
|
|
4c79b5 |
$page_dirs = array_diff_assoc($page_dirs, $intersection);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$dir = str_repeat('../', sizeof($root_dirs)) . implode('/', $page_dirs);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Strip / from the end
|
|
|
4c79b5 |
if ($dir && substr($dir, -1, 1) == '/')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$dir = substr($dir, 0, -1);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Strip / from the beginning
|
|
|
4c79b5 |
if ($dir && substr($dir, 0, 1) == '/')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$dir = substr($dir, 1);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$url = str_replace($pathinfo['dirname'] . '/', '', $url);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Strip / from the beginning
|
|
|
4c79b5 |
if (substr($url, 0, 1) == '/')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = substr($url, 1);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$url = (!empty($dir) ? $dir . '/' : '') . $url;
|
|
|
4c79b5 |
$url = generate_board_url() . '/' . $url;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Make sure no linebreaks are there... to prevent http response splitting for PHP < 4.4.2
|
|
|
4c79b5 |
if (strpos(urldecode($url), "\n") !== false || strpos(urldecode($url), "\r") !== false || strpos($url, ';') !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
trigger_error('Tried to redirect to potentially insecure url.', E_USER_ERROR);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Now, also check the protocol and for a valid url the last time...
|
|
|
4c79b5 |
$allowed_protocols = array('http', 'https', 'ftp', 'ftps');
|
|
|
4c79b5 |
$url_parts = parse_url($url);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($url_parts === false || empty($url_parts['scheme']) || !in_array($url_parts['scheme'], $allowed_protocols))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
trigger_error('Tried to redirect to potentially insecure url.', E_USER_ERROR);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($return)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $url;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Redirect via an HTML form for PITA webservers
|
|
|
4c79b5 |
if (@preg_match('#Microsoft|WebSTAR|Xitami#', getenv('SERVER_SOFTWARE')))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
header('Refresh: 0; URL=' . $url);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
echo '';
|
|
|
4c79b5 |
echo '<html xmlns="http://www.w3.org/1999/xhtml" dir="' . $user->lang['DIRECTION'] . '" lang="' . $user->lang['USER_LANG'] . '" xml:lang="' . $user->lang['USER_LANG'] . '">';
|
|
|
4c79b5 |
echo '<head>';
|
|
|
4c79b5 |
echo '<meta http-equiv="content-type" content="text/html; charset=utf-8" />';
|
|
|
4c79b5 |
echo '<meta http-equiv="refresh" content="0; url=' . str_replace('&', '&', $url) . '" />';
|
|
|
4c79b5 |
echo '<title>' . $user->lang['REDIRECT'] . '</title>';
|
|
|
4c79b5 |
echo '</head>';
|
|
|
4c79b5 |
echo '<body>';
|
|
|
4c79b5 |
echo '' . sprintf($user->lang['URL_REDIRECT'], ' ', '') . ' ';
|
|
|
4c79b5 |
echo '</body>';
|
|
|
4c79b5 |
echo '</html>';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
exit;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Behave as per HTTP/1.1 spec for others
|
|
|
4c79b5 |
header('Location: ' . $url);
|
|
|
4c79b5 |
exit;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Re-Apply session id after page reloads
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function reapply_sid($url)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $phpEx, $phpbb_root_path;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($url === "index.$phpEx")
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return append_sid("index.$phpEx");
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($url === "{$phpbb_root_path}index.$phpEx")
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return append_sid("{$phpbb_root_path}index.$phpEx");
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Remove previously added sid
|
|
|
4c79b5 |
if (strpos($url, '?sid=') !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = preg_replace('/(\?)sid=[a-z0-9]+(&|&)?/', '\1', $url);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (strpos($url, '&sid=') !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = preg_replace('/&sid=[a-z0-9]+(&)?/', '\1', $url);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (strpos($url, '&sid=') !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$url = preg_replace('/&sid=[a-z0-9]+(&)?/', '\1', $url);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return append_sid($url);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Returns url from the session/current page with an re-appended SID with optionally stripping vars from the url
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function build_url($strip_vars = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $user, $phpbb_root_path;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Append SID
|
|
|
4c79b5 |
$redirect = append_sid($user->page['page'], false, false);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Add delimiter if not there...
|
|
|
4c79b5 |
if (strpos($redirect, '?') === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$redirect .= '?';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Strip vars...
|
|
|
4c79b5 |
if ($strip_vars !== false && strpos($redirect, '?') !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (!is_array($strip_vars))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$strip_vars = array($strip_vars);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$query = $_query = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$args = substr($redirect, strpos($redirect, '?') + 1);
|
|
|
4c79b5 |
$args = ($args) ? explode('&', $args) : array();
|
|
|
4c79b5 |
$redirect = substr($redirect, 0, strpos($redirect, '?'));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($args as $argument)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$arguments = explode('=', $argument);
|
|
|
4c79b5 |
$key = $arguments[0];
|
|
|
4c79b5 |
unset($arguments[0]);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$query[$key] = implode('=', $arguments);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Strip the vars off
|
|
|
4c79b5 |
foreach ($strip_vars as $strip)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (isset($query[$strip]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
unset($query[$strip]);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Glue the remaining parts together... already urlencoded
|
|
|
4c79b5 |
foreach ($query as $key => $value)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$_query[] = $key . '=' . $value;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$query = implode('&', $_query);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$redirect .= ($query) ? '?' . $query : '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $phpbb_root_path . str_replace('&', '&', $redirect);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Meta refresh assignment
|
|
|
4c79b5 |
* Adds META template variable with meta http tag.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param int $time Time in seconds for meta refresh tag
|
|
|
4c79b5 |
* @param string $url URL to redirect to. The url will go through redirect() first before the template variable is assigned
|
|
|
4c79b5 |
* @param bool $disable_cd_check If true, meta_refresh() will redirect to an external domain. If false, the redirect point to the boards url if it does not match the current domain. Default is false.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function meta_refresh($time, $url, $disable_cd_check = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $template;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$url = redirect($url, true, $disable_cd_check);
|
|
|
4c79b5 |
$url = str_replace('&', '&', $url);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// For XHTML compatibility we change back & to &
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'META' => '<meta http-equiv="refresh" content="' . $time . ';url=' . $url . '" />')
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $url;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
//Form validation
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Add a secret hash for use in links/GET requests
|
|
|
4c79b5 |
* @param string $link_name The name of the link; has to match the name used in check_link_hash, otherwise no restrictions apply
|
|
|
4c79b5 |
* @return string the hash
|
|
|
4c79b5 |
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function generate_link_hash($link_name)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!isset($user->data["hash_$link_name"]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user->data["hash_$link_name"] = substr(sha1($user->data['user_form_salt'] . $link_name), 0, 8);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $user->data["hash_$link_name"];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* checks a link hash - for GET requests
|
|
|
4c79b5 |
* @param string $token the submitted token
|
|
|
4c79b5 |
* @param string $link_name The name of the link
|
|
|
4c79b5 |
* @return boolean true if all is fine
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function check_link_hash($token, $link_name)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $token === generate_link_hash($link_name);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Add a secret token to the form (requires the S_FORM_TOKEN template variable)
|
|
|
4c79b5 |
* @param string $form_name The name of the form; has to match the name used in check_form_key, otherwise no restrictions apply
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function add_form_key($form_name)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $config, $template, $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$now = time();
|
|
|
4c79b5 |
$token_sid = ($user->data['user_id'] == ANONYMOUS && !empty($config['form_token_sid_guests'])) ? $user->session_id : '';
|
|
|
4c79b5 |
$token = sha1($now . $user->data['user_form_salt'] . $form_name . $token_sid);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$s_fields = build_hidden_fields(array(
|
|
|
4c79b5 |
'creation_time' => $now,
|
|
|
4c79b5 |
'form_token' => $token,
|
|
|
4c79b5 |
));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'S_FORM_TOKEN' => $s_fields,
|
|
|
4c79b5 |
));
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Check the form key. Required for all altering actions not secured by confirm_box
|
|
|
4c79b5 |
* @param string $form_name The name of the form; has to match the name used in add_form_key, otherwise no restrictions apply
|
|
|
4c79b5 |
* @param int $timespan The maximum acceptable age for a submitted form in seconds. Defaults to the config setting.
|
|
|
4c79b5 |
* @param string $return_page The address for the return link
|
|
|
4c79b5 |
* @param bool $trigger If true, the function will triger an error when encountering an invalid form
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function check_form_key($form_name, $timespan = false, $return_page = '', $trigger = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $config, $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($timespan === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// we enforce a minimum value of half a minute here.
|
|
|
4c79b5 |
$timespan = ($config['form_token_lifetime'] == -1) ? -1 : max(30, $config['form_token_lifetime']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (isset($_POST['creation_time']) && isset($_POST['form_token']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$creation_time = abs(request_var('creation_time', 0));
|
|
|
4c79b5 |
$token = request_var('form_token', '');
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$diff = time() - $creation_time;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// If creation_time and the time() now is zero we can assume it was not a human doing this (the check for if ($diff)...
|
|
|
4c79b5 |
if ($diff && ($diff <= $timespan || $timespan === -1))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$token_sid = ($user->data['user_id'] == ANONYMOUS && !empty($config['form_token_sid_guests'])) ? $user->session_id : '';
|
|
|
4c79b5 |
$key = sha1($creation_time . $user->data['user_form_salt'] . $form_name . $token_sid);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($key === $token)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($trigger)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
trigger_error($user->lang['FORM_INVALID'] . $return_page);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Message/Login boxes
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Build Confirm box
|
|
|
4c79b5 |
* @param boolean $check True for checking if confirmed (without any additional parameters) and false for displaying the confirm box
|
|
|
4c79b5 |
* @param string $title Title/Message used for confirm box.
|
|
|
4c79b5 |
* message text is _CONFIRM appended to title.
|
|
|
4c79b5 |
* If title cannot be found in user->lang a default one is displayed
|
|
|
4c79b5 |
* If title_CONFIRM cannot be found in user->lang the text given is used.
|
|
|
4c79b5 |
* @param string $hidden Hidden variables
|
|
|
4c79b5 |
* @param string $html_body Template used for confirm box
|
|
|
4c79b5 |
* @param string $u_action Custom form action
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_body.html', $u_action = '')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $user, $template, $db;
|
|
|
4c79b5 |
global $phpEx, $phpbb_root_path;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (isset($_POST['cancel']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$confirm = false;
|
|
|
4c79b5 |
if (isset($_POST['confirm']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// language frontier
|
|
|
4c79b5 |
if ($_POST['confirm'] === $user->lang['YES'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$confirm = true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($check && $confirm)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user_id = request_var('user_id', 0);
|
|
|
4c79b5 |
$session_id = request_var('sess', '');
|
|
|
4c79b5 |
$confirm_key = request_var('confirm_key', '');
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($user_id != $user->data['user_id'] || $session_id != $user->session_id || !$confirm_key || !$user->data['user_last_confirm_key'] || $confirm_key != $user->data['user_last_confirm_key'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Reset user_last_confirm_key
|
|
|
4c79b5 |
$sql = 'UPDATE ' . USERS_TABLE . " SET user_last_confirm_key = ''
|
|
|
4c79b5 |
WHERE user_id = " . $user->data['user_id'];
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($check)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$s_hidden_fields = build_hidden_fields(array(
|
|
|
4c79b5 |
'user_id' => $user->data['user_id'],
|
|
|
4c79b5 |
'sess' => $user->session_id,
|
|
|
4c79b5 |
'sid' => $user->session_id)
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// generate activation key
|
|
|
4c79b5 |
$confirm_key = gen_rand_string(10);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
adm_page_header((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
page_header((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->set_filenames(array(
|
|
|
4c79b5 |
'body' => $html_body)
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// If activation key already exist, we better do not re-use the key (something very strange is going on...)
|
|
|
4c79b5 |
if (request_var('confirm_key', ''))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// This should not occur, therefore we cancel the operation to safe the user
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// re-add sid / transform & to & for user->page (user->page is always using &)
|
|
|
4c79b5 |
$use_page = ($u_action) ? $phpbb_root_path . $u_action : $phpbb_root_path . str_replace('&', '&', $user->page['page']);
|
|
|
4c79b5 |
$u_action = reapply_sid($use_page);
|
|
|
4c79b5 |
$u_action .= ((strpos($u_action, '?') === false) ? '?' : '&') . 'confirm_key=' . $confirm_key;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'MESSAGE_TITLE' => (!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title],
|
|
|
4c79b5 |
'MESSAGE_TEXT' => (!isset($user->lang[$title . '_CONFIRM'])) ? $title : $user->lang[$title . '_CONFIRM'],
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'YES_VALUE' => $user->lang['YES'],
|
|
|
4c79b5 |
'S_CONFIRM_ACTION' => $u_action,
|
|
|
4c79b5 |
'S_HIDDEN_FIELDS' => $hidden . $s_hidden_fields)
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql = 'UPDATE ' . USERS_TABLE . " SET user_last_confirm_key = '" . $db->sql_escape($confirm_key) . "'
|
|
|
4c79b5 |
WHERE user_id = " . $user->data['user_id'];
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
adm_page_footer();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
page_footer();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Generate login box or verify password
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = false, $s_display = true)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $user, $template, $auth, $phpEx, $phpbb_root_path, $config;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$err = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Make sure user->setup() has been called
|
|
|
4c79b5 |
if (empty($user->lang))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user->setup();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Print out error if user tries to authenticate as an administrator without having the privileges...
|
|
|
4c79b5 |
if ($admin && !$auth->acl_get('a_'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Not authd
|
|
|
4c79b5 |
// anonymous/inactive users are never able to go to the ACP even if they have the relevant permissions
|
|
|
4c79b5 |
if ($user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
trigger_error('NO_AUTH_ADMIN');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (isset($_POST['login']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Get credential
|
|
|
4c79b5 |
if ($admin)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$credential = request_var('credential', '');
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (strspn($credential, 'abcdef0123456789') !== strlen($credential) || strlen($credential) != 32)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
trigger_error('NO_AUTH_ADMIN');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$password = request_var('password_' . $credential, '', true);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$password = request_var('password', '', true);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$username = request_var('username', '', true);
|
|
|
4c79b5 |
$autologin = (!empty($_POST['autologin'])) ? true : false;
|
|
|
4c79b5 |
$viewonline = (!empty($_POST['viewonline'])) ? 0 : 1;
|
|
|
4c79b5 |
$admin = ($admin) ? 1 : 0;
|
|
|
4c79b5 |
$viewonline = ($admin) ? $user->data['session_viewonline'] : $viewonline;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Check if the supplied username is equal to the one stored within the database if re-authenticating
|
|
|
4c79b5 |
if ($admin && utf8_clean_string($username) != utf8_clean_string($user->data['username']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// We log the attempt to use a different username...
|
|
|
4c79b5 |
add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
|
|
|
4c79b5 |
trigger_error('NO_AUTH_ADMIN_USER_DIFFER');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// If authentication is successful we redirect user to previous page
|
|
|
4c79b5 |
$result = $auth->login($username, $password, $autologin, $viewonline, $admin);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// If admin authentication and login, we will log if it was a success or not...
|
|
|
4c79b5 |
// We also break the operation on the first non-success login - it could be argued that the user already knows
|
|
|
4c79b5 |
if ($admin)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($result['status'] == LOGIN_SUCCESS)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
add_log('admin', 'LOG_ADMIN_AUTH_SUCCESS');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Only log the failed attempt if a real user tried to.
|
|
|
4c79b5 |
// anonymous/inactive users are never able to go to the ACP even if they have the relevant permissions
|
|
|
4c79b5 |
if ($user->data['is_registered'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// The result parameter is always an array, holding the relevant information...
|
|
|
4c79b5 |
if ($result['status'] == LOGIN_SUCCESS)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$redirect = request_var('redirect', "{$phpbb_root_path}index.$phpEx");
|
|
|
4c79b5 |
$message = ($l_success) ? $l_success : $user->lang['LOGIN_REDIRECT'];
|
|
|
4c79b5 |
$l_redirect = ($admin) ? $user->lang['PROCEED_TO_ACP'] : (($redirect === "{$phpbb_root_path}index.$phpEx" || $redirect === "index.$phpEx") ? $user->lang['RETURN_INDEX'] : $user->lang['RETURN_PAGE']);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// append/replace SID (may change during the session for AOL users)
|
|
|
4c79b5 |
$redirect = reapply_sid($redirect);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Special case... the user is effectively banned, but we allow founders to login
|
|
|
4c79b5 |
if (defined('IN_CHECK_BAN') && $result['user_row']['user_type'] != USER_FOUNDER)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$redirect = meta_refresh(3, $redirect);
|
|
|
4c79b5 |
trigger_error($message . '
' . sprintf($l_redirect, '', ''));
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Something failed, determine what...
|
|
|
4c79b5 |
if ($result['status'] == LOGIN_BREAK)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
trigger_error($result['error_msg']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Special cases... determine
|
|
|
4c79b5 |
switch ($result['status'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case LOGIN_ERROR_ATTEMPTS:
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Show confirm image
|
|
|
4c79b5 |
$sql = 'DELETE FROM ' . CONFIRM_TABLE . "
|
|
|
4c79b5 |
WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
|
|
|
4c79b5 |
AND confirm_type = " . CONFIRM_LOGIN;
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Generate code
|
|
|
4c79b5 |
$code = gen_rand_string(mt_rand(5, 8));
|
|
|
4c79b5 |
$confirm_id = md5(unique_id($user->ip));
|
|
|
4c79b5 |
$seed = hexdec(substr(unique_id(), 4, 10));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// compute $seed % 0x7fffffff
|
|
|
4c79b5 |
$seed -= 0x7fffffff * floor($seed / 0x7fffffff);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql = 'INSERT INTO ' . CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array(
|
|
|
4c79b5 |
'confirm_id' => (string) $confirm_id,
|
|
|
4c79b5 |
'session_id' => (string) $user->session_id,
|
|
|
4c79b5 |
'confirm_type' => (int) CONFIRM_LOGIN,
|
|
|
4c79b5 |
'code' => (string) $code,
|
|
|
4c79b5 |
'seed' => (int) $seed)
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'S_CONFIRM_CODE' => true,
|
|
|
4c79b5 |
'CONFIRM_ID' => $confirm_id,
|
|
|
4c79b5 |
'CONFIRM_IMAGE' => '',
|
|
|
4c79b5 |
'L_LOGIN_CONFIRM_EXPLAIN' => sprintf($user->lang['LOGIN_CONFIRM_EXPLAIN'], '', ''),
|
|
|
4c79b5 |
));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$err = $user->lang[$result['error_msg']];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case LOGIN_ERROR_PASSWORD_CONVERT:
|
|
|
4c79b5 |
$err = sprintf(
|
|
|
4c79b5 |
$user->lang[$result['error_msg']],
|
|
|
4c79b5 |
($config['email_enable']) ? '' : '',
|
|
|
4c79b5 |
($config['email_enable']) ? '' : '',
|
|
|
4c79b5 |
($config['board_contact']) ? '' : '',
|
|
|
4c79b5 |
($config['board_contact']) ? '' : ''
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Username, password, etc...
|
|
|
4c79b5 |
default:
|
|
|
4c79b5 |
$err = $user->lang[$result['error_msg']];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Assign admin contact to some error messages
|
|
|
4c79b5 |
if ($result['error_msg'] == 'LOGIN_ERROR_USERNAME' || $result['error_msg'] == 'LOGIN_ERROR_PASSWORD')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$err = (!$config['board_contact']) ? sprintf($user->lang[$result['error_msg']], '', '') : sprintf($user->lang[$result['error_msg']], '', '');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$redirect)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// We just use what the session code determined...
|
|
|
4c79b5 |
// If we are not within the admin directory we use the page dir...
|
|
|
4c79b5 |
$redirect = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$admin)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$redirect .= ($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$redirect .= $user->page['page_name'] . (($user->page['query_string']) ? '?' . htmlspecialchars($user->page['query_string']) : '');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Assign credential for username/password pair
|
|
|
4c79b5 |
$credential = ($admin) ? md5(unique_id()) : false;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$s_hidden_fields = array(
|
|
|
4c79b5 |
'redirect' => $redirect,
|
|
|
4c79b5 |
'sid' => $user->session_id,
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($admin)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$s_hidden_fields['credential'] = $credential;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$s_hidden_fields = build_hidden_fields($s_hidden_fields);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'LOGIN_ERROR' => $err,
|
|
|
4c79b5 |
'LOGIN_EXPLAIN' => $l_explain,
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'U_SEND_PASSWORD' => ($config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=sendpassword') : '',
|
|
|
4c79b5 |
'U_RESEND_ACTIVATION' => ($config['require_activation'] != USER_ACTIVATION_NONE && $config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=resend_act') : '',
|
|
|
4c79b5 |
'U_TERMS_USE' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=terms'),
|
|
|
4c79b5 |
'U_PRIVACY' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=privacy'),
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'S_DISPLAY_FULL_LOGIN' => ($s_display) ? true : false,
|
|
|
4c79b5 |
'S_LOGIN_ACTION' => (!$admin) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') : append_sid("index.$phpEx", false, true, $user->session_id), // Needs to stay index.$phpEx because we are within the admin directory
|
|
|
4c79b5 |
'S_HIDDEN_FIELDS' => $s_hidden_fields,
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'S_ADMIN_AUTH' => $admin,
|
|
|
4c79b5 |
'USERNAME' => ($admin) ? $user->data['username'] : '',
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'USERNAME_CREDENTIAL' => 'username',
|
|
|
4c79b5 |
'PASSWORD_CREDENTIAL' => ($admin) ? 'password_' . $credential : 'password',
|
|
|
4c79b5 |
));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
page_header($user->lang['LOGIN'], false);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->set_filenames(array(
|
|
|
4c79b5 |
'body' => 'login_body.html')
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
make_jumpbox(append_sid("{$phpbb_root_path}viewforum.$phpEx"));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
page_footer();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Generate forum login box
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function login_forum_box($forum_data)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $config, $user, $template, $phpEx;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$password = request_var('password', '', true);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql = 'SELECT forum_id
|
|
|
4c79b5 |
FROM ' . FORUMS_ACCESS_TABLE . '
|
|
|
4c79b5 |
WHERE forum_id = ' . $forum_data['forum_id'] . '
|
|
|
4c79b5 |
AND user_id = ' . $user->data['user_id'] . "
|
|
|
4c79b5 |
AND session_id = '" . $db->sql_escape($user->session_id) . "'";
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
$row = $db->sql_fetchrow($result);
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($row)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($password)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Remove expired authorised sessions
|
|
|
4c79b5 |
$sql = 'SELECT f.session_id
|
|
|
4c79b5 |
FROM ' . FORUMS_ACCESS_TABLE . ' f
|
|
|
4c79b5 |
LEFT JOIN ' . SESSIONS_TABLE . ' s ON (f.session_id = s.session_id)
|
|
|
4c79b5 |
WHERE s.session_id IS NULL';
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($row = $db->sql_fetchrow($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql_in = array();
|
|
|
4c79b5 |
do
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql_in[] = (string) $row['session_id'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
while ($row = $db->sql_fetchrow($result));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Remove expired sessions
|
|
|
4c79b5 |
$sql = 'DELETE FROM ' . FORUMS_ACCESS_TABLE . '
|
|
|
4c79b5 |
WHERE ' . $db->sql_in_set('session_id', $sql_in);
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (phpbb_check_hash($password, $forum_data['forum_password']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql_ary = array(
|
|
|
4c79b5 |
'forum_id' => (int) $forum_data['forum_id'],
|
|
|
4c79b5 |
'user_id' => (int) $user->data['user_id'],
|
|
|
4c79b5 |
'session_id' => (string) $user->session_id,
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$db->sql_query('INSERT INTO ' . FORUMS_ACCESS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_var('LOGIN_ERROR', $user->lang['WRONG_PASSWORD']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
page_header($user->lang['LOGIN']);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'S_HIDDEN_FIELDS' => build_hidden_fields(array('f' => $forum_data['forum_id'])))
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->set_filenames(array(
|
|
|
4c79b5 |
'body' => 'login_forum.html')
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
page_footer();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Little helpers
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Little helper for the build_hidden_fields function
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function _build_hidden_fields($key, $value, $specialchar, $stripslashes)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$hidden_fields = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!is_array($value))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$value = ($stripslashes) ? stripslashes($value) : $value;
|
|
|
4c79b5 |
$value = ($specialchar) ? htmlspecialchars($value, ENT_COMPAT, 'UTF-8') : $value;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$hidden_fields .= '<input type="hidden" name="' . $key . '" value="' . $value . '" />' . "\n";
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
foreach ($value as $_key => $_value)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$_key = ($stripslashes) ? stripslashes($_key) : $_key;
|
|
|
4c79b5 |
$_key = ($specialchar) ? htmlspecialchars($_key, ENT_COMPAT, 'UTF-8') : $_key;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$hidden_fields .= _build_hidden_fields($key . '[' . $_key . ']', $_value, $specialchar, $stripslashes);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $hidden_fields;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Build simple hidden fields from array
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @param array $field_ary an array of values to build the hidden field from
|
|
|
4c79b5 |
* @param bool $specialchar if true, keys and values get specialchared
|
|
|
4c79b5 |
* @param bool $stripslashes if true, keys and values get stripslashed
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @return string the hidden fields
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function build_hidden_fields($field_ary, $specialchar = false, $stripslashes = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$s_hidden_fields = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($field_ary as $name => $vars)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$name = ($stripslashes) ? stripslashes($name) : $name;
|
|
|
4c79b5 |
$name = ($specialchar) ? htmlspecialchars($name, ENT_COMPAT, 'UTF-8') : $name;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$s_hidden_fields .= _build_hidden_fields($name, $vars, $specialchar, $stripslashes);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $s_hidden_fields;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Parse cfg file
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function parse_cfg_file($filename, $lines = false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$parsed_items = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($lines === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$lines = file($filename);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($lines as $line)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$line = trim($line);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$line || $line[0] == '#' || ($delim_pos = strpos($line, '=')) === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
continue;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Determine first occurrence, since in values the equal sign is allowed
|
|
|
4c79b5 |
$key = strtolower(trim(substr($line, 0, $delim_pos)));
|
|
|
4c79b5 |
$value = trim(substr($line, $delim_pos + 1));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (in_array($value, array('off', 'false', '0')))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$value = false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (in_array($value, array('on', 'true', '1')))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$value = true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (!trim($value))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$value = '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (($value[0] == "'" && $value[sizeof($value) - 1] == "'") || ($value[0] == '"' && $value[sizeof($value) - 1] == '"'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$value = substr($value, 1, sizeof($value)-2);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$parsed_items[$key] = $value;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $parsed_items;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Add log event
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function add_log()
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$args = func_get_args();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$mode = array_shift($args);
|
|
|
4c79b5 |
$reportee_id = ($mode == 'user') ? intval(array_shift($args)) : '';
|
|
|
4c79b5 |
$forum_id = ($mode == 'mod') ? intval(array_shift($args)) : '';
|
|
|
4c79b5 |
$topic_id = ($mode == 'mod') ? intval(array_shift($args)) : '';
|
|
|
4c79b5 |
$action = array_shift($args);
|
|
|
4c79b5 |
$data = (!sizeof($args)) ? '' : serialize($args);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql_ary = array(
|
|
|
4c79b5 |
'user_id' => (empty($user->data)) ? ANONYMOUS : $user->data['user_id'],
|
|
|
4c79b5 |
'log_ip' => $user->ip,
|
|
|
4c79b5 |
'log_time' => time(),
|
|
|
4c79b5 |
'log_operation' => $action,
|
|
|
4c79b5 |
'log_data' => $data,
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
switch ($mode)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case 'admin':
|
|
|
4c79b5 |
$sql_ary['log_type'] = LOG_ADMIN;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'mod':
|
|
|
4c79b5 |
$sql_ary += array(
|
|
|
4c79b5 |
'log_type' => LOG_MOD,
|
|
|
4c79b5 |
'forum_id' => $forum_id,
|
|
|
4c79b5 |
'topic_id' => $topic_id
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'user':
|
|
|
4c79b5 |
$sql_ary += array(
|
|
|
4c79b5 |
'log_type' => LOG_USERS,
|
|
|
4c79b5 |
'reportee_id' => $reportee_id
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'critical':
|
|
|
4c79b5 |
$sql_ary['log_type'] = LOG_CRITICAL;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
default:
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$db->sql_query('INSERT INTO ' . LOG_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $db->sql_nextid();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Return a nicely formatted backtrace (parts from the php manual by diz at ysagoon dot com)
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function get_backtrace()
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $phpbb_root_path;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$output = '';
|
|
|
4c79b5 |
$backtrace = debug_backtrace();
|
|
|
4c79b5 |
$path = phpbb_realpath($phpbb_root_path);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($backtrace as $number => $trace)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// We skip the first one, because it only shows this file/function
|
|
|
4c79b5 |
if ($number == 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
continue;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Strip the current directory from path
|
|
|
4c79b5 |
if (empty($trace['file']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$trace['file'] = '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$trace['file'] = str_replace(array($path, '\\'), array('', '/'), $trace['file']);
|
|
|
4c79b5 |
$trace['file'] = substr($trace['file'], 1);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$args = array();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// If include/require/include_once is not called, do not show arguments - they may contain sensible information
|
|
|
4c79b5 |
if (!in_array($trace['function'], array('include', 'require', 'include_once')))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
unset($trace['args']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Path...
|
|
|
4c79b5 |
if (!empty($trace['args'][0]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$argument = htmlspecialchars($trace['args'][0]);
|
|
|
4c79b5 |
$argument = str_replace(array($path, '\\'), array('', '/'), $argument);
|
|
|
4c79b5 |
$argument = substr($argument, 1);
|
|
|
4c79b5 |
$args[] = "'{$argument}'";
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$trace['class'] = (!isset($trace['class'])) ? '' : $trace['class'];
|
|
|
4c79b5 |
$trace['type'] = (!isset($trace['type'])) ? '' : $trace['type'];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$output .= ' ';
|
|
|
4c79b5 |
$output .= 'FILE: ' . htmlspecialchars($trace['file']) . ' ';
|
|
|
4c79b5 |
$output .= 'LINE: ' . ((!empty($trace['line'])) ? $trace['line'] : '') . ' ';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$output .= 'CALL: ' . htmlspecialchars($trace['class'] . $trace['type'] . $trace['function']) . '(' . ((sizeof($args)) ? implode(', ', $args) : '') . ') ';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$output .= '';
|
|
|
4c79b5 |
return $output;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* This function returns a regular expression pattern for commonly used expressions
|
|
|
4c79b5 |
* Use with / as delimiter for email mode and # for url modes
|
|
|
4c79b5 |
* mode can be: email|bbcode_htm|url|url_inline|www_url|www_url_inline|relative_url|relative_url_inline|ipv4|ipv6
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function get_preg_expression($mode)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
switch ($mode)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case 'email':
|
|
|
4c79b5 |
return '(?:[a-z0-9\'\.\-_\+\|]++|&)+@[a-z0-9\-]+\.(?:[a-z0-9\-]+\.)*[a-z]+';
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'bbcode_htm':
|
|
|
4c79b5 |
return array(
|
|
|
4c79b5 |
'#.*?#',
|
|
|
4c79b5 |
'#.*?#',
|
|
|
4c79b5 |
'#.*?#',
|
|
|
4c79b5 |
'#
|
|
|
4c79b5 |
'##s',
|
|
|
4c79b5 |
'#<.*?>#s',
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Whoa these look impressive!
|
|
|
4c79b5 |
// The code to generate the following two regular expressions which match valid IPv4/IPv6 addresses
|
|
|
4c79b5 |
// can be found in the develop directory
|
|
|
4c79b5 |
case 'ipv4':
|
|
|
4c79b5 |
return '#^(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$#';
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'ipv6':
|
|
|
4c79b5 |
return '#^(?:(?:(?:[\dA-F]{1,4}:){6}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:::(?:[\dA-F]{1,4}:){5}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:):(?:[\dA-F]{1,4}:){4}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,2}:(?:[\dA-F]{1,4}:){3}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,3}:(?:[\dA-F]{1,4}:){2}(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,4}:(?:[\dA-F]{1,4}:)(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,5}:(?:[\dA-F]{1,4}:[\dA-F]{1,4}|(?:(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.){3}(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])))|(?:(?:[\dA-F]{1,4}:){1,6}:[\dA-F]{1,4})|(?:(?:[\dA-F]{1,4}:){1,7}:))$#i';
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'url':
|
|
|
4c79b5 |
case 'url_inline':
|
|
|
4c79b5 |
$inline = ($mode == 'url') ? ')' : '';
|
|
|
4c79b5 |
$scheme = ($mode == 'url') ? '[a-z\d+\-.]' : '[a-z\d+]'; // avoid automatic parsing of "word" in "last word.http://..."
|
|
|
4c79b5 |
// generated with regex generation file in the develop folder
|
|
|
4c79b5 |
return "[a-z]$scheme*:/{2}(?:(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?";
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'www_url':
|
|
|
4c79b5 |
case 'www_url_inline':
|
|
|
4c79b5 |
$inline = ($mode == 'www_url') ? ')' : '';
|
|
|
4c79b5 |
return "www\.(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?";
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 'relative_url':
|
|
|
4c79b5 |
case 'relative_url_inline':
|
|
|
4c79b5 |
$inline = ($mode == 'relative_url') ? ')' : '';
|
|
|
4c79b5 |
return "(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[a-z0-9\-._~!$&'($inline*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[a-z0-9\-._~!$&'($inline*+,;=:@/?|]+|%[\dA-F]{2})*)?";
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Returns the first block of the specified IPv6 address and as many additional
|
|
|
4c79b5 |
* ones as specified in the length paramater.
|
|
|
4c79b5 |
* If length is zero, then an empty string is returned.
|
|
|
4c79b5 |
* If length is greater than 3 the complete IP will be returned
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function short_ipv6($ip, $length)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($length < 1)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// extend IPv6 addresses
|
|
|
4c79b5 |
$blocks = substr_count($ip, ':') + 1;
|
|
|
4c79b5 |
if ($blocks < 9)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$ip = str_replace('::', ':' . str_repeat('0000:', 9 - $blocks), $ip);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
if ($ip[0] == ':')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$ip = '0000' . $ip;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
if ($length < 4)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$ip = implode(':', array_slice(explode(':', $ip), 0, 1 + $length));
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $ip;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Wrapper for php's checkdnsrr function.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* The windows failover is from the php manual
|
|
|
4c79b5 |
* Please make sure to check the return value for === true and === false, since NULL could
|
|
|
4c79b5 |
* be returned too.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* @return true if entry found, false if not, NULL if this function is not supported by this environment
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function phpbb_checkdnsrr($host, $type = '')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$type = (!$type) ? 'MX' : $type;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (DIRECTORY_SEPARATOR == '\\')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (!function_exists('exec'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return NULL;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// @exec('nslookup -retry=1 -timout=1 -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host), $output);
|
|
|
4c79b5 |
@exec('nslookup -type=' . escapeshellarg($type) . ' ' . escapeshellarg($host) . '.', $output);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// If output is empty, the nslookup failed
|
|
|
4c79b5 |
if (empty($output))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return NULL;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($output as $line)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (!trim($line))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
continue;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Valid records begin with host name:
|
|
|
4c79b5 |
if (strpos($line, $host) === 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (function_exists('checkdnsrr'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// The dot indicates to search the DNS root (helps those having DNS prefixes on the same domain)
|
|
|
4c79b5 |
return (checkdnsrr($host . '.', $type)) ? true : false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return NULL;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Handler, header and footer
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Error and message handler, call with trigger_error if reqd
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function msg_handler($errno, $msg_text, $errfile, $errline)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $cache, $db, $auth, $template, $config, $user;
|
|
|
4c79b5 |
global $phpEx, $phpbb_root_path, $msg_title, $msg_long_text;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Do not display notices if we suppress them via @
|
|
|
4c79b5 |
if (error_reporting() == 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Message handler is stripping text. In case we need it, we are possible to define long text...
|
|
|
4c79b5 |
if (isset($msg_long_text) && $msg_long_text && !$msg_text)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$msg_text = $msg_long_text;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
switch ($errno)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case E_NOTICE:
|
|
|
4c79b5 |
case E_WARNING:
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Check the error reporting level and return if the error level does not match
|
|
|
4c79b5 |
// If DEBUG is defined the default level is E_ALL
|
|
|
4c79b5 |
if (($errno & ((defined('DEBUG')) ? E_ALL : error_reporting())) == 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (strpos($errfile, 'cache') === false && strpos($errfile, 'template.') === false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// flush the content, else we get a white page if output buffering is on
|
|
|
4c79b5 |
if ((int) @ini_get('output_buffering') === 1 || strtolower(@ini_get('output_buffering')) === 'on')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
@ob_flush();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Another quick fix for those having gzip compression enabled, but do not flush if the coder wants to catch "something". ;)
|
|
|
4c79b5 |
if (!empty($config['gzip_compress']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (@extension_loaded('zlib') && !headers_sent() && !ob_get_level())
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
@ob_flush();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// remove complete path to installation, with the risk of changing backslashes meant to be there
|
|
|
4c79b5 |
$errfile = str_replace(array(phpbb_realpath($phpbb_root_path), '\\'), array('', '/'), $errfile);
|
|
|
4c79b5 |
$msg_text = str_replace(array(phpbb_realpath($phpbb_root_path), '\\'), array('', '/'), $msg_text);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
echo '[phpBB Debug] PHP Notice: in file ' . $errfile . ' on line ' . $errline . ': ' . $msg_text . ' ' . "\n";
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case E_USER_ERROR:
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!empty($user) && !empty($user->lang))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$msg_text = (!empty($user->lang[$msg_text])) ? $user->lang[$msg_text] : $msg_text;
|
|
|
4c79b5 |
$msg_title = (!isset($msg_title)) ? $user->lang['GENERAL_ERROR'] : ((!empty($user->lang[$msg_title])) ? $user->lang[$msg_title] : $msg_title);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$l_return_index = sprintf($user->lang['RETURN_INDEX'], '', '');
|
|
|
4c79b5 |
$l_notify = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!empty($config['board_contact']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_notify = '' . sprintf($user->lang['NOTIFY_ADMIN_EMAIL'], $config['board_contact']) . ' ';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$msg_title = 'General Error';
|
|
|
4c79b5 |
$l_return_index = 'Return to index page';
|
|
|
4c79b5 |
$l_notify = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!empty($config['board_contact']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_notify = 'Please notify the board administrator or webmaster: ' . $config['board_contact'] . ' ';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
garbage_collection();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Try to not call the adm page data...
|
|
|
4c79b5 |
|
|
|
4c79b5 |
echo '';
|
|
|
4c79b5 |
echo '<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr">';
|
|
|
4c79b5 |
echo '<head>';
|
|
|
4c79b5 |
echo '<meta http-equiv="content-type" content="text/html; charset=utf-8" />';
|
|
|
4c79b5 |
echo '<title>' . $msg_title . '</title>';
|
|
|
4c79b5 |
echo '<style type="text/css">' . "\n" . '/*
|
|
|
4c79b5 |
echo '* { margin: 0; padding: 0; } html { font-size: 100%; height: 100%; margin-bottom: 1px; background-color: #E4EDF0; } body { font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif; color: #536482; background: #E4EDF0; font-size: 62.5%; margin: 0; } ';
|
|
|
4c79b5 |
echo 'a:link, a:active, a:visited { color: #006699; text-decoration: none; } a:hover { color: #DD6900; text-decoration: underline; } ';
|
|
|
4c79b5 |
echo '#wrap { padding: 0 20px 15px 20px; min-width: 615px; } #page-header { text-align: right; height: 40px; } #page-footer { clear: both; font-size: 1em; text-align: center; } ';
|
|
|
4c79b5 |
echo '.panel { margin: 4px 0; background-color: #FFFFFF; border: solid 1px #A9B8C2; } ';
|
|
|
4c79b5 |
echo '#errorpage #page-header a { font-weight: bold; line-height: 6em; } #errorpage #content { padding: 10px; } #errorpage #content h1 { line-height: 1.2em; margin-bottom: 0; color: #DF075C; } ';
|
|
|
4c79b5 |
echo '#errorpage #content div { margin-top: 20px; margin-bottom: 5px; border-bottom: 1px solid #CCCCCC; padding-bottom: 5px; color: #333333; font: bold 1.2em "Lucida Grande", Arial, Helvetica, sans-serif; text-decoration: none; line-height: 120%; text-align: left; } ';
|
|
|
4c79b5 |
echo "\n" . '/* ]]> */' . "\n";
|
|
|
4c79b5 |
echo '</style>';
|
|
|
4c79b5 |
echo '</head>';
|
|
|
4c79b5 |
echo '<body id="errorpage">';
|
|
|
4c79b5 |
echo '';
|
|
|
4c79b5 |
echo '
|
|
|
4c79b5 |
echo ' ' . $l_return_index;
|
|
|
4c79b5 |
echo ' ';
|
|
|
4c79b5 |
echo ' ';
|
|
|
4c79b5 |
echo ' ';
|
|
|
4c79b5 |
echo ' ';
|
|
|
4c79b5 |
echo ' ' . $msg_title . '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
echo ' ' . $msg_text . ' ';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
echo $l_notify;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
echo ' ';
|
|
|
4c79b5 |
echo ' ';
|
|
|
4c79b5 |
echo ' ';
|
|
|
4c79b5 |
echo '
|
|
|
4c79b5 |
echo ' Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group';
|
|
|
4c79b5 |
echo ' ';
|
|
|
4c79b5 |
echo '';
|
|
|
4c79b5 |
echo '</body>';
|
|
|
4c79b5 |
echo '</html>';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
exit_handler();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// On a fatal error (and E_USER_ERROR *is* fatal) we never want other scripts to continue and force an exit here.
|
|
|
4c79b5 |
exit;
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case E_USER_WARNING:
|
|
|
4c79b5 |
case E_USER_NOTICE:
|
|
|
4c79b5 |
|
|
|
4c79b5 |
define('IN_ERROR_HANDLER', true);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (empty($user->data))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user->session_begin();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// We re-init the auth array to get correct results on login/logout
|
|
|
4c79b5 |
$auth->acl($user->data);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (empty($user->lang))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user->setup();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$msg_text = (!empty($user->lang[$msg_text])) ? $user->lang[$msg_text] : $msg_text;
|
|
|
4c79b5 |
$msg_title = (!isset($msg_title)) ? $user->lang['INFORMATION'] : ((!empty($user->lang[$msg_title])) ? $user->lang[$msg_title] : $msg_title);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!defined('HEADER_INC'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
adm_page_header($msg_title);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
page_header($msg_title);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->set_filenames(array(
|
|
|
4c79b5 |
'body' => 'message_body.html')
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'MESSAGE_TITLE' => $msg_title,
|
|
|
4c79b5 |
'MESSAGE_TEXT' => $msg_text,
|
|
|
4c79b5 |
'S_USER_WARNING' => ($errno == E_USER_WARNING) ? true : false,
|
|
|
4c79b5 |
'S_USER_NOTICE' => ($errno == E_USER_NOTICE) ? true : false)
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// We do not want the cron script to be called on error messages
|
|
|
4c79b5 |
define('IN_CRON', true);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (defined('IN_ADMIN') && isset($user->data['session_admin']) && $user->data['session_admin'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
adm_page_footer();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
page_footer();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
exit_handler();
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// If we notice an error not handled here we pass this back to PHP by returning false
|
|
|
4c79b5 |
// This may not work for all php versions
|
|
|
4c79b5 |
return false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Queries the session table to get information about online guests
|
|
|
4c79b5 |
* @param int $forum_id Limits the search to the forum with this id
|
|
|
4c79b5 |
* @return int The number of active distinct guest sessions
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function obtain_guest_count($forum_id = 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $config;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($forum_id)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$reading_sql = ' AND s.session_forum_id = ' . (int) $forum_id;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$reading_sql = '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$time = (time() - (intval($config['load_online_time']) * 60));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Get number of online guests
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($db->sql_layer === 'sqlite')
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'SELECT COUNT(session_ip) as num_guests
|
|
|
4c79b5 |
FROM (
|
|
|
4c79b5 |
SELECT DISTINCT s.session_ip
|
|
|
4c79b5 |
FROM ' . SESSIONS_TABLE . ' s
|
|
|
4c79b5 |
WHERE s.session_user_id = ' . ANONYMOUS . '
|
|
|
4c79b5 |
AND s.session_time >= ' . ($time - ((int) ($time % 60))) .
|
|
|
4c79b5 |
$reading_sql .
|
|
|
4c79b5 |
')';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'SELECT COUNT(DISTINCT s.session_ip) as num_guests
|
|
|
4c79b5 |
FROM ' . SESSIONS_TABLE . ' s
|
|
|
4c79b5 |
WHERE s.session_user_id = ' . ANONYMOUS . '
|
|
|
4c79b5 |
AND s.session_time >= ' . ($time - ((int) ($time % 60))) .
|
|
|
4c79b5 |
$reading_sql;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$result = $db->sql_query($sql, 60);
|
|
|
4c79b5 |
$guests_online = (int) $db->sql_fetchfield('num_guests');
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $guests_online;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Queries the session table to get information about online users
|
|
|
4c79b5 |
* @param int $forum_id Limits the search to the forum with this id
|
|
|
4c79b5 |
* @return array An array containing the ids of online, hidden and visible users, as well as statistical info
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function obtain_users_online($forum_id = 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $config, $user;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$reading_sql = '';
|
|
|
4c79b5 |
if ($forum_id !== 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$reading_sql = ' AND s.session_forum_id = ' . (int) $forum_id;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$online_users = array(
|
|
|
4c79b5 |
'online_users' => array(),
|
|
|
4c79b5 |
'hidden_users' => array(),
|
|
|
4c79b5 |
'total_online' => 0,
|
|
|
4c79b5 |
'visible_online' => 0,
|
|
|
4c79b5 |
'hidden_online' => 0,
|
|
|
4c79b5 |
'guests_online' => 0,
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($config['load_online_guests'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$online_users['guests_online'] = obtain_guest_count($forum_id);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// a little discrete magic to cache this for 30 seconds
|
|
|
4c79b5 |
$time = (time() - (intval($config['load_online_time']) * 60));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$sql = 'SELECT s.session_user_id, s.session_ip, s.session_viewonline
|
|
|
4c79b5 |
FROM ' . SESSIONS_TABLE . ' s
|
|
|
4c79b5 |
WHERE s.session_time >= ' . ($time - ((int) ($time % 30))) .
|
|
|
4c79b5 |
$reading_sql .
|
|
|
4c79b5 |
' AND s.session_user_id <> ' . ANONYMOUS;
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
while ($row = $db->sql_fetchrow($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Skip multiple sessions for one user
|
|
|
4c79b5 |
if (!isset($online_users['online_users'][$row['session_user_id']]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$online_users['online_users'][$row['session_user_id']] = (int) $row['session_user_id'];
|
|
|
4c79b5 |
if ($row['session_viewonline'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$online_users['visible_online']++;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$online_users['hidden_users'][$row['session_user_id']] = (int) $row['session_user_id'];
|
|
|
4c79b5 |
$online_users['hidden_online']++;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$online_users['total_online'] = $online_users['guests_online'] + $online_users['visible_online'] + $online_users['hidden_online'];
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return $online_users;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Uses the result of obtain_users_online to generate a localized, readable representation.
|
|
|
4c79b5 |
* @param mixed $online_users result of obtain_users_online - array with user_id lists for total, hidden and visible users, and statistics
|
|
|
4c79b5 |
* @param int $forum_id Indicate that the data is limited to one forum and not global.
|
|
|
4c79b5 |
* @return array An array containing the string for output to the template
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function obtain_users_online_string($online_users, $forum_id = 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $config, $db, $user, $auth;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$user_online_link = $online_userlist = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (sizeof($online_users['online_users']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'SELECT username, username_clean, user_id, user_type, user_allow_viewonline, user_colour
|
|
|
4c79b5 |
FROM ' . USERS_TABLE . '
|
|
|
4c79b5 |
WHERE ' . $db->sql_in_set('user_id', $online_users['online_users']) . '
|
|
|
4c79b5 |
ORDER BY username_clean ASC';
|
|
|
4c79b5 |
$result = $db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
while ($row = $db->sql_fetchrow($result))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// User is logged in and therefore not a guest
|
|
|
4c79b5 |
if ($row['user_id'] != ANONYMOUS)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (isset($online_users['hidden_users'][$row['user_id']]))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$row['username'] = '' . $row['username'] . '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user_online_link = get_username_string(($row['user_type'] <> USER_IGNORE) ? 'full' : 'no_profile', $row['user_id'], $row['username'], $row['user_colour']);
|
|
|
4c79b5 |
$online_userlist .= ($online_userlist != '') ? ', ' . $user_online_link : $user_online_link;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
$db->sql_freeresult($result);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$online_userlist)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$online_userlist = $user->lang['NO_ONLINE_USERS'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($forum_id === 0)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$online_userlist = $user->lang['REGISTERED_USERS'] . ' ' . $online_userlist;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if ($config['load_online_guests'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_online = ($online_users['guests_online'] === 1) ? $user->lang['BROWSING_FORUM_GUEST'] : $user->lang['BROWSING_FORUM_GUESTS'];
|
|
|
4c79b5 |
$online_userlist = sprintf($l_online, $online_userlist, $online_users['guests_online']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$online_userlist = sprintf($user->lang['BROWSING_FORUM'], $online_userlist);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
// Build online listing
|
|
|
4c79b5 |
$vars_online = array(
|
|
|
4c79b5 |
'ONLINE' => array('total_online', 'l_t_user_s', 0),
|
|
|
4c79b5 |
'REG' => array('visible_online', 'l_r_user_s', !$config['load_online_guests']),
|
|
|
4c79b5 |
'HIDDEN' => array('hidden_online', 'l_h_user_s', $config['load_online_guests']),
|
|
|
4c79b5 |
'GUEST' => array('guests_online', 'l_g_user_s', 0)
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
foreach ($vars_online as $l_prefix => $var_ary)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($var_ary[2])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_suffix = '_AND';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_suffix = '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
switch ($online_users[$var_ary[0]])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
case 0:
|
|
|
4c79b5 |
${$var_ary[1]} = $user->lang[$l_prefix . '_USERS_ZERO_TOTAL' . $l_suffix];
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
case 1:
|
|
|
4c79b5 |
${$var_ary[1]} = $user->lang[$l_prefix . '_USER_TOTAL' . $l_suffix];
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
default:
|
|
|
4c79b5 |
${$var_ary[1]} = $user->lang[$l_prefix . '_USERS_TOTAL' . $l_suffix];
|
|
|
4c79b5 |
break;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
unset($vars_online);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$l_online_users = sprintf($l_t_user_s, $online_users['total_online']);
|
|
|
4c79b5 |
$l_online_users .= sprintf($l_r_user_s, $online_users['visible_online']);
|
|
|
4c79b5 |
$l_online_users .= sprintf($l_h_user_s, $online_users['hidden_online']);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($config['load_online_guests'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_online_users .= sprintf($l_g_user_s, $online_users['guests_online']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return array(
|
|
|
4c79b5 |
'online_userlist' => $online_userlist,
|
|
|
4c79b5 |
'l_online_users' => $l_online_users,
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Generate page header
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function page_header($page_title = '', $display_online_list = true)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $config, $template, $SID, $_SID, $user, $auth, $phpEx, $phpbb_root_path;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (defined('HEADER_INC'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
define('HEADER_INC', true);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// gzip_compression
|
|
|
4c79b5 |
if ($config['gzip_compress'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (@extension_loaded('zlib') && !headers_sent())
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
ob_start('ob_gzhandler');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Generate logged in/logged out status
|
|
|
4c79b5 |
if ($user->data['user_id'] != ANONYMOUS)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=logout', true, $user->session_id);
|
|
|
4c79b5 |
$l_login_logout = sprintf($user->lang['LOGOUT_USER'], $user->data['username']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login');
|
|
|
4c79b5 |
$l_login_logout = $user->lang['LOGIN'];
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Last visit date/time
|
|
|
4c79b5 |
$s_last_visit = ($user->data['user_id'] != ANONYMOUS) ? $user->format_date($user->data['session_last_visit']) : '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Get users online list ... if required
|
|
|
4c79b5 |
$l_online_users = $online_userlist = $l_online_record = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($config['load_online'] && $config['load_online_time'] && $display_online_list)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$f = request_var('f', 0);
|
|
|
4c79b5 |
$f = max($f, 0);
|
|
|
4c79b5 |
$online_users = obtain_users_online($f);
|
|
|
4c79b5 |
$user_online_strings = obtain_users_online_string($online_users, $f);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$l_online_users = $user_online_strings['l_online_users'];
|
|
|
4c79b5 |
$online_userlist = $user_online_strings['online_userlist'];
|
|
|
4c79b5 |
$total_online_users = $online_users['total_online'];
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($total_online_users > $config['record_online_users'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
set_config('record_online_users', $total_online_users, true);
|
|
|
4c79b5 |
set_config('record_online_date', time(), true);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$l_online_record = sprintf($user->lang['RECORD_ONLINE_USERS'], $config['record_online_users'], $user->format_date($config['record_online_date']));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$l_online_time = ($config['load_online_time'] == 1) ? 'VIEW_ONLINE_TIME' : 'VIEW_ONLINE_TIMES';
|
|
|
4c79b5 |
$l_online_time = sprintf($user->lang[$l_online_time], $config['load_online_time']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_online_time = '';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$l_privmsgs_text = $l_privmsgs_text_unread = '';
|
|
|
4c79b5 |
$s_privmsg_new = false;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Obtain number of new private messages if user is logged in
|
|
|
4c79b5 |
if (!empty($user->data['is_registered']))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($user->data['user_new_privmsg'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_message_new = ($user->data['user_new_privmsg'] == 1) ? $user->lang['NEW_PM'] : $user->lang['NEW_PMS'];
|
|
|
4c79b5 |
$l_privmsgs_text = sprintf($l_message_new, $user->data['user_new_privmsg']);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!$user->data['user_last_privmsg'] || $user->data['user_last_privmsg'] > $user->data['session_last_visit'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$sql = 'UPDATE ' . USERS_TABLE . '
|
|
|
4c79b5 |
SET user_last_privmsg = ' . $user->data['session_last_visit'] . '
|
|
|
4c79b5 |
WHERE user_id = ' . $user->data['user_id'];
|
|
|
4c79b5 |
$db->sql_query($sql);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$s_privmsg_new = true;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$s_privmsg_new = false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_privmsgs_text = $user->lang['NO_NEW_PM'];
|
|
|
4c79b5 |
$s_privmsg_new = false;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$l_privmsgs_text_unread = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($user->data['user_unread_privmsg'] && $user->data['user_unread_privmsg'] != $user->data['user_new_privmsg'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$l_message_unread = ($user->data['user_unread_privmsg'] == 1) ? $user->lang['UNREAD_PM'] : $user->lang['UNREAD_PMS'];
|
|
|
4c79b5 |
$l_privmsgs_text_unread = sprintf($l_message_unread, $user->data['user_unread_privmsg']);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Which timezone?
|
|
|
4c79b5 |
$tz = ($user->data['user_id'] != ANONYMOUS) ? strval(doubleval($user->data['user_timezone'])) : strval(doubleval($config['board_timezone']));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Send a proper content-language to the output
|
|
|
4c79b5 |
$user_lang = $user->lang['USER_LANG'];
|
|
|
4c79b5 |
if (strpos($user_lang, '-x-') !== false)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$user_lang = substr($user_lang, 0, strpos($user_lang, '-x-'));
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// The following assigns all _common_ variables that may be used at any point in a template.
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'SITENAME' => $config['sitename'],
|
|
|
4c79b5 |
'SITE_DESCRIPTION' => $config['site_desc'],
|
|
|
4c79b5 |
'PAGE_TITLE' => $page_title,
|
|
|
4c79b5 |
'SCRIPT_NAME' => str_replace('.' . $phpEx, '', $user->page['page_name']),
|
|
|
4c79b5 |
'LAST_VISIT_DATE' => sprintf($user->lang['YOU_LAST_VISIT'], $s_last_visit),
|
|
|
4c79b5 |
'LAST_VISIT_YOU' => $s_last_visit,
|
|
|
4c79b5 |
'CURRENT_TIME' => sprintf($user->lang['CURRENT_TIME'], $user->format_date(time(), false, true)),
|
|
|
4c79b5 |
'TOTAL_USERS_ONLINE' => $l_online_users,
|
|
|
4c79b5 |
'LOGGED_IN_USER_LIST' => $online_userlist,
|
|
|
4c79b5 |
'RECORD_USERS' => $l_online_record,
|
|
|
4c79b5 |
'PRIVATE_MESSAGE_INFO' => $l_privmsgs_text,
|
|
|
4c79b5 |
'PRIVATE_MESSAGE_INFO_UNREAD' => $l_privmsgs_text_unread,
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'S_USER_NEW_PRIVMSG' => $user->data['user_new_privmsg'],
|
|
|
4c79b5 |
'S_USER_UNREAD_PRIVMSG' => $user->data['user_unread_privmsg'],
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'SID' => $SID,
|
|
|
4c79b5 |
'_SID' => $_SID,
|
|
|
4c79b5 |
'SESSION_ID' => $user->session_id,
|
|
|
4c79b5 |
'ROOT_PATH' => $phpbb_root_path,
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'L_LOGIN_LOGOUT' => $l_login_logout,
|
|
|
4c79b5 |
'L_INDEX' => $user->lang['FORUM_INDEX'],
|
|
|
4c79b5 |
'L_ONLINE_EXPLAIN' => $l_online_time,
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'U_PRIVATEMSGS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'),
|
|
|
4c79b5 |
'U_RETURN_INBOX' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&folder=inbox'),
|
|
|
4c79b5 |
'U_POPUP_PM' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=popup'),
|
|
|
4c79b5 |
'UA_POPUP_PM' => addslashes(append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=pm&mode=popup')),
|
|
|
4c79b5 |
'U_MEMBERLIST' => append_sid("{$phpbb_root_path}memberlist.$phpEx"),
|
|
|
4c79b5 |
'U_VIEWONLINE' => ($auth->acl_gets('u_viewprofile', 'a_user', 'a_useradd', 'a_userdel')) ? append_sid("{$phpbb_root_path}viewonline.$phpEx") : '',
|
|
|
4c79b5 |
'U_LOGIN_LOGOUT' => $u_login_logout,
|
|
|
4c79b5 |
'U_INDEX' => append_sid("{$phpbb_root_path}index.$phpEx"),
|
|
|
4c79b5 |
'U_SEARCH' => append_sid("{$phpbb_root_path}search.$phpEx"),
|
|
|
4c79b5 |
'U_REGISTER' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'),
|
|
|
4c79b5 |
'U_PROFILE' => append_sid("{$phpbb_root_path}ucp.$phpEx"),
|
|
|
4c79b5 |
'U_MODCP' => append_sid("{$phpbb_root_path}mcp.$phpEx", false, true, $user->session_id),
|
|
|
4c79b5 |
'U_FAQ' => append_sid("{$phpbb_root_path}faq.$phpEx"),
|
|
|
4c79b5 |
'U_SEARCH_SELF' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=egosearch'),
|
|
|
4c79b5 |
'U_SEARCH_NEW' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=newposts'),
|
|
|
4c79b5 |
'U_SEARCH_UNANSWERED' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=unanswered'),
|
|
|
4c79b5 |
'U_SEARCH_ACTIVE_TOPICS'=> append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=active_topics'),
|
|
|
4c79b5 |
'U_DELETE_COOKIES' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=delete_cookies'),
|
|
|
4c79b5 |
'U_TEAM' => ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile')) ? '' : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=leaders'),
|
|
|
4c79b5 |
'U_RESTORE_PERMISSIONS' => ($user->data['user_perm_from'] && $auth->acl_get('a_switchperm')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=restore_perm') : '',
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'S_USER_LOGGED_IN' => ($user->data['user_id'] != ANONYMOUS) ? true : false,
|
|
|
4c79b5 |
'S_AUTOLOGIN_ENABLED' => ($config['allow_autologin']) ? true : false,
|
|
|
4c79b5 |
'S_BOARD_DISABLED' => ($config['board_disable']) ? true : false,
|
|
|
4c79b5 |
'S_REGISTERED_USER' => (!empty($user->data['is_registered'])) ? true : false,
|
|
|
4c79b5 |
'S_IS_BOT' => (!empty($user->data['is_bot'])) ? true : false,
|
|
|
4c79b5 |
'S_USER_PM_POPUP' => $user->optionget('popuppm'),
|
|
|
4c79b5 |
'S_USER_LANG' => $user_lang,
|
|
|
4c79b5 |
'S_USER_BROWSER' => (isset($user->data['session_browser'])) ? $user->data['session_browser'] : $user->lang['UNKNOWN_BROWSER'],
|
|
|
4c79b5 |
'S_USERNAME' => $user->data['username'],
|
|
|
4c79b5 |
'S_CONTENT_DIRECTION' => $user->lang['DIRECTION'],
|
|
|
4c79b5 |
'S_CONTENT_FLOW_BEGIN' => ($user->lang['DIRECTION'] == 'ltr') ? 'left' : 'right',
|
|
|
4c79b5 |
'S_CONTENT_FLOW_END' => ($user->lang['DIRECTION'] == 'ltr') ? 'right' : 'left',
|
|
|
4c79b5 |
'S_CONTENT_ENCODING' => 'UTF-8',
|
|
|
4c79b5 |
'S_TIMEZONE' => ($user->data['user_dst'] || ($user->data['user_id'] == ANONYMOUS && $config['board_dst'])) ? sprintf($user->lang['ALL_TIMES'], $user->lang['tz'][$tz], $user->lang['tz']['dst']) : sprintf($user->lang['ALL_TIMES'], $user->lang['tz'][$tz], ''),
|
|
|
4c79b5 |
'S_DISPLAY_ONLINE_LIST' => ($l_online_time) ? 1 : 0,
|
|
|
4c79b5 |
'S_DISPLAY_SEARCH' => (!$config['load_search']) ? 0 : (isset($auth) ? ($auth->acl_get('u_search') && $auth->acl_getf_global('f_search')) : 1),
|
|
|
4c79b5 |
'S_DISPLAY_PM' => ($config['allow_privmsg'] && !empty($user->data['is_registered']) && ($auth->acl_get('u_readpm') || $auth->acl_get('u_sendpm'))) ? true : false,
|
|
|
4c79b5 |
'S_DISPLAY_MEMBERLIST' => (isset($auth)) ? $auth->acl_get('u_viewprofile') : 0,
|
|
|
4c79b5 |
'S_NEW_PM' => ($s_privmsg_new) ? 1 : 0,
|
|
|
4c79b5 |
'S_REGISTER_ENABLED' => ($config['require_activation'] != USER_ACTIVATION_DISABLE) ? true : false,
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'T_THEME_PATH' => "{$phpbb_root_path}styles/" . $user->theme['theme_path'] . '/theme',
|
|
|
4c79b5 |
'T_TEMPLATE_PATH' => "{$phpbb_root_path}styles/" . $user->theme['template_path'] . '/template',
|
|
|
4c79b5 |
'T_SUPER_TEMPLATE_PATH' => (isset($user->theme['template_inherit_path']) && $user->theme['template_inherit_path']) ? "{$phpbb_root_path}styles/" . $user->theme['template_inherit_path'] . '/template' : "{$phpbb_root_path}styles/" . $user->theme['template_path'] . '/template',
|
|
|
4c79b5 |
'T_IMAGESET_PATH' => "{$phpbb_root_path}styles/" . $user->theme['imageset_path'] . '/imageset',
|
|
|
4c79b5 |
'T_IMAGESET_LANG_PATH' => "{$phpbb_root_path}styles/" . $user->theme['imageset_path'] . '/imageset/' . $user->data['user_lang'],
|
|
|
4c79b5 |
'T_IMAGES_PATH' => "{$phpbb_root_path}images/",
|
|
|
4c79b5 |
'T_SMILIES_PATH' => "{$phpbb_root_path}{$config['smilies_path']}/",
|
|
|
4c79b5 |
'T_AVATAR_PATH' => "{$phpbb_root_path}{$config['avatar_path']}/",
|
|
|
4c79b5 |
'T_AVATAR_GALLERY_PATH' => "{$phpbb_root_path}{$config['avatar_gallery_path']}/",
|
|
|
4c79b5 |
'T_ICONS_PATH' => "{$phpbb_root_path}{$config['icons_path']}/",
|
|
|
4c79b5 |
'T_RANKS_PATH' => "{$phpbb_root_path}{$config['ranks_path']}/",
|
|
|
4c79b5 |
'T_UPLOAD_PATH' => "{$phpbb_root_path}{$config['upload_path']}/",
|
|
|
4c79b5 |
'T_STYLESHEET_LINK' => (!$user->theme['theme_storedb']) ? "{$phpbb_root_path}styles/" . $user->theme['theme_path'] . '/theme/stylesheet.css' : "{$phpbb_root_path}style.$phpEx?sid=$user->session_id&id=" . $user->theme['style_id'] . '&lang=' . $user->data['user_lang'],
|
|
|
4c79b5 |
'T_STYLESHEET_NAME' => $user->theme['theme_name'],
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'SITE_LOGO_IMG' => $user->img('site_logo'),
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'A_COOKIE_SETTINGS' => addslashes('; path=' . $config['cookie_path'] . ((!$config['cookie_domain'] || $config['cookie_domain'] == 'localhost' || $config['cookie_domain'] == '127.0.0.1') ? '' : '; domain=' . $config['cookie_domain']) . ((!$config['cookie_secure']) ? '' : '; secure')),
|
|
|
4c79b5 |
));
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// application/xhtml+xml not used because of IE
|
|
|
4c79b5 |
header('Content-type: text/html; charset=UTF-8');
|
|
|
4c79b5 |
|
|
|
4c79b5 |
header('Cache-Control: private, no-cache="set-cookie"');
|
|
|
4c79b5 |
header('Expires: 0');
|
|
|
4c79b5 |
header('Pragma: no-cache');
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Generate page footer
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function page_footer($run_cron = true)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $db, $config, $template, $user, $auth, $cache, $starttime, $phpbb_root_path, $phpEx;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Output page creation time
|
|
|
4c79b5 |
if (defined('DEBUG'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$mtime = explode(' ', microtime());
|
|
|
4c79b5 |
$totaltime = $mtime[0] + $mtime[1] - $starttime;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!empty($_REQUEST['explain']) && $auth->acl_get('a_') && defined('DEBUG_EXTRA') && method_exists($db, 'sql_report'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$db->sql_report('display');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$debug_output = sprintf('Time : %.3fs | ' . $db->sql_num_queries() . ' Queries | GZIP : ' . (($config['gzip_compress']) ? 'On' : 'Off') . (($user->load) ? ' | Load : ' . $user->load : ''), $totaltime);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($auth->acl_get('a_') && defined('DEBUG_EXTRA'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if (function_exists('memory_get_usage'))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($memory_usage = memory_get_usage())
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $base_memory_usage;
|
|
|
4c79b5 |
$memory_usage -= $base_memory_usage;
|
|
|
4c79b5 |
$memory_usage = get_formatted_filesize($memory_usage);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$debug_output .= ' | Memory Usage: ' . $memory_usage;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$debug_output .= ' | Explain';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->assign_vars(array(
|
|
|
4c79b5 |
'DEBUG_OUTPUT' => (defined('DEBUG')) ? $debug_output : '',
|
|
|
4c79b5 |
'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '',
|
|
|
4c79b5 |
|
|
|
4c79b5 |
'U_ACP' => ($auth->acl_get('a_') && !empty($user->data['is_registered'])) ? append_sid("{$phpbb_root_path}adm/index.$phpEx", false, true, $user->session_id) : '')
|
|
|
4c79b5 |
);
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Call cron-type script
|
|
|
4c79b5 |
if (!defined('IN_CRON') && $run_cron && !$config['board_disable'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$cron_type = '';
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (time() - $config['queue_interval'] > $config['last_queue_run'] && !defined('IN_ADMIN') && file_exists($phpbb_root_path . 'cache/queue.' . $phpEx))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Process email queue
|
|
|
4c79b5 |
$cron_type = 'queue';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (method_exists($cache, 'tidy') && time() - $config['cache_gc'] > $config['cache_last_gc'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Tidy the cache
|
|
|
4c79b5 |
$cron_type = 'tidy_cache';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (time() - $config['warnings_gc'] > $config['warnings_last_gc'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$cron_type = 'tidy_warnings';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (time() - $config['database_gc'] > $config['database_last_gc'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Tidy the database
|
|
|
4c79b5 |
$cron_type = 'tidy_database';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (time() - $config['search_gc'] > $config['search_last_gc'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
// Tidy the search
|
|
|
4c79b5 |
$cron_type = 'tidy_search';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
else if (time() - $config['session_gc'] > $config['session_last_gc'])
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$cron_type = 'tidy_sessions';
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if ($cron_type)
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$template->assign_var('RUN_CRON_TASK', '');
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
$template->display('body');
|
|
|
4c79b5 |
|
|
|
4c79b5 |
garbage_collection();
|
|
|
4c79b5 |
exit_handler();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Closing the cache object and the database
|
|
|
4c79b5 |
* Cool function name, eh? We might want to add operations to it later
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function garbage_collection()
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $cache, $db;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Unload cache, must be done before the DB connection if closed
|
|
|
4c79b5 |
if (!empty($cache))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$cache->unload();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// Close our DB connection.
|
|
|
4c79b5 |
if (!empty($db))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
$db->sql_close();
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Handler for exit calls in phpBB.
|
|
|
4c79b5 |
* This function supports hooks.
|
|
|
4c79b5 |
*
|
|
|
4c79b5 |
* Note: This function is called after the template has been outputted.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function exit_handler()
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $phpbb_hook, $config;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($phpbb_hook->hook_return(__FUNCTION__))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $phpbb_hook->hook_return_result(__FUNCTION__);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
// As a pre-caution... some setups display a blank page if the flush() is not there.
|
|
|
4c79b5 |
(empty($config['gzip_compress'])) ? @flush() : @ob_flush();
|
|
|
4c79b5 |
|
|
|
4c79b5 |
exit;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
/**
|
|
|
4c79b5 |
* Handler for init calls in phpBB. This function is called in user::setup();
|
|
|
4c79b5 |
* This function supports hooks.
|
|
|
4c79b5 |
*/
|
|
|
4c79b5 |
function phpbb_user_session_handler()
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
global $phpbb_hook;
|
|
|
4c79b5 |
|
|
|
4c79b5 |
if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
if ($phpbb_hook->hook_return(__FUNCTION__))
|
|
|
4c79b5 |
{
|
|
|
4c79b5 |
return $phpbb_hook->hook_return_result(__FUNCTION__);
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
return;
|
|
|
4c79b5 |
}
|
|
|
4c79b5 |
|
|
|
4c79b5 |
?>
|