aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/functions.php
diff options
context:
space:
mode:
authorNils Adermann <naderman@naderman.de>2010-03-02 01:05:40 +0100
committerNils Adermann <naderman@naderman.de>2010-03-02 01:05:40 +0100
commit021c186be91095397d4e76801738373989360a52 (patch)
tree4a5b42c0ebcaeb0be77edacb839bf164fe2dadc0 /phpBB/includes/functions.php
parent4f9c3b8f5c0181c2ebf367436f3c0336d8f2251d (diff)
parent3ddedd5ff228cdcc3c0b05000affe3944afc7854 (diff)
downloadforums-021c186be91095397d4e76801738373989360a52.tar
forums-021c186be91095397d4e76801738373989360a52.tar.gz
forums-021c186be91095397d4e76801738373989360a52.tar.bz2
forums-021c186be91095397d4e76801738373989360a52.tar.xz
forums-021c186be91095397d4e76801738373989360a52.zip
Merge commit 'release-3.0.6-RC1'
Diffstat (limited to 'phpBB/includes/functions.php')
-rw-r--r--phpBB/includes/functions.php619
1 files changed, 500 insertions, 119 deletions
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 476565452c..092a5d5d86 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -71,12 +71,13 @@ function request_var($var_name, $default, $multibyte = false, $cookie = false)
$_REQUEST[$var_name] = isset($_POST[$var_name]) ? $_POST[$var_name] : $_GET[$var_name];
}
- if (!isset($_REQUEST[$var_name]) || (is_array($_REQUEST[$var_name]) && !is_array($default)) || (is_array($default) && !is_array($_REQUEST[$var_name])))
+ $super_global = ($cookie) ? '_COOKIE' : '_REQUEST';
+ if (!isset($GLOBALS[$super_global][$var_name]) || is_array($GLOBALS[$super_global][$var_name]) != is_array($default))
{
return (is_array($default)) ? array() : $default;
}
- $var = $_REQUEST[$var_name];
+ $var = $GLOBALS[$super_global][$var_name];
if (!is_array($default))
{
$type = gettype($default);
@@ -174,7 +175,7 @@ function set_config_count($config_name, $increment, $is_dynamic = false)
switch ($db->sql_layer)
{
case 'firebird':
- $sql_update = 'CAST(CAST(config_value as integer) + ' . (int) $increment . ' as CHAR)';
+ $sql_update = 'CAST(CAST(config_value as integer) + ' . (int) $increment . ' as VARCHAR(255))';
break;
case 'postgres':
@@ -231,27 +232,82 @@ function unique_id($extra = 'c')
/**
* Return formatted string for filesizes
+*
+* @param int $value filesize in bytes
+* @param bool $string_only true if language string should be returned
+* @param array $allowed_units only allow these units (data array indexes)
+*
+* @return mixed data array if $string_only is false
+* @author bantu
*/
-function get_formatted_filesize($bytes, $add_size_lang = true)
+function get_formatted_filesize($value, $string_only = true, $allowed_units = false)
{
global $user;
- if ($bytes >= pow(2, 30))
+ $available_units = array(
+ 'gb' => array(
+ 'min' => 1073741824, // pow(2, 30)
+ 'index' => 3,
+ 'si_unit' => 'GB',
+ 'iec_unit' => 'GIB',
+ ),
+ 'mb' => array(
+ 'min' => 1048576, // pow(2, 20)
+ 'index' => 2,
+ 'si_unit' => 'MB',
+ 'iec_unit' => 'MIB',
+ ),
+ 'kb' => array(
+ 'min' => 1024, // pow(2, 10)
+ 'index' => 1,
+ 'si_unit' => 'KB',
+ 'iec_unit' => 'KIB',
+ ),
+ 'b' => array(
+ 'min' => 0,
+ 'index' => 0,
+ 'si_unit' => 'BYTES', // Language index
+ 'iec_unit' => 'BYTES', // Language index
+ ),
+ );
+
+ foreach ($available_units as $si_identifier => $unit_info)
{
- return ($add_size_lang) ? round($bytes / 1024 / 1024 / 1024, 2) . ' ' . $user->lang['GIB'] : round($bytes / 1024 / 1024 / 1024, 2);
+ if (!empty($allowed_units) && $si_identifier != 'b' && !in_array($si_identifier, $allowed_units))
+ {
+ continue;
+ }
+
+ if ($value >= $unit_info['min'])
+ {
+ $unit_info['si_identifier'] = $si_identifier;
+
+ break;
+ }
}
+ unset($available_units);
- if ($bytes >= pow(2, 20))
+ for ($i = 0; $i < $unit_info['index']; $i++)
{
- return ($add_size_lang) ? round($bytes / 1024 / 1024, 2) . ' ' . $user->lang['MIB'] : round($bytes / 1024 / 1024, 2);
+ $value /= 1024;
}
+ $value = round($value, 2);
+
+ // Lookup units in language dictionary
+ $unit_info['si_unit'] = (isset($user->lang[$unit_info['si_unit']])) ? $user->lang[$unit_info['si_unit']] : $unit_info['si_unit'];
+ $unit_info['iec_unit'] = (isset($user->lang[$unit_info['iec_unit']])) ? $user->lang[$unit_info['iec_unit']] : $unit_info['iec_unit'];
- if ($bytes >= pow(2, 10))
+ // Default to IEC
+ $unit_info['unit'] = $unit_info['iec_unit'];
+
+ if (!$string_only)
{
- return ($add_size_lang) ? round($bytes / 1024, 2) . ' ' . $user->lang['KIB'] : round($bytes / 1024, 2);
+ $unit_info['value'] = $value;
+
+ return $unit_info;
}
- return ($add_size_lang) ? ($bytes) . ' ' . $user->lang['BYTES'] : ($bytes);
+ return $value . ' ' . $unit_info['unit'];
}
/**
@@ -496,6 +552,18 @@ function _hash_crypt_private($password, $setting, &$itoa64)
}
/**
+* Hashes an email address to a big integer
+*
+* @param string $email Email address
+*
+* @return string Big Integer
+*/
+function phpbb_email_hash($email)
+{
+ return crc32(strtolower($email)) . strlen($email);
+}
+
+/**
* Global function for chmodding directories and files for internal use
*
* This function determines owner and group whom the file belongs to and user and group of PHP and then set safest possible file permissions.
@@ -669,6 +737,67 @@ function phpbb_chmod($filename, $perms = CHMOD_READ)
return $result;
}
+/**
+* Test if a file/directory is writable
+*
+* This function calls the native is_writable() when not running under
+* Windows and it is not disabled.
+*
+* @param string $file Path to perform write test on
+* @return bool True when the path is writable, otherwise false.
+*/
+function phpbb_is_writable($file)
+{
+ if (strtolower(substr(PHP_OS, 0, 3)) === 'win' || !function_exists('is_writable'))
+ {
+ if (file_exists($file))
+ {
+ // Canonicalise path to absolute path
+ $file = phpbb_realpath($file);
+
+ if (is_dir($file))
+ {
+ // Test directory by creating a file inside the directory
+ $result = @tempnam($file, 'i_w');
+
+ if (is_string($result) && file_exists($result))
+ {
+ unlink($result);
+
+ // Ensure the file is actually in the directory (returned realpathed)
+ return (strpos($result, $file) === 0) ? true : false;
+ }
+ }
+ else
+ {
+ $handle = @fopen($file, 'r+');
+
+ if (is_resource($handle))
+ {
+ fclose($handle);
+ return true;
+ }
+ }
+ }
+ else
+ {
+ // file does not exist test if we can write to the directory
+ $dir = dirname($file);
+
+ if (file_exists($dir) && is_dir($dir) && phpbb_is_writable($dir))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ else
+ {
+ return is_writable($file);
+ }
+}
+
// Compatibility functions
if (!function_exists('array_combine'))
@@ -1047,7 +1176,7 @@ function tz_select($default = '', $truncate = false)
if (is_numeric($offset))
{
$selected = ($offset == $default) ? ' selected="selected"' : '';
- $tz_select .= '<option title="'.$zone.'" value="' . $offset . '"' . $selected . '>' . $zone_trunc . '</option>';
+ $tz_select .= '<option title="' . $zone . '" value="' . $offset . '"' . $selected . '>' . $zone_trunc . '</option>';
}
}
@@ -1110,7 +1239,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
}
// Add 0 to forums array to mark global announcements correctly
- $forum_id[] = 0;
+ // $forum_id[] = 0;
if ($config['load_db_lastread'] && $user->data['is_registered'])
{
@@ -1528,6 +1657,135 @@ function get_complete_topic_tracking($forum_id, $topic_ids, $global_announce_lis
}
/**
+* Get list of unread topics
+*
+* @param int $user_id User ID (or false for current user)
+* @param string $sql_extra Extra WHERE SQL statement
+* @param string $sql_sort ORDER BY SQL sorting statement
+* @param string $sql_limit Limits the size of unread topics list, 0 for unlimited query
+*
+* @return array[int][int] Topic ids as keys, mark_time of topic as value
+*/
+function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $sql_limit = 1001)
+{
+ global $config, $db, $user;
+
+ $user_id = ($user_id === false) ? (int) $user->data['user_id'] : (int) $user_id;
+
+ // Data array we're going to return
+ $unread_topics = array();
+
+ if (empty($sql_sort))
+ {
+ $sql_sort = 'ORDER BY t.topic_last_post_time DESC';
+ }
+
+ if ($config['load_db_lastread'] && $user->data['is_registered'])
+ {
+ // Get list of the unread topics
+ $last_mark = $user->data['user_lastmark'];
+
+ $sql_array = array(
+ 'SELECT' => 't.topic_id, t.topic_last_post_time, tt.mark_time as topic_mark_time, ft.mark_time as forum_mark_time',
+
+ 'FROM' => array(TOPICS_TABLE => 't'),
+
+ 'LEFT_JOIN' => array(
+ array(
+ 'FROM' => array(TOPICS_TRACK_TABLE => 'tt'),
+ 'ON' => "tt.user_id = $user_id AND t.topic_id = tt.topic_id AND tt.mark_time > $last_mark",
+ ),
+ array(
+ 'FROM' => array(FORUMS_TRACK_TABLE => 'ft'),
+ 'ON' => "ft.user_id = $user_id AND t.forum_id = ft.forum_id AND ft.mark_time > $last_mark",
+ ),
+ ),
+
+ 'WHERE' => "
+ (
+ (tt.mark_time IS NOT NULL AND t.topic_last_post_time > tt.mark_time) OR
+ (tt.mark_time IS NULL AND ft.mark_time IS NOT NULL AND t.topic_last_post_time > ft.mark_time) OR
+ (
+ ((tt.mark_time IS NULL AND ft.mark_time IS NULL) OR (tt.mark_time < $last_mark AND ft.mark_time < $last_mark))
+ AND t.topic_last_post_time > $last_mark
+ )
+ )
+ $sql_extra
+ $sql_sort",
+ );
+
+ $sql = $db->sql_build_query('SELECT', $sql_array);
+ $result = $db->sql_query_limit($sql, $sql_limit);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $topic_id = (int) $row['topic_id'];
+ $unread_topics[$topic_id] = ($row['topic_mark_time']) ? (int) $row['topic_mark_time'] : (($row['forum_mark_time']) ? (int) $row['forum_mark_time'] : $last_mark);
+ }
+ $db->sql_freeresult($result);
+ }
+ else if ($config['load_anon_lastread'] || $user->data['is_registered'])
+ {
+ global $tracking_topics;
+
+ if (empty($tracking_topics))
+ {
+ $tracking_topics = request_var($config['cookie_name'] . '_track', '', false, true);
+ $tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
+ }
+
+ if (!$user->data['is_registered'])
+ {
+ $user_lastmark = (isset($tracking_topics['l'])) ? base_convert($tracking_topics['l'], 36, 10) + $config['board_startdate'] : 0;
+ }
+ else
+ {
+ $user_lastmark = (int) $user->data['user_lastmark'];
+ }
+
+ $sql = 'SELECT t.topic_id, t.forum_id, t.topic_last_post_time
+ FROM ' . TOPICS_TABLE . ' t
+ WHERE t.topic_last_post_time > ' . $user_lastmark . "
+ $sql_extra
+ $sql_sort";
+ $result = $db->sql_query_limit($sql, $sql_limit);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $forum_id = (int) $row['forum_id'];
+ $topic_id = (int) $row['topic_id'];
+ $topic_id36 = base_convert($topic_id, 10, 36);
+
+ if (isset($tracking_topics['t'][$topic_id36]))
+ {
+ $last_read = base_convert($tracking_topics['t'][$topic_id36], 36, 10) + $config['board_startdate'];
+
+ if ($row['topic_last_post_time'] > $last_read)
+ {
+ $unread_topics[$topic_id] = $last_read;
+ }
+ }
+ else if (isset($tracking_topics['f'][$forum_id]))
+ {
+ $mark_time = base_convert($tracking_topics['f'][$forum_id], 36, 10) + $config['board_startdate'];
+
+ if ($row['topic_last_post_time'] > $mark_time)
+ {
+ $unread_topics[$topic_id] = $mark_time;
+ }
+ }
+ else
+ {
+ $unread_topics[$topic_id] = $user_lastmark;
+ }
+ }
+ $db->sql_freeresult($result);
+ }
+
+ return $unread_topics;
+}
+
+/**
* Check for read forums and update topic tracking info accordingly
*
* @param int $forum_id the forum id to check
@@ -1777,7 +2035,7 @@ function generate_pagination($base_url, $num_items, $per_page, $start_item, $add
}
$on_page = floor($start_item / $per_page) + 1;
- $url_delim = (strpos($base_url, '?') === false) ? '?' : '&amp;';
+ $url_delim = (strpos($base_url, '?') === false) ? '?' : ((strpos($base_url, '?') === strlen($base_url) - 1) ? '' : '&amp;');
$page_string = ($on_page == 1) ? '<strong>1</strong>' : '<a href="' . $base_url . '">1</a>';
@@ -2056,7 +2314,7 @@ function redirect($url, $return = false, $disable_cd_check = false)
$url = str_replace('&amp;', '&', $url);
// Determine which type of redirect we need to handle...
- $url_parts = parse_url($url);
+ $url_parts = @parse_url($url);
if ($url_parts === false)
{
@@ -2200,17 +2458,12 @@ function reapply_sid($url)
}
// Remove previously added sid
- if (strpos($url, '?sid=') !== false)
- {
- $url = preg_replace('/(\?)sid=[a-z0-9]+(&amp;|&)?/', '\1', $url);
- }
- else if (strpos($url, '&sid=') !== false)
+ if (strpos($url, 'sid=') !== false)
{
- $url = preg_replace('/&sid=[a-z0-9]+(&)?/', '\1', $url);
- }
- else if (strpos($url, '&amp;sid=') !== false)
- {
- $url = preg_replace('/&amp;sid=[a-z0-9]+(&amp;)?/', '\1', $url);
+ // All kind of links
+ $url = preg_replace('/(\?)?(&amp;|&)?sid=[a-z0-9]+/', '', $url);
+ // if the sid was the first param, make the old second as first ones
+ $url = preg_replace("/$phpEx(&amp;|&)+?/", "$phpEx?", $url);
}
return append_sid($url);
@@ -2274,6 +2527,18 @@ function build_url($strip_vars = false)
$redirect .= ($query) ? '?' . $query : '';
}
+ // We need to be cautious here.
+ // On some situations, the redirect path is an absolute URL, sometimes a relative path
+ // For a relative path, let's prefix it with $phpbb_root_path to point to the correct location,
+ // else we use the URL directly.
+ $url_parts = @parse_url($redirect);
+
+ // URL
+ if ($url_parts !== false && !empty($url_parts['scheme']) && !empty($url_parts['host']))
+ {
+ return str_replace('&', '&amp;', $redirect);
+ }
+
return $phpbb_root_path . str_replace('&', '&amp;', $redirect);
}
@@ -2435,7 +2700,7 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
if ($check && $confirm)
{
- $user_id = request_var('user_id', 0);
+ $user_id = request_var('confirm_uid', 0);
$session_id = request_var('sess', '');
$confirm_key = request_var('confirm_key', '');
@@ -2457,10 +2722,10 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
}
$s_hidden_fields = build_hidden_fields(array(
- 'user_id' => $user->data['user_id'],
- 'sess' => $user->session_id,
- 'sid' => $user->session_id)
- );
+ 'confirm_uid' => $user->data['user_id'],
+ 'sess' => $user->session_id,
+ 'sid' => $user->session_id,
+ ));
// generate activation key
$confirm_key = gen_rand_string(10);
@@ -2471,7 +2736,7 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
}
else
{
- page_header((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]);
+ page_header(((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]), false);
}
$template->set_filenames(array(
@@ -2520,6 +2785,11 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
{
global $db, $user, $template, $auth, $phpEx, $phpbb_root_path, $config;
+ if (!class_exists('phpbb_captcha_factory'))
+ {
+ include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
+ }
+
$err = '';
// Make sure user->setup() has been called
@@ -2630,38 +2900,15 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
{
case LOGIN_ERROR_ATTEMPTS:
- // Show confirm image
- $sql = 'DELETE FROM ' . CONFIRM_TABLE . "
- WHERE session_id = '" . $db->sql_escape($user->session_id) . "'
- AND confirm_type = " . CONFIRM_LOGIN;
- $db->sql_query($sql);
-
- // Generate code
- $code = gen_rand_string(mt_rand(CAPTCHA_MIN_CHARS, CAPTCHA_MAX_CHARS));
- $confirm_id = md5(unique_id($user->ip));
- $seed = hexdec(substr(unique_id(), 4, 10));
-
- // compute $seed % 0x7fffffff
- $seed -= 0x7fffffff * floor($seed / 0x7fffffff);
-
- $sql = 'INSERT INTO ' . CONFIRM_TABLE . ' ' . $db->sql_build_array('INSERT', array(
- 'confirm_id' => (string) $confirm_id,
- 'session_id' => (string) $user->session_id,
- 'confirm_type' => (int) CONFIRM_LOGIN,
- 'code' => (string) $code,
- 'seed' => (int) $seed)
- );
- $db->sql_query($sql);
+ $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha->init(CONFIRM_LOGIN);
+ // $captcha->reset();
$template->assign_vars(array(
- 'S_CONFIRM_CODE' => true,
- 'CONFIRM_ID' => $confirm_id,
- 'CONFIRM_IMAGE' => '<img src="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=confirm&amp;id=' . $confirm_id . '&amp;type=' . CONFIRM_LOGIN) . '" alt="" title="" />',
- 'L_LOGIN_CONFIRM_EXPLAIN' => sprintf($user->lang['LOGIN_CONFIRM_EXPLAIN'], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>'),
+ 'CAPTCHA_TEMPLATE' => $captcha->get_template(),
));
$err = $user->lang[$result['error_msg']];
-
break;
case LOGIN_ERROR_PASSWORD_CONVERT:
@@ -2688,28 +2935,18 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
}
}
- if (!$redirect)
- {
- // We just use what the session code determined...
- // If we are not within the admin directory we use the page dir...
- $redirect = '';
-
- if (!$admin)
- {
- $redirect .= ($user->page['page_dir']) ? $user->page['page_dir'] . '/' : '';
- }
-
- $redirect .= $user->page['page_name'] . (($user->page['query_string']) ? '?' . htmlspecialchars($user->page['query_string']) : '');
- }
-
// Assign credential for username/password pair
$credential = ($admin) ? md5(unique_id()) : false;
$s_hidden_fields = array(
- 'redirect' => $redirect,
'sid' => $user->session_id,
);
+ if ($redirect)
+ {
+ $s_hidden_fields['redirect'] = $redirect;
+ }
+
if ($admin)
{
$s_hidden_fields['credential'] = $credential;
@@ -2722,12 +2959,11 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
'LOGIN_EXPLAIN' => $l_explain,
'U_SEND_PASSWORD' => ($config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=sendpassword') : '',
- 'U_RESEND_ACTIVATION' => ($config['require_activation'] != USER_ACTIVATION_NONE && $config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=resend_act') : '',
+ 'U_RESEND_ACTIVATION' => ($config['require_activation'] == USER_ACTIVATION_SELF && $config['email_enable']) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=resend_act') : '',
'U_TERMS_USE' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=terms'),
'U_PRIVACY' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=privacy'),
'S_DISPLAY_FULL_LOGIN' => ($s_display) ? true : false,
- '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
'S_HIDDEN_FIELDS' => $s_hidden_fields,
'S_ADMIN_AUTH' => $admin,
@@ -2811,7 +3047,7 @@ function login_forum_box($forum_data)
$template->assign_var('LOGIN_ERROR', $user->lang['WRONG_PASSWORD']);
}
- page_header($user->lang['LOGIN']);
+ page_header($user->lang['LOGIN'], false);
$template->assign_vars(array(
'S_HIDDEN_FIELDS' => build_hidden_fields(array('f' => $forum_data['forum_id'])))
@@ -2933,6 +3169,14 @@ function add_log()
{
global $db, $user;
+ // In phpBB 3.1.x i want to have logging in a class to be able to control it
+ // For now, we need a quite hakish approach to circumvent logging for some actions
+ // @todo implement cleanly
+ if (!empty($GLOBALS['skip_add_log']))
+ {
+ return false;
+ }
+
$args = func_get_args();
$mode = array_shift($args);
@@ -3200,7 +3444,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
global $phpEx, $phpbb_root_path, $msg_title, $msg_long_text;
// Do not display notices if we suppress them via @
- if (error_reporting() == 0)
+ if (error_reporting() == 0 && $errno != E_USER_ERROR && $errno != E_USER_WARNING && $errno != E_USER_NOTICE)
{
return;
}
@@ -3211,6 +3455,11 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
$msg_text = $msg_long_text;
}
+ if (!defined('E_DEPRECATED'))
+ {
+ define('E_DEPRECATED', 8192);
+ }
+
switch ($errno)
{
case E_NOTICE:
@@ -3243,8 +3492,13 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
// remove complete path to installation, with the risk of changing backslashes meant to be there
$errfile = str_replace(array(phpbb_realpath($phpbb_root_path), '\\'), array('', '/'), $errfile);
$msg_text = str_replace(array(phpbb_realpath($phpbb_root_path), '\\'), array('', '/'), $msg_text);
-
echo '<b>[phpBB Debug] PHP Notice</b>: in file <b>' . $errfile . '</b> on line <b>' . $errline . '</b>: <b>' . $msg_text . '</b><br />' . "\n";
+
+ // we are writing an image - the user won't see the debug, so let's place it in the log
+ if (defined('IMAGE_OUTPUT') || defined('IN_CRON'))
+ {
+ add_log('critical', 'LOG_IMAGE_GENERATION_ERROR', $errfile, $errline, $msg_text);
+ }
// echo '<br /><br />BACKTRACE<br />' . get_backtrace() . '<br />' . "\n";
}
@@ -3279,6 +3533,17 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
}
}
+ if (defined('DEBUG') || defined('IN_CRON') || defined('IMAGE_OUTPUT'))
+ {
+ // let's avoid loops
+ $db->sql_return_on_error(true);
+ add_log('critical', 'LOG_GENERAL_ERROR', $msg_title, $msg_text);
+ $db->sql_return_on_error(false);
+ }
+
+ // Do not send 200 OK, but service unavailable on errors
+ header('HTTP/1.1 503 Service Unavailable');
+
garbage_collection();
// Try to not call the adm page data...
@@ -3357,7 +3622,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
}
else
{
- page_header($msg_title);
+ page_header($msg_title, false);
}
}
@@ -3386,6 +3651,11 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
exit_handler();
break;
+
+ // PHP4 compatibility
+ case E_DEPRECATED:
+ return true;
+ break;
}
// If we notice an error not handled here we pass this back to PHP by returning false
@@ -3395,16 +3665,17 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
/**
* Queries the session table to get information about online guests
-* @param int $forum_id Limits the search to the forum with this id
+* @param int $item_id Limits the search to the item with this id
+* @param string $item The name of the item which is stored in the session table as session_{$item}_id
* @return int The number of active distinct guest sessions
*/
-function obtain_guest_count($forum_id = 0)
+function obtain_guest_count($item_id = 0, $item = 'forum')
{
global $db, $config;
- if ($forum_id)
+ if ($item_id)
{
- $reading_sql = ' AND s.session_forum_id = ' . (int) $forum_id;
+ $reading_sql = ' AND s.session_' . $item . '_id = ' . (int) $item_id;
}
else
{
@@ -3442,17 +3713,18 @@ function obtain_guest_count($forum_id = 0)
/**
* Queries the session table to get information about online users
-* @param int $forum_id Limits the search to the forum with this id
+* @param int $item_id Limits the search to the item with this id
+* @param string $item The name of the item which is stored in the session table as session_{$item}_id
* @return array An array containing the ids of online, hidden and visible users, as well as statistical info
*/
-function obtain_users_online($forum_id = 0)
+function obtain_users_online($item_id = 0, $item = 'forum')
{
global $db, $config, $user;
$reading_sql = '';
- if ($forum_id !== 0)
+ if ($item_id !== 0)
{
- $reading_sql = ' AND s.session_forum_id = ' . (int) $forum_id;
+ $reading_sql = ' AND s.session_' . $item . '_id = ' . (int) $item_id;
}
$online_users = array(
@@ -3466,7 +3738,7 @@ function obtain_users_online($forum_id = 0)
if ($config['load_online_guests'])
{
- $online_users['guests_online'] = obtain_guest_count($forum_id);
+ $online_users['guests_online'] = obtain_guest_count($item_id, $item);
}
// a little discrete magic to cache this for 30 seconds
@@ -3505,14 +3777,17 @@ function obtain_users_online($forum_id = 0)
/**
* Uses the result of obtain_users_online to generate a localized, readable representation.
* @param mixed $online_users result of obtain_users_online - array with user_id lists for total, hidden and visible users, and statistics
-* @param int $forum_id Indicate that the data is limited to one forum and not global.
+* @param int $item_id Indicate that the data is limited to one item and not global
+* @param string $item The name of the item which is stored in the session table as session_{$item}_id
* @return array An array containing the string for output to the template
*/
-function obtain_users_online_string($online_users, $forum_id = 0)
+function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum')
{
global $config, $db, $user, $auth;
$user_online_link = $online_userlist = '';
+ // Need caps version of $item for language-strings
+ $item_caps = strtoupper($item);
if (sizeof($online_users['online_users']))
{
@@ -3547,18 +3822,18 @@ function obtain_users_online_string($online_users, $forum_id = 0)
$online_userlist = $user->lang['NO_ONLINE_USERS'];
}
- if ($forum_id === 0)
+ if ($item_id === 0)
{
$online_userlist = $user->lang['REGISTERED_USERS'] . ' ' . $online_userlist;
}
else if ($config['load_online_guests'])
{
- $l_online = ($online_users['guests_online'] === 1) ? $user->lang['BROWSING_FORUM_GUEST'] : $user->lang['BROWSING_FORUM_GUESTS'];
+ $l_online = ($online_users['guests_online'] === 1) ? $user->lang['BROWSING_' . $item_caps . '_GUEST'] : $user->lang['BROWSING_' . $item_caps . '_GUESTS'];
$online_userlist = sprintf($l_online, $online_userlist, $online_users['guests_online']);
}
else
{
- $online_userlist = sprintf($user->lang['BROWSING_FORUM'], $online_userlist);
+ $online_userlist = sprintf($user->lang['BROWSING_' . $item_caps], $online_userlist);
}
// Build online listing
$vars_online = array(
@@ -3612,11 +3887,45 @@ function obtain_users_online_string($online_users, $forum_id = 0)
);
}
+/**
+* Get option bitfield from custom data
+*
+* @param int $bit The bit/value to get
+* @param int $data Current bitfield to check
+* @return bool Returns true if value of constant is set in bitfield, else false
+*/
+function phpbb_optionget($bit, $data)
+{
+ return ($data & 1 << (int) $bit) ? true : false;
+}
+
+/**
+* Set option bitfield
+*
+* @param int $bit The bit/value to set/unset
+* @param bool $set True if option should be set, false if option should be unset.
+* @param int $data Current bitfield to change
+*
+* @return int The new bitfield
+*/
+function phpbb_optionset($bit, $set, $data)
+{
+ if ($set && !($data & 1 << $bit))
+ {
+ $data += 1 << $bit;
+ }
+ else if (!$set && ($data & 1 << $bit))
+ {
+ $data -= 1 << $bit;
+ }
+
+ return $data;
+}
/**
* Generate page header
*/
-function page_header($page_title = '', $display_online_list = true)
+function page_header($page_title = '', $display_online_list = true, $item_id = 0, $item = 'forum')
{
global $db, $config, $template, $SID, $_SID, $user, $auth, $phpEx, $phpbb_root_path;
@@ -3656,10 +3965,14 @@ function page_header($page_title = '', $display_online_list = true)
if ($config['load_online'] && $config['load_online_time'] && $display_online_list)
{
- $f = request_var('f', 0);
- $f = max($f, 0);
- $online_users = obtain_users_online($f);
- $user_online_strings = obtain_users_online_string($online_users, $f);
+ /**
+ * Load online data:
+ * For obtaining another session column use $item and $item_id in the function-parameter, whereby the column is session_{$item}_id.
+ */
+ $item_id = max($item_id, 0);
+
+ $online_users = obtain_users_online($item_id, $item);
+ $user_online_strings = obtain_users_online_string($online_users, $item_id, $item);
$l_online_users = $user_online_strings['l_online_users'];
$online_userlist = $user_online_strings['online_userlist'];
@@ -3731,6 +4044,26 @@ function page_header($page_title = '', $display_online_list = true)
$user_lang = substr($user_lang, 0, strpos($user_lang, '-x-'));
}
+ $forum_id = request_var('f', 0);
+ $topic_id = request_var('t', 0);
+
+ $s_feed_news = false;
+
+ // Get option for news
+ if ($config['feed_enable'])
+ {
+ $sql = 'SELECT forum_id
+ FROM ' . FORUMS_TABLE . '
+ WHERE ' . $db->sql_bit_and('forum_options', FORUM_OPTION_FEED_NEWS, '<> 0');
+ $result = $db->sql_query_limit($sql, 1, 0, 600);
+ $s_feed_news = (int) $db->sql_fetchfield('forum_id');
+ $db->sql_freeresult($result);
+ }
+
+ // Determine board url - we may need it later
+ $board_url = generate_board_url() . '/';
+ $web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $phpbb_root_path;
+
// The following assigns all _common_ variables that may be used at any point in a template.
$template->assign_vars(array(
'SITENAME' => $config['sitename'],
@@ -3748,11 +4081,13 @@ function page_header($page_title = '', $display_online_list = true)
'S_USER_NEW_PRIVMSG' => $user->data['user_new_privmsg'],
'S_USER_UNREAD_PRIVMSG' => $user->data['user_unread_privmsg'],
+ 'S_USER_NEW' => $user->data['user_new'],
'SID' => $SID,
'_SID' => $_SID,
'SESSION_ID' => $user->session_id,
'ROOT_PATH' => $phpbb_root_path,
+ 'BOARD_URL' => $board_url,
'L_LOGIN_LOGOUT' => $l_login_logout,
'L_INDEX' => $user->lang['FORUM_INDEX'],
@@ -3774,10 +4109,14 @@ function page_header($page_title = '', $display_online_list = true)
'U_SEARCH_SELF' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=egosearch'),
'U_SEARCH_NEW' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=newposts'),
'U_SEARCH_UNANSWERED' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=unanswered'),
+ 'U_SEARCH_UNREAD' => append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=unreadposts'),
'U_SEARCH_ACTIVE_TOPICS'=> append_sid("{$phpbb_root_path}search.$phpEx", 'search_id=active_topics'),
'U_DELETE_COOKIES' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=delete_cookies'),
'U_TEAM' => ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile')) ? '' : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=leaders'),
+ 'U_TERMS_USE' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=terms'),
+ 'U_PRIVACY' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=privacy'),
'U_RESTORE_PERMISSIONS' => ($user->data['user_perm_from'] && $auth->acl_get('a_switchperm')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=restore_perm') : '',
+ 'U_FEED' => generate_board_url() . "/feed.$phpEx",
'S_USER_LOGGED_IN' => ($user->data['user_id'] != ANONYMOUS) ? true : false,
'S_AUTOLOGIN_ENABLED' => ($config['allow_autologin']) ? true : false,
@@ -3799,22 +4138,44 @@ function page_header($page_title = '', $display_online_list = true)
'S_DISPLAY_MEMBERLIST' => (isset($auth)) ? $auth->acl_get('u_viewprofile') : 0,
'S_NEW_PM' => ($s_privmsg_new) ? 1 : 0,
'S_REGISTER_ENABLED' => ($config['require_activation'] != USER_ACTIVATION_DISABLE) ? true : false,
-
- 'T_THEME_PATH' => "{$phpbb_root_path}styles/" . $user->theme['theme_path'] . '/theme',
- 'T_TEMPLATE_PATH' => "{$phpbb_root_path}styles/" . $user->theme['template_path'] . '/template',
- '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',
- 'T_IMAGESET_PATH' => "{$phpbb_root_path}styles/" . $user->theme['imageset_path'] . '/imageset',
- 'T_IMAGESET_LANG_PATH' => "{$phpbb_root_path}styles/" . $user->theme['imageset_path'] . '/imageset/' . $user->data['user_lang'],
- 'T_IMAGES_PATH' => "{$phpbb_root_path}images/",
- 'T_SMILIES_PATH' => "{$phpbb_root_path}{$config['smilies_path']}/",
- 'T_AVATAR_PATH' => "{$phpbb_root_path}{$config['avatar_path']}/",
- 'T_AVATAR_GALLERY_PATH' => "{$phpbb_root_path}{$config['avatar_gallery_path']}/",
- 'T_ICONS_PATH' => "{$phpbb_root_path}{$config['icons_path']}/",
- 'T_RANKS_PATH' => "{$phpbb_root_path}{$config['ranks_path']}/",
- 'T_UPLOAD_PATH' => "{$phpbb_root_path}{$config['upload_path']}/",
- '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&amp;id=" . $user->theme['style_id'] . '&amp;lang=' . $user->data['user_lang'],
+ 'S_FORUM_ID' => $forum_id,
+ 'S_TOPIC_ID' => $topic_id,
+
+ 'S_LOGIN_ACTION' => (!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') . '&amp;redirect=' . urlencode(str_replace('&amp;', '&', build_url())) : append_sid("index.$phpEx", false, true, $user->session_id) . '&amp;redirect=' . urlencode(str_replace('&amp;', '&', build_url())),
+
+ 'S_ENABLE_FEEDS' => ($config['feed_enable']) ? true : false,
+ 'S_ENABLE_FEEDS_FORUMS' => ($config['feed_overall_forums']) ? true : false,
+ 'S_ENABLE_FEEDS_TOPICS' => ($config['feed_overall_topics']) ? true : false,
+ 'S_ENABLE_FEEDS_NEWS' => ($s_feed_news) ? true : false,
+
+ 'T_THEME_PATH' => "{$web_path}styles/" . $user->theme['theme_path'] . '/theme',
+ 'T_TEMPLATE_PATH' => "{$web_path}styles/" . $user->theme['template_path'] . '/template',
+ 'T_SUPER_TEMPLATE_PATH' => (isset($user->theme['template_inherit_path']) && $user->theme['template_inherit_path']) ? "{$web_path}styles/" . $user->theme['template_inherit_path'] . '/template' : "{$web_path}styles/" . $user->theme['template_path'] . '/template',
+ 'T_IMAGESET_PATH' => "{$web_path}styles/" . $user->theme['imageset_path'] . '/imageset',
+ 'T_IMAGESET_LANG_PATH' => "{$web_path}styles/" . $user->theme['imageset_path'] . '/imageset/' . $user->data['user_lang'],
+ 'T_IMAGES_PATH' => "{$web_path}images/",
+ 'T_SMILIES_PATH' => "{$web_path}{$config['smilies_path']}/",
+ 'T_AVATAR_PATH' => "{$web_path}{$config['avatar_path']}/",
+ 'T_AVATAR_GALLERY_PATH' => "{$web_path}{$config['avatar_gallery_path']}/",
+ 'T_ICONS_PATH' => "{$web_path}{$config['icons_path']}/",
+ 'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/",
+ 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/",
+ 'T_STYLESHEET_LINK' => (!$user->theme['theme_storedb']) ? "{$web_path}styles/" . $user->theme['theme_path'] . '/theme/stylesheet.css' : append_sid("{$phpbb_root_path}style.$phpEx", 'id=' . $user->theme['style_id'] . '&amp;lang=' . $user->data['user_lang']),
'T_STYLESHEET_NAME' => $user->theme['theme_name'],
+ 'T_THEME_NAME' => $user->theme['theme_path'],
+ 'T_TEMPLATE_NAME' => $user->theme['template_path'],
+ 'T_SUPER_TEMPLATE_NAME' => (isset($user->theme['template_inherit_path']) && $user->theme['template_inherit_path']) ? $user->theme['template_inherit_path'] : $user->theme['template_path'],
+ 'T_IMAGESET_NAME' => $user->theme['imageset_path'],
+ 'T_IMAGESET_LANG_NAME' => $user->data['user_lang'],
+ 'T_IMAGES' => 'images',
+ 'T_SMILIES' => $config['smilies_path'],
+ 'T_AVATAR' => $config['avatar_path'],
+ 'T_AVATAR_GALLERY' => $config['avatar_gallery_path'],
+ 'T_ICONS' => $config['icons_path'],
+ 'T_RANKS' => $config['ranks_path'],
+ 'T_UPLOAD' => $config['upload_path'],
+
'SITE_LOGO_IMG' => $user->img('site_logo'),
'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')),
@@ -3848,7 +4209,7 @@ function page_footer($run_cron = true)
$db->sql_report('display');
}
- $debug_output = sprintf('Time : %.3fs | ' . $db->sql_num_queries() . ' Queries | GZIP : ' . (($config['gzip_compress']) ? 'On' : 'Off') . (($user->load) ? ' | Load : ' . $user->load : ''), $totaltime);
+ $debug_output = sprintf('Time : %.3fs | ' . $db->sql_num_queries() . ' Queries | GZIP : ' . (($config['gzip_compress'] && @extension_loaded('zlib')) ? 'On' : 'Off') . (($user->load) ? ' | Load : ' . $user->load : ''), $totaltime);
if ($auth->acl_get('a_') && defined('DEBUG_EXTRA'))
{
@@ -3876,35 +4237,55 @@ function page_footer($run_cron = true)
);
// Call cron-type script
+ $call_cron = false;
if (!defined('IN_CRON') && $run_cron && !$config['board_disable'])
{
+ $call_cron = true;
+ $time_now = (!empty($user->time_now) && is_int($user->time_now)) ? $user->time_now : time();
+
+ // Any old lock present?
+ if (!empty($config['cron_lock']))
+ {
+ $cron_time = explode(' ', $config['cron_lock']);
+
+ // If 1 hour lock is present we do not call cron.php
+ if ($cron_time[0] + 3600 >= $time_now)
+ {
+ $call_cron = false;
+ }
+ }
+ }
+
+ // Call cron job?
+ if ($call_cron)
+ {
$cron_type = '';
- if (time() - $config['queue_interval'] > $config['last_queue_run'] && !defined('IN_ADMIN') && file_exists($phpbb_root_path . 'cache/queue.' . $phpEx))
+ if ($time_now - $config['queue_interval'] > $config['last_queue_run'] && !defined('IN_ADMIN') && file_exists($phpbb_root_path . 'cache/queue.' . $phpEx))
{
// Process email queue
$cron_type = 'queue';
}
- else if (method_exists($cache, 'tidy') && time() - $config['cache_gc'] > $config['cache_last_gc'])
+ else if (method_exists($cache, 'tidy') && $time_now - $config['cache_gc'] > $config['cache_last_gc'])
{
// Tidy the cache
$cron_type = 'tidy_cache';
}
- else if (time() - $config['warnings_gc'] > $config['warnings_last_gc'])
+ else if ($config['warnings_expire_days'] && ($time_now - $config['warnings_gc'] > $config['warnings_last_gc']))
{
$cron_type = 'tidy_warnings';
}
- else if (time() - $config['database_gc'] > $config['database_last_gc'])
+ else if ($time_now - $config['database_gc'] > $config['database_last_gc'])
{
// Tidy the database
$cron_type = 'tidy_database';
}
- else if (time() - $config['search_gc'] > $config['search_last_gc'])
+ else if ($time_now - $config['search_gc'] > $config['search_last_gc'])
{
// Tidy the search
$cron_type = 'tidy_search';
}
- else if (time() - $config['session_gc'] > $config['session_last_gc'])
+ else if ($time_now - $config['session_gc'] > $config['session_last_gc'])
{
$cron_type = 'tidy_sessions';
}