diff options
Diffstat (limited to 'phpBB/phpbb')
50 files changed, 989 insertions, 307 deletions
diff --git a/phpBB/phpbb/avatar/driver/local.php b/phpBB/phpbb/avatar/driver/local.php index 07b3ed59de..8888686b2d 100644 --- a/phpBB/phpbb/avatar/driver/local.php +++ b/phpBB/phpbb/avatar/driver/local.php @@ -154,7 +154,7 @@ class local extends \phpbb\avatar\driver\driver */ protected function get_avatar_list($user) { - $avatar_list = ($this->cache == null) ? false : $this->cache->get('avatar_local_list'); + $avatar_list = ($this->cache == null) ? false : $this->cache->get('_avatar_local_list'); if ($avatar_list === false) { @@ -192,7 +192,7 @@ class local extends \phpbb\avatar\driver\driver if ($this->cache != null) { - $this->cache->put('avatar_local_list', $avatar_list, 86400); + $this->cache->put('_avatar_local_list', $avatar_list, 86400); } } diff --git a/phpBB/phpbb/avatar/driver/remote.php b/phpBB/phpbb/avatar/driver/remote.php index 1bd7f6c927..4b0ee3f06f 100644 --- a/phpBB/phpbb/avatar/driver/remote.php +++ b/phpBB/phpbb/avatar/driver/remote.php @@ -130,8 +130,24 @@ class remote extends \phpbb\avatar\driver\driver { // Timeout after 1 second stream_set_timeout($file_stream, 1); + // read some data to ensure headers are present + fread($file_stream, 1024); $meta = stream_get_meta_data($file_stream); - foreach ($meta['wrapper_data'] as $header) + + if (isset($meta['wrapper_data']['headers']) && is_array($meta['wrapper_data']['headers'])) + { + $headers = $meta['wrapper_data']['headers']; + } + else if (isset($meta['wrapper_data']) && is_array($meta['wrapper_data'])) + { + $headers = $meta['wrapper_data']; + } + else + { + $headers = array(); + } + + foreach ($headers as $header) { $header = preg_split('/ /', $header, 2); if (strtr(strtolower(trim($header[0], ':')), '_', '-') === 'content-type') diff --git a/phpBB/phpbb/cache/driver/memory.php b/phpBB/phpbb/cache/driver/memory.php index 56308be8da..0b0e323e3d 100644 --- a/phpBB/phpbb/cache/driver/memory.php +++ b/phpBB/phpbb/cache/driver/memory.php @@ -208,12 +208,24 @@ abstract class memory extends \phpbb\cache\driver\base // determine which tables this query belongs to // Some queries use backticks, namely the get_database_size() query // don't check for conformity, the SQL would error and not reach here. - if (!preg_match('/FROM \\(?(`?\\w+`?(?: \\w+)?(?:, ?`?\\w+`?(?: \\w+)?)*)\\)?/', $query, $regs)) + if (!preg_match_all('/(?:FROM \\(?(`?\\w+`?(?: \\w+)?(?:, ?`?\\w+`?(?: \\w+)?)*)\\)?)|(?:JOIN (`?\\w+`?(?: \\w+)?))/', $query, $regs, PREG_SET_ORDER)) { // Bail out if the match fails. return $query_result; } - $tables = array_map('trim', explode(',', $regs[1])); + + $tables = array(); + foreach ($regs as $match) + { + if ($match[0][0] == 'F') + { + $tables = array_merge($tables, array_map('trim', explode(',', $match[1]))); + } + else + { + $tables[] = $match[2]; + } + } foreach ($tables as $table_name) { diff --git a/phpBB/phpbb/console/command/cache/purge.php b/phpBB/phpbb/console/command/cache/purge.php index ec8229200c..d0c2ef6f72 100644 --- a/phpBB/phpbb/console/command/cache/purge.php +++ b/phpBB/phpbb/console/command/cache/purge.php @@ -26,7 +26,7 @@ class purge extends \phpbb\console\command\command /** @var \phpbb\auth\auth */ protected $auth; - /** @var \phpbb\log\log */ + /** @var \phpbb\log\log_interface */ protected $log; /** @var \phpbb\config\config */ @@ -42,7 +42,7 @@ class purge extends \phpbb\console\command\command * @param \phpbb\log\log $log Logger instance * @param \phpbb\config\config $config Config instance */ - public function __construct(\phpbb\user $user, \phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\auth\auth $auth, \phpbb\log\log $log, \phpbb\config\config $config) + public function __construct(\phpbb\user $user, \phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\auth\auth $auth, \phpbb\log\log_interface $log, \phpbb\config\config $config) { $this->cache = $cache; $this->db = $db; diff --git a/phpBB/phpbb/console/command/db/console_migrator_output_handler.php b/phpBB/phpbb/console/command/db/console_migrator_output_handler.php new file mode 100644 index 0000000000..b9741a3838 --- /dev/null +++ b/phpBB/phpbb/console/command/db/console_migrator_output_handler.php @@ -0,0 +1,69 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\console\command\db; + +use phpbb\user; +use phpbb\db\migrator_output_handler_interface; +use Symfony\Component\Console\Output\OutputInterface; + +class console_migrator_output_handler implements migrator_output_handler_interface +{ + /** + * User object. + * + * @var user + */ + private $user; + + /** + * Console output object. + * + * @var OutputInterface + */ + private $output; + + /** + * Constructor + * + * @param user $user User object + * @param OutputInterface $output Console output object + */ + public function __construct(user $user, OutputInterface $output) + { + $this->user = $user; + $this->output = $output; + } + + /** + * {@inheritdoc} + */ + public function write($message, $verbosity) + { + if ($verbosity <= $this->output->getVerbosity()) + { + $translated_message = call_user_func_array(array($this->user, 'lang'), $message); + + if ($verbosity === migrator_output_handler_interface::VERBOSITY_NORMAL) + { + $translated_message = '<info>' . $translated_message . '</info>'; + } + else if ($verbosity === migrator_output_handler_interface::VERBOSITY_VERBOSE) + { + $translated_message = '<comment>' . $translated_message . '</comment>'; + } + + $this->output->writeln($translated_message); + } + } +} diff --git a/phpBB/phpbb/console/command/db/migrate.php b/phpBB/phpbb/console/command/db/migrate.php index 86545c237d..87c2a057d1 100644 --- a/phpBB/phpbb/console/command/db/migrate.php +++ b/phpBB/phpbb/console/command/db/migrate.php @@ -32,13 +32,17 @@ class migrate extends \phpbb\console\command\command /** @var \phpbb\log\log */ protected $log; - function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log) + /** @var string phpBB root path */ + protected $phpbb_root_path; + + function __construct(\phpbb\user $user, \phpbb\db\migrator $migrator, \phpbb\extension\manager $extension_manager, \phpbb\config\config $config, \phpbb\cache\service $cache, \phpbb\log\log $log, $phpbb_root_path) { $this->migrator = $migrator; $this->extension_manager = $extension_manager; $this->config = $config; $this->cache = $cache; $this->log = $log; + $this->phpbb_root_path = $phpbb_root_path; parent::__construct($user); $this->user->add_lang(array('common', 'install', 'migrator')); } @@ -53,14 +57,16 @@ class migrate extends \phpbb\console\command\command protected function execute(InputInterface $input, OutputInterface $output) { + $this->migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($this->user, new console_migrator_output_handler($this->user, $output), $this->phpbb_root_path . 'store/migrations_' . time() . '.log')); + $this->migrator->create_migrations_table(); + $this->cache->purge(); + $this->load_migrations(); $orig_version = $this->config['version']; while (!$this->migrator->finished()) { - $migration_start_time = microtime(true); - try { $this->migrator->update(); @@ -71,36 +77,6 @@ class migrate extends \phpbb\console\command\command $this->finalise_update(); return 1; } - - $migration_stop_time = microtime(true) - $migration_start_time; - - $state = array_merge( - array( - 'migration_schema_done' => false, - 'migration_data_done' => false, - ), - $this->migrator->last_run_migration['state'] - ); - - if (!empty($this->migrator->last_run_migration['effectively_installed'])) - { - $msg = $this->user->lang('MIGRATION_EFFECTIVELY_INSTALLED', $this->migrator->last_run_migration['name']); - $output->writeln("<comment>$msg</comment>"); - } - else if ($this->migrator->last_run_migration['task'] == 'process_data_step' && $state['migration_data_done']) - { - $msg = $this->user->lang('MIGRATION_DATA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time); - $output->writeln("<info>$msg</info>"); - } - else if ($this->migrator->last_run_migration['task'] == 'process_data_step') - { - $output->writeln($this->user->lang('MIGRATION_DATA_IN_PROGRESS', $this->migrator->last_run_migration['name'], $migration_stop_time)); - } - else if ($state['migration_schema_done']) - { - $msg = $this->user->lang('MIGRATION_SCHEMA_DONE', $this->migrator->last_run_migration['name'], $migration_stop_time); - $output->writeln("<info>$msg</info>"); - } } if ($orig_version != $this->config['version']) diff --git a/phpBB/phpbb/controller/helper.php b/phpBB/phpbb/controller/helper.php index fc19b855c0..187e455d48 100644 --- a/phpBB/phpbb/controller/helper.php +++ b/phpBB/phpbb/controller/helper.php @@ -140,14 +140,17 @@ class helper // If enable_mod_rewrite is false we need to replace the current front-end by app.php, otherwise we need to remove it. $base_url = str_replace('/' . $page_name, empty($this->config['enable_mod_rewrite']) ? '/app.' . $this->php_ext : '', $base_url); - // We need to update the base url to move to the directory of the app.php file - if (empty($this->config['enable_mod_rewrite'])) + // We need to update the base url to move to the directory of the app.php file if the current script is not app.php + if ($page_name !== 'app.php') { - $base_url = str_replace('/app.' . $this->php_ext, '/' . $this->phpbb_root_path . 'app.' . $this->php_ext, $base_url); - } - else - { - $base_url .= preg_replace(get_preg_expression('path_remove_dot_trailing_slash'), '$2', $this->phpbb_root_path); + if (empty($this->config['enable_mod_rewrite'])) + { + $base_url = str_replace('/app.' . $this->php_ext, '/' . $this->phpbb_root_path . 'app.' . $this->php_ext, $base_url); + } + else + { + $base_url .= preg_replace(get_preg_expression('path_remove_dot_trailing_slash'), '$2', $this->phpbb_root_path); + } } $base_url = $this->filesystem->clean_path($base_url); diff --git a/phpBB/phpbb/cron/manager.php b/phpBB/phpbb/cron/manager.php index 5c8ac04b77..079ce8107e 100644 --- a/phpBB/phpbb/cron/manager.php +++ b/phpBB/phpbb/cron/manager.php @@ -73,6 +73,7 @@ class manager */ public function find_one_ready_task() { + shuffle($this->tasks); foreach ($this->tasks as $task) { if ($task->is_ready()) diff --git a/phpBB/phpbb/cron/task/core/queue.php b/phpBB/phpbb/cron/task/core/queue.php index 796a96d7f5..a9345a44df 100644 --- a/phpBB/phpbb/cron/task/core/queue.php +++ b/phpBB/phpbb/cron/task/core/queue.php @@ -73,6 +73,6 @@ class queue extends \phpbb\cron\task\base */ public function should_run() { - return $this->config['last_queue_run'] < time() - $this->config['queue_interval_config']; + return $this->config['last_queue_run'] < time() - $this->config['queue_interval']; } } diff --git a/phpBB/phpbb/datetime.php b/phpBB/phpbb/datetime.php index e674707883..63cdba90fd 100644 --- a/phpBB/phpbb/datetime.php +++ b/phpBB/phpbb/datetime.php @@ -91,25 +91,28 @@ class datetime extends \DateTime $midnight = $midnight->getTimestamp(); - $day = false; - - if ($timestamp > $midnight + 86400) - { - $day = 'TOMORROW'; - } - else if ($timestamp > $midnight) - { - $day = 'TODAY'; - } - else if ($timestamp > $midnight - 86400) - { - $day = 'YESTERDAY'; - } - - if ($day !== false) + if ($timestamp <= $midnight + 2 * 86400) { - // Format using the short formatting and finally swap out the relative token placeholder with the correct value - return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang'])); + $day = false; + + if ($timestamp > $midnight + 86400) + { + $day = 'TOMORROW'; + } + else if ($timestamp > $midnight) + { + $day = 'TODAY'; + } + else if ($timestamp > $midnight - 86400) + { + $day = 'YESTERDAY'; + } + + if ($day !== false) + { + // Format using the short formatting and finally swap out the relative token placeholder with the correct value + return str_replace(self::RELATIVE_WRAPPER . self::RELATIVE_WRAPPER, $this->user->lang['datetime'][$day], strtr(parent::format($format['format_short']), $format['lang'])); + } } } } diff --git a/phpBB/phpbb/db/html_migrator_output_handler.php b/phpBB/phpbb/db/html_migrator_output_handler.php new file mode 100644 index 0000000000..e37c667463 --- /dev/null +++ b/phpBB/phpbb/db/html_migrator_output_handler.php @@ -0,0 +1,48 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db; + +use phpbb\user; + +class html_migrator_output_handler implements migrator_output_handler_interface +{ + /** + * User object. + * + * @var user + */ + private $user; + + /** + * Constructor + * + * @param user $user User object + */ + public function __construct(user $user) + { + $this->user = $user; + } + + /** + * {@inheritdoc} + */ + public function write($message, $verbosity) + { + if ($verbosity <= migrator_output_handler_interface::VERBOSITY_VERBOSE) + { + $final_message = call_user_func_array(array($this->user, 'lang'), $message); + echo $final_message . "<br />\n"; + } + } +} diff --git a/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php b/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php new file mode 100644 index 0000000000..94c293dc45 --- /dev/null +++ b/phpBB/phpbb/db/log_wrapper_migrator_output_handler.php @@ -0,0 +1,95 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db; + +use phpbb\user; + +class log_wrapper_migrator_output_handler implements migrator_output_handler_interface +{ + /** + * User object. + * + * @var user + */ + protected $user; + + /** + * A migrator output handler + * + * @var migrator_output_handler_interface + */ + protected $migrator; + + /** + * Log file handle + * @var resource + */ + protected $file_handle = false; + + /** + * Constructor + * + * @param user $user User object + * @param migrator_output_handler_interface $migrator Migrator output handler + * @param string $log_file File to log to + */ + public function __construct(user $user, migrator_output_handler_interface $migrator, $log_file) + { + $this->user = $user; + $this->migrator = $migrator; + $this->file_open($log_file); + } + + /** + * Open file for logging + * + * @param string $file File to open + */ + protected function file_open($file) + { + if (phpbb_is_writable(dirname($file))) + { + $this->file_handle = fopen($file, 'w'); + } + else + { + throw new \RuntimeException('Unable to write to migrator log file'); + } + } + + /** + * {@inheritdoc} + */ + public function write($message, $verbosity) + { + $this->migrator->write($message, $verbosity); + + if ($this->file_handle !== false) + { + $translated_message = call_user_func_array(array($this->user, 'lang'), $message) . "\n"; + + if ($verbosity <= migrator_output_handler_interface::VERBOSITY_NORMAL) + { + $translated_message = '[INFO] ' . $translated_message; + } + else + { + $translated_message = '[DEBUG] ' . $translated_message; + } + + fwrite($this->file_handle, $translated_message); + fflush($this->file_handle); + } + } +} diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php index 8600472cca..f9f6d9f7f7 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_12_rc1.php @@ -31,7 +31,6 @@ class release_3_0_12_rc1 extends \phpbb\db\migration\migration { return array( array('custom', array(array(&$this, 'update_module_auth'))), - array('custom', array(array(&$this, 'update_bots'))), array('custom', array(array(&$this, 'disable_bots_from_receiving_pms'))), array('config.update', array('version', '3.0.12-RC1')), @@ -70,60 +69,4 @@ class release_3_0_12_rc1 extends \phpbb\db\migration\migration AND module_mode = \'signature\''; $this->sql_query($sql); } - - public function update_bots() - { - // Update bots - if (!function_exists('user_delete')) - { - include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); - } - - $bots_updates = array( - // Bot Deletions - 'NG-Search [Bot]' => false, - 'Nutch/CVS [Bot]' => false, - 'OmniExplorer [Bot]' => false, - 'Seekport [Bot]' => false, - 'Synoo [Bot]' => false, - 'WiseNut [Bot]' => false, - - // Bot Updates - // Bot name to bot user agent map - 'Baidu [Spider]' => 'Baiduspider', - 'Exabot [Bot]' => 'Exabot', - 'Voyager [Bot]' => 'voyager/', - 'W3C [Validator]' => 'W3C_Validator', - ); - - foreach ($bots_updates as $bot_name => $bot_agent) - { - $sql = 'SELECT user_id - FROM ' . USERS_TABLE . ' - WHERE user_type = ' . USER_IGNORE . " - AND username_clean = '" . $this->db->sql_escape(utf8_clean_string($bot_name)) . "'"; - $result = $this->db->sql_query($sql); - $bot_user_id = (int) $this->db->sql_fetchfield('user_id'); - $this->db->sql_freeresult($result); - - if ($bot_user_id) - { - if ($bot_agent === false) - { - $sql = 'DELETE FROM ' . BOTS_TABLE . " - WHERE user_id = $bot_user_id"; - $this->sql_query($sql); - - user_delete('retain', $bot_user_id); - } - else - { - $sql = 'UPDATE ' . BOTS_TABLE . " - SET bot_agent = '" . $this->db->sql_escape($bot_agent) . "' - WHERE user_id = $bot_user_id"; - $this->sql_query($sql); - } - } - } - } } diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php index f593c32181..2cc7786046 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_5_rc1.php @@ -55,6 +55,9 @@ class release_3_0_5_rc1 extends \phpbb\db\migration\migration public function hash_old_passwords() { + global $phpbb_container; + + $passwords_manager = $phpbb_container->get('passwords.manager'); $sql = 'SELECT user_id, user_password FROM ' . $this->table_prefix . 'users WHERE user_pass_convert = 1'; @@ -65,7 +68,7 @@ class release_3_0_5_rc1 extends \phpbb\db\migration\migration if (strlen($row['user_password']) == 32) { $sql_ary = array( - 'user_password' => phpbb_hash($row['user_password']), + 'user_password' => '$CP$' . $passwords_manager->hash($row['user_password'], 'passwords.driver.salted_md5'), ); $this->sql_query('UPDATE ' . $this->table_prefix . 'users SET ' . $this->db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id']); diff --git a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php index 4e863fa143..22fd51543b 100644 --- a/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php +++ b/phpBB/phpbb/db/migration/data/v30x/release_3_0_8_rc1.php @@ -30,7 +30,6 @@ class release_3_0_8_rc1 extends \phpbb\db\migration\migration return array( array('custom', array(array(&$this, 'update_file_extension_group_names'))), array('custom', array(array(&$this, 'update_module_auth'))), - array('custom', array(array(&$this, 'update_bots'))), array('custom', array(array(&$this, 'delete_orphan_shadow_topics'))), array('module.add', array( 'acp', @@ -114,70 +113,6 @@ class release_3_0_8_rc1 extends \phpbb\db\migration\migration $this->sql_query($sql); } - public function update_bots() - { - $bot_name = 'Bing [Bot]'; - $bot_name_clean = utf8_clean_string($bot_name); - - $sql = 'SELECT user_id - FROM ' . USERS_TABLE . " - WHERE username_clean = '" . $this->db->sql_escape($bot_name_clean) . "'"; - $result = $this->db->sql_query($sql); - $bing_already_added = (bool) $this->db->sql_fetchfield('user_id'); - $this->db->sql_freeresult($result); - - if (!$bing_already_added) - { - $bot_agent = 'bingbot/'; - $bot_ip = ''; - $sql = 'SELECT group_id, group_colour - FROM ' . GROUPS_TABLE . " - WHERE group_name = 'BOTS'"; - $result = $this->db->sql_query($sql); - $group_row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - if (!$group_row) - { - // default fallback, should never get here - $group_row['group_id'] = 6; - $group_row['group_colour'] = '9E8DA7'; - } - - if (!function_exists('user_add')) - { - include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); - } - - $user_row = array( - 'user_type' => USER_IGNORE, - 'group_id' => $group_row['group_id'], - 'username' => $bot_name, - 'user_regdate' => time(), - 'user_password' => '', - 'user_colour' => $group_row['group_colour'], - 'user_email' => '', - 'user_lang' => $this->config['default_lang'], - 'user_style' => $this->config['default_style'], - 'user_timezone' => 0, - 'user_dateformat' => $this->config['default_dateformat'], - 'user_allow_massemail' => 0, - ); - - $user_id = user_add($user_row); - - $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $this->db->sql_build_array('INSERT', array( - 'bot_active' => 1, - 'bot_name' => (string) $bot_name, - 'user_id' => (int) $user_id, - 'bot_agent' => (string) $bot_agent, - 'bot_ip' => (string) $bot_ip, - )); - - $this->sql_query($sql); - } - } - public function delete_orphan_shadow_topics() { // Delete shadow topics pointing to not existing topics diff --git a/phpBB/phpbb/db/migration/data/v310/bot_update.php b/phpBB/phpbb/db/migration/data/v310/bot_update.php new file mode 100644 index 0000000000..39b16c68f8 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/bot_update.php @@ -0,0 +1,150 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db\migration\data\v310; + +class bot_update extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\rc6'); + } + + public function update_data() + { + return array( + array('custom', array(array(&$this, 'update_bing_bot'))), + array('custom', array(array(&$this, 'update_bots'))), + ); + } + + public function update_bing_bot() + { + $bot_name = 'Bing [Bot]'; + $bot_name_clean = utf8_clean_string($bot_name); + + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . " + WHERE username_clean = '" . $this->db->sql_escape($bot_name_clean) . "'"; + $result = $this->db->sql_query($sql); + $bing_already_added = (bool) $this->db->sql_fetchfield('user_id'); + $this->db->sql_freeresult($result); + + if (!$bing_already_added) + { + $bot_agent = 'bingbot/'; + $bot_ip = ''; + $sql = 'SELECT group_id, group_colour + FROM ' . GROUPS_TABLE . " + WHERE group_name = 'BOTS'"; + $result = $this->db->sql_query($sql); + $group_row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + if (!$group_row) + { + // default fallback, should never get here + $group_row['group_id'] = 6; + $group_row['group_colour'] = '9E8DA7'; + } + + if (!function_exists('user_add')) + { + include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); + } + + $user_row = array( + 'user_type' => USER_IGNORE, + 'group_id' => $group_row['group_id'], + 'username' => $bot_name, + 'user_regdate' => time(), + 'user_password' => '', + 'user_colour' => $group_row['group_colour'], + 'user_email' => '', + 'user_lang' => $this->config['default_lang'], + 'user_style' => $this->config['default_style'], + 'user_timezone' => 0, + 'user_dateformat' => $this->config['default_dateformat'], + 'user_allow_massemail' => 0, + ); + + $user_id = user_add($user_row); + + $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $this->db->sql_build_array('INSERT', array( + 'bot_active' => 1, + 'bot_name' => (string) $bot_name, + 'user_id' => (int) $user_id, + 'bot_agent' => (string) $bot_agent, + 'bot_ip' => (string) $bot_ip, + )); + + $this->sql_query($sql); + } + } + + public function update_bots() + { + // Update bots + if (!function_exists('user_delete')) + { + include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); + } + + $bots_updates = array( + // Bot Deletions + 'NG-Search [Bot]' => false, + 'Nutch/CVS [Bot]' => false, + 'OmniExplorer [Bot]' => false, + 'Seekport [Bot]' => false, + 'Synoo [Bot]' => false, + 'WiseNut [Bot]' => false, + + // Bot Updates + // Bot name to bot user agent map + 'Baidu [Spider]' => 'Baiduspider', + 'Exabot [Bot]' => 'Exabot', + 'Voyager [Bot]' => 'voyager/', + 'W3C [Validator]' => 'W3C_Validator', + ); + + foreach ($bots_updates as $bot_name => $bot_agent) + { + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . ' + WHERE user_type = ' . USER_IGNORE . " + AND username_clean = '" . $this->db->sql_escape(utf8_clean_string($bot_name)) . "'"; + $result = $this->db->sql_query($sql); + $bot_user_id = (int) $this->db->sql_fetchfield('user_id'); + $this->db->sql_freeresult($result); + + if ($bot_user_id) + { + if ($bot_agent === false) + { + $sql = 'DELETE FROM ' . BOTS_TABLE . " + WHERE user_id = $bot_user_id"; + $this->sql_query($sql); + + user_delete('retain', $bot_user_id); + } + else + { + $sql = 'UPDATE ' . BOTS_TABLE . " + SET bot_agent = '" . $this->db->sql_escape($bot_agent) . "' + WHERE user_id = $bot_user_id"; + $this->sql_query($sql); + } + } + } + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php b/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php index c2dd09ddf6..5736369f1a 100644 --- a/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php +++ b/phpBB/phpbb/db/migration/data/v310/contact_admin_form.php @@ -20,6 +20,11 @@ class contact_admin_form extends \phpbb\db\migration\migration return isset($this->config['contact_admin_form_enable']); } + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\config_db_text'); + } + public function update_data() { return array( diff --git a/phpBB/phpbb/db/migration/data/v310/gold.php b/phpBB/phpbb/db/migration/data/v310/gold.php new file mode 100644 index 0000000000..e84c7ee951 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/gold.php @@ -0,0 +1,32 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db\migration\data\v310; + +class gold extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\rc6', + '\phpbb\db\migration\data\v310\bot_update', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.0')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/notifications_use_full_name.php b/phpBB/phpbb/db/migration/data/v310/notifications_use_full_name.php index f749b32119..112c1e85e8 100644 --- a/phpBB/phpbb/db/migration/data/v310/notifications_use_full_name.php +++ b/phpBB/phpbb/db/migration/data/v310/notifications_use_full_name.php @@ -92,10 +92,41 @@ class notifications_use_full_name extends \phpbb\db\migration\migration foreach ($this->notification_types as $notification_type) { - $sql = 'UPDATE ' . NOTIFICATION_TYPES_TABLE . " - SET notification_type_name = 'notification.type.{$notification_type}' - WHERE notification_type_name = '{$notification_type}'"; - $this->db->sql_query($sql); + $sql = 'SELECT notification_type_id + FROM ' . NOTIFICATION_TYPES_TABLE . " + WHERE notification_type_name = 'notification.type.{$notification_type}'"; + $result = $this->db->sql_query($sql); + $new_type_id = (int) $this->db->sql_fetchfield('notification_type_id'); + $this->db->sql_freeresult($result); + + if ($new_type_id) + { + // New type name already exists, + // so we delete the old type and update the type id of existing entries. + $sql = 'SELECT notification_type_id + FROM ' . NOTIFICATION_TYPES_TABLE . " + WHERE notification_type_name = '{$notification_type}'"; + $result = $this->db->sql_query($sql); + $old_type_id = (int) $this->db->sql_fetchfield('notification_type_id'); + $this->db->sql_freeresult($result); + + $sql = 'UPDATE ' . NOTIFICATIONS_TABLE . ' + SET notification_type_id = ' . (int) $new_type_id . ' + WHERE notification_type_id = ' . (int) $old_type_id; + $this->db->sql_query($sql); + + $sql = 'DELETE FROM ' . NOTIFICATION_TYPES_TABLE . " + WHERE notification_type_name = '{$notification_type}'"; + $this->db->sql_query($sql); + } + else + { + // Otherwise we just update the name + $sql = 'UPDATE ' . NOTIFICATION_TYPES_TABLE . " + SET notification_type_name = 'notification.type.{$notification_type}' + WHERE notification_type_name = '{$notification_type}'"; + $this->db->sql_query($sql); + } $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . " SET item_type = 'notification.type.{$notification_type}' @@ -108,10 +139,41 @@ class notifications_use_full_name extends \phpbb\db\migration\migration { foreach ($this->notification_types as $notification_type) { - $sql = 'UPDATE ' . NOTIFICATION_TYPES_TABLE . " - SET notification_type_name = '{$notification_type}' - WHERE notification_type_name = 'notification.type.{$notification_type}'"; - $this->db->sql_query($sql); + $sql = 'SELECT notification_type_id + FROM ' . NOTIFICATION_TYPES_TABLE . " + WHERE notification_type_name = '{$notification_type}'"; + $result = $this->db->sql_query($sql); + $new_type_id = (int) $this->db->sql_fetchfield('notification_type_id'); + $this->db->sql_freeresult($result); + + if ($new_type_id) + { + // New type name already exists, + // so we delete the old type and update the type id of existing entries. + $sql = 'SELECT notification_type_id + FROM ' . NOTIFICATION_TYPES_TABLE . " + WHERE notification_type_name = 'notification.type.{$notification_type}'"; + $result = $this->db->sql_query($sql); + $old_type_id = (int) $this->db->sql_fetchfield('notification_type_id'); + $this->db->sql_freeresult($result); + + $sql = 'UPDATE ' . NOTIFICATIONS_TABLE . ' + SET notification_type_id = ' . (int) $new_type_id . ' + WHERE notification_type_id = ' . (int) $old_type_id; + $this->db->sql_query($sql); + + $sql = 'DELETE FROM ' . NOTIFICATION_TYPES_TABLE . " + WHERE notification_type_name = 'notification.type.{$notification_type}'"; + $this->db->sql_query($sql); + } + else + { + // Otherwise we just update the name + $sql = 'UPDATE ' . NOTIFICATION_TYPES_TABLE . " + SET notification_type_name = '{$notification_type}' + WHERE notification_type_name = 'notification.type.{$notification_type}'"; + $this->db->sql_query($sql); + } $sql = 'UPDATE ' . USER_NOTIFICATIONS_TABLE . " SET item_type = '{$notification_type}' diff --git a/phpBB/phpbb/db/migration/data/v310/profilefield_field_validation_length.php b/phpBB/phpbb/db/migration/data/v310/profilefield_field_validation_length.php new file mode 100644 index 0000000000..c7d8b2dc91 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/profilefield_field_validation_length.php @@ -0,0 +1,90 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db\migration\data\v310; + +class profilefield_field_validation_length extends \phpbb\db\migration\migration +{ + protected $validation_options_old = array( + 'ALPHA_SPACERS' => '[\w_\+\. \-\[\]]+', + ); + + protected $validation_options_new = array( + 'ALPHA_SPACERS' => '[\w\x20_+\-\[\]]+', + ); + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\rc3', + ); + } + + public function update_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'profile_fields' => array( + 'field_validation' => array('VCHAR_UNI:64', ''), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'profile_fields' => array( + 'field_validation' => array('VCHAR_UNI:20', ''), + ), + ), + ); + } + + public function update_data() + { + return array( + array('custom', array(array($this, 'update_profile_fields_validation'))), + ); + } + + public function revert_data() + { + return array( + array('custom', array(array($this, 'revert_profile_fields_validation'))), + ); + } + + public function update_profile_fields_validation() + { + foreach ($this->validation_options_new as $validation_type => $regex) + { + $sql = 'UPDATE ' . $this->table_prefix . "profile_fields + SET field_validation = '" . $this->db->sql_escape($this->validation_options_new[$validation_type]) . "' + WHERE field_validation = '" . $this->db->sql_escape($this->validation_options_old[$validation_type]) . "'"; + $this->sql_query($sql); + } + } + + public function revert_profile_fields_validation() + { + foreach ($this->validation_options_new as $validation_type => $regex) + { + $sql = 'UPDATE ' . $this->table_prefix . "profile_fields + SET field_validation = '" . $this->db->sql_escape($this->validation_options_old[$validation_type]) . "' + WHERE field_validation = '" . $this->db->sql_escape($this->validation_options_new[$validation_type]) . "'"; + $this->sql_query($sql); + } + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/rc5.php b/phpBB/phpbb/db/migration/data/v310/rc5.php new file mode 100644 index 0000000000..5b6f70e32e --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/rc5.php @@ -0,0 +1,33 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db\migration\data\v310; + +class rc5 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\rc4', + '\phpbb\db\migration\data\v310\profilefield_field_validation_length', + '\phpbb\db\migration\data\v310\remove_acp_styles_cache', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.0-RC5')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/rc6.php b/phpBB/phpbb/db/migration/data/v310/rc6.php new file mode 100644 index 0000000000..b84f2edcc9 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/rc6.php @@ -0,0 +1,31 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db\migration\data\v310; + +class rc6 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v310\rc5', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.0-RC6')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v310/remove_acp_styles_cache.php b/phpBB/phpbb/db/migration/data/v310/remove_acp_styles_cache.php new file mode 100644 index 0000000000..7b84539814 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v310/remove_acp_styles_cache.php @@ -0,0 +1,51 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db\migration\data\v310; + +class remove_acp_styles_cache extends \phpbb\db\migration\migration +{ + public function effectively_installed() + { + $sql = 'SELECT module_id + FROM ' . MODULES_TABLE . " + WHERE module_class = 'acp' + AND module_langname = 'ACP_STYLES_CACHE'"; + $result = $this->db->sql_query($sql); + $module_id = $this->db->sql_fetchfield('module_id'); + $this->db->sql_freeresult($result); + + return !$module_id; + } + + static public function depends_on() + { + return array('\phpbb\db\migration\data\v310\rc4'); + } + + public function update_data() + { + return array( + array('module.remove', array( + 'acp', + 'ACP_STYLE_MANAGEMENT', + array( + 'module_basename' => 'acp_styles', + 'module_langname' => 'ACP_STYLES_CACHE', + 'module_mode' => 'cache', + 'module_auth' => 'acl_a_styles', + ), + )), + ); + } +} diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index 44bea3c5d2..621a808a03 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -68,6 +68,13 @@ class migrator public $last_run_migration = false; /** + * The output handler. A null handler is configured by default. + * + * @var migrator_output_handler + */ + public $output_handler; + + /** * Constructor of the database migrator */ public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper) @@ -84,6 +91,8 @@ class migrator $this->table_prefix = $table_prefix; + $this->output_handler = new null_migrator_output_handler(); + foreach ($tools as $tool) { $this->tools[$tool->get_name()] = $tool; @@ -95,6 +104,16 @@ class migrator } /** + * Set the output handler. + * + * @param migrator_output_handler $handler The output handler + */ + public function set_output_handler(migrator_output_handler_interface $handler) + { + $this->output_handler = $handler; + } + + /** * Loads all migrations and their application state from the database. * * @return null @@ -161,6 +180,10 @@ class migrator return; } } + else + { + $this->output_handler->write(array('MIGRATION_EFFECTIVELY_INSTALLED', $name), migrator_output_handler_interface::VERBOSITY_DEBUG); + } } } @@ -175,6 +198,7 @@ class migrator { if (!class_exists($name)) { + $this->output_handler->write(array('MIGRATION_NOT_VALID', $name), migrator_output_handler_interface::VERBOSITY_DEBUG); return false; } @@ -191,6 +215,11 @@ class migrator 'migration_end_time' => 0, ); + if (!empty($state['migration_depends_on'])) + { + $this->output_handler->write(array('MIGRATION_APPLY_DEPENDENCIES', $name), migrator_output_handler_interface::VERBOSITY_DEBUG); + } + foreach ($state['migration_depends_on'] as $depend) { if ($this->unfulfillable($depend) !== false) @@ -227,6 +256,8 @@ class migrator ); $this->last_run_migration['effectively_installed'] = true; + + $this->output_handler->write(array('MIGRATION_EFFECTIVELY_INSTALLED', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE); } else { @@ -238,23 +269,43 @@ class migrator if (!$state['migration_schema_done']) { + $this->output_handler->write(array('MIGRATION_SCHEMA_RUNNING', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE); + $this->last_run_migration['task'] = 'process_schema_step'; + $elapsed_time = microtime(true); $steps = $this->helper->get_schema_steps($migration->update_schema()); $result = $this->process_data_step($steps, $state['migration_data_state']); + $elapsed_time = microtime(true) - $elapsed_time; $state['migration_data_state'] = ($result === true) ? '' : $result; $state['migration_schema_done'] = ($result === true); + + $this->output_handler->write(array('MIGRATION_SCHEMA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL); } else if (!$state['migration_data_done']) { try { + $this->output_handler->write(array('MIGRATION_DATA_RUNNING', $name), migrator_output_handler_interface::VERBOSITY_VERBOSE); + $this->last_run_migration['task'] = 'process_data_step'; + + $elapsed_time = microtime(true); $result = $this->process_data_step($migration->update_data(), $state['migration_data_state']); + $elapsed_time = microtime(true) - $elapsed_time; $state['migration_data_state'] = ($result === true) ? '' : $result; $state['migration_data_done'] = ($result === true); $state['migration_end_time'] = ($result === true) ? time() : 0; + + if ($state['migration_schema_done']) + { + $this->output_handler->write(array('MIGRATION_DATA_DONE', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_NORMAL); + } + else + { + $this->output_handler->write(array('MIGRATION_DATA_IN_PROGRESS', $name, $elapsed_time), migrator_output_handler_interface::VERBOSITY_VERY_VERBOSE); + } } catch (\phpbb\db\migration\exception $e) { diff --git a/phpBB/phpbb/db/migrator_output_handler_interface.php b/phpBB/phpbb/db/migrator_output_handler_interface.php new file mode 100644 index 0000000000..a923af99f6 --- /dev/null +++ b/phpBB/phpbb/db/migrator_output_handler_interface.php @@ -0,0 +1,31 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db; + +interface migrator_output_handler_interface +{ + const VERBOSITY_QUIET = 0; + const VERBOSITY_NORMAL = 1; + const VERBOSITY_VERBOSE = 2; + const VERBOSITY_VERY_VERBOSE = 3; + const VERBOSITY_DEBUG = 4; + + /** + * Write output using the configured closure. + * + * @param string|array $message The message to write or an array containing the language key and all of its parameters. + * @param int $verbosity The verbosity of the message. + */ + public function write($message, $verbosity); +} diff --git a/phpBB/phpbb/db/null_migrator_output_handler.php b/phpBB/phpbb/db/null_migrator_output_handler.php new file mode 100644 index 0000000000..0e8cfbb049 --- /dev/null +++ b/phpBB/phpbb/db/null_migrator_output_handler.php @@ -0,0 +1,24 @@ +<?php +/** +* +* 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. +* +*/ + +namespace phpbb\db; + +class null_migrator_output_handler implements migrator_output_handler_interface +{ + /** + * {@inheritdoc} + */ + public function write($message, $verbosity) + { + } +} diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php index 3567570137..0781d7425e 100644 --- a/phpBB/phpbb/db/tools.php +++ b/phpBB/phpbb/db/tools.php @@ -1512,7 +1512,7 @@ class tools $sql .= (strpos($column_data[1], '0x') === 0) ? "DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' "; } - if (!is_null($column_data[1])) + if (!is_null($column_data[1]) || (isset($column_data[2]) && $column_data[2] == 'auto_increment')) { $sql .= 'NOT NULL'; } diff --git a/phpBB/phpbb/di/pass/kernel_pass.php b/phpBB/phpbb/di/pass/kernel_pass.php deleted file mode 100644 index c154c7532d..0000000000 --- a/phpBB/phpbb/di/pass/kernel_pass.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php -/** -* -* 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. -* -*/ - -namespace phpbb\di\pass; - -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; - -class kernel_pass implements CompilerPassInterface -{ - /** - * Modify the container before it is passed to the rest of the code - * - * @param ContainerBuilder $container ContainerBuilder object - * @return null - * @throws \InvalidArgumentException - */ - public function process(ContainerBuilder $container) - { - $definition = $container->getDefinition('dispatcher'); - - foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) - { - foreach ($events as $event) - { - $priority = isset($event['priority']) ? $event['priority'] : 0; - - if (!isset($event['event'])) - { - throw new \InvalidArgumentException(sprintf('Service "%1$s" must define the "event" attribute on "kernel.event_listener" tags.', $id)); - } - - if (!isset($event['method'])) - { - throw new \InvalidArgumentException(sprintf('Service "%1$s" must define the "method" attribute on "kernel.event_listener" tags.', $id)); - } - - $definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority)); - } - } - - foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) - { - // We must assume that the class value has been correctly filled, even if the service is created by a factory - $class = $container->getDefinition($id)->getClass(); - - $refClass = new \ReflectionClass($class); - $interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface'; - if (!$refClass->implementsInterface($interface)) - { - throw new \InvalidArgumentException(sprintf('Service "%1$s" must implement interface "%2$s".', $id, $interface)); - } - - $definition->addMethodCall('addSubscriberService', array($id, $class)); - } - } -} diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php index badbbb48fd..35144eeeec 100644 --- a/phpBB/phpbb/event/php_exporter.php +++ b/phpBB/phpbb/event/php_exporter.php @@ -253,7 +253,7 @@ class php_exporter public function get_event_name($event_line, $is_dispatch) { $event_text_line = $this->file_lines[$event_line]; - $event_text_line = ltrim($event_text_line, "\t"); + $event_text_line = ltrim($event_text_line, "\t "); if ($is_dispatch) { @@ -389,7 +389,7 @@ class php_exporter $found_comment_end = false; while (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") !== '/**') { - if (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t") === '*/') + if (ltrim($this->file_lines[$this->current_event_line - $current_doc_line], "\t ") === '*/') { $found_comment_end = true; } @@ -471,7 +471,7 @@ class php_exporter { $find_tag_line = 0; $found_comment_end = false; - while (strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t"), '* @' . $find_tag . ' ') !== 0) + while (strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t "), '* @' . $find_tag . ' ') !== 0) { if ($found_comment_end && ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '/**') { @@ -482,7 +482,7 @@ class php_exporter foreach ($disallowed_tags as $disallowed_tag) { - if ($found_comment_end && strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t"), '* @' . $disallowed_tag) === 0) + if ($found_comment_end && strpos(ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t "), '* @' . $disallowed_tag) === 0) { // Found @var after the @since throw new \LogicException("Found '@{$disallowed_tag}' information after '@{$find_tag}' for event " @@ -490,7 +490,7 @@ class php_exporter } } - if (ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t") === '*/') + if (ltrim($this->file_lines[$this->current_event_line - $find_tag_line], "\t ") === '*/') { $found_comment_end = true; } @@ -550,7 +550,7 @@ class php_exporter public function validate_since($line) { $match = array(); - preg_match('#^\* @since (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)$#', ltrim($line, "\t"), $match); + preg_match('#^\* @since (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)$#', ltrim($line, "\t "), $match); if (!isset($match[1])) { throw new \LogicException("Invalid '@since' information for event " @@ -570,7 +570,7 @@ class php_exporter */ public function validate_event($event_name, $line) { - $event = substr(ltrim($line, "\t"), strlen('* @event ')); + $event = substr(ltrim($line, "\t "), strlen('* @event ')); if ($event !== trim($event)) { diff --git a/phpBB/phpbb/notification/type/admin_activate_user.php b/phpBB/phpbb/notification/type/admin_activate_user.php index 038ca3726e..dfc0157558 100644 --- a/phpBB/phpbb/notification/type/admin_activate_user.php +++ b/phpBB/phpbb/notification/type/admin_activate_user.php @@ -131,7 +131,7 @@ class admin_activate_user extends \phpbb\notification\type\base public function get_email_template_variables() { $board_url = generate_board_url(); - $username = $this->user_loader->get_username($this->item_id, 'no_profile'); + $username = $this->user_loader->get_username($this->item_id, 'username'); return array( 'USERNAME' => htmlspecialchars_decode($username), diff --git a/phpBB/phpbb/pagination.php b/phpBB/phpbb/pagination.php index 8aba41d651..7a81c25ad2 100644 --- a/phpBB/phpbb/pagination.php +++ b/phpBB/phpbb/pagination.php @@ -21,18 +21,26 @@ class pagination /** @var \phpbb\user */ protected $user; + /** @var \phpbb\controller\helper */ + protected $helper; + + /** @var \phpbb\event\dispatcher_interface */ + protected $phpbb_dispatcher; + /** * Constructor * - * @param \phpbb\template\template $template - * @param \phpbb\user $user - * @param \phpbb\controller\helper $helper + * @param \phpbb\template\template $template + * @param \phpbb\user $user + * @param \phpbb\controller\helper $helper + * @param \phpbb\event\dispatcher_interface $phpbb_dispatcher */ - public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper) + public function __construct(\phpbb\template\template $template, \phpbb\user $user, \phpbb\controller\helper $helper, \phpbb\event\dispatcher_interface $phpbb_dispatcher) { $this->template = $template; $this->user = $user; $this->helper = $helper; + $this->phpbb_dispatcher = $phpbb_dispatcher; } /** @@ -50,6 +58,36 @@ class pagination */ protected function generate_page_link($base_url, $on_page, $start_name, $per_page) { + // A listener can set this variable to the new pagination URL + // to override the generate_page_link() function generated value + $generate_page_link_override = false; + + /** + * Execute code and/or override generate_page_link() + * + * To override the generate_page_link() function generated value + * set $generate_page_link_override to the new URL value + * + * @event core.pagination_generate_page_link + * @var string base_url is url prepended to all links generated within the function + * If you use page numbers inside your controller route, base_url should contains a placeholder (%d) + * for the page. Also be sure to specify the pagination path information into the start_name argument + * @var string on_page is the page for which we want to generate the link + * @var string start_name is the name of the parameter containing the first item of the given page (example: start=20) + * If you use page numbers inside your controller route, start name should be the string + * that should be removed for the first page (example: /page/%d) + * @var int per_page the number of items, posts, etc. to display per page, used to determine the number of pages to produce + * @var bool|string generate_page_link_override Shall we return custom pagination link (string URL) or not (false) + * @since 3.1.0-RC5 + */ + $vars = array('base_url', 'on_page', 'start_name', 'per_page', 'generate_page_link_override'); + extract($this->phpbb_dispatcher->trigger_event('core.pagination_generate_page_link', compact($vars))); + + if ($generate_page_link_override) + { + return $generate_page_link_override; + } + if (!is_string($base_url)) { if (is_array($base_url['routes'])) diff --git a/phpBB/phpbb/passwords/driver/bcrypt.php b/phpBB/phpbb/passwords/driver/bcrypt.php index 23add37a56..eab1c3d569 100644 --- a/phpBB/phpbb/passwords/driver/bcrypt.php +++ b/phpBB/phpbb/passwords/driver/bcrypt.php @@ -68,7 +68,7 @@ class bcrypt extends base return false; } - if ($hash == $this->hash($password, $salt)) + if ($this->helper->string_compare($hash, $this->hash($password, $salt))) { return true; } diff --git a/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php b/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php index 2d6f897a7b..0eee98d7b7 100644 --- a/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php +++ b/phpBB/phpbb/passwords/driver/bcrypt_wcf2.php @@ -78,7 +78,7 @@ class bcrypt_wcf2 extends base return false; } // Works for standard WCF 2.x, i.e. WBB4 and similar - return $hash === $this->bcrypt->hash($this->bcrypt->hash($password, $salt), $salt); + return $this->helper->string_compare($hash, $this->bcrypt->hash($this->bcrypt->hash($password, $salt), $salt)); } } } diff --git a/phpBB/phpbb/passwords/driver/helper.php b/phpBB/phpbb/passwords/driver/helper.php index 2b3ebce53a..caa65080ac 100644 --- a/phpBB/phpbb/passwords/driver/helper.php +++ b/phpBB/phpbb/passwords/driver/helper.php @@ -142,4 +142,24 @@ class helper } return $random; } + + /** + * Compare two strings byte by byte + * + * @param string $string_a The first string + * @param string $string_b The second string + * + * @return bool True if strings are the same, false if not + */ + public function string_compare($string_a, $string_b) + { + $difference = strlen($string_a) != strlen($string_b); + + for ($i = 0; $i < strlen($string_a) && $i < strlen($string_b); $i++) + { + $difference |= $string_a[$i] != $string_b[$i]; + } + + return $difference === 0; + } } diff --git a/phpBB/phpbb/passwords/driver/md5_mybb.php b/phpBB/phpbb/passwords/driver/md5_mybb.php index 61ea8dafd8..f631ceae78 100644 --- a/phpBB/phpbb/passwords/driver/md5_mybb.php +++ b/phpBB/phpbb/passwords/driver/md5_mybb.php @@ -54,7 +54,7 @@ class md5_mybb extends base else { // Works for myBB 1.1.x, 1.2.x, 1.4.x, 1.6.x - return $hash === md5(md5($user_row['user_passwd_salt']) . md5($password)); + return $this->helper->string_compare($hash, md5(md5($user_row['user_passwd_salt']) . md5($password))); } } } diff --git a/phpBB/phpbb/passwords/driver/md5_phpbb2.php b/phpBB/phpbb/passwords/driver/md5_phpbb2.php index 86a4b62ea5..bd8cc51e5a 100644 --- a/phpBB/phpbb/passwords/driver/md5_phpbb2.php +++ b/phpBB/phpbb/passwords/driver/md5_phpbb2.php @@ -23,6 +23,9 @@ class md5_phpbb2 extends base /** @var \phpbb\passwords\driver\salted_md5 */ protected $salted_md5; + /** @var \phpbb\passwords\driver\helper */ + protected $helper; + /** @var string phpBB root path */ protected $phpbb_root_path; @@ -34,13 +37,15 @@ class md5_phpbb2 extends base * * @param \phpbb\request\request $request phpBB request object * @param \phpbb\passwords\driver\salted_md5 $salted_md5 Salted md5 driver + * @param \phpbb\passwords\driver\helper $helper Driver helper * @param string $phpbb_root_path phpBB root path * @param string $php_ext PHP file extension */ - public function __construct($request, \phpbb\passwords\driver\salted_md5 $salted_md5, $phpbb_root_path, $php_ext) + public function __construct($request, salted_md5 $salted_md5, helper $helper, $phpbb_root_path, $php_ext) { $this->request = $request; $this->salted_md5 = $salted_md5; + $this->helper = $helper; $this->phpbb_root_path = $phpbb_root_path; $this->php_ext = $php_ext; } @@ -105,7 +110,7 @@ class md5_phpbb2 extends base include($this->phpbb_root_path . 'includes/utf/data/recode_basic.' . $this->php_ext); } - if (md5($password_old_format) === $hash || md5(\utf8_to_cp1252($password_old_format)) === $hash + if ($this->helper->string_compare(md5($password_old_format), $hash) || $this->helper->string_compare(md5(\utf8_to_cp1252($password_old_format)), $hash) || $this->salted_md5->check(md5($password_old_format), $hash) === true || $this->salted_md5->check(md5(\utf8_to_cp1252($password_old_format)), $hash) === true) { diff --git a/phpBB/phpbb/passwords/driver/md5_vb.php b/phpBB/phpbb/passwords/driver/md5_vb.php index c83c32a596..280b7114c7 100644 --- a/phpBB/phpbb/passwords/driver/md5_vb.php +++ b/phpBB/phpbb/passwords/driver/md5_vb.php @@ -54,7 +54,7 @@ class md5_vb extends base else { // Works for vB 3.8.x, 4.x.x, 5.0.x - return $hash === md5(md5($password) . $user_row['user_passwd_salt']); + return $this->helper->string_compare($hash, md5(md5($password) . $user_row['user_passwd_salt'])); } } } diff --git a/phpBB/phpbb/passwords/driver/salted_md5.php b/phpBB/phpbb/passwords/driver/salted_md5.php index 97a2b9154b..81ac010785 100644 --- a/phpBB/phpbb/passwords/driver/salted_md5.php +++ b/phpBB/phpbb/passwords/driver/salted_md5.php @@ -107,7 +107,7 @@ class salted_md5 extends base return md5($password) === $hash; } - return $hash === $this->hash($password, $hash); + return $this->helper->string_compare($hash, $this->hash($password, $hash)); } /** diff --git a/phpBB/phpbb/passwords/driver/sha1.php b/phpBB/phpbb/passwords/driver/sha1.php index 0852fd32fc..1abead42cd 100644 --- a/phpBB/phpbb/passwords/driver/sha1.php +++ b/phpBB/phpbb/passwords/driver/sha1.php @@ -47,6 +47,6 @@ class sha1 extends base */ public function check($password, $hash, $user_row = array()) { - return (strlen($hash) == 40) ? $hash === sha1($password) : false; + return (strlen($hash) == 40) ? $this->helper->string_compare($hash, sha1($password)) : false; } } diff --git a/phpBB/phpbb/passwords/driver/sha1_smf.php b/phpBB/phpbb/passwords/driver/sha1_smf.php index ec64bd6afb..b30d87265e 100644 --- a/phpBB/phpbb/passwords/driver/sha1_smf.php +++ b/phpBB/phpbb/passwords/driver/sha1_smf.php @@ -46,6 +46,6 @@ class sha1_smf extends base */ public function check($password, $hash, $user_row = array()) { - return (strlen($hash) == 40) ? $hash === $this->hash($password, $user_row) : false; + return (strlen($hash) == 40) ? $this->helper->string_compare($hash, $this->hash($password, $user_row)) : false; } } diff --git a/phpBB/phpbb/passwords/driver/sha1_wcf1.php b/phpBB/phpbb/passwords/driver/sha1_wcf1.php index 919fa2bb71..68006486c4 100644 --- a/phpBB/phpbb/passwords/driver/sha1_wcf1.php +++ b/phpBB/phpbb/passwords/driver/sha1_wcf1.php @@ -54,7 +54,7 @@ class sha1_wcf1 extends base else { // Works for standard WCF 1.x, i.e. WBB3 and similar - return $hash === sha1($user_row['user_passwd_salt'] . sha1($user_row['user_passwd_salt'] . sha1($password))); + return $this->helper->string_compare($hash, sha1($user_row['user_passwd_salt'] . sha1($user_row['user_passwd_salt'] . sha1($password)))); } } } diff --git a/phpBB/phpbb/passwords/driver/sha_xf1.php b/phpBB/phpbb/passwords/driver/sha_xf1.php index 7a1ea1450a..9d8f01796e 100644 --- a/phpBB/phpbb/passwords/driver/sha_xf1.php +++ b/phpBB/phpbb/passwords/driver/sha_xf1.php @@ -54,8 +54,8 @@ class sha_xf1 extends base else { // Works for xenforo 1.0, 1.1 - if ($hash === sha1(sha1($password) . $user_row['user_passwd_salt']) - || $hash === hash('sha256', hash('sha256', $password) . $user_row['user_passwd_salt'])) + if ($this->helper->string_compare($hash, sha1(sha1($password) . $user_row['user_passwd_salt'])) + || $this->helper->string_compare($hash, hash('sha256', hash('sha256', $password) . $user_row['user_passwd_salt']))) { return true; } diff --git a/phpBB/phpbb/profilefields/type/type_base.php b/phpBB/phpbb/profilefields/type/type_base.php index c770a0d93c..52f5d15511 100644 --- a/phpBB/phpbb/profilefields/type/type_base.php +++ b/phpBB/phpbb/profilefields/type/type_base.php @@ -133,7 +133,7 @@ abstract class type_base implements type_interface { foreach ($field_data[$key] as $lang_id => $options) { - $field_data[$key][$lang_id] = explode("\n", $options); + $field_data[$key][$lang_id] = is_array($options) ? $options : explode("\n", $options); } return $current_value; diff --git a/phpBB/phpbb/profilefields/type/type_string_common.php b/phpBB/phpbb/profilefields/type/type_string_common.php index 0eaf7e527d..ff33a7b49c 100644 --- a/phpBB/phpbb/profilefields/type/type_string_common.php +++ b/phpBB/phpbb/profilefields/type/type_string_common.php @@ -21,8 +21,13 @@ abstract class type_string_common extends type_base 'ALPHA_ONLY' => '[\w]+', 'ALPHA_UNDERSCORE' => '[\w_]+', 'ALPHA_DOTS' => '[\w.]+', - 'ALPHA_SPACERS' => '[\w_\+\. \-\[\]]+', + 'ALPHA_SPACERS' => '[\w\x20_+\-\[\]]+', 'ALPHA_PUNCTUATION' => '[a-zA-Z][\w\.,\-_]+', + 'LETTER_NUM_ONLY' => '[\p{Lu}\p{Ll}0-9]+', + 'LETTER_NUM_UNDERSCORE' => '[\p{Lu}\p{Ll}0-9_]+', + 'LETTER_NUM_DOTS' => '[\p{Lu}\p{Ll}0-9.]+', + 'LETTER_NUM_SPACERS' => '[\p{Lu}\p{Ll}0-9\x20_+\-\[\]]+', + 'LETTER_NUM_PUNCTUATION' => '[\p{Lu}\p{Ll}][\p{Lu}\p{Ll}0-9.,\-_]+', ); /** @@ -79,7 +84,7 @@ abstract class type_string_common extends type_base if (!empty($field_data['field_validation']) && $field_data['field_validation'] != '.*') { $field_validate = ($field_type != 'text') ? $field_value : bbcode_nl2br($field_value); - if (!preg_match('#^' . str_replace('\\\\', '\\', $field_data['field_validation']) . '$#i', $field_validate)) + if (!preg_match('#^' . str_replace('\\\\', '\\', $field_data['field_validation']) . '$#iu', $field_validate)) { $validation = array_search($field_data['field_validation'], $this->validation_options); if ($validation) diff --git a/phpBB/phpbb/search/fulltext_sphinx.php b/phpBB/phpbb/search/fulltext_sphinx.php index 79d68d2ae1..eb53ca6d40 100644 --- a/phpBB/phpbb/search/fulltext_sphinx.php +++ b/phpBB/phpbb/search/fulltext_sphinx.php @@ -256,8 +256,8 @@ class fulltext_sphinx array('type', $this->dbtype . ' # mysql or pgsql'), // This config value sql_host needs to be changed incase sphinx and sql are on different servers array('sql_host', $dbhost . ' # SQL server host sphinx connects to'), - array('sql_user', $dbuser), - array('sql_pass', $dbpasswd), + array('sql_user', '[dbuser]'), + array('sql_pass', '[dbpassword]'), array('sql_db', $dbname), array('sql_port', $dbport . ' # optional, default is 3306 for mysql and 5432 for pgsql'), array('sql_query_pre', 'SET NAMES \'utf8\''), @@ -715,6 +715,7 @@ class fulltext_sphinx ), 'ON' => 'p1.topic_id = p2.topic_id', )), + 'WHERE' => 'p2.post_id = ' . ((int) $post_id), ); $sql = $this->db->sql_build_query('SELECT', $sql_array); diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 30b364821d..477e91efd6 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -441,12 +441,13 @@ class session if (!$session_expired) { - // Only update session DB a minute or so after last update or if page changes and is not ajax request - if (($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page'])) && !$request->is_ajax()) + // Only update session DB a minute or so after last update or if page changes + if ($this->time_now - $this->data['session_time'] > 60 || ($this->update_session_page && $this->data['session_page'] != $this->page['page'])) { $sql_ary = array('session_time' => $this->time_now); - if ($this->update_session_page) + // Do not update the session page for ajax requests, so the view online still works as intended + if ($this->update_session_page && !$request->is_ajax()) { $sql_ary['session_page'] = substr($this->page['page'], 0, 199); $sql_ary['session_forum_id'] = $this->page['forum']; @@ -580,6 +581,11 @@ class session $provider = $provider_collection->get_provider(); $this->data = $provider->autologin(); + if ($user_id !== false && sizeof($this->data) && $this->data['user_id'] != $user_id) + { + $this->data = array(); + } + if (sizeof($this->data)) { $this->cookie_data['k'] = ''; @@ -597,11 +603,18 @@ class session AND k.user_id = u.user_id AND k.key_id = '" . $db->sql_escape(md5($this->cookie_data['k'])) . "'"; $result = $db->sql_query($sql); - $this->data = $db->sql_fetchrow($result); + $user_data = $db->sql_fetchrow($result); + + if ($user_id === false || (isset($user_data['user_id']) && $user_id == $user_data['user_id'])) + { + $this->data = $user_data; + $bot = false; + } + $db->sql_freeresult($result); - $bot = false; } - else if ($user_id !== false && !sizeof($this->data)) + + if ($user_id !== false && !sizeof($this->data)) { $this->cookie_data['k'] = ''; $this->cookie_data['u'] = $user_id; diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php index ab0e1f281d..9a40702ba8 100644 --- a/phpBB/phpbb/template/base.php +++ b/phpBB/phpbb/template/base.php @@ -142,11 +142,11 @@ abstract class base implements template { global $phpbb_hook; - if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array(__CLASS__, $method), $handle, $this)) + if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array('template', $method), $handle, $this)) { - if ($phpbb_hook->hook_return(array(__CLASS__, $method))) + if ($phpbb_hook->hook_return(array('template', $method))) { - $result = $phpbb_hook->hook_return_result(array(__CLASS__, $method)); + $result = $phpbb_hook->hook_return_result(array('template', $method)); return array($result); } } diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php index ea98034434..882e9cef26 100644 --- a/phpBB/phpbb/user.php +++ b/phpBB/phpbb/user.php @@ -717,7 +717,7 @@ class user extends \phpbb\session $utc = new \DateTimeZone('UTC'); } - $time = new \phpbb\datetime($this, "@$gmepoch", $utc); + $time = new $this->datetime($this, "@$gmepoch", $utc); $time->setTimezone($this->timezone); return $time->format($format, $forcedate); diff --git a/phpBB/phpbb/user_loader.php b/phpBB/phpbb/user_loader.php index c9707ee432..24e663b150 100644 --- a/phpBB/phpbb/user_loader.php +++ b/phpBB/phpbb/user_loader.php @@ -212,7 +212,7 @@ class user_loader return ''; } - if (!function_exists('get_user_rank')) + if (!function_exists('phpbb_get_user_rank')) { include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext); } @@ -223,7 +223,10 @@ class user_loader 'rank_img_src', ); - get_user_rank($user['user_rank'], (($user['user_id'] == ANONYMOUS) ? false : $user['user_posts']), $rank['rank_title'], $rank['rank_img'], $rank['rank_img_src']); + $user_rank_data = phpbb_get_user_rank($user, (($user['user_id'] == ANONYMOUS) ? false : $user['user_posts'])); + $rank['rank_title'] = $user_rank_data['title']; + $rank['rank_img'] = $user_rank_data['img']; + $rank['rank_img_src'] = $user_rank_data['img_src']; return $rank; } diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index 968a57428f..96386f6d04 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -239,7 +239,7 @@ class version_helper */ public function get_versions($force_update = false, $force_cache = false) { - $cache_file = 'versioncheck_' . $this->host . $this->path . $this->file; + $cache_file = '_versioncheck_' . $this->host . $this->path . $this->file; $info = $this->cache->get($cache_file); |