aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/functions.php
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes/functions.php')
-rw-r--r--phpBB/includes/functions.php2062
1 files changed, 770 insertions, 1292 deletions
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 689a682de3..38879caf5f 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -1,9 +1,13 @@
<?php
/**
*
-* @package phpBB3
-* @copyright (c) 2005 phpBB Group
-* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
*
*/
@@ -17,144 +21,46 @@ if (!defined('IN_PHPBB'))
// Common global functions
/**
-* Casts a variable to the given type.
-*
-* @deprecated
-*/
-function set_var(&$result, $var, $type, $multibyte = false)
-{
- // no need for dependency injection here, if you have the object, call the method yourself!
- $type_cast_helper = new \phpbb\request\type_cast_helper();
- $type_cast_helper->set_var($result, $var, $type, $multibyte);
-}
-
-/**
-* Wrapper function of \phpbb\request\request::variable which exists for backwards compatability.
-* See {@link \phpbb\request\request_interface::variable \phpbb\request\request_interface::variable} for
-* documentation of this function's use.
-*
-* @deprecated
-* @param mixed $var_name The form variable's name from which data shall be retrieved.
-* If the value is an array this may be an array of indizes which will give
-* direct access to a value at any depth. E.g. if the value of "var" is array(1 => "a")
-* then specifying array("var", 1) as the name will return "a".
-* If you pass an instance of {@link \phpbb\request\request_interface phpbb_request_interface}
-* as this parameter it will overwrite the current request class instance. If you do
-* not do so, it will create its own instance (but leave superglobals enabled).
-* @param mixed $default A default value that is returned if the variable was not set.
-* This function will always return a value of the same type as the default.
-* @param bool $multibyte If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters
-* Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks
-* @param bool $cookie This param is mapped to \phpbb\request\request_interface::COOKIE as the last param for
-* \phpbb\request\request_interface::variable for backwards compatability reasons.
-* @param \phpbb\request\request_interface|null|false If an instance of \phpbb\request\request_interface is given the instance is stored in
-* a static variable and used for all further calls where this parameters is null. Until
-* the function is called with an instance it automatically creates a new \phpbb\request\request
-* instance on every call. By passing false this per-call instantiation can be restored
-* after having passed in a \phpbb\request\request_interface instance.
-*
-* @return mixed The value of $_REQUEST[$var_name] run through {@link set_var set_var} to ensure that the type is the
-* the same as that of $default. If the variable is not set $default is returned.
-*/
-function request_var($var_name, $default, $multibyte = false, $cookie = false, $request = null)
-{
- // This is all just an ugly hack to add "Dependency Injection" to a function
- // the only real code is the function call which maps this function to a method.
- static $static_request = null;
-
- if ($request instanceof \phpbb\request\request_interface)
- {
- $static_request = $request;
-
- if (empty($var_name))
- {
- return;
- }
- }
- else if ($request === false)
- {
- $static_request = null;
-
- if (empty($var_name))
- {
- return;
- }
- }
-
- $tmp_request = $static_request;
-
- // no request class set, create a temporary one ourselves to keep backwards compatability
- if ($tmp_request === null)
- {
- // false param: enable super globals, so the created request class does not
- // make super globals inaccessible everywhere outside this function.
- $tmp_request = new \phpbb\request\request(new \phpbb\request\type_cast_helper(), false);
- }
-
- return $tmp_request->variable($var_name, $default, $multibyte, ($cookie) ? \phpbb\request\request_interface::COOKIE : \phpbb\request\request_interface::REQUEST);
-}
-
-/**
-* Sets a configuration option's value.
-*
-* Please note that this function does not update the is_dynamic value for
-* an already existing config option.
-*
-* @param string $config_name The configuration option's name
-* @param string $config_value New configuration value
-* @param bool $is_dynamic Whether this variable should be cached (false) or
-* if it changes too frequently (true) to be
-* efficiently cached.
+* Load the autoloaders added by the extensions.
*
-* @return null
-*
-* @deprecated
+* @param string $phpbb_root_path Path to the phpbb root directory.
*/
-function set_config($config_name, $config_value, $is_dynamic = false, \phpbb\config\config $set_config = null)
+function phpbb_load_extensions_autoloaders($phpbb_root_path)
{
- static $config = null;
+ $iterator = new \RecursiveIteratorIterator(
+ new \phpbb\recursive_dot_prefix_filter_iterator(
+ new \RecursiveDirectoryIterator(
+ $phpbb_root_path . 'ext/',
+ \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::FOLLOW_SYMLINKS
+ )
+ ),
+ \RecursiveIteratorIterator::SELF_FIRST
+ );
+ $iterator->setMaxDepth(2);
- if ($set_config !== null)
+ foreach ($iterator as $file_info)
{
- $config = $set_config;
-
- if (empty($config_name))
+ if ($file_info->getFilename() === 'vendor' && $iterator->getDepth() === 2)
{
- return;
+ $filename = $file_info->getRealPath() . '/autoload.php';
+ if (file_exists($filename))
+ {
+ require $filename;
+ }
}
}
-
- $config->set($config_name, $config_value, !$is_dynamic);
}
/**
-* Increments an integer config value directly in the database.
-*
-* @param string $config_name The configuration option's name
-* @param int $increment Amount to increment by
-* @param bool $is_dynamic Whether this variable should be cached (false) or
-* if it changes too frequently (true) to be
-* efficiently cached.
-*
-* @return null
+* Casts a variable to the given type.
*
* @deprecated
*/
-function set_config_count($config_name, $increment, $is_dynamic = false, \phpbb\config\config $set_config = null)
+function set_var(&$result, $var, $type, $multibyte = false)
{
- static $config = null;
-
- if ($set_config !== null)
- {
- $config = $set_config;
-
- if (empty($config_name))
- {
- return;
- }
- }
-
- $config->increment($config_name, $increment, !$is_dynamic);
+ // no need for dependency injection here, if you have the object, call the method yourself!
+ $type_cast_helper = new \phpbb\request\type_cast_helper();
+ $type_cast_helper->set_var($result, $var, $type, $multibyte);
}
/**
@@ -200,8 +106,8 @@ function unique_id($extra = 'c')
if ($dss_seeded !== true && ($config['rand_seed_last_update'] < time() - rand(1,10)))
{
- set_config('rand_seed_last_update', time(), true);
- set_config('rand_seed', $config['rand_seed'], true);
+ $config->set('rand_seed_last_update', time(), false);
+ $config->set('rand_seed', $config['rand_seed'], false);
$dss_seeded = true;
}
@@ -254,7 +160,6 @@ function phpbb_gmgetdate($time = false)
* @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($value, $string_only = true, $allowed_units = false)
{
@@ -342,8 +247,7 @@ function still_on_time($extra_time = 15)
{
static $max_execution_time, $start_time;
- $time = explode(' ', microtime());
- $current_time = $time[0] + $time[1];
+ $current_time = microtime(true);
if (empty($max_execution_time))
{
@@ -368,41 +272,6 @@ function still_on_time($extra_time = 15)
}
/**
-* Hash the password
-*
-* @deprecated 3.1.0-a2 (To be removed: 3.3.0)
-*
-* @param string $password Password to be hashed
-*
-* @return string|bool Password hash or false if something went wrong during hashing
-*/
-function phpbb_hash($password)
-{
- global $phpbb_container;
-
- $passwords_manager = $phpbb_container->get('passwords.manager');
- return $passwords_manager->hash($password);
-}
-
-/**
-* Check for correct password
-*
-* @deprecated 3.1.0-a2 (To be removed: 3.3.0)
-*
-* @param string $password The password in plain text
-* @param string $hash The stored password hash
-*
-* @return bool Returns true if the password is correct, false if not.
-*/
-function phpbb_check_hash($password, $hash)
-{
- global $phpbb_container;
-
- $passwords_manager = $phpbb_container->get('passwords.manager');
- return $passwords_manager->check($password, $hash);
-}
-
-/**
* Hashes an email address to a big integer
*
* @param string $email Email address
@@ -442,489 +311,6 @@ function phpbb_version_compare($version1, $version2, $operator = null)
}
}
-/**
-* 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.
-* The function determines owner and group from common.php file and sets the same to the provided file.
-* The function uses bit fields to build the permissions.
-* The function sets the appropiate execute bit on directories.
-*
-* Supported constants representing bit fields are:
-*
-* CHMOD_ALL - all permissions (7)
-* CHMOD_READ - read permission (4)
-* CHMOD_WRITE - write permission (2)
-* CHMOD_EXECUTE - execute permission (1)
-*
-* 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.
-*
-* @param string $filename The file/directory to be chmodded
-* @param int $perms Permissions to set
-*
-* @return bool true on success, otherwise false
-* @author faw, phpBB Group
-*/
-function phpbb_chmod($filename, $perms = CHMOD_READ)
-{
- static $_chmod_info;
-
- // Return if the file no longer exists.
- if (!file_exists($filename))
- {
- return false;
- }
-
- // Determine some common vars
- if (empty($_chmod_info))
- {
- if (!function_exists('fileowner') || !function_exists('filegroup'))
- {
- // No need to further determine owner/group - it is unknown
- $_chmod_info['process'] = false;
- }
- else
- {
- global $phpbb_root_path, $phpEx;
-
- // Determine owner/group of common.php file and the filename we want to change here
- $common_php_owner = @fileowner($phpbb_root_path . 'common.' . $phpEx);
- $common_php_group = @filegroup($phpbb_root_path . 'common.' . $phpEx);
-
- // And the owner and the groups PHP is running under.
- $php_uid = (function_exists('posix_getuid')) ? @posix_getuid() : false;
- $php_gids = (function_exists('posix_getgroups')) ? @posix_getgroups() : false;
-
- // If we are unable to get owner/group, then do not try to set them by guessing
- if (!$php_uid || empty($php_gids) || !$common_php_owner || !$common_php_group)
- {
- $_chmod_info['process'] = false;
- }
- else
- {
- $_chmod_info = array(
- 'process' => true,
- 'common_owner' => $common_php_owner,
- 'common_group' => $common_php_group,
- 'php_uid' => $php_uid,
- 'php_gids' => $php_gids,
- );
- }
- }
- }
-
- if ($_chmod_info['process'])
- {
- $file_uid = @fileowner($filename);
- $file_gid = @filegroup($filename);
-
- // Change owner
- if (@chown($filename, $_chmod_info['common_owner']))
- {
- clearstatcache();
- $file_uid = @fileowner($filename);
- }
-
- // Change group
- if (@chgrp($filename, $_chmod_info['common_group']))
- {
- clearstatcache();
- $file_gid = @filegroup($filename);
- }
-
- // If the file_uid/gid now match the one from common.php we can process further, else we are not able to change something
- if ($file_uid != $_chmod_info['common_owner'] || $file_gid != $_chmod_info['common_group'])
- {
- $_chmod_info['process'] = false;
- }
- }
-
- // Still able to process?
- if ($_chmod_info['process'])
- {
- if ($file_uid == $_chmod_info['php_uid'])
- {
- $php = 'owner';
- }
- else if (in_array($file_gid, $_chmod_info['php_gids']))
- {
- $php = 'group';
- }
- else
- {
- // Since we are setting the everyone bit anyway, no need to do expensive operations
- $_chmod_info['process'] = false;
- }
- }
-
- // We are not able to determine or change something
- if (!$_chmod_info['process'])
- {
- $php = 'other';
- }
-
- // Owner always has read/write permission
- $owner = CHMOD_READ | CHMOD_WRITE;
- if (is_dir($filename))
- {
- $owner |= CHMOD_EXECUTE;
-
- // Only add execute bit to the permission if the dir needs to be readable
- if ($perms & CHMOD_READ)
- {
- $perms |= CHMOD_EXECUTE;
- }
- }
-
- switch ($php)
- {
- case 'owner':
- $result = @chmod($filename, ($owner << 6) + (0 << 3) + (0 << 0));
-
- clearstatcache();
-
- if (is_readable($filename) && phpbb_is_writable($filename))
- {
- break;
- }
-
- case 'group':
- $result = @chmod($filename, ($owner << 6) + ($perms << 3) + (0 << 0));
-
- clearstatcache();
-
- if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || phpbb_is_writable($filename)))
- {
- break;
- }
-
- case 'other':
- $result = @chmod($filename, ($owner << 6) + ($perms << 3) + ($perms << 0));
-
- clearstatcache();
-
- if ((!($perms & CHMOD_READ) || is_readable($filename)) && (!($perms & CHMOD_WRITE) || phpbb_is_writable($filename)))
- {
- break;
- }
-
- default:
- return false;
- break;
- }
-
- 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);
- }
-}
-
-/**
-* Checks if a path ($path) is absolute or relative
-*
-* @param string $path Path to check absoluteness of
-* @return boolean
-*/
-function phpbb_is_absolute($path)
-{
- return (isset($path[0]) && $path[0] == '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false;
-}
-
-/**
-* @author Chris Smith <chris@project-minerva.org>
-* @copyright 2006 Project Minerva Team
-* @param string $path The path which we should attempt to resolve.
-* @return mixed
-*/
-function phpbb_own_realpath($path)
-{
- global $request;
-
- // Now to perform funky shizzle
-
- // Switch to use UNIX slashes
- $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
- $path_prefix = '';
-
- // Determine what sort of path we have
- if (phpbb_is_absolute($path))
- {
- $absolute = true;
-
- if ($path[0] == '/')
- {
- // Absolute path, *NIX style
- $path_prefix = '';
- }
- else
- {
- // Absolute path, Windows style
- // Remove the drive letter and colon
- $path_prefix = $path[0] . ':';
- $path = substr($path, 2);
- }
- }
- else
- {
- // Relative Path
- // Prepend the current working directory
- if (function_exists('getcwd'))
- {
- // This is the best method, hopefully it is enabled!
- $path = str_replace(DIRECTORY_SEPARATOR, '/', getcwd()) . '/' . $path;
- $absolute = true;
- if (preg_match('#^[a-z]:#i', $path))
- {
- $path_prefix = $path[0] . ':';
- $path = substr($path, 2);
- }
- else
- {
- $path_prefix = '';
- }
- }
- else if ($request->server('SCRIPT_FILENAME'))
- {
- // Warning: If chdir() has been used this will lie!
- // Warning: This has some problems sometime (CLI can create them easily)
- $filename = htmlspecialchars_decode($request->server('SCRIPT_FILENAME'));
- $path = str_replace(DIRECTORY_SEPARATOR, '/', dirname($filename)) . '/' . $path;
- $absolute = true;
- $path_prefix = '';
- }
- else
- {
- // We have no way of getting the absolute path, just run on using relative ones.
- $absolute = false;
- $path_prefix = '.';
- }
- }
-
- // Remove any repeated slashes
- $path = preg_replace('#/{2,}#', '/', $path);
-
- // Remove the slashes from the start and end of the path
- $path = trim($path, '/');
-
- // Break the string into little bits for us to nibble on
- $bits = explode('/', $path);
-
- // Remove any . in the path, renumber array for the loop below
- $bits = array_values(array_diff($bits, array('.')));
-
- // Lets get looping, run over and resolve any .. (up directory)
- for ($i = 0, $max = sizeof($bits); $i < $max; $i++)
- {
- // @todo Optimise
- if ($bits[$i] == '..' )
- {
- if (isset($bits[$i - 1]))
- {
- if ($bits[$i - 1] != '..')
- {
- // We found a .. and we are able to traverse upwards, lets do it!
- unset($bits[$i]);
- unset($bits[$i - 1]);
- $i -= 2;
- $max -= 2;
- $bits = array_values($bits);
- }
- }
- else if ($absolute) // ie. !isset($bits[$i - 1]) && $absolute
- {
- // We have an absolute path trying to descend above the root of the filesystem
- // ... Error!
- return false;
- }
- }
- }
-
- // Prepend the path prefix
- array_unshift($bits, $path_prefix);
-
- $resolved = '';
-
- $max = sizeof($bits) - 1;
-
- // Check if we are able to resolve symlinks, Windows cannot.
- $symlink_resolve = (function_exists('readlink')) ? true : false;
-
- foreach ($bits as $i => $bit)
- {
- if (@is_dir("$resolved/$bit") || ($i == $max && @is_file("$resolved/$bit")))
- {
- // Path Exists
- if ($symlink_resolve && is_link("$resolved/$bit") && ($link = readlink("$resolved/$bit")))
- {
- // Resolved a symlink.
- $resolved = $link . (($i == $max) ? '' : '/');
- continue;
- }
- }
- else
- {
- // Something doesn't exist here!
- // This is correct realpath() behaviour but sadly open_basedir and safe_mode make this problematic
- // return false;
- }
- $resolved .= $bit . (($i == $max) ? '' : '/');
- }
-
- // @todo If the file exists fine and open_basedir only has one path we should be able to prepend it
- // because we must be inside that basedir, the question is where...
- // @internal The slash in is_dir() gets around an open_basedir restriction
- if (!@file_exists($resolved) || (!@is_dir($resolved . '/') && !is_file($resolved)))
- {
- return false;
- }
-
- // Put the slashes back to the native operating systems slashes
- $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved);
-
- // Check for DIRECTORY_SEPARATOR at the end (and remove it!)
- if (substr($resolved, -1) == DIRECTORY_SEPARATOR)
- {
- return substr($resolved, 0, -1);
- }
-
- return $resolved; // We got here, in the end!
-}
-
-if (!function_exists('realpath'))
-{
- /**
- * A wrapper for realpath
- * @ignore
- */
- function phpbb_realpath($path)
- {
- return phpbb_own_realpath($path);
- }
-}
-else
-{
- /**
- * A wrapper for realpath
- */
- function phpbb_realpath($path)
- {
- $realpath = realpath($path);
-
- // Strangely there are provider not disabling realpath but returning strange values. :o
- // We at least try to cope with them.
- if ($realpath === $path || $realpath === false)
- {
- return phpbb_own_realpath($path);
- }
-
- // Check for DIRECTORY_SEPARATOR at the end (and remove it!)
- if (substr($realpath, -1) == DIRECTORY_SEPARATOR)
- {
- $realpath = substr($realpath, 0, -1);
- }
-
- return $realpath;
- }
-}
-
-/**
-* Eliminates useless . and .. components from specified path.
-*
-* Deprecated, use filesystem class instead
-*
-* @param string $path Path to clean
-* @return string Cleaned path
-*
-* @deprecated
-*/
-function phpbb_clean_path($path)
-{
- global $phpbb_path_helper, $phpbb_container;
-
- if (!$phpbb_path_helper && $phpbb_container)
- {
- $phpbb_path_helper = $phpbb_container->get('path_helper');
- }
- else if (!$phpbb_path_helper)
- {
- // The container is not yet loaded, use a new instance
- if (!class_exists('\phpbb\path_helper'))
- {
- global $phpbb_root_path, $phpEx;
- require($phpbb_root_path . 'phpbb/path_helper.' . $phpEx);
- }
-
- $phpbb_path_helper = new phpbb\path_helper(
- new phpbb\symfony_request(
- new phpbb\request\request()
- ),
- new phpbb\filesystem(),
- $phpbb_root_path,
- $phpEx
- );
- }
-
- return $phpbb_path_helper->clean_path($path);
-}
-
// functions used for building option fields
/**
@@ -979,14 +365,20 @@ function style_select($default = '', $all = false)
* Format the timezone offset with hours and minutes
*
* @param int $tz_offset Timezone offset in seconds
+* @param bool $show_null Whether null offsets should be shown
* @return string Normalized offset string: -7200 => -02:00
* 16200 => +04:30
*/
-function phpbb_format_timezone_offset($tz_offset)
+function phpbb_format_timezone_offset($tz_offset, $show_null = false)
{
$sign = ($tz_offset < 0) ? '-' : '+';
$time_offset = abs($tz_offset);
+ if ($time_offset == 0 && $show_null == false)
+ {
+ return '';
+ }
+
$offset_seconds = $time_offset % 3600;
$offset_minutes = $offset_seconds / 60;
$offset_hours = ($time_offset - $offset_seconds) / 3600;
@@ -1071,7 +463,7 @@ function phpbb_get_timezone_identifiers($selected_timezone)
$validate_timezone = new DateTimeZone($selected_timezone);
$timezones[] = $selected_timezone;
}
- catch (Exception $e)
+ catch (\Exception $e)
{
}
}
@@ -1080,33 +472,16 @@ function phpbb_get_timezone_identifiers($selected_timezone)
}
/**
-* Pick a timezone
-*
-* @param string $default A timezone to select
-* @param boolean $truncate Shall we truncate the options text
-*
-* @return string Returns the options for timezone selector only
-*
-* @deprecated
-*/
-function tz_select($default = '', $truncate = false)
-{
- global $user;
-
- $timezone_select = phpbb_timezone_select($user, $default, $truncate);
- return $timezone_select['tz_select'];
-}
-
-/**
* Options to pick a timezone and date/time
*
+* @param \phpbb\template\template $template phpBB template object
* @param \phpbb\user $user Object of the current user
* @param string $default A timezone to select
* @param boolean $truncate Shall we truncate the options text
*
-* @return array Returns an array, also containing the options for the time selector.
+* @return array Returns an array containing the options for the time selector.
*/
-function phpbb_timezone_select($user, $default = '', $truncate = false)
+function phpbb_timezone_select($template, $user, $default = '', $truncate = false)
{
static $timezones;
@@ -1119,18 +494,18 @@ function phpbb_timezone_select($user, $default = '', $truncate = false)
foreach ($unsorted_timezones as $timezone)
{
$tz = new DateTimeZone($timezone);
- $dt = new \phpbb\datetime($user, 'now', $tz);
+ $dt = $user->create_datetime('now', $tz);
$offset = $dt->getOffset();
$current_time = $dt->format($user->lang['DATETIME_FORMAT'], true);
- $offset_string = phpbb_format_timezone_offset($offset);
- $timezones['GMT' . $offset_string . ' - ' . $timezone] = array(
+ $offset_string = phpbb_format_timezone_offset($offset, true);
+ $timezones['UTC' . $offset_string . ' - ' . $timezone] = array(
'tz' => $timezone,
- 'offest' => 'GMT' . $offset_string,
+ 'offset' => $offset_string,
'current' => $current_time,
);
if ($timezone === $default)
{
- $default_offset = 'GMT' . $offset_string;
+ $default_offset = 'UTC' . $offset_string;
}
}
unset($unsorted_timezones);
@@ -1138,18 +513,27 @@ function phpbb_timezone_select($user, $default = '', $truncate = false)
uksort($timezones, 'phpbb_tz_select_compare');
}
- $tz_select = $tz_dates = $opt_group = '';
+ $tz_select = $opt_group = '';
- foreach ($timezones as $timezone)
+ foreach ($timezones as $key => $timezone)
{
- if ($opt_group != $timezone['offest'])
+ if ($opt_group != $timezone['offset'])
{
+ // Generate tz_select for backwards compatibility
$tz_select .= ($opt_group) ? '</optgroup>' : '';
- $tz_select .= '<optgroup label="' . $timezone['offest'] . ' - ' . $timezone['current'] . '">';
- $opt_group = $timezone['offest'];
+ $tz_select .= '<optgroup label="' . $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current']) . '">';
+ $opt_group = $timezone['offset'];
+ $template->assign_block_vars('timezone_select', array(
+ 'LABEL' => $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current']),
+ 'VALUE' => $key . ' - ' . $timezone['current'],
+ ));
- $selected = ($default_offset == $timezone['offest']) ? ' selected="selected"' : '';
- $tz_dates .= '<option value="' . $timezone['offest'] . ' - ' . $timezone['current'] . '"' . $selected . '>' . $timezone['offest'] . ' - ' . $timezone['current'] . '</option>';
+ $selected = (!empty($default_offset) && strpos($key, $default_offset) !== false) ? ' selected="selected"' : '';
+ $template->assign_block_vars('timezone_date', array(
+ 'VALUE' => $key . ' - ' . $timezone['current'],
+ 'SELECTED' => !empty($selected),
+ 'TITLE' => $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $timezone['current']),
+ ));
}
$label = $timezone['tz'];
@@ -1157,22 +541,26 @@ function phpbb_timezone_select($user, $default = '', $truncate = false)
{
$label = $user->lang['timezones'][$label];
}
- $title = $timezone['offest'] . ' - ' . $label;
+ $title = $user->lang(array('timezones', 'UTC_OFFSET_CURRENT'), $timezone['offset'], $label);
if ($truncate)
{
$label = truncate_string($label, 50, 255, false, '...');
}
+ // Also generate timezone_select for backwards compatibility
$selected = ($timezone['tz'] === $default) ? ' selected="selected"' : '';
$tz_select .= '<option title="' . $title . '" value="' . $timezone['tz'] . '"' . $selected . '>' . $label . '</option>';
+ $template->assign_block_vars('timezone_select.timezone_options', array(
+ 'TITLE' => $title,
+ 'VALUE' => $timezone['tz'],
+ 'SELECTED' => !empty($selected),
+ 'LABEL' => $label,
+ ));
}
$tz_select .= '</optgroup>';
- return array(
- 'tz_select' => $tz_select,
- 'tz_dates' => $tz_dates,
- );
+ return $tz_select;
}
// Functions handling topic/post tracking/marking
@@ -1190,26 +578,59 @@ function phpbb_timezone_select($user, $default = '', $truncate = false)
function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $user_id = 0)
{
global $db, $user, $config;
- global $request, $phpbb_container;
+ global $request, $phpbb_container, $phpbb_dispatcher;
$post_time = ($post_time === 0 || $post_time > time()) ? time() : (int) $post_time;
+ $should_markread = true;
+
+ /**
+ * This event is used for performing actions directly before marking forums,
+ * topics or posts as read.
+ *
+ * It is also possible to prevent the marking. For that, the $should_markread parameter
+ * should be set to FALSE.
+ *
+ * @event core.markread_before
+ * @var string mode Variable containing marking mode value
+ * @var mixed forum_id Variable containing forum id, or false
+ * @var mixed topic_id Variable containing topic id, or false
+ * @var int post_time Variable containing post time
+ * @var int user_id Variable containing the user id
+ * @var bool should_markread Flag indicating if the markread should be done or not.
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'mode',
+ 'forum_id',
+ 'topic_id',
+ 'post_time',
+ 'user_id',
+ 'should_markread',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.markread_before', compact($vars)));
+
+ if (!$should_markread)
+ {
+ return;
+ }
+
if ($mode == 'all')
{
if ($forum_id === false || !sizeof($forum_id))
{
// Mark all forums read (index page)
-
+ /* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
// Mark all topic notifications read for this user
- $phpbb_notifications->mark_notifications_read(array(
- 'topic',
- 'quote',
- 'bookmark',
- 'post',
- 'approve_topic',
- 'approve_post',
+ $phpbb_notifications->mark_notifications(array(
+ 'notification.type.topic',
+ 'notification.type.quote',
+ 'notification.type.bookmark',
+ 'notification.type.post',
+ 'notification.type.approve_topic',
+ 'notification.type.approve_post',
), false, $user->data['user_id'], $post_time);
if ($config['load_db_lastread'] && $user->data['is_registered'])
@@ -1265,12 +686,17 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
{
$forum_id = array($forum_id);
}
+ else
+ {
+ $forum_id = array_unique($forum_id);
+ }
+ /* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $phpbb_notifications->mark_notifications_read_by_parent(array(
- 'topic',
- 'approve_topic',
+ $phpbb_notifications->mark_notifications_by_parent(array(
+ 'notification.type.topic',
+ 'notification.type.approve_topic',
), $forum_id, $user->data['user_id'], $post_time);
// Mark all post/quote notifications read for this user in this forum
@@ -1285,11 +711,11 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
}
$db->sql_freeresult($result);
- $phpbb_notifications->mark_notifications_read_by_parent(array(
- 'quote',
- 'bookmark',
- 'post',
- 'approve_post',
+ $phpbb_notifications->mark_notifications_by_parent(array(
+ 'notification.type.quote',
+ 'notification.type.bookmark',
+ 'notification.type.post',
+ 'notification.type.approve_post',
), $topic_ids, $user->data['user_id'], $post_time);
// Add 0 to forums array to mark global announcements correctly
@@ -1388,19 +814,20 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
return;
}
+ /* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
// Mark post notifications read for this user in this topic
- $phpbb_notifications->mark_notifications_read(array(
- 'topic',
- 'approve_topic',
+ $phpbb_notifications->mark_notifications(array(
+ 'notification.type.topic',
+ 'notification.type.approve_topic',
), $topic_id, $user->data['user_id'], $post_time);
- $phpbb_notifications->mark_notifications_read_by_parent(array(
- 'quote',
- 'bookmark',
- 'post',
- 'approve_post',
+ $phpbb_notifications->mark_notifications_by_parent(array(
+ 'notification.type.quote',
+ 'notification.type.bookmark',
+ 'notification.type.post',
+ 'notification.type.approve_post',
), $topic_id, $user->data['user_id'], $post_time);
if ($config['load_db_lastread'] && $user->data['is_registered'])
@@ -1528,7 +955,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
*/
function get_topic_tracking($forum_id, $topic_ids, &$rowset, $forum_mark_time, $global_announce_list = false)
{
- global $config, $user;
+ global $user;
$last_read = array();
@@ -1687,7 +1114,8 @@ function get_complete_topic_tracking($forum_id, $topic_ids, $global_announce_lis
*/
function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $sql_limit = 1001, $sql_limit_offset = 0)
{
- global $config, $db, $user;
+ global $config, $db, $user, $request;
+ global $phpbb_dispatcher;
$user_id = ($user_id === false) ? (int) $user->data['user_id'] : (int) $user_id;
@@ -1696,7 +1124,7 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
if (empty($sql_sort))
{
- $sql_sort = 'ORDER BY t.topic_last_post_time DESC';
+ $sql_sort = 'ORDER BY t.topic_last_post_time DESC, t.topic_last_post_id DESC';
}
if ($config['load_db_lastread'] && $user->data['is_registered'])
@@ -1731,6 +1159,24 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
$sql_sort",
);
+ /**
+ * Change SQL query for fetching unread topics data
+ *
+ * @event core.get_unread_topics_modify_sql
+ * @var array sql_array Fully assembled SQL query with keys SELECT, FROM, LEFT_JOIN, WHERE
+ * @var int last_mark User's last_mark time
+ * @var string sql_extra Extra WHERE SQL statement
+ * @var string sql_sort ORDER BY SQL sorting statement
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'sql_array',
+ 'last_mark',
+ 'sql_extra',
+ 'sql_sort',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.get_unread_topics_modify_sql', compact($vars)));
+
$sql = $db->sql_build_query('SELECT', $sql_array);
$result = $db->sql_query_limit($sql, $sql_limit, $sql_limit_offset);
@@ -1747,7 +1193,7 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
if (empty($tracking_topics))
{
- $tracking_topics = request_var($config['cookie_name'] . '_track', '', false, true);
+ $tracking_topics = $request->variable($config['cookie_name'] . '_track', '', false, \phpbb\request\request_interface::COOKIE);
$tracking_topics = ($tracking_topics) ? tracking_unserialize($tracking_topics) : array();
}
@@ -1814,7 +1260,7 @@ function get_unread_topics($user_id = false, $sql_extra = '', $sql_sort = '', $s
*/
function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_time = false, $mark_time_forum = false)
{
- global $db, $tracking_topics, $user, $config, $auth, $request, $phpbb_container;
+ global $db, $tracking_topics, $user, $config, $request, $phpbb_container;
// Determine the users last forum mark time if not given.
if ($mark_time_forum === false)
@@ -1839,6 +1285,7 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti
// Handle update of unapproved topics info.
// Only update for moderators having m_approve permission for the forum.
+ /* @var $phpbb_content_visibility \phpbb\content_visibility */
$phpbb_content_visibility = $phpbb_container->get('content.visibility');
// Check the forum for any left unread topics.
@@ -1871,8 +1318,6 @@ function update_forum_tracking_info($forum_id, $forum_last_post_time, $f_mark_ti
else if ($config['load_anon_lastread'] || $user->data['is_registered'])
{
// Get information from cookie
- $row = false;
-
if (!isset($tracking_topics['tf'][$forum_id]))
{
// We do not need to mark read, this happened before. Therefore setting this to true
@@ -2049,6 +1494,9 @@ function tracking_unserialize($string, $max_depth = 3)
* @param mixed $params String or array of additional url parameters
* @param bool $is_amp Is url using &amp; (true) or & (false)
* @param string $session_id Possibility to use a custom session id instead of the global one
+* @param bool $is_route Is url generated by a route.
+*
+* @return string The corrected url.
*
* Examples:
* <code>
@@ -2059,7 +1507,7 @@ function tracking_unserialize($string, $max_depth = 3)
* </code>
*
*/
-function append_sid($url, $params = false, $is_amp = true, $session_id = false)
+function append_sid($url, $params = false, $is_amp = true, $session_id = false, $is_route = false)
{
global $_SID, $_EXTRA_URL, $phpbb_hook, $phpbb_path_helper;
global $phpbb_dispatcher;
@@ -2071,7 +1519,7 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)
}
// Update the root path with the correct relative web path
- if ($phpbb_path_helper instanceof \phpbb\path_helper)
+ if (!$is_route && $phpbb_path_helper instanceof \phpbb\path_helper)
{
$url = $phpbb_path_helper->update_web_root_path($url);
}
@@ -2097,9 +1545,10 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false)
* the global one (false)
* @var bool|string append_sid_overwrite Overwrite function (string
* URL) or not (false)
- * @since 3.1-A1
+ * @var bool is_route Is url generated by a route.
+ * @since 3.1.0-a1
*/
- $vars = array('url', 'params', 'is_amp', 'session_id', 'append_sid_overwrite');
+ $vars = array('url', 'params', 'is_amp', 'session_id', 'append_sid_overwrite', 'is_route');
extract($phpbb_dispatcher->trigger_event('core.append_sid', compact($vars)));
if ($append_sid_overwrite)
@@ -2268,20 +1717,13 @@ function generate_board_url($without_script_path = false)
*/
function redirect($url, $return = false, $disable_cd_check = false)
{
- global $db, $cache, $config, $user, $phpbb_root_path, $phpbb_filesystem, $phpbb_path_helper, $phpEx;
-
- $failover_flag = false;
+ global $user, $phpbb_path_helper, $phpbb_dispatcher;
- if (empty($user->lang))
+ if (!$user->is_setup())
{
$user->add_lang('common');
}
- if (!$return)
- {
- garbage_collection();
- }
-
// Make sure no &amp;'s are in, this will break the redirect
$url = str_replace('&amp;', '&', $url);
@@ -2298,7 +1740,7 @@ function redirect($url, $return = false, $disable_cd_check = false)
// Attention: only able to redirect within the same domain if $disable_cd_check is false (yourdomain.com -> www.yourdomain.com will not work)
if (!$disable_cd_check && $url_parts['host'] !== $user->host)
{
- $url = generate_board_url();
+ trigger_error('INSECURE_REDIRECT', E_USER_ERROR);
}
}
else if ($url[0] == '/')
@@ -2336,7 +1778,7 @@ function redirect($url, $return = false, $disable_cd_check = false)
// Clean URL and check if we go outside the forum directory
$url = $phpbb_path_helper->clean_url($url);
- if (!$disable_cd_check && strpos($url, generate_board_url(true)) === false)
+ if (!$disable_cd_check && strpos($url, generate_board_url(true) . '/') !== 0)
{
trigger_error('INSECURE_REDIRECT', E_USER_ERROR);
}
@@ -2356,13 +1798,29 @@ function redirect($url, $return = false, $disable_cd_check = false)
trigger_error('INSECURE_REDIRECT', E_USER_ERROR);
}
+ /**
+ * Execute code and/or overwrite redirect()
+ *
+ * @event core.functions.redirect
+ * @var string url The url
+ * @var bool return If true, do not redirect but return the sanitized URL.
+ * @var 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.
+ * @since 3.1.0-RC3
+ */
+ $vars = array('url', 'return', 'disable_cd_check');
+ extract($phpbb_dispatcher->trigger_event('core.functions.redirect', compact($vars)));
+
if ($return)
{
return $url;
}
+ else
+ {
+ garbage_collection();
+ }
// Redirect via an HTML form for PITA webservers
- if (@preg_match('#Microsoft|WebSTAR|Xitami#', getenv('SERVER_SOFTWARE')))
+ if (@preg_match('#WebSTAR|Xitami#', getenv('SERVER_SOFTWARE')))
{
header('Refresh: 0; URL=' . $url);
@@ -2419,79 +1877,23 @@ function reapply_sid($url)
*/
function build_url($strip_vars = false)
{
- global $user, $phpbb_root_path;
-
- $page = $user->page['page'];
-
- // 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($page);
+ global $config, $user, $phpbb_path_helper;
- // URL
- if ($url_parts === false || empty($url_parts['scheme']) || empty($url_parts['host']))
- {
- $page = $phpbb_root_path . $page;
- }
+ $page = $phpbb_path_helper->get_valid_page($user->page['page'], $config['enable_mod_rewrite']);
// Append SID
$redirect = append_sid($page, false, false);
- // Add delimiter if not there...
- if (strpos($redirect, '?') === false)
+ if ($strip_vars !== false)
{
- $redirect .= '?';
+ $redirect = $phpbb_path_helper->strip_url_params($redirect, $strip_vars, false);
}
-
- // Strip vars...
- if ($strip_vars !== false && strpos($redirect, '?') !== false)
+ else
{
- if (!is_array($strip_vars))
- {
- $strip_vars = array($strip_vars);
- }
-
- $query = $_query = array();
-
- $args = substr($redirect, strpos($redirect, '?') + 1);
- $args = ($args) ? explode('&', $args) : array();
- $redirect = substr($redirect, 0, strpos($redirect, '?'));
-
- foreach ($args as $argument)
- {
- $arguments = explode('=', $argument);
- $key = $arguments[0];
- unset($arguments[0]);
-
- if ($key === '')
- {
- continue;
- }
-
- $query[$key] = implode('=', $arguments);
- }
-
- // Strip the vars off
- foreach ($strip_vars as $strip)
- {
- if (isset($query[$strip]))
- {
- unset($query[$strip]);
- }
- }
-
- // Glue the remaining parts together... already urlencoded
- foreach ($query as $key => $value)
- {
- $_query[] = $key . '=' . $value;
- }
- $query = implode('&', $_query);
-
- $redirect .= ($query) ? '?' . $query : '';
+ $redirect = str_replace('&', '&amp;', $redirect);
}
- return str_replace('&', '&amp;', $redirect);
+ return $redirect . ((strpos($redirect, '?') === false) ? '?' : '');
}
/**
@@ -2506,19 +1908,19 @@ function meta_refresh($time, $url, $disable_cd_check = false)
{
global $template, $refresh_data, $request;
+ $url = redirect($url, true, $disable_cd_check);
if ($request->is_ajax())
{
$refresh_data = array(
'time' => $time,
- 'url' => str_replace('&amp;', '&', $url)
+ 'url' => $url,
);
}
else
{
- $url = redirect($url, true, $disable_cd_check);
+ // For XHTML compatibility we change back & to &amp;
$url = str_replace('&', '&amp;', $url);
- // For XHTML compatibility we change back & to &amp;
$template->assign_vars(array(
'META' => '<meta http-equiv="refresh" content="' . $time . '; url=' . $url . '" />')
);
@@ -2573,13 +1975,19 @@ function phpbb_request_http_version()
{
global $request;
+ $version = '';
if ($request && $request->server('SERVER_PROTOCOL'))
{
- return $request->server('SERVER_PROTOCOL');
+ $version = $request->server('SERVER_PROTOCOL');
}
else if (isset($_SERVER['SERVER_PROTOCOL']))
{
- return $_SERVER['SERVER_PROTOCOL'];
+ $version = $_SERVER['SERVER_PROTOCOL'];
+ }
+
+ if (!empty($version) && is_string($version) && preg_match('#^HTTP/[0-9]\.[0-9]$#', $version))
+ {
+ return $version;
}
return 'HTTP/1.0';
@@ -2624,7 +2032,7 @@ function check_link_hash($token, $link_name)
*/
function add_form_key($form_name)
{
- global $config, $template, $user;
+ global $config, $template, $user, $phpbb_dispatcher;
$now = time();
$token_sid = ($user->data['user_id'] == ANONYMOUS && !empty($config['form_token_sid_guests'])) ? $user->session_id : '';
@@ -2635,21 +2043,44 @@ function add_form_key($form_name)
'form_token' => $token,
));
+ /**
+ * Perform additional actions on creation of the form token
+ *
+ * @event core.add_form_key
+ * @var string form_name The form name
+ * @var int now Current time timestamp
+ * @var string s_fields Generated hidden fields
+ * @var string token Form token
+ * @var string token_sid User session ID
+ *
+ * @since 3.1.0-RC3
+ */
+ $vars = array(
+ 'form_name',
+ 'now',
+ 's_fields',
+ 'token',
+ 'token_sid',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.add_form_key', compact($vars)));
+
$template->assign_vars(array(
'S_FORM_TOKEN' => $s_fields,
));
}
/**
-* Check the form key. Required for all altering actions not secured by confirm_box
-* @param string $form_name The name of the form; has to match the name used in add_form_key, otherwise no restrictions apply
-* @param int $timespan The maximum acceptable age for a submitted form in seconds. Defaults to the config setting.
-* @param string $return_page The address for the return link
-* @param bool $trigger If true, the function will triger an error when encountering an invalid form
-*/
-function check_form_key($form_name, $timespan = false, $return_page = '', $trigger = false)
+ * Check the form key. Required for all altering actions not secured by confirm_box
+ *
+ * @param string $form_name The name of the form; has to match the name used
+ * in add_form_key, otherwise no restrictions apply
+ * @param int $timespan The maximum acceptable age for a submitted form
+ * in seconds. Defaults to the config setting.
+ * @return bool True, if the form key was valid, false otherwise
+ */
+function check_form_key($form_name, $timespan = false)
{
- global $config, $user;
+ global $config, $request, $user;
if ($timespan === false)
{
@@ -2657,10 +2088,10 @@ function check_form_key($form_name, $timespan = false, $return_page = '', $trigg
$timespan = ($config['form_token_lifetime'] == -1) ? -1 : max(30, $config['form_token_lifetime']);
}
- if (isset($_POST['creation_time']) && isset($_POST['form_token']))
+ if ($request->is_set_post('creation_time') && $request->is_set_post('form_token'))
{
- $creation_time = abs(request_var('creation_time', 0));
- $token = request_var('form_token', '');
+ $creation_time = abs($request->variable('creation_time', 0));
+ $token = $request->variable('form_token', '');
$diff = time() - $creation_time;
@@ -2677,11 +2108,6 @@ function check_form_key($form_name, $timespan = false, $return_page = '', $trigg
}
}
- if ($trigger)
- {
- trigger_error($user->lang['FORM_INVALID'] . $return_page);
- }
-
return false;
}
@@ -2701,7 +2127,7 @@ function check_form_key($form_name, $timespan = false, $return_page = '', $trigg
function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_body.html', $u_action = '')
{
global $user, $template, $db, $request;
- global $phpEx, $phpbb_root_path, $request;
+ global $config, $phpbb_path_helper;
if (isset($_POST['cancel']))
{
@@ -2712,9 +2138,9 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
if ($check && $confirm)
{
- $user_id = request_var('confirm_uid', 0);
- $session_id = request_var('sess', '');
- $confirm_key = request_var('confirm_key', '');
+ $user_id = $request->variable('confirm_uid', 0);
+ $session_id = $request->variable('sess', '');
+ $confirm_key = $request->variable('confirm_key', '');
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'])
{
@@ -2748,7 +2174,7 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
}
else
{
- page_header(((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]), false);
+ page_header((!isset($user->lang[$title])) ? $user->lang['CONFIRM'] : $user->lang[$title]);
}
$template->set_filenames(array(
@@ -2756,15 +2182,15 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
);
// If activation key already exist, we better do not re-use the key (something very strange is going on...)
- if (request_var('confirm_key', ''))
+ if ($request->variable('confirm_key', ''))
{
// This should not occur, therefore we cancel the operation to safe the user
return false;
}
// re-add sid / transform & to &amp; for user->page (user->page is always using &)
- $use_page = ($u_action) ? $phpbb_root_path . $u_action : $phpbb_root_path . str_replace('&', '&amp;', $user->page['page']);
- $u_action = reapply_sid($use_page);
+ $use_page = ($u_action) ? $u_action : str_replace('&', '&amp;', $user->page['page']);
+ $u_action = reapply_sid($phpbb_path_helper->get_valid_page($use_page, $config['enable_mod_rewrite']));
$u_action .= ((strpos($u_action, '?') === false) ? '?' : '&amp;') . 'confirm_key=' . $confirm_key;
$template->assign_vars(array(
@@ -2781,7 +2207,6 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
WHERE user_id = " . $user->data['user_id'];
$db->sql_query($sql);
-
if ($request->is_ajax())
{
$u_action .= '&confirm_uid=' . $user->data['user_id'] . '&sess=' . $user->session_id . '&sid=' . $user->session_id;
@@ -2812,18 +2237,13 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo
*/
function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = false, $s_display = true)
{
- global $db, $user, $template, $auth, $phpEx, $phpbb_root_path, $config;
- global $request, $phpbb_container;
-
- if (!class_exists('phpbb_captcha_factory', false))
- {
- include($phpbb_root_path . 'includes/captcha/captcha_factory.' . $phpEx);
- }
+ global $user, $template, $auth, $phpEx, $phpbb_root_path, $config;
+ global $request, $phpbb_container, $phpbb_dispatcher, $phpbb_log;
$err = '';
// Make sure user->setup() has been called
- if (empty($user->lang))
+ if (!$user->is_setup())
{
$user->setup();
}
@@ -2835,7 +2255,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
// anonymous/inactive users are never able to go to the ACP even if they have the relevant permissions
if ($user->data['is_registered'])
{
- add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ADMIN_AUTH_FAIL');
}
trigger_error('NO_AUTH_ADMIN');
}
@@ -2845,13 +2265,13 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
// Get credential
if ($admin)
{
- $credential = request_var('credential', '');
+ $credential = $request->variable('credential', '');
if (strspn($credential, 'abcdef0123456789') !== strlen($credential) || strlen($credential) != 32)
{
if ($user->data['is_registered'])
{
- add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ADMIN_AUTH_FAIL');
}
trigger_error('NO_AUTH_ADMIN');
}
@@ -2863,7 +2283,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
$password = $request->untrimmed_variable('password', '', true);
}
- $username = request_var('username', '', true);
+ $username = $request->variable('username', '', true);
$autologin = $request->is_set_post('autologin');
$viewonline = (int) !$request->is_set_post('viewonline');
$admin = ($admin) ? 1 : 0;
@@ -2873,7 +2293,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
if ($admin && utf8_clean_string($username) != utf8_clean_string($user->data['username']))
{
// We log the attempt to use a different username...
- add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ADMIN_AUTH_FAIL');
trigger_error('NO_AUTH_ADMIN_USER_DIFFER');
}
@@ -2886,7 +2306,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
{
if ($result['status'] == LOGIN_SUCCESS)
{
- add_log('admin', 'LOG_ADMIN_AUTH_SUCCESS');
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ADMIN_AUTH_SUCCESS');
}
else
{
@@ -2894,7 +2314,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
// anonymous/inactive users are never able to go to the ACP even if they have the relevant permissions
if ($user->data['is_registered'])
{
- add_log('admin', 'LOG_ADMIN_AUTH_FAIL');
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_ADMIN_AUTH_FAIL');
}
}
}
@@ -2902,9 +2322,19 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
// The result parameter is always an array, holding the relevant information...
if ($result['status'] == LOGIN_SUCCESS)
{
- $redirect = request_var('redirect', "{$phpbb_root_path}index.$phpEx");
- $message = ($l_success) ? $l_success : $user->lang['LOGIN_REDIRECT'];
- $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']);
+ $redirect = $request->variable('redirect', "{$phpbb_root_path}index.$phpEx");
+
+ /**
+ * This event allows an extension to modify the redirection when a user successfully logs in
+ *
+ * @event core.login_box_redirect
+ * @var string redirect Redirect string
+ * @var boolean admin Is admin?
+ * @var bool return If true, do not redirect but return the sanitized URL.
+ * @since 3.1.0-RC5
+ */
+ $vars = array('redirect', 'admin', 'return');
+ extract($phpbb_dispatcher->trigger_event('core.login_box_redirect', compact($vars)));
// append/replace SID (may change during the session for AOL users)
$redirect = reapply_sid($redirect);
@@ -2927,28 +2357,26 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
// Special cases... determine
switch ($result['status'])
{
+ case LOGIN_ERROR_PASSWORD_CONVERT:
+ $err = sprintf(
+ $user->lang[$result['error_msg']],
+ ($config['email_enable']) ? '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=sendpassword') . '">' : '',
+ ($config['email_enable']) ? '</a>' : '',
+ '<a href="' . phpbb_get_board_contact_link($config, $phpbb_root_path, $phpEx) . '">',
+ '</a>'
+ );
+ break;
+
case LOGIN_ERROR_ATTEMPTS:
- $captcha = phpbb_captcha_factory::get_instance($config['captcha_plugin']);
+ $captcha = $phpbb_container->get('captcha.factory')->get_instance($config['captcha_plugin']);
$captcha->init(CONFIRM_LOGIN);
// $captcha->reset();
$template->assign_vars(array(
'CAPTCHA_TEMPLATE' => $captcha->get_template(),
));
-
- $err = $user->lang[$result['error_msg']];
- break;
-
- case LOGIN_ERROR_PASSWORD_CONVERT:
- $err = sprintf(
- $user->lang[$result['error_msg']],
- ($config['email_enable']) ? '<a href="' . append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=sendpassword') . '">' : '',
- ($config['email_enable']) ? '</a>' : '',
- ($config['board_contact']) ? '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">' : '',
- ($config['board_contact']) ? '</a>' : ''
- );
- break;
+ // no break;
// Username, password, etc...
default:
@@ -2957,11 +2385,24 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
// Assign admin contact to some error messages
if ($result['error_msg'] == 'LOGIN_ERROR_USERNAME' || $result['error_msg'] == 'LOGIN_ERROR_PASSWORD')
{
- $err = (!$config['board_contact']) ? sprintf($user->lang[$result['error_msg']], '', '') : sprintf($user->lang[$result['error_msg']], '<a href="mailto:' . htmlspecialchars($config['board_contact']) . '">', '</a>');
+ $err = sprintf($user->lang[$result['error_msg']], '<a href="' . append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contactadmin') . '">', '</a>');
}
break;
}
+
+ /**
+ * This event allows an extension to process when a user fails a login attempt
+ *
+ * @event core.login_box_failed
+ * @var array result Login result data
+ * @var string username User name used to login
+ * @var string password Password used to login
+ * @var string err Error message
+ * @since 3.1.3-RC1
+ */
+ $vars = array('result', 'username', 'password', 'err');
+ extract($phpbb_dispatcher->trigger_event('core.login_box_failed', compact($vars)));
}
// Assign credential for username/password pair
@@ -2981,7 +2422,9 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
$s_hidden_fields['credential'] = $credential;
}
- $auth_provider = $phpbb_container->get('auth.provider.' . $config['auth_method']);
+ /* @var $provider_collection \phpbb\auth\provider_collection */
+ $provider_collection = $phpbb_container->get('auth.provider_collection');
+ $auth_provider = $provider_collection->get_provider();
$auth_provider_data = $auth_provider->get_login_data();
if ($auth_provider_data)
@@ -3025,7 +2468,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
'PASSWORD_CREDENTIAL' => ($admin) ? 'password_' . $credential : 'password',
));
- page_header($user->lang['LOGIN'], false);
+ page_header($user->lang['LOGIN']);
$template->set_filenames(array(
'body' => 'login_body.html')
@@ -3040,7 +2483,7 @@ function login_box($redirect = '', $l_explain = '', $l_success = '', $admin = fa
*/
function login_forum_box($forum_data)
{
- global $db, $phpbb_container, $request, $template, $user;
+ global $db, $phpbb_container, $request, $template, $user, $phpbb_dispatcher;
$password = $request->variable('password', '', true);
@@ -3083,6 +2526,7 @@ function login_forum_box($forum_data)
}
$db->sql_freeresult($result);
+ /* @var $passwords_manager \phpbb\passwords\manager */
$passwords_manager = $phpbb_container->get('passwords.manager');
if ($passwords_manager->check($password, $forum_data['forum_password']))
@@ -3101,7 +2545,18 @@ function login_forum_box($forum_data)
$template->assign_var('LOGIN_ERROR', $user->lang['WRONG_PASSWORD']);
}
- page_header($user->lang['LOGIN'], false);
+ /**
+ * Performing additional actions, load additional data on forum login
+ *
+ * @event core.login_forum_box
+ * @var array forum_data Array with forum data
+ * @var string password Password entered
+ * @since 3.1.0-RC3
+ */
+ $vars = array('forum_data', 'password');
+ extract($phpbb_dispatcher->trigger_event('core.login_forum_box', compact($vars)));
+
+ page_header($user->lang['LOGIN']);
$template->assign_vars(array(
'FORUM_NAME' => isset($forum_data['forum_name']) ? $forum_data['forum_name'] : '',
@@ -3192,7 +2647,7 @@ function parse_cfg_file($filename, $lines = false)
}
// Determine first occurrence, since in values the equal sign is allowed
- $key = strtolower(trim(substr($line, 0, $delim_pos)));
+ $key = htmlspecialchars(strtolower(trim(substr($line, 0, $delim_pos))));
$value = trim(substr($line, $delim_pos + 1));
if (in_array($value, array('off', 'false', '0')))
@@ -3209,7 +2664,11 @@ function parse_cfg_file($filename, $lines = false)
}
else if (($value[0] == "'" && $value[sizeof($value) - 1] == "'") || ($value[0] == '"' && $value[sizeof($value) - 1] == '"'))
{
- $value = substr($value, 1, sizeof($value)-2);
+ $value = htmlspecialchars(substr($value, 1, sizeof($value)-2));
+ }
+ else
+ {
+ $value = htmlspecialchars($value);
}
$parsed_items[$key] = $value;
@@ -3224,52 +2683,6 @@ function parse_cfg_file($filename, $lines = false)
}
/**
-* Add log entry
-*
-* @param string $mode The mode defines which log_type is used and from which log the entry is retrieved
-* @param int $forum_id Mode 'mod' ONLY: forum id of the related item, NOT INCLUDED otherwise
-* @param int $topic_id Mode 'mod' ONLY: topic id of the related item, NOT INCLUDED otherwise
-* @param int $reportee_id Mode 'user' ONLY: user id of the reportee, NOT INCLUDED otherwise
-* @param string $log_operation Name of the operation
-* @param array $additional_data More arguments can be added, depending on the log_type
-*
-* @return int|bool Returns the log_id, if the entry was added to the database, false otherwise.
-*
-* @deprecated Use $phpbb_log->add() instead
-*/
-function add_log()
-{
- global $phpbb_log, $user;
-
- $args = func_get_args();
- $mode = array_shift($args);
-
- // This looks kind of dirty, but add_log has some additional data before the log_operation
- $additional_data = array();
- switch ($mode)
- {
- case 'admin':
- case 'critical':
- break;
- case 'mod':
- $additional_data['forum_id'] = array_shift($args);
- $additional_data['topic_id'] = array_shift($args);
- break;
- case 'user':
- $additional_data['reportee_id'] = array_shift($args);
- break;
- }
-
- $log_operation = array_shift($args);
- $additional_data = array_merge($additional_data, $args);
-
- $user_id = (empty($user->data)) ? ANONYMOUS : $user->data['user_id'];
- $user_ip = (empty($user->ip)) ? '' : $user->ip;
-
- return $phpbb_log->add($mode, $user_id, $user_ip, $log_operation, time(), $additional_data);
-}
-
-/**
* Return a nicely formatted backtrace.
*
* Turns the array returned by debug_backtrace() into HTML markup.
@@ -3325,14 +2738,14 @@ function get_preg_expression($mode)
case 'email':
// Regex written by James Watts and Francisco Jose Martin Moreno
// http://fightingforalostcause.net/misc/2006/compare-email-regex.php
- return '([\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&amp;)+@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)';
+ return '((?:[\w\!\#$\%\&\'\*\+\-\/\=\?\^\`{\|\}\~]+\.)*(?:[\w\!\#$\%\'\*\+\-\/\=\?\^\`{\|\}\~]|&amp;)+)@((((([a-z0-9]{1}[a-z0-9\-]{0,62}[a-z0-9]{1})|[a-z])\.)+[a-z]{2,63})|(\d{1,3}\.){3}\d{1,3}(\:\d{1,5})?)';
break;
case 'bbcode_htm':
return array(
'#<!\-\- e \-\-><a href="mailto:(.*?)">.*?</a><!\-\- e \-\->#',
'#<!\-\- l \-\-><a (?:class="[\w-]+" )?href="(.*?)(?:(&amp;|\?)sid=[0-9a-f]{32})?">.*?</a><!\-\- l \-\->#',
- '#<!\-\- ([mw]) \-\-><a (?:class="[\w-]+" )?href="(.*?)">.*?</a><!\-\- \1 \-\->#',
+ '#<!\-\- ([mw]) \-\-><a (?:class="[\w-]+" )?href="(.*?)">(.*?)</a><!\-\- \1 \-\->#',
'#<!\-\- s(.*?) \-\-><img src="\{SMILIES_PATH\}\/.*? \/><!\-\- s\1 \-\->#',
'#<!\-\- .*? \-\->#s',
'#<.*?>#s',
@@ -3351,28 +2764,43 @@ function get_preg_expression($mode)
break;
case 'url':
+ // generated with regex_idn.php file in the develop folder
+ return "[a-z][a-z\d+\-.]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+ break;
+
case 'url_inline':
- $inline = ($mode == 'url') ? ')' : '';
- $scheme = ($mode == 'url') ? '[a-z\d+\-.]' : '[a-z\d+]'; // avoid automatic parsing of "word" in "last word.http://..."
- // generated with regex generation file in the develop folder
- 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})*)?";
+ // generated with regex_idn.php file in the develop folder
+ return "[a-z][a-z\d+]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?";
break;
case 'www_url':
+ // generated with regex_idn.php file in the develop folder
+ return "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+ break;
+
case 'www_url_inline':
- $inline = ($mode == 'www_url') ? ')' : '';
- 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})*)?";
+ // generated with regex_idn.php file in the develop folder
+ return "www\.(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?";
break;
case 'relative_url':
+ // generated with regex_idn.php file in the develop folder
+ return "(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";
+ break;
+
case 'relative_url_inline':
- $inline = ($mode == 'relative_url') ? ')' : '';
- 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})*)?";
+ // generated with regex_idn.php file in the develop folder
+ return "(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?";
break;
case 'table_prefix':
return '#^[a-zA-Z][a-zA-Z0-9_]*$#';
break;
+
+ // Matches the predecing dot
+ case 'path_remove_dot_trailing_slash':
+ return '#^(?:(\.)?)+(?:(.+)?)+(?:([\\/\\\])$)#';
+ break;
}
return '';
@@ -3383,31 +2811,19 @@ function get_preg_expression($mode)
* Depends on whether installed PHP version supports unicode properties
*
* @param string $word word template to be replaced
-* @param bool $use_unicode whether or not to take advantage of PCRE supporting unicode
*
* @return string $preg_expr regex to use with word censor
*/
-function get_censor_preg_expression($word, $use_unicode = true)
+function get_censor_preg_expression($word)
{
// Unescape the asterisk to simplify further conversions
$word = str_replace('\*', '*', preg_quote($word, '#'));
- if ($use_unicode && phpbb_pcre_utf8_support())
- {
- // Replace asterisk(s) inside the pattern, at the start and at the end of it with regexes
- $word = preg_replace(array('#(?<=[\p{Nd}\p{L}_])\*+(?=[\p{Nd}\p{L}_])#iu', '#^\*+#', '#\*+$#'), array('([\x20]*?|[\p{Nd}\p{L}_-]*?)', '[\p{Nd}\p{L}_-]*?', '[\p{Nd}\p{L}_-]*?'), $word);
-
- // Generate the final substitution
- $preg_expr = '#(?<![\p{Nd}\p{L}_-])(' . $word . ')(?![\p{Nd}\p{L}_-])#iu';
- }
- else
- {
- // Replace the asterisk inside the pattern, at the start and at the end of it with regexes
- $word = preg_replace(array('#(?<=\S)\*+(?=\S)#iu', '#^\*+#', '#\*+$#'), array('(\x20*?\S*?)', '\S*?', '\S*?'), $word);
+ // Replace asterisk(s) inside the pattern, at the start and at the end of it with regexes
+ $word = preg_replace(array('#(?<=[\p{Nd}\p{L}_])\*+(?=[\p{Nd}\p{L}_])#iu', '#^\*+#', '#\*+$#'), array('([\x20]*?|[\p{Nd}\p{L}_-]*?)', '[\p{Nd}\p{L}_-]*?', '[\p{Nd}\p{L}_-]*?'), $word);
- // Generate the final substitution
- $preg_expr = '#(?<!\S)(' . $word . ')(?!\S)#iu';
- }
+ // Generate the final substitution
+ $preg_expr = '#(?<![\p{Nd}\p{L}_-])(' . $word . ')(?![\p{Nd}\p{L}_-])#iu';
return $preg_expr;
}
@@ -3457,8 +2873,6 @@ function short_ipv6($ip, $length)
*
* @return mixed false if specified address is not valid,
* string otherwise
-*
-* @author bantu
*/
function phpbb_ip_normalise($address)
{
@@ -3487,8 +2901,6 @@ function phpbb_ip_normalise($address)
*
* @return mixed false on failure,
* string otherwise
-*
-* @author APTX
*/
function phpbb_inet_ntop($in_addr)
{
@@ -3558,8 +2970,6 @@ function phpbb_inet_ntop($in_addr)
*
* @return mixed false if address is invalid,
* in_addr representation of the given address otherwise (string)
-*
-* @author APTX
*/
function phpbb_inet_pton($address)
{
@@ -3639,8 +3049,6 @@ function phpbb_inet_pton($address)
*
* Since null can also be returned, you probably want to compare the result
* with === true or === false,
-*
-* @author bantu
*/
function phpbb_checkdnsrr($host, $type = 'MX')
{
@@ -3663,38 +3071,12 @@ function phpbb_checkdnsrr($host, $type = 'MX')
return (@gethostbyname($host_fqdn) == $host_fqdn) ? false : true;
}
- // checkdnsrr() is available on Windows since PHP 5.3,
- // but until 5.3.3 it only works for MX records
- // See: http://bugs.php.net/bug.php?id=51844
-
- // Call checkdnsrr() if
- // we're looking for an MX record or
- // we're not on Windows or
- // we're running a PHP version where #51844 has been fixed
-
- // checkdnsrr() supports AAAA since 5.0.0
- // checkdnsrr() supports TXT since 5.2.4
- if (
- ($type == 'MX' || DIRECTORY_SEPARATOR != '\\' || version_compare(PHP_VERSION, '5.3.3', '>=')) &&
- ($type != 'AAAA' || version_compare(PHP_VERSION, '5.0.0', '>=')) &&
- ($type != 'TXT' || version_compare(PHP_VERSION, '5.2.4', '>=')) &&
- function_exists('checkdnsrr')
- )
+ if (function_exists('checkdnsrr'))
{
return checkdnsrr($host_fqdn, $type);
}
- // dns_get_record() is available since PHP 5; since PHP 5.3 also on Windows,
- // but on Windows it does not work reliable for AAAA records before PHP 5.3.1
-
- // Call dns_get_record() if
- // we're not looking for an AAAA record or
- // we're not on Windows or
- // we're running a PHP version where AAAA lookups work reliable
- if (
- ($type != 'AAAA' || DIRECTORY_SEPARATOR != '\\' || version_compare(PHP_VERSION, '5.3.1', '>=')) &&
- function_exists('dns_get_record')
- )
+ if (function_exists('dns_get_record'))
{
// dns_get_record() expects an integer as second parameter
// We have to convert the string $type to the corresponding integer constant.
@@ -3827,7 +3209,7 @@ function phpbb_checkdnsrr($host, $type = 'MX')
function msg_handler($errno, $msg_text, $errfile, $errline)
{
global $cache, $db, $auth, $template, $config, $user, $request;
- global $phpEx, $phpbb_root_path, $msg_title, $msg_long_text;
+ global $phpbb_root_path, $msg_title, $msg_long_text, $phpbb_log;
// Do not display notices if we suppress them via @
if (error_reporting() == 0 && $errno != E_USER_ERROR && $errno != E_USER_WARNING && $errno != E_USER_NOTICE)
@@ -3841,11 +3223,6 @@ 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:
@@ -3868,7 +3245,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
// 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);
+ $phpbb_log->add('critical', $user->data['user_id'], $user->ip, 'LOG_IMAGE_GENERATION_ERROR', false, array($errfile, $errline, $msg_text));
}
// echo '<br /><br />BACKTRACE<br />' . get_backtrace() . '<br />' . "\n";
}
@@ -3879,7 +3256,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
case E_USER_ERROR:
- if (!empty($user) && !empty($user->lang))
+ if (!empty($user) && $user->is_setup())
{
$msg_text = (!empty($user->lang[$msg_text])) ? $user->lang[$msg_text] : $msg_text;
$msg_title = (!isset($msg_title)) ? $user->lang['GENERAL_ERROR'] : ((!empty($user->lang[$msg_title])) ? $user->lang[$msg_title] : $msg_title);
@@ -3914,13 +3291,23 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
if (defined('IN_INSTALL') || defined('DEBUG') || isset($auth) && $auth->acl_get('a_'))
{
$msg_text = $log_text;
+
+ // If this is defined there already was some output
+ // So let's not break it
+ if (defined('IN_DB_UPDATE'))
+ {
+ echo '<div class="errorbox">' . $msg_text . '</div>';
+
+ $db->sql_return_on_error(true);
+ phpbb_end_update($cache, $config);
+ }
}
if ((defined('IN_CRON') || defined('IMAGE_OUTPUT')) && isset($db))
{
// let's avoid loops
$db->sql_return_on_error(true);
- add_log('critical', 'LOG_GENERAL_ERROR', $msg_title, $log_text);
+ $phpbb_log->add('critical', $user->data['user_id'], $user->ip, 'LOG_GENERAL_ERROR', false, array($msg_title, $log_text));
$db->sql_return_on_error(false);
}
@@ -3964,7 +3351,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
echo ' </div>';
echo ' </div>';
echo ' <div id="page-footer">';
- echo ' Powered by <a href="https://www.phpbb.com/">phpBB</a>&reg; Forum Software &copy; phpBB Group';
+ echo ' Powered by <a href="https://www.phpbb.com/">phpBB</a>&reg; Forum Software &copy; phpBB Limited';
echo ' </div>';
echo '</div>';
echo '</body>';
@@ -3989,7 +3376,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
// We re-init the auth array to get correct results on login/logout
$auth->acl($user->data);
- if (empty($user->lang))
+ if (!$user->is_setup())
{
$user->setup();
}
@@ -4010,7 +3397,7 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
}
else
{
- page_header($msg_title, false);
+ page_header($msg_title);
}
}
@@ -4078,11 +3465,21 @@ function msg_handler($errno, $msg_text, $errfile, $errline)
*/
function phpbb_filter_root_path($errfile)
{
+ global $phpbb_filesystem;
+
static $root_path;
if (empty($root_path))
{
- $root_path = phpbb_realpath(dirname(__FILE__) . '/../');
+ if ($phpbb_filesystem)
+ {
+ $root_path = $phpbb_filesystem->realpath(dirname(__FILE__) . '/../');
+ }
+ else
+ {
+ $filesystem = new \phpbb\filesystem\filesystem();
+ $root_path = $filesystem->realpath(dirname(__FILE__) . '/../');
+ }
}
return str_replace(array($root_path, '\\'), array('[ROOT]', '/'), $errfile);
@@ -4110,7 +3507,7 @@ function obtain_guest_count($item_id = 0, $item = 'forum')
// Get number of online guests
- if ($db->sql_layer === 'sqlite')
+ if ($db->get_sql_layer() === 'sqlite' || $db->get_sql_layer() === 'sqlite3')
{
$sql = 'SELECT COUNT(session_ip) as num_guests
FROM (
@@ -4144,7 +3541,7 @@ function obtain_guest_count($item_id = 0, $item = 'forum')
*/
function obtain_users_online($item_id = 0, $item = 'forum')
{
- global $db, $config, $user;
+ global $db, $config;
$reading_sql = '';
if ($item_id !== 0)
@@ -4208,21 +3605,45 @@ function obtain_users_online($item_id = 0, $item = 'forum')
*/
function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum')
{
- global $config, $db, $user, $auth;
+ global $config, $db, $user, $auth, $phpbb_dispatcher;
- $user_online_link = $online_userlist = '';
+ $user_online_link = $rowset = array();
// Need caps version of $item for language-strings
$item_caps = strtoupper($item);
if (sizeof($online_users['online_users']))
{
- $sql = 'SELECT username, username_clean, user_id, user_type, user_allow_viewonline, user_colour
- FROM ' . USERS_TABLE . '
- WHERE ' . $db->sql_in_set('user_id', $online_users['online_users']) . '
- ORDER BY username_clean ASC';
- $result = $db->sql_query($sql);
+ $sql_ary = array(
+ 'SELECT' => 'u.username, u.username_clean, u.user_id, u.user_type, u.user_allow_viewonline, u.user_colour',
+ 'FROM' => array(
+ USERS_TABLE => 'u',
+ ),
+ 'WHERE' => $db->sql_in_set('u.user_id', $online_users['online_users']),
+ 'ORDER_BY' => 'u.username_clean ASC',
+ );
- while ($row = $db->sql_fetchrow($result))
+ /**
+ * Modify SQL query to obtain online users data
+ *
+ * @event core.obtain_users_online_string_sql
+ * @var array online_users Array with online users data
+ * from obtain_users_online()
+ * @var int item_id Restrict online users to item id
+ * @var string item Restrict online users to a certain
+ * session item, e.g. forum for
+ * session_forum_id
+ * @var string sql_ary SQL query to obtain users online data
+ * @since 3.1.4-RC1
+ * @changed 3.1.7-RC1 Change sql query into array and adjust var accordingly. Allows extension authors the ability to adjust the sql_ary.
+ */
+ $vars = array('online_users', 'item_id', 'item', 'sql_ary');
+ extract($phpbb_dispatcher->trigger_event('core.obtain_users_online_string_sql', compact($vars)));
+
+ $result = $db->sql_query($db->sql_build_query('SELECT', $sql_ary));
+ $rowset = $db->sql_fetchrowset($result);
+ $db->sql_freeresult($result);
+
+ foreach ($rowset as $row)
{
// User is logged in and therefore not a guest
if ($row['user_id'] != ANONYMOUS)
@@ -4232,15 +3653,14 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum'
$row['username'] = '<em>' . $row['username'] . '</em>';
}
- if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline'))
+ if (!isset($online_users['hidden_users'][$row['user_id']]) || $auth->acl_get('u_viewonline') || $row['user_id'] === $user->data['user_id'])
{
- $user_online_link = get_username_string(($row['user_type'] <> USER_IGNORE) ? 'full' : 'no_profile', $row['user_id'], $row['username'], $row['user_colour']);
- $online_userlist .= ($online_userlist != '') ? ', ' . $user_online_link : $user_online_link;
+ $user_online_link[$row['user_id']] = get_username_string(($row['user_type'] <> USER_IGNORE) ? 'full' : 'no_profile', $row['user_id'], $row['username'], $row['user_colour']);
}
}
}
- $db->sql_freeresult($result);
}
+ $online_userlist = implode(', ', $user_online_link);
if (!$online_userlist)
{
@@ -4273,6 +3693,33 @@ function obtain_users_online_string($online_users, $item_id = 0, $item = 'forum'
$l_online_users = $user->lang('ONLINE_USERS_TOTAL', (int) $online_users['total_online'], $visible_online, $hidden_online);
}
+ /**
+ * Modify online userlist data
+ *
+ * @event core.obtain_users_online_string_modify
+ * @var array online_users Array with online users data
+ * from obtain_users_online()
+ * @var int item_id Restrict online users to item id
+ * @var string item Restrict online users to a certain
+ * session item, e.g. forum for
+ * session_forum_id
+ * @var array rowset Array with online users data
+ * @var array user_online_link Array with online users items (usernames)
+ * @var string online_userlist String containing users online list
+ * @var string l_online_users String with total online users count info
+ * @since 3.1.4-RC1
+ */
+ $vars = array(
+ 'online_users',
+ 'item_id',
+ 'item',
+ 'rowset',
+ 'user_online_link',
+ 'online_userlist',
+ 'l_online_users',
+ );
+ extract($phpbb_dispatcher->trigger_event('core.obtain_users_online_string_modify', compact($vars)));
+
return array(
'online_userlist' => $online_userlist,
'l_online_users' => $l_online_users,
@@ -4315,178 +3762,6 @@ function phpbb_optionset($bit, $set, $data)
}
/**
-* Determine which plural form we should use.
-* For some languages this is not as simple as for English.
-*
-* @param $rule int ID of the plural rule we want to use, see http://wiki.phpbb.com/Plural_Rules#Plural_Rules
-* @param $number int|float The number we want to get the plural case for. Float numbers are floored.
-* @return int The plural-case we need to use for the number plural-rule combination
-*/
-function phpbb_get_plural_form($rule, $number)
-{
- $number = (int) $number;
-
- if ($rule > 15 || $rule < 0)
- {
- trigger_error('INVALID_PLURAL_RULE');
- }
-
- /**
- * The following plural rules are based on a list published by the Mozilla Developer Network
- * https://developer.mozilla.org/en/Localization_and_Plurals
- */
- switch ($rule)
- {
- case 0:
- /**
- * Families: Asian (Chinese, Japanese, Korean, Vietnamese), Persian, Turkic/Altaic (Turkish), Thai, Lao
- * 1 - everything: 0, 1, 2, ...
- */
- return 1;
-
- case 1:
- /**
- * Families: Germanic (Danish, Dutch, English, Faroese, Frisian, German, Norwegian, Swedish), Finno-Ugric (Estonian, Finnish, Hungarian), Language isolate (Basque), Latin/Greek (Greek), Semitic (Hebrew), Romanic (Italian, Portuguese, Spanish, Catalan)
- * 1 - 1
- * 2 - everything else: 0, 2, 3, ...
- */
- return ($number == 1) ? 1 : 2;
-
- case 2:
- /**
- * Families: Romanic (French, Brazilian Portuguese)
- * 1 - 0, 1
- * 2 - everything else: 2, 3, ...
- */
- return (($number == 0) || ($number == 1)) ? 1 : 2;
-
- case 3:
- /**
- * Families: Baltic (Latvian)
- * 1 - 0
- * 2 - ends in 1, not 11: 1, 21, ... 101, 121, ...
- * 3 - everything else: 2, 3, ... 10, 11, 12, ... 20, 22, ...
- */
- return ($number == 0) ? 1 : ((($number % 10 == 1) && ($number % 100 != 11)) ? 2 : 3);
-
- case 4:
- /**
- * Families: Celtic (Scottish Gaelic)
- * 1 - is 1 or 11: 1, 11
- * 2 - is 2 or 12: 2, 12
- * 3 - others between 3 and 19: 3, 4, ... 10, 13, ... 18, 19
- * 4 - everything else: 0, 20, 21, ...
- */
- return ($number == 1 || $number == 11) ? 1 : (($number == 2 || $number == 12) ? 2 : (($number >= 3 && $number <= 19) ? 3 : 4));
-
- case 5:
- /**
- * Families: Romanic (Romanian)
- * 1 - 1
- * 2 - is 0 or ends in 01-19: 0, 2, 3, ... 19, 101, 102, ... 119, 201, ...
- * 3 - everything else: 20, 21, ...
- */
- return ($number == 1) ? 1 : ((($number == 0) || (($number % 100 > 0) && ($number % 100 < 20))) ? 2 : 3);
-
- case 6:
- /**
- * Families: Baltic (Lithuanian)
- * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ...
- * 2 - ends in 0 or ends in 10-20: 0, 10, 11, 12, ... 19, 20, 30, 40, ...
- * 3 - everything else: 2, 3, ... 8, 9, 22, 23, ... 29, 32, 33, ...
- */
- return (($number % 10 == 1) && ($number % 100 != 11)) ? 1 : ((($number % 10 < 2) || (($number % 100 >= 10) && ($number % 100 < 20))) ? 2 : 3);
-
- case 7:
- /**
- * Families: Slavic (Croatian, Serbian, Russian, Ukrainian)
- * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, ...
- * 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ...
- * 3 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 25, 26, ...
- */
- return (($number % 10 == 1) && ($number % 100 != 11)) ? 1 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 10) || ($number % 100 >= 20))) ? 2 : 3);
-
- case 8:
- /**
- * Families: Slavic (Slovak, Czech)
- * 1 - 1
- * 2 - 2, 3, 4
- * 3 - everything else: 0, 5, 6, 7, ...
- */
- return ($number == 1) ? 1 : ((($number >= 2) && ($number <= 4)) ? 2 : 3);
-
- case 9:
- /**
- * Families: Slavic (Polish)
- * 1 - 1
- * 2 - ends in 2-4, not 12-14: 2, 3, 4, 22, 23, 24, 32, ... 104, 122, ...
- * 3 - everything else: 0, 5, 6, ... 11, 12, 13, 14, 15, ... 20, 21, 25, ...
- */
- return ($number == 1) ? 1 : ((($number % 10 >= 2) && ($number % 10 <= 4) && (($number % 100 < 12) || ($number % 100 > 14))) ? 2 : 3);
-
- case 10:
- /**
- * Families: Slavic (Slovenian, Sorbian)
- * 1 - ends in 01: 1, 101, 201, ...
- * 2 - ends in 02: 2, 102, 202, ...
- * 3 - ends in 03-04: 3, 4, 103, 104, 203, 204, ...
- * 4 - everything else: 0, 5, 6, 7, 8, 9, 10, 11, ...
- */
- return ($number % 100 == 1) ? 1 : (($number % 100 == 2) ? 2 : ((($number % 100 == 3) || ($number % 100 == 4)) ? 3 : 4));
-
- case 11:
- /**
- * Families: Celtic (Irish Gaeilge)
- * 1 - 1
- * 2 - 2
- * 3 - is 3-6: 3, 4, 5, 6
- * 4 - is 7-10: 7, 8, 9, 10
- * 5 - everything else: 0, 11, 12, ...
- */
- return ($number == 1) ? 1 : (($number == 2) ? 2 : (($number >= 3 && $number <= 6) ? 3 : (($number >= 7 && $number <= 10) ? 4 : 5)));
-
- case 12:
- /**
- * Families: Semitic (Arabic)
- * 1 - 1
- * 2 - 2
- * 3 - ends in 03-10: 3, 4, ... 10, 103, 104, ... 110, 203, 204, ...
- * 4 - ends in 11-99: 11, ... 99, 111, 112, ...
- * 5 - everything else: 100, 101, 102, 200, 201, 202, ...
- * 6 - 0
- */
- return ($number == 1) ? 1 : (($number == 2) ? 2 : ((($number % 100 >= 3) && ($number % 100 <= 10)) ? 3 : ((($number % 100 >= 11) && ($number % 100 <= 99)) ? 4 : (($number != 0) ? 5 : 6))));
-
- case 13:
- /**
- * Families: Semitic (Maltese)
- * 1 - 1
- * 2 - is 0 or ends in 01-10: 0, 2, 3, ... 9, 10, 101, 102, ...
- * 3 - ends in 11-19: 11, 12, ... 18, 19, 111, 112, ...
- * 4 - everything else: 20, 21, ...
- */
- return ($number == 1) ? 1 : ((($number == 0) || (($number % 100 > 1) && ($number % 100 < 11))) ? 2 : ((($number % 100 > 10) && ($number % 100 < 20)) ? 3 : 4));
-
- case 14:
- /**
- * Families: Slavic (Macedonian)
- * 1 - ends in 1: 1, 11, 21, ...
- * 2 - ends in 2: 2, 12, 22, ...
- * 3 - everything else: 0, 3, 4, ... 10, 13, 14, ... 20, 23, ...
- */
- return ($number % 10 == 1) ? 1 : (($number % 10 == 2) ? 2 : 3);
-
- case 15:
- /**
- * Families: Icelandic
- * 1 - ends in 1, not 11: 1, 21, 31, ... 101, 121, 131, ...
- * 2 - everything else: 0, 2, 3, ... 10, 11, 12, ... 20, 22, ...
- */
- return (($number % 10 == 1) && ($number % 100 != 11)) ? 1 : 2;
- }
-}
-
-/**
* Login using http authenticate.
*
* @param array $param Parameter array, see $param_defaults array.
@@ -4685,9 +3960,133 @@ function phpbb_build_hidden_fields_for_query_params($request, $exclude = null)
}
/**
+* Get user avatar
+*
+* @param array $user_row Row from the users table
+* @param string $alt Optional language string for alt tag within image, can be a language key or text
+* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+* @param bool $lazy If true, will be lazy loaded (requires JS)
+*
+* @return string Avatar html
+*/
+function phpbb_get_user_avatar($user_row, $alt = 'USER_AVATAR', $ignore_config = false, $lazy = false)
+{
+ $row = \phpbb\avatar\manager::clean_row($user_row, 'user');
+ return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
+}
+
+/**
+* Get group avatar
+*
+* @param array $group_row Row from the groups table
+* @param string $alt Optional language string for alt tag within image, can be a language key or text
+* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+* @param bool $lazy If true, will be lazy loaded (requires JS)
+*
+* @return string Avatar html
+*/
+function phpbb_get_group_avatar($user_row, $alt = 'GROUP_AVATAR', $ignore_config = false, $lazy = false)
+{
+ $row = \phpbb\avatar\manager::clean_row($user_row, 'group');
+ return phpbb_get_avatar($row, $alt, $ignore_config, $lazy);
+}
+
+/**
+* Get avatar
+*
+* @param array $row Row cleaned by \phpbb\avatar\manager::clean_row
+* @param string $alt Optional language string for alt tag within image, can be a language key or text
+* @param bool $ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+* @param bool $lazy If true, will be lazy loaded (requires JS)
+*
+* @return string Avatar html
+*/
+function phpbb_get_avatar($row, $alt, $ignore_config = false, $lazy = false)
+{
+ global $user, $config;
+ global $phpbb_container, $phpbb_dispatcher;
+
+ if (!$config['allow_avatar'] && !$ignore_config)
+ {
+ return '';
+ }
+
+ $avatar_data = array(
+ 'src' => $row['avatar'],
+ 'width' => $row['avatar_width'],
+ 'height' => $row['avatar_height'],
+ );
+
+ /* @var $phpbb_avatar_manager \phpbb\avatar\manager */
+ $phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
+ $driver = $phpbb_avatar_manager->get_driver($row['avatar_type'], !$ignore_config);
+ $html = '';
+
+ if ($driver)
+ {
+ $html = $driver->get_custom_html($user, $row, $alt);
+ if (!empty($html))
+ {
+ return $html;
+ }
+
+ $avatar_data = $driver->get_data($row);
+ }
+ else
+ {
+ $avatar_data['src'] = '';
+ }
+
+ if (!empty($avatar_data['src']))
+ {
+ if ($lazy)
+ {
+ // Determine board url - we may need it later
+ $board_url = generate_board_url() . '/';
+ // This path is sent with the base template paths in the assign_vars()
+ // call below. We need to correct it in case we are accessing from a
+ // controller because the web paths will be incorrect otherwise.
+ $phpbb_path_helper = $phpbb_container->get('path_helper');
+ $corrected_path = $phpbb_path_helper->get_web_root_path();
+
+ $web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $corrected_path;
+
+ $theme = "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme';
+
+ $src = 'src="' . $theme . '/images/no_avatar.gif" data-src="' . $avatar_data['src'] . '"';
+ }
+ else
+ {
+ $src = 'src="' . $avatar_data['src'] . '"';
+ }
+
+ $html = '<img class="avatar" ' . $src . ' ' .
+ ($avatar_data['width'] ? ('width="' . $avatar_data['width'] . '" ') : '') .
+ ($avatar_data['height'] ? ('height="' . $avatar_data['height'] . '" ') : '') .
+ 'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />';
+ }
+
+ /**
+ * Event to modify HTML <img> tag of avatar
+ *
+ * @event core.get_avatar_after
+ * @var array row Row cleaned by \phpbb\avatar\manager::clean_row
+ * @var string alt Optional language string for alt tag within image, can be a language key or text
+ * @var bool ignore_config Ignores the config-setting, to be still able to view the avatar in the UCP
+ * @var array avatar_data The HTML attributes for avatar <img> tag
+ * @var string html The HTML <img> tag of generated avatar
+ * @since 3.1.6-RC1
+ */
+ $vars = array('row', 'alt', 'ignore_config', 'avatar_data', 'html');
+ extract($phpbb_dispatcher->trigger_event('core.get_avatar_after', compact($vars)));
+
+ return $html;
+}
+
+/**
* Generate page header
*/
-function page_header($page_title = '', $display_online_list = true, $item_id = 0, $item = 'forum')
+function page_header($page_title = '', $display_online_list = false, $item_id = 0, $item = 'forum')
{
global $db, $config, $template, $SID, $_SID, $_EXTRA_URL, $user, $auth, $phpEx, $phpbb_root_path;
global $phpbb_dispatcher, $request, $phpbb_container, $phpbb_admin_path;
@@ -4714,7 +4113,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
* @var int item_id Restrict online users to item id
* @var bool page_header_override Shall we return instead of running
* the rest of page_header()
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('page_title', 'display_online_list', 'item_id', 'item', 'page_header_override');
extract($phpbb_dispatcher->trigger_event('core.page_header', compact($vars)));
@@ -4751,7 +4150,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
if ($user->data['user_id'] != ANONYMOUS)
{
$u_login_logout = append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=logout', true, $user->session_id);
- $l_login_logout = sprintf($user->lang['LOGOUT_USER'], $user->data['username']);
+ $l_login_logout = $user->lang['LOGOUT'];
}
else
{
@@ -4782,8 +4181,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
if ($total_online_users > $config['record_online_users'])
{
- set_config('record_online_users', $total_online_users, true);
- set_config('record_online_date', time(), true);
+ $config->set('record_online_users', $total_online_users, false);
+ $config->set('record_online_date', time(), false);
}
$l_online_record = $user->lang('RECORD_ONLINE_USERS', (int) $config['record_online_users'], $user->format_date($config['record_online_date'], false, true));
@@ -4818,8 +4217,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
}
}
- $forum_id = request_var('f', 0);
- $topic_id = request_var('t', 0);
+ $forum_id = $request->variable('f', 0);
+ $topic_id = $request->variable('t', 0);
$s_feed_news = false;
@@ -4839,6 +4238,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
// This path is sent with the base template paths in the assign_vars()
// call below. We need to correct it in case we are accessing from a
// controller because the web paths will be incorrect otherwise.
+ /* @var $phpbb_path_helper \phpbb\path_helper */
$phpbb_path_helper = $phpbb_container->get('path_helper');
$corrected_path = $phpbb_path_helper->get_web_root_path();
$web_path = (defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH) ? $board_url : $corrected_path;
@@ -4865,8 +4265,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
}
}
- $dt = new \phpbb\datetime($user, 'now', $user->timezone);
- $timezone_offset = 'GMT' . phpbb_format_timezone_offset($dt->getOffset());
+ $dt = $user->create_datetime();
+ $timezone_offset = $user->lang(array('timezones', 'UTC_OFFSET'), phpbb_format_timezone_offset($dt->getOffset()));
$timezone_name = $user->timezone->getName();
if (isset($user->lang['timezones'][$timezone_name]))
{
@@ -4875,11 +4275,12 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
// Output the notifications
$notifications = false;
- if ($config['load_notifications'] && $user->data['user_id'] != ANONYMOUS && $user->data['user_type'] != USER_IGNORE)
+ if ($config['load_notifications'] && $config['allow_board_notifications'] && $user->data['user_id'] != ANONYMOUS && $user->data['user_type'] != USER_IGNORE)
{
+ /* @var $phpbb_notifications \phpbb\notification\manager */
$phpbb_notifications = $phpbb_container->get('notification_manager');
- $notifications = $phpbb_notifications->load_notifications(array(
+ $notifications = $phpbb_notifications->load_notifications('notification.method.board', array(
'all_unread' => true,
'limit' => 5,
));
@@ -4890,7 +4291,8 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
}
}
- $hidden_fields_for_jumpbox = phpbb_build_hidden_fields_for_query_params($request, array('f'));
+ /** @var \phpbb\controller\helper $controller_helper */
+ $controller_helper = $phpbb_container->get('controller.helper');
$notification_mark_hash = generate_link_hash('mark_all_notifications_read');
// The following assigns all _common_ variables that may be used at any point in a template.
@@ -4905,15 +4307,17 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
'TOTAL_USERS_ONLINE' => $l_online_users,
'LOGGED_IN_USER_LIST' => $online_userlist,
'RECORD_USERS' => $l_online_record,
- 'PRIVATE_MESSAGE_COUNT' => (!empty($user->data['user_unread_privmsg'])) ? $user->data['user_unread_privmsg'] : 0,
- 'HIDDEN_FIELDS_FOR_JUMPBOX' => $hidden_fields_for_jumpbox,
+ 'PRIVATE_MESSAGE_COUNT' => (!empty($user->data['user_unread_privmsg'])) ? $user->data['user_unread_privmsg'] : 0,
+ 'CURRENT_USER_AVATAR' => phpbb_get_user_avatar($user->data),
+ 'CURRENT_USERNAME_SIMPLE' => get_username_string('no_profile', $user->data['user_id'], $user->data['username'], $user->data['user_colour']),
+ 'CURRENT_USERNAME_FULL' => get_username_string('full', $user->data['user_id'], $user->data['username'], $user->data['user_colour']),
'UNREAD_NOTIFICATIONS_COUNT' => ($notifications !== false) ? $notifications['unread_count'] : '',
'NOTIFICATIONS_COUNT' => ($notifications !== false) ? $notifications['unread_count'] : '',
'U_VIEW_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications'),
'U_MARK_ALL_NOTIFICATIONS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&amp;mode=notification_list&amp;mark=all&amp;token=' . $notification_mark_hash),
'U_NOTIFICATION_SETTINGS' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'i=ucp_notifications&amp;mode=notification_options'),
- 'S_NOTIFICATIONS_DISPLAY' => $config['load_notifications'],
+ 'S_NOTIFICATIONS_DISPLAY' => $config['load_notifications'] && $config['allow_board_notifications'],
'S_USER_NEW_PRIVMSG' => $user->data['user_new_privmsg'],
'S_USER_UNREAD_PRIVMSG' => $user->data['user_unread_privmsg'],
@@ -4940,19 +4344,21 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
'U_SITE_HOME' => $config['site_home_url'],
'U_REGISTER' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=register'),
'U_PROFILE' => append_sid("{$phpbb_root_path}ucp.$phpEx"),
+ 'U_USER_PROFILE' => get_username_string('profile', $user->data['user_id'], $user->data['username'], $user->data['user_colour']),
'U_MODCP' => append_sid("{$phpbb_root_path}mcp.$phpEx", false, true, $user->session_id),
- 'U_FAQ' => append_sid("{$phpbb_root_path}faq.$phpEx"),
+ 'U_FAQ' => $controller_helper->route('phpbb_help_faq_controller'),
'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_CONTACT_US' => ($config['contact_admin_form_enable'] && $config['email_enable']) ? append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contactadmin') : '',
+ 'U_TEAM' => ($user->data['user_id'] != ANONYMOUS && !$auth->acl_get('u_viewprofile')) ? '' : append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=team'),
'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",
+ 'U_FEED' => $controller_helper->route('phpbb_feed_index'),
'S_USER_LOGGED_IN' => ($user->data['user_id'] != ANONYMOUS) ? true : false,
'S_AUTOLOGIN_ENABLED' => ($config['allow_autologin']) ? true : false,
@@ -4977,7 +4383,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
'S_TOPIC_ID' => $topic_id,
'S_LOGIN_ACTION' => ((!defined('ADMIN_START')) ? append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login') : append_sid("{$phpbb_admin_path}index.$phpEx", false, true, $user->session_id)),
- 'S_LOGIN_REDIRECT' => build_hidden_fields(array('redirect' => build_url())),
+ 'S_LOGIN_REDIRECT' => build_hidden_fields(array('redirect' => $phpbb_path_helper->remove_web_root_path(build_url()))),
'S_ENABLE_FEEDS' => ($config['feed_enable']) ? true : false,
'S_ENABLE_FEEDS_OVERALL' => ($config['feed_overall']) ? true : false,
@@ -5003,8 +4409,9 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/",
'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/",
'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'],
- 'T_STYLESHEET_LANG_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'],
- 'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.js?assets_version=" . $config['assets_version'],
+ 'T_STYLESHEET_LANG_LINK'=> "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'],
+ 'T_FONT_AWESOME_LINK' => !empty($config['allow_cdn']) && !empty($config['load_font_awesome_url']) ? $config['load_font_awesome_url'] : "{$web_path}assets/css/font-awesome.min.css?assets_version=" . $config['assets_version'],
+ 'T_JQUERY_LINK' => !empty($config['allow_cdn']) && !empty($config['load_jquery_url']) ? $config['load_jquery_url'] : "{$web_path}assets/javascript/jquery.min.js?assets_version=" . $config['assets_version'],
'S_ALLOW_CDN' => !empty($config['allow_cdn']),
'T_THEME_NAME' => rawurlencode($user->style['style_path']),
@@ -5022,23 +4429,123 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
'SITE_LOGO_IMG' => $user->img('site_logo'),
));
- // application/xhtml+xml not used because of IE
- header('Content-type: text/html; charset=UTF-8');
-
- header('Cache-Control: private, no-cache="set-cookie"');
- header('Expires: 0');
- header('Pragma: no-cache');
-
+ // An array of http headers that phpbb will set. The following event may override these.
+ $http_headers = array(
+ // application/xhtml+xml not used because of IE
+ 'Content-type' => 'text/html; charset=UTF-8',
+ 'Cache-Control' => 'private, no-cache="set-cookie"',
+ 'Expires' => gmdate('D, d M Y H:i:s', time()) . ' GMT',
+ );
if (!empty($user->data['is_bot']))
{
// Let reverse proxies know we detected a bot.
- header('X-PHPBB-IS-BOT: yes');
+ $http_headers['X-PHPBB-IS-BOT'] = 'yes';
+ }
+
+ /**
+ * Execute code and/or overwrite _common_ template variables after they have been assigned.
+ *
+ * @event core.page_header_after
+ * @var string page_title Page title
+ * @var bool display_online_list Do we display online users list
+ * @var string item Restrict online users to a certain
+ * session item, e.g. forum for
+ * session_forum_id
+ * @var int item_id Restrict online users to item id
+ * @var array http_headers HTTP headers that should be set by phpbb
+ *
+ * @since 3.1.0-b3
+ */
+ $vars = array('page_title', 'display_online_list', 'item_id', 'item', 'http_headers');
+ extract($phpbb_dispatcher->trigger_event('core.page_header_after', compact($vars)));
+
+ foreach ($http_headers as $hname => $hval)
+ {
+ header((string) $hname . ': ' . (string) $hval);
}
return;
}
/**
+* Check and display the SQL report if requested.
+*
+* @param \phpbb\request\request_interface $request Request object
+* @param \phpbb\auth\auth $auth Auth object
+* @param \phpbb\db\driver\driver_interface $db Database connection
+*/
+function phpbb_check_and_display_sql_report(\phpbb\request\request_interface $request, \phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db)
+{
+ if ($request->variable('explain', false) && $auth->acl_get('a_') && defined('DEBUG'))
+ {
+ $db->sql_report('display');
+ }
+}
+
+/**
+* Generate the debug output string
+*
+* @param \phpbb\db\driver\driver_interface $db Database connection
+* @param \phpbb\config\config $config Config object
+* @param \phpbb\auth\auth $auth Auth object
+* @param \phpbb\user $user User object
+* @param \phpbb\event\dispatcher_interface $phpbb_dispatcher Event dispatcher
+* @return string
+*/
+function phpbb_generate_debug_output(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\auth\auth $auth, \phpbb\user $user, \phpbb\event\dispatcher_interface $phpbb_dispatcher)
+{
+ $debug_info = array();
+
+ // Output page creation time
+ if (defined('PHPBB_DISPLAY_LOAD_TIME'))
+ {
+ if (isset($GLOBALS['starttime']))
+ {
+ $totaltime = microtime(true) - $GLOBALS['starttime'];
+ $debug_info[] = sprintf('<span title="SQL time: %.3fs / PHP time: %.3fs">Time: %.3fs</span>', $db->get_sql_time(), ($totaltime - $db->get_sql_time()), $totaltime);
+ }
+
+ $debug_info[] = sprintf('<span title="Cached: %d">Queries: %d</span>', $db->sql_num_queries(true), $db->sql_num_queries());
+
+ $memory_usage = memory_get_peak_usage();
+ if ($memory_usage)
+ {
+ $memory_usage = get_formatted_filesize($memory_usage);
+
+ $debug_info[] = 'Peak Memory Usage: ' . $memory_usage;
+ }
+ }
+
+ if (defined('DEBUG'))
+ {
+ $debug_info[] = 'GZIP: ' . (($config['gzip_compress'] && @extension_loaded('zlib')) ? 'On' : 'Off');
+
+ if ($user->load)
+ {
+ $debug_info[] = 'Load: ' . $user->load;
+ }
+
+ if ($auth->acl_get('a_'))
+ {
+ $debug_info[] = '<a href="' . build_url() . '&amp;explain=1">SQL Explain</a>';
+ }
+ }
+
+ /**
+ * Modify debug output information
+ *
+ * @event core.phpbb_generate_debug_output
+ * @var array debug_info Array of strings with debug information
+ *
+ * @since 3.1.0-RC3
+ */
+ $vars = array('debug_info');
+ extract($phpbb_dispatcher->trigger_event('core.phpbb_generate_debug_output', compact($vars)));
+
+ return implode(' | ', $debug_info);
+}
+
+/**
* Generate page footer
*
* @param bool $run_cron Whether or not to run the cron
@@ -5047,7 +4554,7 @@ function page_header($page_title = '', $display_online_list = true, $item_id = 0
*/
function page_footer($run_cron = true, $display_template = true, $exit_handler = true)
{
- global $db, $config, $template, $user, $auth, $cache, $starttime, $phpbb_root_path, $phpEx;
+ global $db, $config, $template, $user, $auth, $cache, $phpEx;
global $request, $phpbb_dispatcher, $phpbb_admin_path;
// A listener can set this variable to `true` when it overrides this function
@@ -5060,7 +4567,7 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =
* @var bool run_cron Shall we run cron tasks
* @var bool page_footer_override Shall we return instead of running
* the rest of page_footer()
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$vars = array('run_cron', 'page_footer_override');
extract($phpbb_dispatcher->trigger_event('core.page_footer', compact($vars)));
@@ -5070,46 +4577,21 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =
return;
}
- // Output page creation time
- if (defined('DEBUG'))
- {
- $mtime = explode(' ', microtime());
- $totaltime = $mtime[0] + $mtime[1] - $starttime;
-
- if ($request->variable('explain', false) && $auth->acl_get('a_') && defined('DEBUG') && method_exists($db, 'sql_report'))
- {
- $db->sql_report('display');
- }
+ $user->update_session_infos();
- $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'))
- {
- if (function_exists('memory_get_peak_usage'))
- {
- if ($memory_usage = memory_get_peak_usage())
- {
- $memory_usage = get_formatted_filesize($memory_usage);
-
- $debug_output .= ' | Peak Memory Usage: ' . $memory_usage;
- }
- }
-
- $debug_output .= ' | <a href="' . build_url() . '&amp;explain=1">Explain</a>';
- }
- }
+ phpbb_check_and_display_sql_report($request, $auth, $db);
$template->assign_vars(array(
- 'DEBUG_OUTPUT' => (defined('DEBUG')) ? $debug_output : '',
+ 'DEBUG_OUTPUT' => phpbb_generate_debug_output($db, $config, $auth, $user, $phpbb_dispatcher),
'TRANSLATION_INFO' => (!empty($user->lang['TRANSLATION_INFO'])) ? $user->lang['TRANSLATION_INFO'] : '',
- 'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>&reg; Forum Software &copy; phpBB Group'),
+ 'CREDIT_LINE' => $user->lang('POWERED_BY', '<a href="https://www.phpbb.com/">phpBB</a>&reg; Forum Software &copy; phpBB Limited'),
'U_ACP' => ($auth->acl_get('a_') && !empty($user->data['is_registered'])) ? append_sid("{$phpbb_admin_path}index.$phpEx", false, true, $user->session_id) : '')
);
// Call cron-type script
$call_cron = false;
- if (!defined('IN_CRON') && !$config['use_system_cron'] && $run_cron && !$config['board_disable'] && !$user->data['is_bot'])
+ if (!defined('IN_CRON') && !$config['use_system_cron'] && $run_cron && !$config['board_disable'] && !$user->data['is_bot'] && !$cache->get('_cron.lock_check'))
{
$call_cron = true;
$time_now = (!empty($user->time_now) && is_int($user->time_now)) ? $user->time_now : time();
@@ -5130,7 +4612,10 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =
// Call cron job?
if ($call_cron)
{
- global $cron;
+ global $phpbb_container;
+
+ /* @var $cron \phpbb\cron\manager */
+ $cron = $phpbb_container->get('cron.manager');
$task = $cron->find_one_ready_task();
if ($task)
@@ -5138,8 +4623,24 @@ function page_footer($run_cron = true, $display_template = true, $exit_handler =
$url = $task->get_url();
$template->assign_var('RUN_CRON_TASK', '<img src="' . $url . '" width="1" height="1" alt="cron" />');
}
+ else
+ {
+ $cache->put('_cron.lock_check', true, 60);
+ }
}
+ /**
+ * Execute code and/or modify output before displaying the template.
+ *
+ * @event core.page_footer_after
+ * @var bool display_template Whether or not to display the template
+ * @var bool exit_handler Whether or not to run the exit_handler()
+ *
+ * @since 3.1.0-RC5
+ */
+ $vars = array('display_template', 'exit_handler');
+ extract($phpbb_dispatcher->trigger_event('core.page_footer_after', compact($vars)));
+
if ($display_template)
{
$template->display('body');
@@ -5168,7 +4669,7 @@ function garbage_collection()
* Unload some objects, to free some memory, before we finish our task
*
* @event core.garbage_collection
- * @since 3.1-A1
+ * @since 3.1.0-a1
*/
$phpbb_dispatcher->dispatch('core.garbage_collection');
}
@@ -5194,7 +4695,7 @@ function garbage_collection()
*/
function exit_handler()
{
- global $phpbb_hook, $config;
+ global $phpbb_hook;
if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__))
{
@@ -5230,22 +4731,6 @@ function phpbb_user_session_handler()
}
/**
-* Check if PCRE has UTF-8 support
-* PHP may not be linked with the bundled PCRE lib and instead with an older version
-*
-* @return bool Returns true if PCRE (the regular expressions library) supports UTF-8 encoding
-*/
-function phpbb_pcre_utf8_support()
-{
- static $utf8_pcre_properties = null;
- if (is_null($utf8_pcre_properties))
- {
- $utf8_pcre_properties = (@preg_match('/\p{L}/u', 'a') !== false);
- }
- return $utf8_pcre_properties;
-}
-
-/**
* Casts a numeric string $input to an appropriate numeric type (i.e. integer or float)
*
* @param string $input A numeric string.
@@ -5259,47 +4744,40 @@ function phpbb_to_numeric($input)
}
/**
-* Convert either 3.0 dbms or 3.1 db driver class name to 3.1 db driver class name.
-*
-* If $dbms is a valid 3.1 db driver class name, returns it unchanged.
-* Otherwise prepends phpbb\db\driver\ to the dbms to convert a 3.0 dbms
-* to 3.1 db driver class name.
+* Get the board contact details (e.g. for emails)
*
-* @param string $dbms dbms parameter
-* @return db driver class
+* @param \phpbb\config\config $config
+* @param string $phpEx
+* @return string
*/
-function phpbb_convert_30_dbms_to_31($dbms)
+function phpbb_get_board_contact(\phpbb\config\config $config, $phpEx)
{
- // Note: this check is done first because mysqli extension
- // supplies a mysqli class, and class_exists($dbms) would return
- // true for mysqli class.
- // However, per the docblock any valid 3.1 driver name should be
- // recognized by this function, and have priority over 3.0 dbms.
- if (class_exists('phpbb\db\driver\\' . $dbms))
+ if ($config['contact_admin_form_enable'])
{
- return 'phpbb\db\driver\\' . $dbms;
+ return generate_board_url() . '/memberlist.' . $phpEx . '?mode=contactadmin';
}
-
- if (class_exists($dbms))
+ else
{
- // Additionally we could check that $dbms extends phpbb\db\driver\driver.
- // http://php.net/manual/en/class.reflectionclass.php
- // Beware of possible performance issues:
- // http://stackoverflow.com/questions/294582/php-5-reflection-api-performance
- // We could check for interface implementation in all paths or
- // only when we do not prepend phpbb\db\driver\.
-
- /*
- $reflection = new \ReflectionClass($dbms);
-
- if ($reflection->isSubclassOf('phpbb\db\driver\driver'))
- {
- return $dbms;
- }
- */
-
- return $dbms;
+ return $config['board_contact'];
}
+}
- throw new \RuntimeException("You have specified an invalid dbms driver: $dbms");
+/**
+* Get a clickable board contact details link
+*
+* @param \phpbb\config\config $config
+* @param string $phpbb_root_path
+* @param string $phpEx
+* @return string
+*/
+function phpbb_get_board_contact_link(\phpbb\config\config $config, $phpbb_root_path, $phpEx)
+{
+ if ($config['contact_admin_form_enable'] && $config['email_enable'])
+ {
+ return append_sid("{$phpbb_root_path}memberlist.$phpEx", 'mode=contactadmin');
+ }
+ else
+ {
+ return 'mailto:' . htmlspecialchars($config['board_contact']);
+ }
}