diff options
Diffstat (limited to 'phpBB/phpbb')
42 files changed, 708 insertions, 104 deletions
diff --git a/phpBB/phpbb/auth/auth.php b/phpBB/phpbb/auth/auth.php index fc7cc1a0b1..dbd83f1eb0 100644 --- a/phpBB/phpbb/auth/auth.php +++ b/phpBB/phpbb/auth/auth.php @@ -514,7 +514,7 @@ class auth */ function acl_clear_prefetch($user_id = false) { - global $db, $cache; + global $db, $cache, $phpbb_dispatcher; // Rebuild options cache $cache->destroy('_role_cache'); @@ -553,6 +553,16 @@ class auth $where_sql"; $db->sql_query($sql); + /** + * Event is triggered after user(s) permission settings cache has been cleared + * + * @event core.acl_clear_prefetch_after + * @var mixed user_id User ID(s) + * @since 3.1.11-RC1 + */ + $vars = array('user_id'); + extract($phpbb_dispatcher->trigger_event('core.acl_clear_prefetch_after', compact($vars))); + return; } diff --git a/phpBB/phpbb/cache/driver/file.php b/phpBB/phpbb/cache/driver/file.php index a210d877f0..497f00c06b 100644 --- a/phpBB/phpbb/cache/driver/file.php +++ b/phpBB/phpbb/cache/driver/file.php @@ -608,6 +608,6 @@ class file extends \phpbb\cache\driver\base */ protected function clean_varname($varname) { - return str_replace('/', '-', $varname); + return str_replace(array('/', '\\'), '-', $varname); } } diff --git a/phpBB/phpbb/db/migration/data/v320/cookie_notice.php b/phpBB/phpbb/db/migration/data/v320/cookie_notice.php new file mode 100644 index 0000000000..75cb03b3ef --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/cookie_notice.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\v320; + +class cookie_notice extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320rc2', + ); + } + + public function update_data() + { + return array( + array('config.add', array('cookie_notice', false)), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v320/v320.php b/phpBB/phpbb/db/migration/data/v320/v320.php new file mode 100644 index 0000000000..20e741cb8b --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320.php @@ -0,0 +1,40 @@ +<?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\v320; + +use phpbb\db\migration\migration; + +class v320 extends migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\increase_size_of_emotion', + '\phpbb\db\migration\data\v320\cookie_notice', + ); + + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php b/phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php new file mode 100644 index 0000000000..1a83175705 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/cookie_notice_p2.php @@ -0,0 +1,36 @@ +<?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\v32x; + +class cookie_notice_p2 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320', + ); + } + + public function effectively_installed() + { + return isset($this->config['cookie_notice']); + } + + public function update_data() + { + return array( + array('config.add', array('cookie_notice', '0')), + ); + } +} diff --git a/phpBB/phpbb/db/tools.php b/phpBB/phpbb/db/tools.php new file mode 100644 index 0000000000..4d1b91f7b4 --- /dev/null +++ b/phpBB/phpbb/db/tools.php @@ -0,0 +1,21 @@ +<?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; + +/** + * @deprecated 3.2.0-dev (To be removed 3.3.0) use \phpbb\db\tools\tools instead + */ +class tools extends \phpbb\db\tools\tools +{ +} diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index a132832005..d31aa2ba0b 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -477,7 +477,7 @@ class mssql extends tools { $statements = array(); - $statements[] = 'DROP INDEX ' . $table_name . '.' . $index_name; + $statements[] = 'DROP INDEX [' . $table_name . '].[' . $index_name . ']'; return $this->_sql_run_sql($statements); } @@ -524,7 +524,10 @@ class mssql extends tools { $statements = array(); - $this->check_index_name_length($table_name, $index_name); + if ($this->is_sql_server_2000()) + { + $this->check_index_name_length($table_name, $index_name); + } $statements[] = 'CREATE UNIQUE INDEX [' . $index_name . '] ON [' . $table_name . ']([' . implode('], [', $column) . '])'; @@ -538,7 +541,10 @@ class mssql extends tools { $statements = array(); - $this->check_index_name_length($table_name, $index_name); + if ($this->is_sql_server_2000()) + { + $this->check_index_name_length($table_name, $index_name); + } // remove index length $column = preg_replace('#:.*$#', '', $column); @@ -601,7 +607,7 @@ class mssql extends tools // Change the column $statements[] = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql']; - if (!empty($column_data['default'])) + if (!empty($column_data['default']) && !$this->mssql_is_column_identity($table_name, $column_name)) { // Add new default value constraint $statements[] = 'ALTER TABLE [' . $table_name . '] ADD CONSTRAINT [DF_' . $table_name . '_' . $column_name . '_1] ' . $column_data['default'] . ' FOR [' . $column_name . ']'; @@ -679,6 +685,37 @@ class mssql extends tools } /** + * Checks to see if column is an identity column + * + * Identity columns cannot have defaults set for them. + * + * @param string $table_name + * @param string $column_name + * @return bool true if identity, false if not + */ + protected function mssql_is_column_identity($table_name, $column_name) + { + if ($this->mssql_is_sql_server_2000()) + { + // http://msdn.microsoft.com/en-us/library/aa175912%28v=sql.80%29.aspx + // Deprecated in SQL Server 2005 + $sql = "SELECT COLUMNPROPERTY(object_id('{$table_name}'), '{$column_name}', 'IsIdentity') AS is_identity"; + } + else + { + $sql = "SELECT is_identity FROM sys.columns + WHERE object_id = object_id('{$table_name}') + AND name = '{$column_name}'"; + } + + $result = $this->db->sql_query($sql); + $is_identity = $this->db->sql_fetchfield('is_identity'); + $this->db->sql_freeresult($result); + + return (bool) $is_identity; + } + + /** * Get a list with existing indexes for the column * * @param string $table_name @@ -717,6 +754,7 @@ class mssql extends tools AND cols.object_id = ix.object_id WHERE ix.object_id = object_id('{$table_name}') AND cols.name = '{$column_name}' + AND ix.is_primary_key = 0 AND ix.is_unique = " . ($unique ? '1' : '0'); } diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 4d5f189f12..ac1a1a1733 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -51,6 +51,11 @@ class container_builder protected $container; /** + * @var \phpbb\db\driver\driver_interface + */ + protected $dbal_connection = null; + + /** * Indicates whether extensions should be used (default to true). * * @var bool @@ -197,6 +202,8 @@ class container_builder $this->container->set('config.php', $this->config_php_file); } + $this->inject_dbal_driver(); + return $this->container; } catch (\Exception $e) @@ -511,7 +518,38 @@ class container_builder { $this->container->setParameter($key, $value); } + } + /** + * Inject the dbal connection driver into container + */ + protected function inject_dbal_driver() + { + if (empty($this->config_php_file)) + { + return; + } + + $config_data = $this->config_php_file->get_all(); + if (!empty($config_data)) + { + if ($this->dbal_connection === null) + { + $dbal_driver_class = $this->config_php_file->convert_30_dbms_to_31($this->config_php_file->get('dbms')); + /** @var \phpbb\db\driver\driver_interface $dbal_connection */ + $this->dbal_connection = new $dbal_driver_class(); + $this->dbal_connection->sql_connect( + $this->config_php_file->get('dbhost'), + $this->config_php_file->get('dbuser'), + $this->config_php_file->get('dbpasswd'), + $this->config_php_file->get('dbname'), + $this->config_php_file->get('dbport'), + false, + defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK + ); + } + $this->container->set('dbal.conn.driver', $this->dbal_connection); + } } /** diff --git a/phpBB/phpbb/di/extension/config.php b/phpBB/phpbb/di/extension/config.php index 7984a783df..8c9de48823 100644 --- a/phpBB/phpbb/di/extension/config.php +++ b/phpBB/phpbb/di/extension/config.php @@ -43,12 +43,6 @@ class config extends Extension 'core.adm_relative_path' => $this->config_php->get('phpbb_adm_relative_path') ? $this->config_php->get('phpbb_adm_relative_path') : 'adm/', 'core.table_prefix' => $this->config_php->get('table_prefix'), 'cache.driver.class' => $this->convert_30_acm_type($this->config_php->get('acm_type')), - 'dbal.driver.class' => $this->config_php->convert_30_dbms_to_31($this->config_php->get('dbms')), - 'dbal.dbhost' => $this->config_php->get('dbhost'), - 'dbal.dbuser' => $this->config_php->get('dbuser'), - 'dbal.dbpasswd' => $this->config_php->get('dbpasswd'), - 'dbal.dbname' => $this->config_php->get('dbname'), - 'dbal.dbport' => $this->config_php->get('dbport'), 'dbal.new_link' => defined('PHPBB_DB_NEW_LINK') && PHPBB_DB_NEW_LINK, ); $parameter_bag = $container->getParameterBag(); diff --git a/phpBB/phpbb/di/proxy_instantiator.php b/phpBB/phpbb/di/proxy_instantiator.php index a388e82c0e..70295a3dec 100644 --- a/phpBB/phpbb/di/proxy_instantiator.php +++ b/phpBB/phpbb/di/proxy_instantiator.php @@ -13,8 +13,6 @@ namespace phpbb\di; -use bantu\IniGetWrapper\IniGetWrapper; -use phpbb\filesystem\filesystem; use ProxyManager\Configuration; use ProxyManager\Factory\LazyLoadingValueHolderFactory; use ProxyManager\GeneratorStrategy\EvaluatingGeneratorStrategy; @@ -45,11 +43,8 @@ class proxy_instantiator implements InstantiatorInterface // Prevent trying to write to system temp dir in case of open_basedir // restrictions being in effect - $ini_wrapper = new IniGetWrapper(); - $filesystem = new filesystem(); $tmp_dir = (function_exists('sys_get_temp_dir')) ? sys_get_temp_dir() : ''; - if (empty($tmp_dir) || $ini_wrapper->getString('open_basedir') && - (!$filesystem->exists($tmp_dir) || !$filesystem->is_writable($tmp_dir))) + if (empty($tmp_dir) || !@file_exists($tmp_dir) || !@is_writable($tmp_dir)) { $config->setProxiesTargetDir($cache_dir); } diff --git a/phpBB/phpbb/event/php_exporter.php b/phpBB/phpbb/event/php_exporter.php index d2ab0595c0..ae3553c558 100644 --- a/phpBB/phpbb/event/php_exporter.php +++ b/phpBB/phpbb/event/php_exporter.php @@ -510,7 +510,7 @@ class php_exporter /** * Find the "@changed" Information lines * - * @param string $tag_name Should be 'changed' or 'change' + * @param string $tag_name Should be 'change', not 'changed' * @return array Absolute line numbers * @throws \LogicException */ @@ -658,7 +658,7 @@ class php_exporter { $match = array(); $line = str_replace("\t", ' ', ltrim($line, "\t ")); - preg_match('#^\* @change(d)? (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)( (?:.*))?$#', $line, $match); + preg_match('#^\* @changed (\d+\.\d+\.\d+(?:-(?:a|b|RC|pl)\d+)?)( (?:.*))?$#', $line, $match); if (!isset($match[2])) { throw new \LogicException("Invalid '@changed' information for event " diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php index b2b60aaa9b..ca0ff31d5d 100644 --- a/phpBB/phpbb/extension/manager.php +++ b/phpBB/phpbb/extension/manager.php @@ -589,7 +589,7 @@ class manager $version_helper = new \phpbb\version_helper($this->cache, $this->config, new file_downloader()); $version_helper->set_current_version($meta['version']); - $version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename']); + $version_helper->set_file_location($version_check['host'], $version_check['directory'], $version_check['filename'], isset($version_check['ssl']) ? $version_check['ssl'] : false); $version_helper->force_stability($stability); return $updates = $version_helper->get_suggested_updates($force_update, $force_cache); diff --git a/phpBB/phpbb/extension/metadata_manager.php b/phpBB/phpbb/extension/metadata_manager.php index 2b8b1bbd6a..ae1af10c1d 100644 --- a/phpBB/phpbb/extension/metadata_manager.php +++ b/phpBB/phpbb/extension/metadata_manager.php @@ -214,7 +214,20 @@ class metadata_manager case 'all': $this->validate('display'); - $this->validate_enable(); + if (!$this->validate_dir()) + { + throw new \phpbb\extension\exception('EXTENSION_DIR_INVALID'); + } + + if (!$this->validate_require_phpbb()) + { + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('soft-require')); + } + + if (!$this->validate_require_php()) + { + throw new \phpbb\extension\exception('META_FIELD_NOT_SET', array('require php')); + } break; case 'display': diff --git a/phpBB/phpbb/feed/attachments_base.php b/phpBB/phpbb/feed/attachments_base.php index b14dafe15a..5d3272e0d9 100644 --- a/phpBB/phpbb/feed/attachments_base.php +++ b/phpBB/phpbb/feed/attachments_base.php @@ -25,8 +25,11 @@ abstract class attachments_base extends base /** * Retrieve the list of attachments that may be displayed + * + * @param array $post_ids Specify for which post IDs to fetch the attachments (optional) + * @param array $topic_ids Specify for which topic IDs to fetch the attachments (optional) */ - protected function fetch_attachments() + protected function fetch_attachments($post_ids = array(), $topic_ids = array()) { $sql_array = array( 'SELECT' => 'a.*', @@ -37,7 +40,20 @@ abstract class attachments_base extends base 'ORDER_BY' => 'a.filetime DESC, a.post_msg_id ASC', ); - if (isset($this->topic_id)) + if (!empty($post_ids)) + { + $sql_array['WHERE'] .= 'AND ' . $this->db->sql_in_set('a.post_msg_id', $post_ids); + } + else if (!empty($topic_ids)) + { + if (isset($this->topic_id)) + { + $topic_ids[] = $this->topic_id; + } + + $sql_array['WHERE'] .= 'AND ' . $this->db->sql_in_set('a.topic_id', $topic_ids); + } + else if (isset($this->topic_id)) { $sql_array['WHERE'] .= 'AND a.topic_id = ' . (int) $this->topic_id; } @@ -51,6 +67,11 @@ abstract class attachments_base extends base ); $sql_array['WHERE'] .= 'AND t.forum_id = ' . (int) $this->forum_id; } + else + { + // Do not allow querying the full attachments table + throw new \RuntimeException($this->user->lang('INVALID_FEED_ATTACHMENTS')); + } $sql = $this->db->sql_build_query('SELECT', $sql_array); $result = $this->db->sql_query($sql); @@ -64,15 +85,6 @@ abstract class attachments_base extends base } /** - * {@inheritDoc} - */ - public function open() - { - parent::open(); - $this->fetch_attachments(); - } - - /** * Get attachments related to a given post * * @param $post_id int Post id diff --git a/phpBB/phpbb/feed/forum.php b/phpBB/phpbb/feed/forum.php index f522e91169..0c142e8cc8 100644 --- a/phpBB/phpbb/feed/forum.php +++ b/phpBB/phpbb/feed/forum.php @@ -138,6 +138,8 @@ class forum extends post_base return false; } + parent::fetch_attachments(array(), $topic_ids); + $this->sql = array( 'SELECT' => 'p.post_id, p.topic_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' . 'u.username, u.user_id', diff --git a/phpBB/phpbb/feed/news.php b/phpBB/phpbb/feed/news.php index fb6fa09278..13ca82c093 100644 --- a/phpBB/phpbb/feed/news.php +++ b/phpBB/phpbb/feed/news.php @@ -90,6 +90,8 @@ class news extends topic_base return false; } + parent::fetch_attachments($post_ids); + $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time, diff --git a/phpBB/phpbb/feed/overall.php b/phpBB/phpbb/feed/overall.php index 40cf94ace0..b083df922d 100644 --- a/phpBB/phpbb/feed/overall.php +++ b/phpBB/phpbb/feed/overall.php @@ -55,6 +55,8 @@ class overall extends post_base return false; } + parent::fetch_attachments(array(), $topic_ids); + // Get the actual data $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, ' . diff --git a/phpBB/phpbb/feed/topic.php b/phpBB/phpbb/feed/topic.php index e5f2c41468..2504e411b1 100644 --- a/phpBB/phpbb/feed/topic.php +++ b/phpBB/phpbb/feed/topic.php @@ -126,6 +126,8 @@ class topic extends post_base */ protected function get_sql() { + parent::fetch_attachments(); + $this->sql = array( 'SELECT' => 'p.post_id, p.post_time, p.post_edit_time, p.post_visibility, p.post_subject, p.post_text, p.bbcode_bitfield, p.bbcode_uid, p.enable_bbcode, p.enable_smilies, p.enable_magic_url, p.post_attachment, ' . 'u.username, u.user_id', diff --git a/phpBB/phpbb/feed/topics.php b/phpBB/phpbb/feed/topics.php index cf4a2e579e..183c29d11c 100644 --- a/phpBB/phpbb/feed/topics.php +++ b/phpBB/phpbb/feed/topics.php @@ -58,6 +58,8 @@ class topics extends topic_base return false; } + parent::fetch_attachments($post_ids); + $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, t.topic_id, t.topic_title, t.topic_poster, t.topic_first_poster_name, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, t.topic_time, t.topic_last_post_time, diff --git a/phpBB/phpbb/feed/topics_active.php b/phpBB/phpbb/feed/topics_active.php index 52340dc2d5..7ae0bde56b 100644 --- a/phpBB/phpbb/feed/topics_active.php +++ b/phpBB/phpbb/feed/topics_active.php @@ -77,6 +77,8 @@ class topics_active extends topic_base return false; } + parent::fetch_attachments($post_ids); + $this->sql = array( 'SELECT' => 'f.forum_id, f.forum_name, t.topic_id, t.topic_title, t.topic_posts_approved, t.topic_posts_unapproved, t.topic_posts_softdeleted, t.topic_views, diff --git a/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php index 258a035768..5cdc331cbc 100644 --- a/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php +++ b/phpBB/phpbb/install/helper/file_updater/ftp_file_updater.php @@ -47,7 +47,7 @@ class ftp_file_updater implements file_updater_interface * @param string $phpbb_root_path * @param string $php_ext */ - public function __constructor(update_helper $update_helper, $phpbb_root_path, $php_ext) + public function __construct(update_helper $update_helper, $phpbb_root_path, $php_ext) { $this->transfer = null; $this->update_helper = $update_helper; diff --git a/phpBB/phpbb/install/module/install_data/task/create_search_index.php b/phpBB/phpbb/install/module/install_data/task/create_search_index.php new file mode 100644 index 0000000000..8a2f6aa1de --- /dev/null +++ b/phpBB/phpbb/install/module/install_data/task/create_search_index.php @@ -0,0 +1,134 @@ +<?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\install\module\install_data\task; + +use phpbb\auth\auth; +use phpbb\db\driver\driver_interface; +use phpbb\event\dispatcher; +use phpbb\config\config; +use phpbb\install\helper\container_factory; +use phpbb\language\language; +use phpbb\search\fulltext_native; +use phpbb\user; + +class create_search_index extends \phpbb\install\task_base +{ + /** + * @var auth + */ + protected $auth; + + /** + * @var config + */ + protected $config; + + /** + * @var driver_interface + */ + protected $db; + + /** + * @var dispatcher + */ + protected $phpbb_dispatcher; + + /** + * @var language + */ + protected $language; + + /** + * @var user + */ + protected $user; + + /** + * @var string phpBB root path + */ + protected $phpbb_root_path; + + /** + * @var string PHP file extension + */ + protected $php_ext; + + /** + * Constructor + * + * @param config $config phpBB config + * @param container_factory $container Installer's DI container + * @param string $phpbb_root_path phpBB root path + * @param string $php_ext PHP file extension + */ + public function __construct(config $config, container_factory $container, + $phpbb_root_path, $php_ext) + { + $this->auth = $container->get('auth'); + $this->config = $config; + $this->db = $container->get('dbal.conn'); + $this->language = $container->get('language'); + $this->phpbb_dispatcher = $container->get('dispatcher'); + $this->user = $container->get('user'); + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Make sure fulltext native load update is set + $this->config->set('fulltext_native_load_upd', 1); + + $error = false; + $search = new fulltext_native( + $error, + $this->phpbb_root_path, + $this->php_ext, + $this->auth, + $this->config, + $this->db, + $this->user, + $this->phpbb_dispatcher + ); + + $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id + FROM ' . POSTS_TABLE; + $result = $this->db->sql_query($sql); + + while ($row = $this->db->sql_fetchrow($result)) + { + $search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']); + } + $this->db->sql_freeresult($result); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_CREATE_SEARCH_INDEX'; + } +} diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php index 1cb4f04297..e8a9c971b7 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_email_data.php @@ -84,7 +84,7 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta $email_form = array( 'email_enable' => array( 'label' => 'ENABLE_EMAIL', - 'description' => 'COOKIE_SECURE_EXPLAIN', + 'description' => 'ENABLE_EMAIL_EXPLAIN', 'type' => 'radio', 'options' => array( array( diff --git a/phpBB/phpbb/install/module/update_database/task/update_extensions.php b/phpBB/phpbb/install/module/update_database/task/update_extensions.php index 13c1591dcd..b66847b243 100644 --- a/phpBB/phpbb/install/module/update_database/task/update_extensions.php +++ b/phpBB/phpbb/install/module/update_database/task/update_extensions.php @@ -138,7 +138,7 @@ class update_extensions extends task_base $default_update_extensions = []; foreach (self::$default_extensions_update as $version => $extensions) { - if ($this->update_helper->phpbb_version_compare($version_from, $version, '<=')) + if ($this->update_helper->phpbb_version_compare($version_from, $version, '<')) { $default_update_extensions = array_merge($default_update_extensions, $extensions); } diff --git a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php index e3e6db6263..1792a3b723 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/diff_files.php @@ -132,41 +132,62 @@ class diff_files extends task_base $file_contents = array(); // Handle the special case when user created a file with the filename that is now new in the core - $file_contents[0] = (file_exists($old_path . $filename)) ? file_get_contents($old_path . $filename) : ''; + if (file_exists($old_path . $filename)) + { + $file_contents[0] = file_get_contents($old_path . $filename); - $filenames = array( - $this->phpbb_root_path . $filename, - $new_path . $filename - ); + $filenames = array( + $this->phpbb_root_path . $filename, + $new_path . $filename + ); - foreach ($filenames as $file_to_diff) - { - $file_contents[] = file_get_contents($file_to_diff); + foreach ($filenames as $file_to_diff) + { + $file_contents[] = file_get_contents($file_to_diff); + + if ($file_contents[sizeof($file_contents) - 1] === false) + { + $this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); + unset($file_contents); + throw new user_interaction_required_exception(); + } + } - if ($file_contents[sizeof($file_contents) - 1] === false) + $diff = new \diff3($file_contents[0], $file_contents[1], $file_contents[2]); + unset($file_contents); + + // Handle conflicts + if ($diff->get_num_conflicts() !== 0) { - $this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); - unset($file_contents); - throw new user_interaction_required_exception(); + $merge_conflicts[] = $filename; } - } - $diff = new \diff3($file_contents[0], $file_contents[1], $file_contents[2]); - unset($file_contents); + // Save merged output + $this->cache->put( + '_file_' . md5($filename), + base64_encode(implode("\n", $diff->merged_output())) + ); - // Handle conflicts - if ($diff->get_num_conflicts() !== 0) - { - $merge_conflicts[] = $filename; + unset($diff); } + else + { + $new_file_content = file_get_contents($new_path . $filename); - // Save merged output - $this->cache->put( - '_file_' . md5($filename), - base64_encode(implode("\n", $diff->merged_output())) - ); + if ($new_file_content === false) + { + $this->iohandler->add_error_message(array('FILE_DIFFER_ERROR_FILE_CANNOT_BE_READ', $files_to_diff)); + unset($new_file_content ); + throw new user_interaction_required_exception(); + } - unset($diff); + // Save new file content to cache + $this->cache->put( + '_file_' . md5($filename), + base64_encode($new_file_content) + ); + unset($new_file_content); + } $progress_count++; $this->iohandler->set_progress('UPDATE_FILE_DIFF', $progress_count); diff --git a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php index 5b48350e73..47a71eb844 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/file_check.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/file_check.php @@ -123,7 +123,7 @@ class file_check extends task_base $default_update_extensions = []; foreach (\phpbb\install\module\update_database\task\update_extensions::$default_extensions_update as $version => $extensions) { - if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '>')) + if ($this->update_helper->phpbb_version_compare($update_info['version']['from'], $version, '>=')) { $default_update_extensions = array_merge($default_update_extensions, $extensions); } diff --git a/phpBB/phpbb/notification/type/post.php b/phpBB/phpbb/notification/type/post.php index b9afc6d70a..03221e7c7a 100644 --- a/phpBB/phpbb/notification/type/post.php +++ b/phpBB/phpbb/notification/type/post.php @@ -456,6 +456,12 @@ class post extends \phpbb\notification\type\base return array(); } - return array('notification_data' => $serialized_data); + $data_array = array_merge(array( + 'post_time' => $post['post_time'], + 'post_id' => $post['post_id'], + 'topic_id' => $post['topic_id'] + ), $this->get_data(false)); + + return $data_array; } } diff --git a/phpBB/phpbb/pagination.php b/phpBB/phpbb/pagination.php index 7a81c25ad2..a5a95b096d 100644 --- a/phpBB/phpbb/pagination.php +++ b/phpBB/phpbb/pagination.php @@ -284,7 +284,7 @@ class pagination */ public function get_on_page($per_page, $start) { - return floor($start / $per_page) + 1; + return floor((int) $start / (int) $per_page) + 1; } /** diff --git a/phpBB/phpbb/profilefields/type/type_date.php b/phpBB/phpbb/profilefields/type/type_date.php index 414484920b..139ceabeec 100644 --- a/phpBB/phpbb/profilefields/type/type_date.php +++ b/phpBB/phpbb/profilefields/type/type_date.php @@ -72,7 +72,7 @@ class type_date extends type_base 'lang_options' => $field_data['lang_options'], ); - $always_now = $request->variable('always_now', -1); + $always_now = $this->request->variable('always_now', -1); if ($always_now == -1) { $s_checked = ($field_data['field_default_value'] == 'now') ? true : false; diff --git a/phpBB/phpbb/search/fulltext_mysql.php b/phpBB/phpbb/search/fulltext_mysql.php index 73d7bc1574..d5165df016 100644 --- a/phpBB/phpbb/search/fulltext_mysql.php +++ b/phpBB/phpbb/search/fulltext_mysql.php @@ -942,38 +942,45 @@ class fulltext_mysql extends \phpbb\search\base $this->get_stats(); } - $alter = array(); + $alter_list = array(); if (!isset($this->stats['post_subject'])) { + $alter_entry = array(); if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) { - $alter[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL'; + $alter_entry[] = 'MODIFY post_subject varchar(255) COLLATE utf8_unicode_ci DEFAULT \'\' NOT NULL'; } else { - $alter[] = 'MODIFY post_subject text NOT NULL'; + $alter_entry[] = 'MODIFY post_subject text NOT NULL'; } - $alter[] = 'ADD FULLTEXT (post_subject)'; + $alter_entry[] = 'ADD FULLTEXT (post_subject)'; + $alter_list[] = $alter_entry; } if (!isset($this->stats['post_content'])) { + $alter_entry = array(); if ($this->db->get_sql_layer() == 'mysqli' || version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) { - $alter[] = 'MODIFY post_text mediumtext COLLATE utf8_unicode_ci NOT NULL'; + $alter_entry[] = 'MODIFY post_text mediumtext COLLATE utf8_unicode_ci NOT NULL'; } else { - $alter[] = 'MODIFY post_text mediumtext NOT NULL'; + $alter_entry[] = 'MODIFY post_text mediumtext NOT NULL'; } - $alter[] = 'ADD FULLTEXT post_content (post_text, post_subject)'; + $alter_entry[] = 'ADD FULLTEXT post_content (post_text, post_subject)'; + $alter_list[] = $alter_entry; } - if (sizeof($alter)) + if (sizeof($alter_list)) { - $this->db->sql_query('ALTER TABLE ' . POSTS_TABLE . ' ' . implode(', ', $alter)); + foreach ($alter_list as $alter) + { + $this->db->sql_query('ALTER TABLE ' . POSTS_TABLE . ' ' . implode(', ', $alter)); + } } $this->db->sql_query('TRUNCATE TABLE ' . SEARCH_RESULTS_TABLE); diff --git a/phpBB/phpbb/search/fulltext_native.php b/phpBB/phpbb/search/fulltext_native.php index 2071a973e5..73dcfce9a5 100644 --- a/phpBB/phpbb/search/fulltext_native.php +++ b/phpBB/phpbb/search/fulltext_native.php @@ -120,7 +120,7 @@ class fulltext_native extends \phpbb\search\base $this->phpbb_dispatcher = $phpbb_dispatcher; $this->user = $user; - $this->word_length = array('min' => $this->config['fulltext_native_min_chars'], 'max' => $this->config['fulltext_native_max_chars']); + $this->word_length = array('min' => (int) $this->config['fulltext_native_min_chars'], 'max' => (int) $this->config['fulltext_native_max_chars']); /** * Load the UTF tools diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index cbe2f02851..cc200b1adc 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -838,7 +838,7 @@ class session $sql = 'SELECT COUNT(session_id) AS sessions FROM ' . SESSIONS_TABLE . ' WHERE session_user_id = ' . (int) $this->data['user_id'] . ' - AND session_time >= ' . (int) ($this->time_now - (max($config['session_length'], $config['form_token_lifetime']))); + AND session_time >= ' . (int) ($this->time_now - (max((int) $config['session_length'], (int) $config['form_token_lifetime']))); $result = $db->sql_query($sql); $row = $db->sql_fetchrow($result); $db->sql_freeresult($result); diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php index 9a40702ba8..41c0a01ba8 100644 --- a/phpBB/phpbb/template/base.php +++ b/phpBB/phpbb/template/base.php @@ -133,6 +133,14 @@ abstract class base implements template } /** + * {@inheritdoc} + */ + public function find_key_index($blockname, $key) + { + return $this->context->find_key_index($blockname, $key); + } + + /** * Calls hook if any is defined. * * @param string $handle Template handle being displayed. diff --git a/phpBB/phpbb/template/context.php b/phpBB/phpbb/template/context.php index 4ee48205c8..c7df29d62c 100644 --- a/phpBB/phpbb/template/context.php +++ b/phpBB/phpbb/template/context.php @@ -264,6 +264,89 @@ class context } /** + * Find the index for a specified key in the innermost specified block + * + * @param string $blockname the blockname, for example 'loop' + * @param mixed $key Key to search for + * + * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] + * + * int: Position [the position to search for] + * + * If key is false the position is set to 0 + * If key is true the position is set to the last entry + * + * @return mixed false if not found, index position otherwise; be sure to test with === + */ + public function find_key_index($blockname, $key) + { + // For nested block, $blockcount > 0, for top-level block, $blockcount == 0 + $blocks = explode('.', $blockname); + $blockcount = sizeof($blocks) - 1; + + $block = $this->tpldata; + for ($i = 0; $i < $blockcount; $i++) + { + if (($pos = strpos($blocks[$i], '[')) !== false) + { + $name = substr($blocks[$i], 0, $pos); + + if (strpos($blocks[$i], '[]') === $pos) + { + $index = sizeof($block[$name]) - 1; + } + else + { + $index = min((int) substr($blocks[$i], $pos + 1, -1), sizeof($block[$name]) - 1); + } + } + else + { + $name = $blocks[$i]; + $index = sizeof($block[$name]) - 1; + } + if (!isset($block[$name])) + { + return false; + } + $block = $block[$name]; + if (!isset($block[$index])) + { + return false; + } + $block = $block[$index]; + } + + if (!isset($block[$blocks[$i]])) + { + return false; + } + $block = $block[$blocks[$i]]; // Traverse the last block + + // Change key to zero (change first position) if false and to last position if true + if ($key === false || $key === true) + { + return ($key === false) ? 0 : sizeof($block) - 1; + } + + // Get correct position if array given + if (is_array($key)) + { + // Search array to get correct position + list($search_key, $search_value) = @each($key); + foreach ($block as $i => $val_ary) + { + if ($val_ary[$search_key] === $search_value) + { + return $i; + } + } + } + + return (is_int($key) && ((0 <= $key) && ($key < sizeof($block)))) ? $key : false; + } + + /** * Change already assigned key variable pair (one-dimensional - single loop entry) * * An example of how to use this function: @@ -365,15 +448,15 @@ class context if ($mode == 'insert') { // Make sure we are not exceeding the last iteration - if ($key >= sizeof($this->tpldata[$blockname])) + if ($key >= sizeof($block)) { - $key = sizeof($this->tpldata[$blockname]); - unset($this->tpldata[$blockname][($key - 1)]['S_LAST_ROW']); + $key = sizeof($block); + unset($block[($key - 1)]['S_LAST_ROW']); $vararray['S_LAST_ROW'] = true; } else if ($key === 0) { - unset($this->tpldata[$blockname][0]['S_FIRST_ROW']); + unset($block[0]['S_FIRST_ROW']); $vararray['S_FIRST_ROW'] = true; } diff --git a/phpBB/phpbb/template/template.php b/phpBB/phpbb/template/template.php index 041ecb12e4..9e3d658ca8 100644 --- a/phpBB/phpbb/template/template.php +++ b/phpBB/phpbb/template/template.php @@ -173,6 +173,23 @@ interface template public function alter_block_array($blockname, array $vararray, $key = false, $mode = 'insert'); /** + * Find the index for a specified key in the innermost specified block + * + * @param string $blockname the blockname, for example 'loop' + * @param mixed $key Key to search for + * + * array: KEY => VALUE [the key/value pair to search for within the loop to determine the correct position] + * + * int: Position [the position to search for] + * + * If key is false the position is set to 0 + * If key is true the position is set to the last entry + * + * @return mixed false if not found, index position otherwise; be sure to test with === + */ + public function find_key_index($blockname, $key); + + /** * Get path to template for handle (required for BBCode parser) * * @param string $handle Handle to retrieve the source file diff --git a/phpBB/phpbb/template/twig/extension.php b/phpBB/phpbb/template/twig/extension.php index 92f87a0331..f0e716d697 100644 --- a/phpBB/phpbb/template/twig/extension.php +++ b/phpBB/phpbb/template/twig/extension.php @@ -170,8 +170,7 @@ class extension extends \Twig_Extension $args = func_get_args(); $key = $args[0]; - $context = $this->context->get_data_ref(); - $context_vars = $context['.'][0]; + $context_vars = $this->context->get_root_ref(); if (isset($context_vars['L_' . $key])) { diff --git a/phpBB/phpbb/textformatter/data_access.php b/phpBB/phpbb/textformatter/data_access.php index 2103bf8e60..0d37e62c87 100644 --- a/phpBB/phpbb/textformatter/data_access.php +++ b/phpBB/phpbb/textformatter/data_access.php @@ -81,11 +81,8 @@ class data_access public function get_bbcodes() { $sql = 'SELECT bbcode_match, bbcode_tpl FROM ' . $this->bbcodes_table; - $result = $this->db->sql_query($sql); - $rows = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - return $rows; + return $this->fetch_decoded_rowset($sql, ['bbcode_match']); } /** @@ -101,11 +98,8 @@ class data_access $sql = 'SELECT code, emotion, smiley_url, smiley_width, smiley_height FROM ' . $this->smilies_table . ' ORDER BY display_on_posting DESC'; - $result = $this->db->sql_query($sql); - $rows = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - return $rows; + return $this->fetch_decoded_rowset($sql, ['code', 'emotion', 'smiley_url']); } /** @@ -116,11 +110,8 @@ class data_access protected function get_styles() { $sql = 'SELECT style_id, style_path, style_parent_id, bbcode_bitfield FROM ' . $this->styles_table; - $result = $this->db->sql_query($sql); - $rows = $this->db->sql_fetchrowset($result); - $this->db->sql_freeresult($result); - return $rows; + return $this->fetch_decoded_rowset($sql); } /** @@ -219,10 +210,43 @@ class data_access public function get_censored_words() { $sql = 'SELECT word, replacement FROM ' . $this->words_table; + + return $this->fetch_decoded_rowset($sql, ['word', 'replacement']); + } + + /** + * Decode HTML special chars in given rowset + * + * @param array $rows Original rowset + * @param array $columns List of columns to decode + * @return array Decoded rowset + */ + protected function decode_rowset(array $rows, array $columns) + { + foreach ($rows as &$row) + { + foreach ($columns as $column) + { + $row[$column] = htmlspecialchars_decode($row[$column]); + } + } + + return $rows; + } + + /** + * Fetch all rows for given query and decode plain text columns + * + * @param string $sql SELECT query + * @param array $columns List of columns to decode + * @return array + */ + protected function fetch_decoded_rowset($sql, array $columns = []) + { $result = $this->db->sql_query($sql); $rows = $this->db->sql_fetchrowset($result); $this->db->sql_freeresult($result); - return $rows; + return $this->decode_rowset($rows, $columns); } } diff --git a/phpBB/phpbb/textformatter/s9e/factory.php b/phpBB/phpbb/textformatter/s9e/factory.php index a310c67359..5cbf2712f7 100644 --- a/phpBB/phpbb/textformatter/s9e/factory.php +++ b/phpBB/phpbb/textformatter/s9e/factory.php @@ -333,8 +333,7 @@ class factory implements \phpbb\textformatter\cache_interface $configurator->plugins->load('Censor', array('tagName' => 'censor:tag')); foreach ($censor as $row) { - // NOTE: words are stored as HTML, we need to decode them to plain text - $configurator->Censor->add(htmlspecialchars_decode($row['word']), htmlspecialchars_decode($row['replacement'])); + $configurator->Censor->add($row['word'], $row['replacement']); } } @@ -348,10 +347,10 @@ class factory implements \phpbb\textformatter\cache_interface $configurator->registeredVars['max_img_width'] = 0; // Load the Emoji plugin and modify its tag's template to obey viewsmilies - $configurator->Emoji->setImageSize(18); + $configurator->Emoji->omitImageSize(); $configurator->Emoji->useSVG(); $tag = $configurator->Emoji->getTag(); - $tag->template = '<xsl:choose><xsl:when test="$S_VIEWSMILIES">' . str_replace('class="emoji"', 'class="smilies"', $tag->template) . '</xsl:when><xsl:otherwise><xsl:value-of select="."/></xsl:otherwise></xsl:choose>'; + $tag->template = '<xsl:choose><xsl:when test="$S_VIEWSMILIES">' . str_replace('class="emoji"', 'class="emoji smilies"', $tag->template) . '</xsl:when><xsl:otherwise><xsl:value-of select="."/></xsl:otherwise></xsl:choose>'; /** * Modify the s9e\TextFormatter configurator after the default settings are set diff --git a/phpBB/phpbb/textformatter/s9e/parser.php b/phpBB/phpbb/textformatter/s9e/parser.php index e2653d60f0..05ddfffa11 100644 --- a/phpBB/phpbb/textformatter/s9e/parser.php +++ b/phpBB/phpbb/textformatter/s9e/parser.php @@ -142,6 +142,7 @@ class parser implements \phpbb\textformatter\parser_interface public function disable_smilies() { $this->parser->disablePlugin('Emoticons'); + $this->parser->disablePlugin('Emoji'); } /** @@ -183,6 +184,7 @@ class parser implements \phpbb\textformatter\parser_interface public function enable_smilies() { $this->parser->enablePlugin('Emoticons'); + $this->parser->enablePlugin('Emoji'); } /** diff --git a/phpBB/phpbb/textformatter/s9e/utils.php b/phpBB/phpbb/textformatter/s9e/utils.php index b317fe4a8d..a9a6d4b892 100644 --- a/phpBB/phpbb/textformatter/s9e/utils.php +++ b/phpBB/phpbb/textformatter/s9e/utils.php @@ -136,4 +136,17 @@ class utils implements \phpbb\textformatter\utils_interface { return \s9e\TextFormatter\Unparser::unparse($xml); } + + /** + * {@inheritdoc} + */ + public function is_empty($text) + { + if ($text === null || $text === '') + { + return true; + } + + return trim($this->unparse($text)) === ''; + } } diff --git a/phpBB/phpbb/textformatter/utils_interface.php b/phpBB/phpbb/textformatter/utils_interface.php index 4810453cd1..4b7392976a 100644 --- a/phpBB/phpbb/textformatter/utils_interface.php +++ b/phpBB/phpbb/textformatter/utils_interface.php @@ -62,10 +62,18 @@ interface utils_interface public function remove_bbcode($text, $bbcode_name, $depth = 0); /** - * Return a parsed text to its original form - * - * @param string $text Parsed text - * @return string Original plain text - */ + * Return a parsed text to its original form + * + * @param string $text Parsed text + * @return string Original plain text + */ public function unparse($text); + + /** + * Return whether or not a parsed text represent an empty text. + * + * @param string $text Parsed text + * @return bool Tue if the original text is empty + */ + public function is_empty($text); } diff --git a/phpBB/phpbb/version_helper.php b/phpBB/phpbb/version_helper.php index 17caaa4a60..f80d2b16fc 100644 --- a/phpBB/phpbb/version_helper.php +++ b/phpBB/phpbb/version_helper.php @@ -198,6 +198,49 @@ class version_helper } /** + * Gets the latest update for the current branch the user is on + * Will suggest versions from newer branches when EoL has been reached + * and/or version from newer branch is needed for having all known security + * issues fixed. + * + * @param bool $force_update Ignores cached data. Defaults to false. + * @param bool $force_cache Force the use of the cache. Override $force_update. + * @return array Version info or empty array if there are no updates + * @throws \RuntimeException + */ + public function get_update_on_branch($force_update = false, $force_cache = false) + { + $versions = $this->get_versions_matching_stability($force_update, $force_cache); + + $self = $this; + $current_version = $this->current_version; + + // Filter out any versions less than to the current version + $versions = array_filter($versions, function($data) use ($self, $current_version) { + return $self->compare($data['current'], $current_version, '>='); + }); + + // Get the lowest version from the previous list. + $update_info = array_reduce($versions, function($value, $data) use ($self, $current_version) { + if ($value === null && $self->compare($data['current'], $current_version, '>=')) + { + if (!$data['eol'] && (!$data['security'] || $self->compare($data['security'], $data['current'], '<='))) + { + return ($self->compare($data['current'], $current_version, '>')) ? $data : array(); + } + else + { + return null; + } + } + + return $value; + }); + + return $update_info === null ? array() : $update_info; + } + + /** * Obtains the latest version information * * @param bool $force_update Ignores cached data. Defaults to false. |