diff options
Diffstat (limited to 'phpBB/phpbb')
65 files changed, 2151 insertions, 563 deletions
diff --git a/phpBB/phpbb/cache/driver/base.php b/phpBB/phpbb/cache/driver/base.php index 55cd4668de..85762c4d95 100644 --- a/phpBB/phpbb/cache/driver/base.php +++ b/phpBB/phpbb/cache/driver/base.php @@ -49,6 +49,7 @@ abstract class base implements \phpbb\cache\driver\driver_interface $this->remove_dir($fileInfo->getPathname()); } else if (strpos($filename, 'container_') === 0 || + strpos($filename, 'autoload_') === 0 || strpos($filename, 'url_matcher') === 0 || strpos($filename, 'url_generator') === 0 || strpos($filename, 'sql_') === 0 || diff --git a/phpBB/phpbb/console/command/db/migration_command.php b/phpBB/phpbb/console/command/db/migration_command.php index d44ef8c5cb..b951560588 100644 --- a/phpBB/phpbb/console/command/db/migration_command.php +++ b/phpBB/phpbb/console/command/db/migration_command.php @@ -45,7 +45,7 @@ abstract class migration_command extends \phpbb\console\command\command $this->migrator->set_migrations($migrations); - return $migrations; + return $this->migrator->get_migrations(); } protected function finalise_update() diff --git a/phpBB/phpbb/cron/task/core/tidy_plupload.php b/phpBB/phpbb/cron/task/core/tidy_plupload.php index d7364374af..37d0e9b21a 100644 --- a/phpBB/phpbb/cron/task/core/tidy_plupload.php +++ b/phpBB/phpbb/cron/task/core/tidy_plupload.php @@ -42,6 +42,12 @@ class tidy_plupload extends \phpbb\cron\task\base */ protected $config; + /** @var \phpbb\log\log_interface */ + protected $log; + + /** @var \phpbb\user */ + protected $user; + /** * Directory where plupload stores temporary files. * @var string @@ -53,11 +59,15 @@ class tidy_plupload extends \phpbb\cron\task\base * * @param string $phpbb_root_path The root path * @param \phpbb\config\config $config The config + * @param \phpbb\log\log_interface $log Log + * @param \phpbb\user $user User object */ - public function __construct($phpbb_root_path, \phpbb\config\config $config) + public function __construct($phpbb_root_path, \phpbb\config\config $config, \phpbb\log\log_interface $log, \phpbb\user $user) { $this->phpbb_root_path = $phpbb_root_path; $this->config = $config; + $this->log = $log; + $this->user = $user; $this->plupload_upload_path = $this->phpbb_root_path . $this->config['upload_path'] . '/plupload'; } @@ -67,8 +77,6 @@ class tidy_plupload extends \phpbb\cron\task\base */ public function run() { - global $user, $phpbb_log; - // Remove old temporary file (perhaps failed uploads?) $last_valid_timestamp = time() - $this->max_file_age; try @@ -90,7 +98,7 @@ class tidy_plupload extends \phpbb\cron\task\base } catch (\UnexpectedValueException $e) { - $phpbb_log->add('critical', $user->data['user_id'], $user->ip, 'LOG_PLUPLOAD_TIDY_FAILED', false, array( + $this->log->add('critical', $this->user->data['user_id'], $this->user->ip, 'LOG_PLUPLOAD_TIDY_FAILED', false, array( $this->plupload_upload_path, $e->getMessage(), $e->getTraceAsString() diff --git a/phpBB/phpbb/db/migration/data/v31x/v318rc1.php b/phpBB/phpbb/db/migration/data/v31x/v318rc1.php new file mode 100644 index 0000000000..8bae95c7d6 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v318rc1.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\v31x; + +class v318rc1 extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\increase_size_of_dateformat', + '\phpbb\db\migration\data\v31x\v317pl1', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.1.8-RC1')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v320/default_data_type_ids.php b/phpBB/phpbb/db/migration/data/v320/default_data_type_ids.php new file mode 100644 index 0000000000..65e5b3fa73 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/default_data_type_ids.php @@ -0,0 +1,361 @@ +<?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 default_data_type_ids extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320a2', + '\phpbb\db\migration\data\v320\oauth_states', + ); + } + + public function update_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'acl_users' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'attachments' => array( + 'attach_id' => array('ULINT', null, 'auto_increment'), + 'post_msg_id' => array('ULINT', 0), + 'poster_id' => array('ULINT', 0), + 'topic_id' => array('ULINT', 0), + ), + $this->table_prefix . 'banlist' => array( + 'ban_id' => array('ULINT', null, 'auto_increment'), + 'ban_userid' => array('ULINT', 0), + ), + $this->table_prefix . 'bookmarks' => array( + 'topic_id' => array('ULINT', 0), + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'bots' => array( + 'bot_id' => array('ULINT', null, 'auto_increment'), + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'drafts' => array( + 'draft_id' => array('ULINT', null, 'auto_increment'), + 'user_id' => array('ULINT', 0), + 'topic_id' => array('ULINT', 0), + ), + $this->table_prefix . 'forums' => array( + 'forum_last_post_id' => array('ULINT', 0), + 'forum_last_poster_id' => array('ULINT', 0), + ), + $this->table_prefix . 'forums_access' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'forums_track' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'forums_watch' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'log' => array( + 'log_id' => array('ULINT', null, 'auto_increment'), + 'post_id' => array('ULINT', 0), + 'reportee_id' => array('ULINT', 0), + 'user_id' => array('ULINT', 0), + 'topic_id' => array('ULINT', 0), + ), + $this->table_prefix . 'login_attempts' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'moderator_cache' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'notifications' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'oauth_accounts' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'oauth_states' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'oauth_tokens' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'poll_options' => array( + 'topic_id' => array('ULINT', 0), + ), + $this->table_prefix . 'poll_votes' => array( + 'topic_id' => array('ULINT', 0), + 'vote_user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'posts' => array( + 'post_id' => array('ULINT', null, 'auto_increment'), + 'poster_id' => array('ULINT', 0), + 'post_delete_user' => array('ULINT', 0), + 'post_edit_user' => array('ULINT', 0), + 'topic_id' => array('ULINT', 0), + ), + $this->table_prefix . 'privmsgs' => array( + 'author_id' => array('ULINT', 0), + 'message_edit_user' => array('ULINT', 0), + 'msg_id' => array('ULINT', null, 'auto_increment'), + ), + $this->table_prefix . 'privmsgs_folder' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'privmsgs_rules' => array( + 'rule_user_id' => array('ULINT', 0), + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'privmsgs_to' => array( + 'author_id' => array('ULINT', 0), + 'msg_id' => array('ULINT', 0), + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'profile_fields_data' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'reports' => array( + 'report_id' => array('ULINT', 0), + 'pm_id' => array('ULINT', 0), + 'post_id' => array('ULINT', 0), + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'search_wordlist' => array( + 'word_id' => array('ULINT', null, 'auto_increment'), + ), + $this->table_prefix . 'search_wordmatch' => array( + 'post_id' => array('ULINT', 0), + 'word_id' => array('ULINT', 0), + ), + $this->table_prefix . 'sessions' => array( + 'session_user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'sessions_keys' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'topics' => array( + 'topic_id' => array('ULINT', null, 'auto_increment'), + 'topic_poster' => array('ULINT', 0), + 'topic_first_post_id' => array('ULINT', 0), + 'topic_last_post_id' => array('ULINT', 0), + 'topic_last_poster_id' => array('ULINT', 0), + 'topic_moved_id' => array('ULINT', 0), + 'topic_delete_user' => array('ULINT', 0), + ), + $this->table_prefix . 'topics_track' => array( + 'user_id' => array('ULINT', 0), + 'topic_id' => array('ULINT', 0), + ), + $this->table_prefix . 'topics_posted' => array( + 'user_id' => array('ULINT', 0), + 'topic_id' => array('ULINT', 0), + ), + $this->table_prefix . 'topics_watch' => array( + 'user_id' => array('ULINT', 0), + 'topic_id' => array('ULINT', 0), + ), + $this->table_prefix . 'user_notifications' => array( + 'item_id' => array('ULINT', 0), + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'user_group' => array( + 'user_id' => array('ULINT', 0), + ), + $this->table_prefix . 'users' => array( + 'user_id' => array('ULINT', null, 'auto_increment'), + ), + $this->table_prefix . 'warnings' => array( + 'log_id' => array('ULINT', 0), + 'user_id' => array('ULINT', 0), + 'post_id' => array('ULINT', 0), + ), + $this->table_prefix . 'words' => array( + 'word_id' => array('ULINT', null, 'auto_increment'), + ), + $this->table_prefix . 'zebra' => array( + 'user_id' => array('ULINT', 0), + 'zebra_id' => array('ULINT', 0), + ), + ), + ); + } + + public function revert_schema() + { + return array( + 'change_columns' => array( + $this->table_prefix . 'acl_users' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'attachments' => array( + 'attach_id' => array('UINT', null, 'auto_increment'), + 'post_msg_id' => array('UINT', 0), + 'poster_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + ), + $this->table_prefix . 'banlist' => array( + 'ban_id' => array('UINT', null, 'auto_increment'), + 'ban_userid' => array('UINT', 0), + ), + $this->table_prefix . 'bookmarks' => array( + 'topic_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'bots' => array( + 'bot_id' => array('UINT', null, 'auto_increment'), + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'drafts' => array( + 'draft_id' => array('UINT', null, 'auto_increment'), + 'user_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + ), + $this->table_prefix . 'forums' => array( + 'forum_last_post_id' => array('UINT', 0), + 'forum_last_poster_id' => array('UINT', 0), + ), + $this->table_prefix . 'forums_access' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'forums_track' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'forums_watch' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'log' => array( + 'log_id' => array('UINT', null, 'auto_increment'), + 'post_id' => array('UINT', 0), + 'reportee_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + ), + $this->table_prefix . 'login_attempts' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'moderator_cache' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'notifications' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'oauth_accounts' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'oauth_states' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'oauth_tokens' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'poll_options' => array( + 'topic_id' => array('UINT', 0), + ), + $this->table_prefix . 'poll_votes' => array( + 'topic_id' => array('UINT', 0), + 'vote_user_id' => array('UINT', 0), + ), + $this->table_prefix . 'posts' => array( + 'post_id' => array('UINT', null, 'auto_increment'), + 'poster_id' => array('UINT', 0), + 'post_delete_user' => array('UINT', 0), + 'post_edit_user' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + ), + $this->table_prefix . 'privmsgs' => array( + 'author_id' => array('UINT', 0), + 'message_edit_user' => array('UINT', 0), + 'msg_id' => array('UINT', null, 'auto_increment'), + ), + $this->table_prefix . 'privmsgs_folder' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'privmsgs_rules' => array( + 'rule_user_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'privmsgs_to' => array( + 'author_id' => array('UINT', 0), + 'msg_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'profile_fields_data' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'reports' => array( + 'report_id' => array('UINT', 0), + 'pm_id' => array('UINT', 0), + 'post_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'search_wordlist' => array( + 'word_id' => array('UINT', null, 'auto_increment'), + ), + $this->table_prefix . 'search_wordmatch' => array( + 'post_id' => array('UINT', 0), + 'word_id' => array('UINT', 0), + ), + $this->table_prefix . 'sessions' => array( + 'session_user_id' => array('UINT', 0), + ), + $this->table_prefix . 'sessions_keys' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'topics' => array( + 'topic_id' => array('UINT', null, 'auto_increment'), + 'topic_poster' => array('UINT', 0), + 'topic_first_post_id' => array('UINT', 0), + 'topic_last_post_id' => array('UINT', 0), + 'topic_last_poster_id' => array('UINT', 0), + 'topic_moved_id' => array('UINT', 0), + 'topic_delete_user' => array('UINT', 0), + ), + $this->table_prefix . 'topics_track' => array( + 'user_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + ), + $this->table_prefix . 'topics_posted' => array( + 'user_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + ), + $this->table_prefix . 'topics_watch' => array( + 'user_id' => array('UINT', 0), + 'topic_id' => array('UINT', 0), + ), + $this->table_prefix . 'user_notifications' => array( + 'item_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'user_group' => array( + 'user_id' => array('UINT', 0), + ), + $this->table_prefix . 'users' => array( + 'user_id' => array('UINT', null, 'auto_increment'), + ), + $this->table_prefix . 'warnings' => array( + 'log_id' => array('UINT', 0), + 'user_id' => array('UINT', 0), + 'post_id' => array('UINT', 0), + ), + $this->table_prefix . 'words' => array( + 'word_id' => array('UINT', null, 'auto_increment'), + ), + $this->table_prefix . 'zebra' => array( + 'user_id' => array('UINT', 0), + 'zebra_id' => array('UINT', 0), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php b/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.php new file mode 100644 index 0000000000..d61f6b96fd --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/remote_upload_validation.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 remote_upload_validation extends \phpbb\db\migration\migration +{ + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v320\v320a2', + ); + } + + public function update_data() + { + return array( + array('config.add', array('remote_upload_verify', '0')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/data/v320/text_reparser.php b/phpBB/phpbb/db/migration/data/v320/text_reparser.php index 1d73b74a76..ea614feb40 100644 --- a/phpBB/phpbb/db/migration/data/v320/text_reparser.php +++ b/phpBB/phpbb/db/migration/data/v320/text_reparser.php @@ -17,7 +17,10 @@ class text_reparser extends \phpbb\db\migration\container_aware_migration { static public function depends_on() { - return array('\phpbb\db\migration\data\v310\contact_admin_form'); + return array( + '\phpbb\db\migration\data\v310\contact_admin_form', + '\phpbb\db\migration\data\v320\allowed_schemes_links', + ); } public function effectively_installed() @@ -78,7 +81,7 @@ class text_reparser extends \phpbb\db\migration\container_aware_migration $end = max(1, $resume_data['current']); $reparser->reparse_range($start, $end); - $processed_records = $end - $start + 1; + $processed_records += $end - $start + 1; $resume_data['current'] = $start - 1; if ($start === 1) diff --git a/phpBB/phpbb/db/migration/data/v320/v320b1.php b/phpBB/phpbb/db/migration/data/v320/v320b1.php new file mode 100644 index 0000000000..5c3a3797cd --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v320/v320b1.php @@ -0,0 +1,39 @@ +<?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 v320b1 extends \phpbb\db\migration\container_aware_migration +{ + public function effectively_installed() + { + return version_compare($this->config['version'], '3.2.0-b1', '>='); + } + + static public function depends_on() + { + return array( + '\phpbb\db\migration\data\v31x\v317pl1', + '\phpbb\db\migration\data\v320\v320a2', + '\phpbb\db\migration\data\v31x\increase_size_of_dateformat', + '\phpbb\db\migration\data\v320\default_data_type_ids', + ); + } + + public function update_data() + { + return array( + array('config.update', array('version', '3.2.0-b1')), + ); + } +} diff --git a/phpBB/phpbb/db/migration/migration.php b/phpBB/phpbb/db/migration/migration.php index 2304c8e44c..4e218344f4 100644 --- a/phpBB/phpbb/db/migration/migration.php +++ b/phpBB/phpbb/db/migration/migration.php @@ -20,7 +20,7 @@ namespace phpbb\db\migration; * in a subclass. This class provides various utility methods to simplify editing * a phpBB. */ -abstract class migration +abstract class migration implements migration_interface { /** @var \phpbb\config\config */ protected $config; @@ -70,9 +70,7 @@ abstract class migration } /** - * Defines other migrations to be applied first - * - * @return array An array of migration class names + * {@inheritdoc} */ static public function depends_on() { @@ -80,14 +78,7 @@ abstract class migration } /** - * Allows you to check if the migration is effectively installed (entirely optional) - * - * This is checked when a migration is installed. If true is returned, the migration will be set as - * installed without performing the database changes. - * This function is intended to help moving to migrations from a previous database updater, where some - * migrations may have been installed already even though they are not yet listed in the migrations table. - * - * @return bool True if this migration is installed, False if this migration is not installed (checked on install) + * {@inheritdoc} */ public function effectively_installed() { @@ -95,9 +86,7 @@ abstract class migration } /** - * Updates the database schema by providing a set of change instructions - * - * @return array Array of schema changes (compatible with db_tools->perform_schema_changes()) + * {@inheritdoc} */ public function update_schema() { @@ -105,9 +94,7 @@ abstract class migration } /** - * Reverts the database schema by providing a set of change instructions - * - * @return array Array of schema changes (compatible with db_tools->perform_schema_changes()) + * {@inheritdoc} */ public function revert_schema() { @@ -115,9 +102,7 @@ abstract class migration } /** - * Updates data by returning a list of instructions to be executed - * - * @return array Array of data update instructions + * {@inheritdoc} */ public function update_data() { @@ -125,12 +110,7 @@ abstract class migration } /** - * Reverts data by returning a list of instructions to be executed - * - * @return array Array of data instructions that will be performed on revert - * NOTE: calls to tools (such as config.add) are automatically reverted when - * possible, so you should not attempt to revert those, this is mostly for - * otherwise unrevertable calls (custom functions for example) + * {@inheritdoc} */ public function revert_data() { diff --git a/phpBB/phpbb/db/migration/migration_interface.php b/phpBB/phpbb/db/migration/migration_interface.php new file mode 100644 index 0000000000..2aba5ec608 --- /dev/null +++ b/phpBB/phpbb/db/migration/migration_interface.php @@ -0,0 +1,70 @@ +<?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; + +/** + * Base class interface for database migrations + */ +interface migration_interface +{ + /** + * Defines other migrations to be applied first + * + * @return array An array of migration class names + */ + static public function depends_on(); + + /** + * Allows you to check if the migration is effectively installed (entirely optional) + * + * This is checked when a migration is installed. If true is returned, the migration will be set as + * installed without performing the database changes. + * This function is intended to help moving to migrations from a previous database updater, where some + * migrations may have been installed already even though they are not yet listed in the migrations table. + * + * @return bool True if this migration is installed, False if this migration is not installed (checked on install) + */ + public function effectively_installed(); + + /** + * Updates the database schema by providing a set of change instructions + * + * @return array Array of schema changes (compatible with db_tools->perform_schema_changes()) + */ + public function update_schema(); + + /** + * Reverts the database schema by providing a set of change instructions + * + * @return array Array of schema changes (compatible with db_tools->perform_schema_changes()) + */ + public function revert_schema(); + + /** + * Updates data by returning a list of instructions to be executed + * + * @return array Array of data update instructions + */ + public function update_data(); + + /** + * Reverts data by returning a list of instructions to be executed + * + * @return array Array of data instructions that will be performed on revert + * NOTE: calls to tools (such as config.add) are automatically reverted when + * possible, so you should not attempt to revert those, this is mostly for + * otherwise unrevertable calls (custom functions for example) + */ + public function revert_data(); +} diff --git a/phpBB/phpbb/db/migration/schema_generator.php b/phpBB/phpbb/db/migration/schema_generator.php index 7003844bc4..c579e25824 100644 --- a/phpBB/phpbb/db/migration/schema_generator.php +++ b/phpBB/phpbb/db/migration/schema_generator.php @@ -77,8 +77,15 @@ class schema_generator $check_dependencies = true; while (!empty($migrations)) { - foreach ($migrations as $migration_class) + foreach ($migrations as $key => $migration_class) { + // Unset classes that are not a valid migration + if (\phpbb\db\migrator::is_migration($migration_class) === false) + { + unset($migrations[$key]); + continue; + } + $open_dependencies = array_diff($migration_class::depends_on(), $tree); if (empty($open_dependencies)) diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php index d91860949a..a1e93942cd 100644 --- a/phpBB/phpbb/db/migrator.php +++ b/phpBB/phpbb/db/migrator.php @@ -170,10 +170,28 @@ class migrator */ public function set_migrations($class_names) { + foreach ($class_names as $key => $class) + { + if (!self::is_migration($class)) + { + unset($class_names[$key]); + } + } + $this->migrations = $class_names; } /** + * Get the list of available migration class names + * + * @return array Array of all migrations available to be run + */ + public function get_migrations() + { + return $this->migrations; + } + + /** * Runs a single update step from the next migration to be applied. * * The update step can either be a schema or a (partial) data update. To @@ -857,4 +875,27 @@ class migrator )); } } + + /** + * Check if a class is a migration. + * + * @param string $migration A migration class name + * @return bool Return true if class is a migration, false otherwise + */ + static public function is_migration($migration) + { + if (class_exists($migration)) + { + // Migration classes should extend the abstract class + // phpbb\db\migration\migration (which implements the + // migration_interface) and be instantiable. + $reflector = new \ReflectionClass($migration); + if ($reflector->implementsInterface('\phpbb\db\migration\migration_interface') && $reflector->isInstantiable()) + { + return true; + } + } + + return false; + } } diff --git a/phpBB/phpbb/db/tools/mssql.php b/phpBB/phpbb/db/tools/mssql.php index 6e58171040..a90a85bbb2 100644 --- a/phpBB/phpbb/db/tools/mssql.php +++ b/phpBB/phpbb/db/tools/mssql.php @@ -36,6 +36,7 @@ class mssql extends tools 'mssql' => array( 'INT:' => '[int]', 'BINT' => '[float]', + 'ULINT' => '[int]', 'UINT' => '[int]', 'UINT:' => '[int]', 'TINT:' => '[int]', @@ -66,6 +67,7 @@ class mssql extends tools 'mssqlnative' => array( 'INT:' => '[int]', 'BINT' => '[float]', + 'ULINT' => '[int]', 'UINT' => '[int]', 'UINT:' => '[int]', 'TINT:' => '[int]', diff --git a/phpBB/phpbb/db/tools/postgres.php b/phpBB/phpbb/db/tools/postgres.php index 8b61625c3c..e2a4e668a6 100644 --- a/phpBB/phpbb/db/tools/postgres.php +++ b/phpBB/phpbb/db/tools/postgres.php @@ -30,6 +30,7 @@ class postgres extends tools 'postgres' => array( 'INT:' => 'INT4', 'BINT' => 'INT8', + 'ULINT' => 'INT4', // unsigned 'UINT' => 'INT4', // unsigned 'UINT:' => 'INT4', // unsigned 'USINT' => 'INT2', // unsigned diff --git a/phpBB/phpbb/db/tools/tools.php b/phpBB/phpbb/db/tools/tools.php index f06871a1d7..37ac0d0468 100644 --- a/phpBB/phpbb/db/tools/tools.php +++ b/phpBB/phpbb/db/tools/tools.php @@ -46,6 +46,7 @@ class tools implements tools_interface 'mysql_41' => array( 'INT:' => 'int(%d)', 'BINT' => 'bigint(20)', + 'ULINT' => 'INT(10) UNSIGNED', 'UINT' => 'mediumint(8) UNSIGNED', 'UINT:' => 'int(%d) UNSIGNED', 'TINT:' => 'tinyint(%d)', @@ -76,6 +77,7 @@ class tools implements tools_interface 'mysql_40' => array( 'INT:' => 'int(%d)', 'BINT' => 'bigint(20)', + 'ULINT' => 'INT(10) UNSIGNED', 'UINT' => 'mediumint(8) UNSIGNED', 'UINT:' => 'int(%d) UNSIGNED', 'TINT:' => 'tinyint(%d)', @@ -106,6 +108,7 @@ class tools implements tools_interface 'oracle' => array( 'INT:' => 'number(%d)', 'BINT' => 'number(20)', + 'ULINT' => 'number(10)', 'UINT' => 'number(8)', 'UINT:' => 'number(%d)', 'TINT:' => 'number(%d)', @@ -136,11 +139,12 @@ class tools implements tools_interface 'sqlite' => array( 'INT:' => 'int(%d)', 'BINT' => 'bigint(20)', - 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED', + 'ULINT' => 'INTEGER UNSIGNED', // 'int(10) UNSIGNED', + 'UINT' => 'INTEGER UNSIGNED', // 'mediumint(8) UNSIGNED', 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED', 'TINT:' => 'tinyint(%d)', - 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED', - 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED', + 'USINT' => 'INTEGER UNSIGNED', // 'mediumint(4) UNSIGNED', + 'BOOL' => 'INTEGER UNSIGNED', // 'tinyint(1) UNSIGNED', 'VCHAR' => 'varchar(255)', 'VCHAR:' => 'varchar(%d)', 'CHAR:' => 'char(%d)', @@ -152,7 +156,7 @@ class tools implements tools_interface 'STEXT_UNI' => 'text(65535)', 'TEXT_UNI' => 'text(65535)', 'MTEXT_UNI' => 'mediumtext(16777215)', - 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED', + 'TIMESTAMP' => 'INTEGER UNSIGNED', // 'int(11) UNSIGNED', 'DECIMAL' => 'decimal(5,2)', 'DECIMAL:' => 'decimal(%d,2)', 'PDECIMAL' => 'decimal(6,3)', @@ -166,6 +170,7 @@ class tools implements tools_interface 'sqlite3' => array( 'INT:' => 'INT(%d)', 'BINT' => 'BIGINT(20)', + 'ULINT' => 'INTEGER UNSIGNED', 'UINT' => 'INTEGER UNSIGNED', 'UINT:' => 'INTEGER UNSIGNED', 'TINT:' => 'TINYINT(%d)', @@ -199,7 +204,7 @@ class tools implements tools_interface * A list of types being unsigned for better reference in some db's * @var array */ - var $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); + var $unsigned_types = array('ULINT', 'UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); /** * This is set to true if user only wants to return the 'to-be-executed' SQL statement(s) (as an array). @@ -1161,6 +1166,11 @@ class tools implements tools_interface } } + if (isset($column_data['after'])) + { + $return_array['after'] = $column_data['after']; + } + break; case 'oracle': diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php index 433847b285..9583da14f5 100644 --- a/phpBB/phpbb/di/container_builder.php +++ b/phpBB/phpbb/di/container_builder.php @@ -135,6 +135,11 @@ class container_builder $config_cache = new ConfigCache($container_filename, defined('DEBUG')); if ($this->use_cache && $config_cache->isFresh()) { + if ($this->use_extensions) + { + require($this->get_autoload_filename()); + } + require($config_cache->getPath()); $this->container = new \phpbb_cache_container(); } @@ -405,6 +410,15 @@ class container_builder $extensions = $ext_container->get('ext.manager')->all_enabled(); // Load each extension found + $autoloaders = '<?php +/** + * Loads all extensions custom auto-loaders. + * + * This file has been auto-generated + * by phpBB while loading the extensions. + */ + +'; foreach ($extensions as $ext_name => $path) { $extension_class = '\\' . str_replace('/', '\\', $ext_name) . '\\di\\extension'; @@ -420,9 +434,14 @@ class container_builder $filename = $path . 'vendor/autoload.php'; if (file_exists($filename)) { - require $filename; + $autoloaders .= "require('{$filename}');\n"; } } + + $configCache = new ConfigCache($this->get_autoload_filename(), false); + $configCache->write($autoloaders); + + require($this->get_autoload_filename()); } else { @@ -540,6 +559,16 @@ class container_builder } /** + * Get the filename under which the dumped extensions autoloader will be stored. + * + * @return string Path for dumped extensions autoloader + */ + protected function get_autoload_filename() + { + return $this->get_cache_dir() . 'autoload_' . md5($this->phpbb_root_path) . '.' . $this->php_ext; + } + + /** * Return the name of the current environment. * * @return string diff --git a/phpBB/phpbb/extension/base.php b/phpBB/phpbb/extension/base.php index 5bb530bad4..c7778cfed1 100644 --- a/phpBB/phpbb/extension/base.php +++ b/phpBB/phpbb/extension/base.php @@ -24,7 +24,7 @@ class base implements \phpbb\extension\extension_interface protected $container; /** @var \phpbb\finder */ - protected $finder; + protected $extension_finder; /** @var \phpbb\db\migrator */ protected $migrator; @@ -73,9 +73,7 @@ class base implements \phpbb\extension\extension_interface */ public function enable_step($old_state) { - $migrations = $this->get_migration_file_list(); - - $this->migrator->set_migrations($migrations); + $this->get_migration_file_list(); $this->migrator->update(); @@ -103,8 +101,6 @@ class base implements \phpbb\extension\extension_interface { $migrations = $this->get_migration_file_list(); - $this->migrator->set_migrations($migrations); - foreach ($migrations as $migration) { while ($this->migrator->migration_state($migration) !== false) @@ -137,6 +133,10 @@ class base implements \phpbb\extension\extension_interface $migrations = $this->extension_finder->get_classes_from_files($migrations); + $this->migrator->set_migrations($migrations); + + $migrations = $this->migrator->get_migrations(); + return $migrations; } } diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php index 33cbfb00ae..1fdba0ca32 100644 --- a/phpBB/phpbb/files/types/remote.php +++ b/phpBB/phpbb/files/types/remote.php @@ -14,6 +14,7 @@ namespace phpbb\files\types; use bantu\IniGetWrapper\IniGetWrapper; +use phpbb\config\config; use phpbb\files\factory; use phpbb\files\filespec; use phpbb\language\language; @@ -21,6 +22,9 @@ use phpbb\request\request_interface; class remote extends base { + /** @var config phpBB config */ + protected $config; + /** @var factory Files factory */ protected $factory; @@ -42,14 +46,16 @@ class remote extends base /** * Construct a form upload type * + * @param config $config phpBB config * @param factory $factory Files factory * @param language $language Language class * @param IniGetWrapper $php_ini ini_get() wrapper * @param request_interface $request Request object * @param string $phpbb_root_path phpBB root path */ - public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) + public function __construct(config $config, factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path) { + $this->config = $config; $this->factory = $factory; $this->language = $language; $this->php_ini = $php_ini; @@ -86,10 +92,6 @@ class remote extends base $url = parse_url($upload_url); - $host = $url['host']; - $path = $url['path']; - $port = (!empty($url['port'])) ? (int) $url['port'] : 80; - $upload_ary['type'] = 'application/octet-stream'; $url['path'] = explode('.', $url['path']); @@ -97,108 +99,55 @@ class remote extends base $url['path'] = implode('', $url['path']); $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : ''); - $filesize = 0; $remote_max_filesize = $this->get_max_file_size(); - $errno = 0; - $errstr = ''; + $guzzle_options = [ + 'timeout' => $this->upload->upload_timeout, + 'connect_timeout' => $this->upload->upload_timeout, + 'verify' => !empty($this->config['remote_upload_verify']) ? (bool) $this->config['remote_upload_verify'] : false, + ]; + $client = new \GuzzleHttp\Client($guzzle_options); - if (!($fsock = @fsockopen($host, $port, $errno, $errstr))) + try { - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + $response = $client->get($upload_url, $guzzle_options); } - - // Make sure $path not beginning with / - if (strpos($path, '/') === 0) + catch (\GuzzleHttp\Exception\ClientException $clientException) { - $path = substr($path, 1); + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); } - - fputs($fsock, 'GET /' . $path . " HTTP/1.1\r\n"); - fputs($fsock, "HOST: " . $host . "\r\n"); - fputs($fsock, "Connection: close\r\n\r\n"); - - // Set a proper timeout for the socket - socket_set_timeout($fsock, $this->upload->upload_timeout); - - $get_info = false; - $data = ''; - $length = false; - $timer_stop = time() + $this->upload->upload_timeout; - - while ((!$length || $filesize < $length) && !@feof($fsock)) + catch (\GuzzleHttp\Exception\RequestException $requestException) { - if ($get_info) + if (strpos($requestException->getMessage(), 'cURL error 28') !== false || preg_match('/408|504/', $requestException->getCode())) { - if ($length) - { - // Don't attempt to read past end of file if server indicated length - $block = @fread($fsock, min($length - $filesize, 1024)); - } - else - { - $block = @fread($fsock, 1024); - } - - $filesize += strlen($block); - - if ($remote_max_filesize && $filesize > $remote_max_filesize) - { - $max_filesize = get_formatted_filesize($remote_max_filesize, false); - - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); - } - - $data .= $block; + return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); } else { - $line = @fgets($fsock, 1024); - - if ($line == "\r\n") - { - $get_info = true; - } - else - { - if (stripos($line, 'content-type: ') !== false) - { - $upload_ary['type'] = rtrim(str_replace('content-type: ', '', strtolower($line))); - } - else if ($this->upload->max_filesize && stripos($line, 'content-length: ') !== false) - { - $length = (int) str_replace('content-length: ', '', strtolower($line)); - - if ($remote_max_filesize && $length && $length > $remote_max_filesize) - { - $max_filesize = get_formatted_filesize($remote_max_filesize, false); - - return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); - } - } - else if (stripos($line, '404 not found') !== false) - { - return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND'); - } - } + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); } + } + catch (\Exception $e) + { + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED')); + } - $stream_meta_data = stream_get_meta_data($fsock); + $content_length = $response->getBody()->getSize(); + if ($remote_max_filesize && $content_length > $remote_max_filesize) + { + $max_filesize = get_formatted_filesize($remote_max_filesize, false); - // Cancel upload if we exceed timeout - if (!empty($stream_meta_data['timed_out']) || time() >= $timer_stop) - { - return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT'); - } + return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit'])); } - @fclose($fsock); - if (empty($data)) + if ($content_length == 0) { return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA'); } + $data = $response->getBody(); + $filename = tempnam(sys_get_temp_dir(), unique_id() . '-'); if (!($fp = @fopen($filename, 'wb'))) diff --git a/phpBB/phpbb/install/controller/archive_download.php b/phpBB/phpbb/install/controller/archive_download.php index a0f0ba181d..eabc0a9976 100644 --- a/phpBB/phpbb/install/controller/archive_download.php +++ b/phpBB/phpbb/install/controller/archive_download.php @@ -46,9 +46,9 @@ class archive_download */ public function conflict_archive() { - $filename = $this->installer_config->get('update_file_conflict_archive', false); + $filename = $this->installer_config->get('update_file_conflict_archive', ''); - if (!$filename) + if (empty($filename)) { throw new http_exception(404, 'URL_NOT_FOUND'); } @@ -65,7 +65,7 @@ class archive_download { $filename = $this->installer_config->get('update_file_archive', ''); - if (!$filename) + if (empty($filename)) { throw new http_exception(404, 'URL_NOT_FOUND'); } diff --git a/phpBB/phpbb/install/controller/helper.php b/phpBB/phpbb/install/controller/helper.php index 2dad42b4b6..ff7e691224 100644 --- a/phpBB/phpbb/install/controller/helper.php +++ b/phpBB/phpbb/install/controller/helper.php @@ -160,12 +160,13 @@ class helper * Returns path from route name * * @param string $route_name + * @param array $parameters * * @return string */ - public function route($route_name) + public function route($route_name, $parameters = array()) { - $url = $this->router->generate($route_name); + $url = $this->router->generate($route_name, $parameters); return $url; } @@ -182,11 +183,6 @@ class helper if (!empty($submit)) { $lang = $this->phpbb_request->variable('language', ''); - - if (!empty($lang)) - { - $this->language_cookie = $lang; - } } // Retrieve language from cookie @@ -194,10 +190,10 @@ class helper if (empty($lang) && !empty($lang_cookie)) { $lang = $lang_cookie; - $this->language_cookie = $lang; } $lang = (!empty($lang) && strpos($lang, '/') === false) ? $lang : null; + $this->language_cookie = $lang; $this->render_language_select($lang); diff --git a/phpBB/phpbb/install/controller/install.php b/phpBB/phpbb/install/controller/install.php index b987d91c6a..92506872a3 100644 --- a/phpBB/phpbb/install/controller/install.php +++ b/phpBB/phpbb/install/controller/install.php @@ -123,6 +123,7 @@ class install // Set the appropriate input-output handler $this->installer->set_iohandler($this->iohandler_factory->get()); + $this->controller_helper->handle_language_select(); if ($this->request->is_ajax()) { @@ -142,8 +143,6 @@ class install // Determine whether the installation was started or not if (true) { - $this->controller_helper->handle_language_select(); - // Set active stage $this->menu_provider->set_nav_property( array('install', 0, 'introduction'), diff --git a/phpBB/phpbb/install/controller/update.php b/phpBB/phpbb/install/controller/update.php index 9fff11cae8..6b88827940 100644 --- a/phpBB/phpbb/install/controller/update.php +++ b/phpBB/phpbb/install/controller/update.php @@ -122,6 +122,7 @@ class update // Set the appropriate input-output handler $this->installer->set_iohandler($this->iohandler_factory->get()); + $this->controller_helper->handle_language_select(); // Render the intro page if ($this->request->is_ajax()) @@ -140,8 +141,6 @@ class update } else { - $this->controller_helper->handle_language_select(); - // Set active stage $this->menu_provider->set_nav_property( array('update', 0, 'introduction'), diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php index 0f0840f470..fad6749019 100644 --- a/phpBB/phpbb/install/helper/config.php +++ b/phpBB/phpbb/install/helper/config.php @@ -96,7 +96,8 @@ class config $this->system_data = array(); $this->progress_data = array( 'last_task_module_name' => '', // Stores the service name of the latest finished module - 'last_task_name' => '', // Stores the service name of the latest finished task + 'last_task_module_index' => 0, // Stores the index of the latest finished module + 'last_task_index' => 0, // Stores the index of the latest finished task 'max_task_progress' => 0, 'current_task_progress' => 0, '_restart_points' => array(), @@ -157,10 +158,10 @@ class config { if ($this->system_data['max_execution_time'] <= 0) { - return 1; + return PHP_INT_MAX; } - return ($this->system_data['start_time'] + $this->system_data['max_execution_time']) - time(); + return ($this->system_data['start_time'] + $this->system_data['max_execution_time']) - microtime(true); } /** @@ -187,21 +188,23 @@ class config /** * Saves the latest executed task * - * @param string $task_service_name Name of the installer task service + * @param int $task_service_index Index of the installer task service in the module */ - public function set_finished_task($task_service_name) + public function set_finished_task($task_service_index) { - $this->progress_data['last_task_name'] = $task_service_name; + $this->progress_data['last_task_index'] = $task_service_index; } /** * Set active module * * @param string $module_service_name Name of the installer module service + * @param int $module_service_index Index of the installer module service */ - public function set_active_module($module_service_name) + public function set_active_module($module_service_name, $module_service_index) { $this->progress_data['last_task_module_name'] = $module_service_name; + $this->progress_data['last_task_module_index'] = $module_service_index; } /** @@ -227,18 +230,22 @@ class config $file_content = @file_get_contents($this->install_config_file); $serialized_data = trim(substr($file_content, 8)); - $this->installer_config = array(); - $this->progress_data = array(); - $this->navigation_data = array(); + $installer_config = array(); + $progress_data = array(); + $navigation_data = array(); if (!empty($serialized_data)) { $unserialized_data = json_decode($serialized_data, true); - $this->installer_config = (is_array($unserialized_data['installer_config'])) ? $unserialized_data['installer_config'] : array(); - $this->progress_data = (is_array($unserialized_data['progress_data'])) ? $unserialized_data['progress_data'] : array(); - $this->navigation_data = (is_array($unserialized_data['navigation_data'])) ? $unserialized_data['navigation_data'] : array(); + $installer_config = (is_array($unserialized_data['installer_config'])) ? $unserialized_data['installer_config'] : array(); + $progress_data = (is_array($unserialized_data['progress_data'])) ? $unserialized_data['progress_data'] : array(); + $navigation_data = (is_array($unserialized_data['navigation_data'])) ? $unserialized_data['navigation_data'] : array(); } + + $this->installer_config = array_merge($this->installer_config, $installer_config); + $this->progress_data = array_merge($this->progress_data, $progress_data); + $this->navigation_data = array_merge($this->navigation_data, $navigation_data); } /** @@ -387,6 +394,11 @@ class config */ public function set_finished_navigation_stage($nav_path) { + if (isset($this->navigation_data['finished']) && in_array($nav_path, $this->navigation_data['finished'])) + { + return; + } + $this->navigation_data['finished'][] = $nav_path; } @@ -430,7 +442,7 @@ class config $this->system_data['max_execution_time'] = $execution_time; // Set start time - $this->system_data['start_time'] = time(); + $this->system_data['start_time'] = microtime(true); // Get memory limit $this->system_data['memory_limit'] = $this->php_ini->getBytes('memory_limit'); diff --git a/phpBB/phpbb/install/helper/container_factory.php b/phpBB/phpbb/install/helper/container_factory.php index 6c1ecd2d02..5cf4f8a283 100644 --- a/phpBB/phpbb/install/helper/container_factory.php +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -13,7 +13,6 @@ namespace phpbb\install\helper; -use phpbb\cache\driver\dummy; use phpbb\install\exception\cannot_build_container_exception; use phpbb\language\language; use phpbb\request\request; @@ -157,25 +156,20 @@ class container_factory ->with_environment('production') ->with_config($phpbb_config_php_file) ->with_config_path($config_path) - ->without_cache() ->without_compiled_container() ->get_container(); // Setting request is required for the compatibility globals as those are generated from // this container - $this->container->register('request')->setSynthetic(true); - $this->container->set('request', $this->request); - - $this->container->register('language')->setSynthetic(true); - $this->container->set('language', $this->language); - - // Replace cache service, as config gets cached, and we don't want that when we are installing - if (!is_dir($other_config_path)) + if (!$this->container->isFrozen()) { - $this->container->register('cache.driver')->setSynthetic(true); - $this->container->set('cache.driver', new dummy()); + $this->container->register('request')->setSynthetic(true); + $this->container->register('language')->setSynthetic(true); } + $this->container->set('request', $this->request); + $this->container->set('language', $this->language); + $this->container->compile(); $phpbb_container = $this->container; diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php index 1342ffa30f..8c62ec7bd0 100644 --- a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -72,6 +72,11 @@ class ajax_iohandler extends iohandler_base protected $download; /** + * @var array + */ + protected $redirect_url; + + /** * Constructor * * @param path_helper $path_helper @@ -89,6 +94,7 @@ class ajax_iohandler extends iohandler_base $this->nav_data = array(); $this->cookies = array(); $this->download = array(); + $this->redirect_url = array(); $this->file_status = ''; parent::__construct(); @@ -131,6 +137,14 @@ class ajax_iohandler extends iohandler_base */ public function add_user_form_group($title, $form) { + $this->form = $this->generate_form_render_data($title, $form); + } + + /** + * {@inheritdoc} + */ + public function generate_form_render_data($title, $form) + { $this->template->assign_block_vars('options', array( 'LEGEND' => $this->language->lang($title), 'S_LEGEND' => true, @@ -189,15 +203,21 @@ class ajax_iohandler extends iohandler_base 'form_install' => 'installer_form.html', )); - $this->form = $this->template->assign_display('form_install'); + return $this->template->assign_display('form_install'); } /** * {@inheritdoc} */ - public function send_response() + public function send_response($no_more_output = false) { - $json_data_array = $this->prepare_json_array(); + $json_data_array = $this->prepare_json_array($no_more_output); + + if (empty($json_data_array)) + { + return; + } + $json_data = json_encode($json_data_array); // Try to push content to the browser @@ -209,23 +229,43 @@ class ajax_iohandler extends iohandler_base /** * Prepares iohandler's data to be sent out to the client. * + * @param bool $no_more_output Whether or not there will be more output in this response + * * @return array */ - protected function prepare_json_array() + protected function prepare_json_array($no_more_output = false) { - $json_array = array( - 'errors' => $this->errors, - 'warnings' => $this->warnings, - 'logs' => $this->logs, - 'success' => $this->success, - 'download' => $this->download, - ); + $json_array = array(); + + if (!empty($this->errors)) + { + $json_array['errors'] = $this->errors; + $this->errors = array(); + } + + if (!empty($this->warnings)) + { + $json_array['warnings'] = $this->warnings; + $this->warnings = array(); + } + + if (!empty($this->logs)) + { + $json_array['logs'] = $this->logs; + $this->logs = array(); + } - $this->errors = array(); - $this->warnings = array(); - $this->logs = array(); - $this->success = array(); - $this->download = array(); + if (!empty($this->success)) + { + $json_array['success'] = $this->success; + $this->success = array(); + } + + if (!empty($this->download)) + { + $json_array['download'] = $this->download; + $this->download = array(); + } if (!empty($this->form)) { @@ -273,6 +313,17 @@ class ajax_iohandler extends iohandler_base $this->cookies = array(); } + if (!empty($this->redirect_url)) + { + $json_array['redirect'] = $this->redirect_url; + $this->redirect_url = array(); + } + + if ($no_more_output) + { + $json_array['over'] = true; + } + return $json_array; } @@ -373,6 +424,15 @@ class ajax_iohandler extends iohandler_base } /** + * {@inheritdoc} + */ + public function redirect($url, $use_ajax = false) + { + $this->redirect_url = array('url' => $url, 'use_ajax' => $use_ajax); + $this->send_response(true); + } + + /** * Callback function for language replacing * * @param array $matches diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php index 89f3594378..94550d2db0 100644 --- a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -114,7 +114,7 @@ class cli_iohandler extends iohandler_base /** * {@inheritdoc} */ - public function send_response() + public function send_response($no_more_output = false) { } @@ -289,4 +289,11 @@ class cli_iohandler extends iohandler_base public function render_update_file_status($status_array) { } + + /** + * {@inheritdoc} + */ + public function redirect($url, $use_ajax = false) + { + } } diff --git a/phpBB/phpbb/install/helper/iohandler/factory.php b/phpBB/phpbb/install/helper/iohandler/factory.php index 52d24e49b2..1e8395760a 100644 --- a/phpBB/phpbb/install/helper/iohandler/factory.php +++ b/phpBB/phpbb/install/helper/iohandler/factory.php @@ -75,7 +75,5 @@ class factory throw new iohandler_not_implemented_exception(); break; } - - throw new iohandler_not_implemented_exception(); } } diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php index 7271fe9bc0..fed4bc101f 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_base.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php @@ -170,6 +170,14 @@ abstract class iohandler_base implements iohandler_interface } /** + * {@inheritdoc} + */ + public function generate_form_render_data($title, $form) + { + return ''; + } + + /** * Localize message. * * Note: When an array is passed into the parameters below, it will be diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php index 00aab3283e..f22f33d9cb 100644 --- a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php @@ -20,8 +20,10 @@ interface iohandler_interface { /** * Renders or returns response message + * + * @param bool $no_more_output Whether or not there will be more output in this output unit */ - public function send_response(); + public function send_response($no_more_output = false); /** * Returns input variable @@ -124,6 +126,16 @@ interface iohandler_interface public function add_user_form_group($title, $form); /** + * Returns the rendering information for the form + * + * @param string $title Language variable with the title of the form + * @param array $form An array describing the required data (options etc) + * + * @return string Information to render the form + */ + public function generate_form_render_data($title, $form); + + /** * Sets the number of tasks belonging to the installer in the current mode. * * @param int $task_count Number of tasks @@ -175,6 +187,14 @@ interface iohandler_interface public function add_download_link($route, $title, $msg = null); /** + * Redirects the user to a new page + * + * @param string $url URL to redirect to + * @param bool $use_ajax Whether or not to use AJAX redirect + */ + public function redirect($url, $use_ajax = false); + + /** * Renders the status of update files * * @param array $status_array Array containing files in groups to render diff --git a/phpBB/phpbb/install/helper/navigation/convertor_navigation.php b/phpBB/phpbb/install/helper/navigation/convertor_navigation.php new file mode 100644 index 0000000000..54cab83b1d --- /dev/null +++ b/phpBB/phpbb/install/helper/navigation/convertor_navigation.php @@ -0,0 +1,78 @@ +<?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\helper\navigation; + +use phpbb\install\helper\install_helper; + +class convertor_navigation implements navigation_interface +{ + /** + * @var install_helper + */ + private $install_helper; + + /** + * Constructor + * + * @param install_helper $install_helper + */ + public function __construct(install_helper $install_helper) + { + $this->install_helper = $install_helper; + } + + /** + * {@inheritdoc} + */ + public function get() + { + if (!$this->install_helper->is_phpbb_installed()) + { + return array(); + } + + return array( + 'convert' => array( + 'label' => 'CONVERT', + 'route' => 'phpbb_convert_intro', + 'order' => 3, + array( + 'intro' => array( + 'label' => 'SUB_INTRO', + 'stage' => true, + 'order' => 0, + ), + 'settings' => array( + 'label' => 'STAGE_SETTINGS', + 'stage' => true, + 'route' => 'phpbb_convert_settings', + 'order' => 1, + ), + 'convert' => array( + 'label' => 'STAGE_IN_PROGRESS', + 'stage' => true, + 'route' => 'phpbb_convert_convert', + 'order' => 2, + ), + 'finish' => array( + 'label' => 'CONVERT_COMPLETE', + 'stage' => true, + 'route' => 'phpbb_convert_finish', + 'order' => 3, + ), + ), + ), + ); + } +} diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php index a41b4cd6a6..b5709e96c7 100644 --- a/phpBB/phpbb/install/installer.php +++ b/phpBB/phpbb/install/installer.php @@ -15,11 +15,13 @@ namespace phpbb\install; use phpbb\cache\driver\driver_interface; use phpbb\di\ordered_service_collection; +use phpbb\install\exception\cannot_build_container_exception; use phpbb\install\exception\installer_config_not_writable_exception; use phpbb\install\exception\jump_to_restart_point_exception; use phpbb\install\exception\resource_limit_reached_exception; use phpbb\install\exception\user_interaction_required_exception; use phpbb\install\helper\config; +use phpbb\install\helper\container_factory; use phpbb\install\helper\iohandler\cli_iohandler; use phpbb\install\helper\iohandler\iohandler_interface; use phpbb\path_helper; @@ -32,12 +34,17 @@ class installer protected $cache; /** + * @var container_factory + */ + protected $container_factory; + + /** * @var config */ protected $install_config; /** - * @var array + * @var ordered_service_collection */ protected $installer_modules; @@ -59,18 +66,26 @@ class installer protected $module_step_count; /** + * @var bool + */ + protected $purge_cache_before; + + /** * Constructor * * @param driver_interface $cache Cache service * @param config $config Installer config handler * @param path_helper $path_helper Path helper + * @param container_factory $container Container */ - public function __construct(driver_interface $cache, config $config, path_helper $path_helper) + public function __construct(driver_interface $cache, config $config, path_helper $path_helper, container_factory $container) { $this->cache = $cache; $this->install_config = $config; + $this->container_factory = $container; $this->installer_modules = null; $this->web_root = $path_helper->get_web_root_path(); + $this->purge_cache_before = false; } /** @@ -97,6 +112,16 @@ class installer } /** + * Sets whether to purge cache before the installation process + * + * @param bool $purge_cache_before + */ + public function set_purge_cache_before($purge_cache_before) + { + $this->purge_cache_before = $purge_cache_before; + } + + /** * Run phpBB installer */ public function run() @@ -104,9 +129,16 @@ class installer // Load install progress $this->install_config->load_config(); + if (!$this->install_config->get('cache_purged_before', false) && $this->purge_cache_before) + { + /** @var \phpbb\cache\driver\driver_interface $cache */ + $cache = $this->container_factory->get('cache.driver'); + $cache->purge(); + $this->install_config->set('cache_purged_before', true); + } + // Recover install progress - $module_name = $this->recover_progress(); - $module_found = false; + $module_index = $this->recover_progress(); // Variable used to check if the install process have been finished $install_finished = false; @@ -141,29 +173,13 @@ class installer try { - foreach ($this->installer_modules as $name => $module) - { - // Skip forward until the current task is reached - if (!$module_found) - { - if ($module_name === $name || empty($module_name)) - { - $module_found = true; - } - else - { - continue; - } - } + $iterator = $this->installer_modules->getIterator(); + $iterator->seek($module_index); - // Log progress - $this->install_config->set_active_module($name); - - // Run until there are available resources - if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) - { - throw new resource_limit_reached_exception(); - } + while ($iterator->valid()) + { + $module = $iterator->current(); + $name = $iterator->key(); // Check if module should be executed if (!$module->is_essential() && !$module->check_requirements()) @@ -176,17 +192,31 @@ class installer $name, )); $this->install_config->increment_current_task_progress($this->module_step_count[$name]); - continue; + } + else + { + // Set the correct stage in the navigation bar + $this->install_config->set_active_navigation_stage($module->get_navigation_stage_path()); + $this->iohandler->set_active_stage_menu($module->get_navigation_stage_path()); + + $this->iohandler->send_response(); + + $module->run(); + + $this->install_config->set_finished_navigation_stage($module->get_navigation_stage_path()); + $this->iohandler->set_finished_stage_menu($module->get_navigation_stage_path()); } - // Set the correct stage in the navigation bar - $this->install_config->set_active_navigation_stage($module->get_navigation_stage_path()); - $this->iohandler->set_active_stage_menu($module->get_navigation_stage_path()); + $module_index++; + $iterator->next(); - $module->run(); + // Save progress + $this->install_config->set_active_module($name, $module_index); - $this->install_config->set_finished_navigation_stage($module->get_navigation_stage_path()); - $this->iohandler->set_finished_stage_menu($module->get_navigation_stage_path()); + if ($iterator->valid() && ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)) + { + throw new resource_limit_reached_exception(); + } } // Installation finished @@ -208,7 +238,7 @@ class installer } catch (user_interaction_required_exception $e) { - // Do nothing + $this->iohandler->send_response(true); } catch (resource_limit_reached_exception $e) { @@ -222,7 +252,7 @@ class installer catch (\Exception $e) { $this->iohandler->add_error_message($e->getMessage()); - $this->iohandler->send_response(); + $this->iohandler->send_response(true); $fail_cleanup = true; } @@ -230,11 +260,12 @@ class installer { // Send install finished message $this->iohandler->set_progress('INSTALLER_FINISHED', $this->install_config->get_task_progress_count()); + $this->iohandler->send_response(true); } else if ($send_refresh) { $this->iohandler->request_refresh(); - $this->iohandler->send_response(); + $this->iohandler->send_response(true); } // Save install progress @@ -244,6 +275,17 @@ class installer { $this->install_config->clean_up_config_file(); $this->cache->purge(); + + try + { + /** @var \phpbb\cache\driver\driver_interface $cache */ + $cache = $this->container_factory->get('cache.driver'); + $cache->purge(); + } + catch (cannot_build_container_exception $e) + { + // Do not do anything, this just means there is no config.php yet + } } else { @@ -270,6 +312,6 @@ class installer protected function recover_progress() { $progress_array = $this->install_config->get_progress_data(); - return $progress_array['last_task_module_name']; + return $progress_array['last_task_module_index']; } } diff --git a/phpBB/phpbb/install/module/install_data/task/add_bots.php b/phpBB/phpbb/install/module/install_data/task/add_bots.php index 2ee641ff63..d45a6839a0 100644 --- a/phpBB/phpbb/install/module/install_data/task/add_bots.php +++ b/phpBB/phpbb/install/module/install_data/task/add_bots.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_data\task; +use phpbb\install\exception\resource_limit_reached_exception; + class add_bots extends \phpbb\install\task_base { /** @@ -179,7 +181,10 @@ class add_bots extends \phpbb\install\task_base $this->io_handler->add_error_message('NO_GROUP'); } - foreach ($this->bot_list as $bot_name => $bot_ary) + $i = $this->install_config->get('add_bot_index', 0); + $bot_list = array_slice($this->bot_list, $i); + + foreach ($bot_list as $bot_name => $bot_ary) { $user_row = array( 'user_type' => USER_IGNORE, @@ -221,6 +226,21 @@ class add_bots extends \phpbb\install\task_base )); $this->db->sql_query($sql); + + $i++; + + // Stop execution if resource limit is reached + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + { + break; + } + } + + $this->install_config->set('add_bot_index', $i); + + if ($i < sizeof($this->bot_list)) + { + throw new resource_limit_reached_exception(); } } diff --git a/phpBB/phpbb/install/module/install_data/task/add_modules.php b/phpBB/phpbb/install/module/install_data/task/add_modules.php index bfbe6282bc..d21a5be823 100644 --- a/phpBB/phpbb/install/module/install_data/task/add_modules.php +++ b/phpBB/phpbb/install/module/install_data/task/add_modules.php @@ -13,9 +13,19 @@ namespace phpbb\install\module\install_data\task; +use phpbb\install\exception\resource_limit_reached_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\container_factory; +use phpbb\install\helper\iohandler\iohandler_interface; + class add_modules extends \phpbb\install\task_base { /** + * @var config + */ + protected $config; + + /** * @var \phpbb\db\driver\driver_interface */ protected $db; @@ -136,12 +146,13 @@ class add_modules extends \phpbb\install\task_base /** * Constructor * - * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler Installer's input-output handler - * @param \phpbb\install\helper\container_factory $container Installer's DI container + * @parma config $config Installer's config + * @param iohandler_interface $iohandler Installer's input-output handler + * @param container_factory $container Installer's DI container */ - public function __construct(\phpbb\install\helper\iohandler\iohandler_interface $iohandler, - \phpbb\install\helper\container_factory $container) + public function __construct(config $config, iohandler_interface $iohandler, container_factory $container) { + $this->config = $config; $this->db = $container->get('dbal.conn'); $this->extension_manager = $container->get('ext.manager'); $this->iohandler = $iohandler; @@ -158,11 +169,19 @@ class add_modules extends \phpbb\install\task_base $this->db->sql_return_on_error(true); $module_classes = array('acp', 'mcp', 'ucp'); + $total = sizeof($module_classes); + $i = $this->config->get('module_class_index', 0); + $module_classes = array_slice($module_classes, $i); + foreach ($module_classes as $module_class) { - $categories = array(); + $categories = $this->config->get('module_categories_array', array()); + + $k = $this->config->get('module_categories_index', 0); + $module_categories = array_slice($this->module_categories[$module_class], $k); + $timed_out = false; - foreach ($this->module_categories[$module_class] as $cat_name => $subs) + foreach ($module_categories as $cat_name => $subs) { // Check if this sub-category has a basename. If it has, use it. $basename = (isset($this->module_categories_basenames[$cat_name])) ? $this->module_categories_basenames[$cat_name] : ''; @@ -221,11 +240,31 @@ class add_modules extends \phpbb\install\task_base $categories[$level2_name]['parent_id'] = (int) $categories[$cat_name]['id']; } } + + $k++; + + // Stop execution if resource limit is reached + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + $timed_out = true; + break; + } + } + + $this->config->set('module_categories_array', $categories); + $this->config->set('module_categories_index', $k); + + if ($timed_out) + { + throw new resource_limit_reached_exception(); } // Get the modules we want to add... returned sorted by name $module_info = $this->module_manager->get_module_infos($module_class); + $k = $this->config->get('module_info_index', 0); + $module_info = array_slice($module_info, $k); + foreach ($module_info as $module_basename => $fileinfo) { foreach ($fileinfo['modes'] as $module_mode => $row) @@ -258,189 +297,256 @@ class add_modules extends \phpbb\install\task_base } } } - } - // Move some of the modules around since the code above will put them in the wrong place - if ($module_class === 'acp') - { - // Move main module 4 up... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'acp_main' - AND module_class = 'acp' - AND module_mode = 'main'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $k++; - $this->module_manager->move_module_by($row, 'acp', 'move_up', 4); - - // Move permissions intro screen module 4 up... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'acp_permissions' - AND module_class = 'acp' - AND module_mode = 'intro'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + // Stop execution if resource limit is reached + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + $timed_out = true; + break; + } + } - $this->module_manager->move_module_by($row, 'acp', 'move_up', 4); + $this->config->set('module_info_index', $k); - // Move manage users screen module 5 up... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'acp_users' - AND module_class = 'acp' - AND module_mode = 'overview'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $this->module_manager->move_module_by($row, 'acp', 'move_up', 5); + // Stop execution if resource limit is reached + if ($timed_out) + { + throw new resource_limit_reached_exception(); + } - // Move extension management module 1 up... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_langname = 'ACP_EXTENSION_MANAGEMENT' - AND module_class = 'acp' - AND module_mode = '' - AND module_basename = ''"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + // Move some of the modules around since the code above will put them in the wrong place + if (!$this->config->get('modules_ordered', false)) + { + $this->order_modules($module_class); + $this->config->set('modules_ordered', true); - $this->module_manager->move_module_by($row, 'acp', 'move_up', 1); + // Stop execution if resource limit is reached + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + throw new resource_limit_reached_exception(); + } } - if ($module_class == 'mcp') + // And now for the special ones + // (these are modules which appear in multiple categories and thus get added manually + // to some for more control) + if (isset($this->module_extras[$module_class])) { - // Move pm report details module 3 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'mcp_pm_reports' - AND module_class = 'mcp' - AND module_mode = 'pm_report_details'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $this->add_module_extras($module_class); + } - $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + $this->module_manager->remove_cache_file($module_class); - // Move closed pm reports module 3 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'mcp_pm_reports' - AND module_class = 'mcp' - AND module_mode = 'pm_reports_closed'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + $i++; - $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + $this->config->set('module_class_index', $i); + $this->config->set('module_categories_index', 0); + $this->config->set('module_info_index', 0); + $this->config->set('added_extra_modules', false); + $this->config->set('modules_ordered', false); + $this->config->set('module_categories_array', array()); - // Move open pm reports module 3 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'mcp_pm_reports' - AND module_class = 'mcp' - AND module_mode = 'pm_reports'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + // Stop execution if resource limit is reached + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + break; } + } - if ($module_class == 'ucp') - { - // Move attachment module 4 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'ucp_attachments' - AND module_class = 'ucp' - AND module_mode = 'attachments'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + if ($i < $total) + { + throw new resource_limit_reached_exception(); + } + } - $this->module_manager->move_module_by($row, 'ucp', 'move_down', 4); + /** + * Move modules to their correct place + * + * @param string $module_class + */ + protected function order_modules($module_class) + { + if ($module_class == 'acp') + { + // Move main module 4 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_main' + AND module_class = 'acp' + AND module_mode = 'main'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'acp', 'move_up', 4); + + // Move permissions intro screen module 4 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_permissions' + AND module_class = 'acp' + AND module_mode = 'intro'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'acp', 'move_up', 4); + + // Move manage users screen module 5 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_users' + AND module_class = 'acp' + AND module_mode = 'overview'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'acp', 'move_up', 5); + + // Move extension management module 1 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_langname = 'ACP_EXTENSION_MANAGEMENT' + AND module_class = 'acp' + AND module_mode = '' + AND module_basename = ''"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'acp', 'move_up', 1); + } - // Move notification options module 4 down... - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_basename = 'ucp_notifications' - AND module_class = 'ucp' - AND module_mode = 'notification_options'"; - $result = $this->db->sql_query($sql); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); + if ($module_class == 'mcp') + { + // Move pm report details module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_report_details'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + + // Move closed pm reports module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_reports_closed'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + + // Move open pm reports module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_reports'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'mcp', 'move_down', 3); + } - $this->module_manager->move_module_by($row, 'ucp', 'move_down', 4); + if ($module_class == 'ucp') + { + // Move attachment module 4 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_attachments' + AND module_class = 'ucp' + AND module_mode = 'attachments'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'ucp', 'move_down', 4); + + // Move notification options module 4 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_notifications' + AND module_class = 'ucp' + AND module_mode = 'notification_options'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'ucp', 'move_down', 4); + + // Move OAuth module 5 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_auth_link' + AND module_class = 'ucp' + AND module_mode = 'auth_link'"; + $result = $this->db->sql_query($sql); + $row = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + $this->module_manager->move_module_by($row, 'ucp', 'move_down', 5); + } + } - // Move OAuth module 5 down... + /** + * Add extra modules + * + * @param string $module_class + */ + protected function add_module_extras($module_class) + { + foreach ($this->module_extras[$module_class] as $cat_name => $mods) + { + $sql = 'SELECT module_id, left_id, right_id + FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $this->db->sql_escape($cat_name) . "' + AND module_class = '" . $this->db->sql_escape($module_class) . "'"; + $result = $this->db->sql_query_limit($sql, 1); + $row2 = $this->db->sql_fetchrow($result); + $this->db->sql_freeresult($result); + + foreach ($mods as $mod_name) + { $sql = 'SELECT * FROM ' . MODULES_TABLE . " - WHERE module_basename = 'ucp_auth_link' - AND module_class = 'ucp' - AND module_mode = 'auth_link'"; - $result = $this->db->sql_query($sql); + WHERE module_langname = '" . $this->db->sql_escape($mod_name) . "' + AND module_class = '" . $this->db->sql_escape($module_class) . "' + AND module_basename <> ''"; + $result = $this->db->sql_query_limit($sql, 1); $row = $this->db->sql_fetchrow($result); $this->db->sql_freeresult($result); - $this->module_manager->move_module_by($row, 'ucp', 'move_down', 5); - } - - // And now for the special ones - // (these are modules which appear in multiple categories and thus get added manually - // to some for more control) - if (isset($this->module_extras[$module_class])) - { - foreach ($this->module_extras[$module_class] as $cat_name => $mods) - { - $sql = 'SELECT module_id, left_id, right_id - FROM ' . MODULES_TABLE . " - WHERE module_langname = '" . $this->db->sql_escape($cat_name) . "' - AND module_class = '" . $this->db->sql_escape($module_class) . "'"; - $result = $this->db->sql_query_limit($sql, 1); - $row2 = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - foreach ($mods as $mod_name) - { - $sql = 'SELECT * - FROM ' . MODULES_TABLE . " - WHERE module_langname = '" . $this->db->sql_escape($mod_name) . "' - AND module_class = '" . $this->db->sql_escape($module_class) . "' - AND module_basename <> ''"; - $result = $this->db->sql_query_limit($sql, 1); - $row = $this->db->sql_fetchrow($result); - $this->db->sql_freeresult($result); - - $module_data = array( - 'module_basename' => $row['module_basename'], - 'module_enabled' => (int) $row['module_enabled'], - 'module_display' => (int) $row['module_display'], - 'parent_id' => (int) $row2['module_id'], - 'module_class' => $row['module_class'], - 'module_langname' => $row['module_langname'], - 'module_mode' => $row['module_mode'], - 'module_auth' => $row['module_auth'], - ); + $module_data = array( + 'module_basename' => $row['module_basename'], + 'module_enabled' => (int) $row['module_enabled'], + 'module_display' => (int) $row['module_display'], + 'parent_id' => (int) $row2['module_id'], + 'module_class' => $row['module_class'], + 'module_langname' => $row['module_langname'], + 'module_mode' => $row['module_mode'], + 'module_auth' => $row['module_auth'], + ); - $this->module_manager->update_module_data($module_data); + $this->module_manager->update_module_data($module_data); - // Check for last sql error happened - if ($this->db->get_sql_error_triggered()) - { - $error = $this->db->sql_error($this->db->get_sql_error_sql()); - $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); - } - } + // Check for last sql error happened + if ($this->db->get_sql_error_triggered()) + { + $error = $this->db->sql_error($this->db->get_sql_error_sql()); + $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); } } - - $this->module_manager->remove_cache_file($module_class); } } diff --git a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php index 6fb03ff73d..20b7679ec1 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php +++ b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_database\task; +use phpbb\install\exception\resource_limit_reached_exception; + /** * Create database schema */ @@ -313,6 +315,10 @@ class add_config_settings extends \phpbb\install\task_base WHERE config_name = 'allow_avatar_upload'"; } + $i = $this->install_config->get('add_config_settings_index', 0); + $total = sizeof($sql_ary); + $sql_ary = array_slice($sql_ary, $i); + foreach ($sql_ary as $sql) { if (!$this->db->sql_query($sql)) @@ -320,6 +326,20 @@ class add_config_settings extends \phpbb\install\task_base $error = $this->db->sql_error($this->db->get_sql_error_sql()); $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); } + + $i++; + + // Stop execution if resource limit is reached + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + { + break; + } + } + + if ($i < $total) + { + $this->install_config->set('add_config_settings_index', $i); + throw new resource_limit_reached_exception(); } } diff --git a/phpBB/phpbb/install/module/install_database/task/add_default_data.php b/phpBB/phpbb/install/module/install_database/task/add_default_data.php index 3d73a74618..f5157637ee 100644 --- a/phpBB/phpbb/install/module/install_database/task/add_default_data.php +++ b/phpBB/phpbb/install/module/install_database/task/add_default_data.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_database\task; +use phpbb\install\exception\resource_limit_reached_exception; + /** * Create database schema */ @@ -96,6 +98,10 @@ class add_default_data extends \phpbb\install\task_base $sql_query = $this->database_helper->remove_comments($sql_query); $sql_query = $this->database_helper->split_sql_file($sql_query, $dbms_info[$dbms]['DELIM']); + $i = $this->config->get('add_default_data_index', 0); + $total = sizeof($sql_query); + $sql_query = array_slice($sql_query, $i); + foreach ($sql_query as $sql) { if (!$this->db->sql_query($sql)) @@ -103,6 +109,21 @@ class add_default_data extends \phpbb\install\task_base $error = $this->db->sql_error($this->db->get_sql_error_sql()); $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); } + + $i++; + + // Stop execution if resource limit is reached + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + break; + } + } + + $this->config->set('add_default_data_index', $i); + + if ($i < $total) + { + throw new resource_limit_reached_exception(); } } diff --git a/phpBB/phpbb/install/module/install_database/task/add_tables.php b/phpBB/phpbb/install/module/install_database/task/add_tables.php new file mode 100644 index 0000000000..f344f91582 --- /dev/null +++ b/phpBB/phpbb/install/module/install_database/task/add_tables.php @@ -0,0 +1,151 @@ +<?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_database\task; + +use phpbb\install\exception\resource_limit_reached_exception; + +/** + * Create tables + */ +class add_tables extends \phpbb\install\task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $config; + + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \phpbb\db\tools\tools_interface + */ + protected $db_tools; + + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * @var string + */ + protected $schema_file_path; + + /** + * Constructor + * + * @param \phpbb\install\helper\config $config + * @param \phpbb\install\helper\database $db_helper + * @param \phpbb\filesystem\filesystem_interface $filesystem + * @param string $phpbb_root_path + */ + public function __construct(\phpbb\install\helper\config $config, + \phpbb\install\helper\database $db_helper, + \phpbb\filesystem\filesystem_interface $filesystem, + $phpbb_root_path) + { + $dbms = $db_helper->get_available_dbms($config->get('dbms')); + $dbms = $dbms[$config->get('dbms')]['DRIVER']; + $factory = new \phpbb\db\tools\factory(); + + $this->db = new $dbms(); + $this->db->sql_connect( + $config->get('dbhost'), + $config->get('dbuser'), + $config->get('dbpasswd'), + $config->get('dbname'), + $config->get('dbport'), + false, + false + ); + + $this->config = $config; + $this->db_tools = $factory->get($this->db); + $this->filesystem = $filesystem; + $this->schema_file_path = $phpbb_root_path . 'store/schema.json'; + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->db->sql_return_on_error(true); + + $table_prefix = $this->config->get('table_prefix'); + $change_prefix = $this->config->get('change_table_prefix', true); + + if (!defined('CONFIG_TABLE')) + { + // CONFIG_TABLE is required by sql_create_index() to check the + // length of index names. However table_prefix is not defined + // here yet, so we need to create the constant ourselves. + define('CONFIG_TABLE', $table_prefix . 'config'); + } + + $db_table_schema = @file_get_contents($this->schema_file_path); + $db_table_schema = json_decode($db_table_schema, true); + $total = sizeof($db_table_schema); + $i = $this->config->get('add_table_index', 0); + $db_table_schema = array_slice($db_table_schema, $i); + + foreach ($db_table_schema as $table_name => $table_data) + { + $i++; + + $this->db_tools->sql_create_table( + ( ($change_prefix) ? ($table_prefix . substr($table_name, 6)) : $table_name ), + $table_data + ); + + // Stop execution if resource limit is reached + if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0) + { + break; + } + } + + $this->config->set('add_table_index', $i); + + if ($i < $total) + { + throw new resource_limit_reached_exception(); + } + else + { + @unlink($this->schema_file_path); + } + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_CREATE_TABLES'; + } +} diff --git a/phpBB/phpbb/install/module/install_database/task/create_schema.php b/phpBB/phpbb/install/module/install_database/task/create_schema.php index cabb78787f..a5635d5dbe 100644 --- a/phpBB/phpbb/install/module/install_database/task/create_schema.php +++ b/phpBB/phpbb/install/module/install_database/task/create_schema.php @@ -13,6 +13,8 @@ namespace phpbb\install\module\install_database\task; +use phpbb\install\exception\resource_limit_reached_exception; + /** * Create database schema */ @@ -106,6 +108,17 @@ class create_schema extends \phpbb\install\task_base */ public function run() { + // As this task may take a large amount of time to complete refreshing the page might be necessary for some + // server configurations with limited resources + if (!$this->config->get('pre_schema_forced_refresh')) + { + if ($this->config->get_time_remaining() < 5) + { + $this->config->set('pre_schema_forced_refresh', true); + throw new resource_limit_reached_exception(); + } + } + $this->db->sql_return_on_error(true); $dbms = $this->config->get('dbms'); diff --git a/phpBB/phpbb/install/module/install_database/task/create_schema_file.php b/phpBB/phpbb/install/module/install_database/task/create_schema_file.php new file mode 100644 index 0000000000..b6d6ece17f --- /dev/null +++ b/phpBB/phpbb/install/module/install_database/task/create_schema_file.php @@ -0,0 +1,164 @@ +<?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_database\task; + +use phpbb\install\exception\resource_limit_reached_exception; + +/** + * Create database schema + */ +class create_schema_file extends \phpbb\install\task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $config; + + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * @var string + */ + protected $php_ext; + + /** + * Constructor + * + * @param \phpbb\install\helper\config $config Installer's config provider + * @param \phpbb\install\helper\database $db_helper Installer's database helper + * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem service + * @param string $phpbb_root_path Path phpBB's root + * @param string $php_ext Extension of PHP files + */ + public function __construct(\phpbb\install\helper\config $config, + \phpbb\install\helper\database $db_helper, + \phpbb\filesystem\filesystem_interface $filesystem, + $phpbb_root_path, + $php_ext) + { + $dbms = $db_helper->get_available_dbms($config->get('dbms')); + $dbms = $dbms[$config->get('dbms')]['DRIVER']; + + $this->db = new $dbms(); + $this->db->sql_connect( + $config->get('dbhost'), + $config->get('dbuser'), + $config->get('dbpasswd'), + $config->get('dbname'), + $config->get('dbport'), + false, + false + ); + + $this->config = $config; + $this->filesystem = $filesystem; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $php_ext; + + parent::__construct(true); + } + + /** + * {@inheritdoc} + */ + public function run() + { + // Generate database schema + if ($this->filesystem->exists($this->phpbb_root_path . 'install/schemas/schema.json')) + { + $db_table_schema = @file_get_contents($this->phpbb_root_path . 'install/schemas/schema.json'); + $this->config->set('change_table_prefix', true); + } + else + { + global $table_prefix; + + // As this task may take a large amount of time to complete refreshing the page might be necessary for some + // server configurations with limited resources + if (!$this->config->get('pre_schema_forced_refresh', false)) + { + if ($this->config->get_time_remaining() < 5) + { + $this->config->set('pre_schema_forced_refresh', true); + throw new resource_limit_reached_exception(); + } + } + + $table_prefix = $this->config->get('table_prefix'); + + if (!defined('CONFIG_TABLE')) + { + // We need to include the constants file for the table constants + // when we generate the schema from the migration files. + include ($this->phpbb_root_path . 'includes/constants.' . $this->php_ext); + } + + $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, null, $this->php_ext); + $migrator_classes = $finder->core_path('phpbb/db/migration/data/')->get_classes(); + $factory = new \phpbb\db\tools\factory(); + $db_tools = $factory->get($this->db, true); + $schema_generator = new \phpbb\db\migration\schema_generator( + $migrator_classes, + new \phpbb\config\config(array()), + $this->db, + $db_tools, + $this->phpbb_root_path, + $this->php_ext, + $table_prefix + ); + $db_table_schema = $schema_generator->get_schema(); + $db_table_schema = json_encode($db_table_schema, JSON_PRETTY_PRINT); + + $this->config->set('change_table_prefix', false); + } + + $fp = @fopen($this->phpbb_root_path . 'store/schema.json', 'wb'); + if (!$fp) + { + throw new \Exception('INST_SCHEMA_FILE_NOT_WRITABLE'); + } + + fwrite($fp, $db_table_schema); + fclose($fp); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_CREATE_DATABASE_SCHEMA_FILE'; + } +} diff --git a/phpBB/phpbb/install/module/install_database/task/set_up_database.php b/phpBB/phpbb/install/module/install_database/task/set_up_database.php new file mode 100644 index 0000000000..49c8ea23ad --- /dev/null +++ b/phpBB/phpbb/install/module/install_database/task/set_up_database.php @@ -0,0 +1,164 @@ +<?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_database\task; + +/** + * Set up database for table generation + */ +class set_up_database extends \phpbb\install\task_base +{ + /** + * @var \phpbb\install\helper\config + */ + protected $config; + + /** + * @var \phpbb\db\driver\driver_interface + */ + protected $db; + + /** + * @var \phpbb\install\helper\database + */ + protected $database_helper; + + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + /** + * @var \phpbb\install\helper\iohandler\iohandler_interface + */ + protected $iohandler; + + /** + * @var string + */ + protected $schema_file_path; + + /** + * @var string + */ + protected $phpbb_root_path; + + /** + * Constructor + * + * @param \phpbb\install\helper\config $config + * @param \phpbb\install\helper\database $db_helper + * @param \phpbb\filesystem\filesystem_interface $filesystem + * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler + * @param string $phpbb_root_path + */ + public function __construct(\phpbb\install\helper\config $config, + \phpbb\install\helper\database $db_helper, + \phpbb\filesystem\filesystem_interface $filesystem, + \phpbb\install\helper\iohandler\iohandler_interface $iohandler, + $phpbb_root_path) + { + $dbms = $db_helper->get_available_dbms($config->get('dbms')); + $dbms = $dbms[$config->get('dbms')]['DRIVER']; + + $this->db = new $dbms(); + $this->db->sql_connect( + $config->get('dbhost'), + $config->get('dbuser'), + $config->get('dbpasswd'), + $config->get('dbname'), + $config->get('dbport'), + false, + false + ); + + $this->config = $config; + $this->database_helper = $db_helper; + $this->filesystem = $filesystem; + $this->iohandler = $iohandler; + $this->phpbb_root_path = $phpbb_root_path; + + parent::__construct(false); + } + + /** + * {@inheritdoc} + */ + public function check_requirements() + { + $dbms = $this->config->get('dbms'); + $dbms_info = $this->database_helper->get_available_dbms($dbms); + $schema_name = $dbms_info[$dbms]['SCHEMA']; + + if ($dbms === 'mysql') + { + if (version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) + { + $schema_name .= '_41'; + } + else + { + $schema_name .= '_40'; + } + } + + $this->schema_file_path = $this->phpbb_root_path . 'install/schemas/' . $schema_name . '_schema.sql'; + + return $this->filesystem->exists($this->schema_file_path); + } + + /** + * {@inheritdoc} + */ + public function run() + { + $this->db->sql_return_on_error(true); + + $dbms = $this->config->get('dbms'); + $dbms_info = $this->database_helper->get_available_dbms($dbms); + $delimiter = $dbms_info[$dbms]['DELIM']; + $table_prefix = $this->config->get('table_prefix'); + + $sql_query = @file_get_contents($this->schema_file_path); + $sql_query = preg_replace('#phpbb_#i', $table_prefix, $sql_query); + $sql_query = $this->database_helper->remove_comments($sql_query); + $sql_query = $this->database_helper->split_sql_file($sql_query, $delimiter); + + foreach ($sql_query as $sql) + { + if (!$this->db->sql_query($sql)) + { + $error = $this->db->sql_error($this->db->get_sql_error_sql()); + $this->iohandler->add_error_message('INST_ERR_DB', $error['message']); + } + } + + unset($sql_query); + } + + /** + * {@inheritdoc} + */ + static public function get_step_count() + { + return 1; + } + + /** + * {@inheritdoc} + */ + public function get_task_lang_name() + { + return 'TASK_SETUP_DATABASE'; + } +} diff --git a/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php b/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php index e0890a929c..5bc425b929 100644 --- a/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php +++ b/phpBB/phpbb/install/module/install_filesystem/task/create_config_file.php @@ -129,7 +129,6 @@ class create_config_file extends \phpbb\install\task_base else { $this->iohandler->add_error_message('UNABLE_TO_WRITE_CONFIG_FILE'); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } @@ -139,7 +138,6 @@ class create_config_file extends \phpbb\install\task_base { // We were unable to create the lock file - abort $this->iohandler->add_error_message('UNABLE_TO_WRITE_LOCK'); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } @fclose($fp); diff --git a/phpBB/phpbb/install/module/install_finish/task/notify_user.php b/phpBB/phpbb/install/module/install_finish/task/notify_user.php index 5268b85a42..292be57f5f 100644 --- a/phpBB/phpbb/install/module/install_finish/task/notify_user.php +++ b/phpBB/phpbb/install/module/install_finish/task/notify_user.php @@ -87,9 +87,13 @@ class notify_user extends \phpbb\install\task_base $this->php_ext = $php_ext; // We need to reload config for cases when it doesn't have all values + /** @var \phpbb\cache\driver\driver_interface $cache */ + $cache = $container->get('cache.driver'); + $cache->destroy('config'); + $this->config = new db( $container->get('dbal.conn'), - $container->get('cache.driver'), + $cache, $container->get_parameter('tables.config') ); diff --git a/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php b/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php index 8629d9aea3..34541c361e 100644 --- a/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php +++ b/phpBB/phpbb/install/module/install_finish/task/populate_migrations.php @@ -13,12 +13,21 @@ namespace phpbb\install\module\install_finish\task; +use phpbb\install\exception\resource_limit_reached_exception; +use phpbb\install\helper\config; +use phpbb\install\helper\container_factory; + /** * Populates migrations */ class populate_migrations extends \phpbb\install\task_base { /** + * @var config + */ + protected $config; + + /** * @var \phpbb\extension\manager */ protected $extension_manager; @@ -31,10 +40,12 @@ class populate_migrations extends \phpbb\install\task_base /** * Constructor * - * @param \phpbb\install\helper\container_factory $container phpBB's DI contianer + * @param config $config Installer's config + * @param container_factory $container phpBB's DI contianer */ - public function __construct(\phpbb\install\helper\container_factory $container) + public function __construct(config $config, container_factory $container) { + $this->config = $config; $this->extension_manager = $container->get('ext.manager'); $this->migrator = $container->get('migrator'); @@ -46,6 +57,15 @@ class populate_migrations extends \phpbb\install\task_base */ public function run() { + if (!$this->config->get('populate_migration_refresh_before', false)) + { + if ($this->config->get_time_remaining() < 1) + { + $this->config->set('populate_migration_refresh_before', true); + throw new resource_limit_reached_exception(); + } + } + $finder = $this->extension_manager->get_finder(); $migrations = $finder diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php index ac305e8ab5..d1f1af6b83 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_admin_data.php @@ -136,7 +136,6 @@ class obtain_admin_data extends \phpbb\install\task_base implements \phpbb\insta $this->io_handler->add_user_form_group('ADMIN_CONFIG', $admin_form); // Require user interaction - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php index 6c54561d14..ff2a0a2f86 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_board_data.php @@ -164,7 +164,6 @@ class obtain_board_data extends \phpbb\install\task_base implements \phpbb\insta $this->io_handler->add_user_form_group('BOARD_CONFIG', $board_form); - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php index 3458aab63e..ce720dbf76 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_database_data.php @@ -188,7 +188,6 @@ class obtain_database_data extends \phpbb\install\task_base implements \phpbb\in $this->io_handler->add_user_form_group('DB_CONFIG', $database_form); // Require user interaction - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } 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 b04b8e353f..606e4a2ddd 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 @@ -144,7 +144,6 @@ class obtain_email_data extends \phpbb\install\task_base implements \phpbb\insta $this->io_handler->add_user_form_group('EMAIL_CONFIG', $email_form); - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php index 9bcb73a6a9..d5a8855c37 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_file_updater_method.php @@ -115,7 +115,6 @@ class obtain_file_updater_method extends task_base ), )); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php index 654b5534a9..1ef70eae08 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_server_data.php @@ -180,7 +180,6 @@ class obtain_server_data extends \phpbb\install\task_base implements \phpbb\inst $this->io_handler->add_user_form_group('SERVER_CONFIG', $server_form); - $this->io_handler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php index a4d362a0f1..f31472fc58 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_ftp_data.php @@ -141,7 +141,6 @@ class obtain_update_ftp_data extends task_base ), )); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php index 6a98721e77..c139b70fa4 100644 --- a/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php +++ b/phpBB/phpbb/install/module/obtain_data/task/obtain_update_settings.php @@ -57,22 +57,35 @@ class obtain_update_settings extends task_base } else { + if ($this->installer_config->get('disable_filesystem_update', false)) + { + $options[] = array( + 'value' => 'db_only', + 'label' => 'UPDATE_TYPE_DB_ONLY', + 'selected' => true, + ); + } + else + { + $options = array( + array( + 'value' => 'all', + 'label' => 'UPDATE_TYPE_ALL', + 'selected' => true, + ), + array( + 'value' => 'db_only', + 'label' => 'UPDATE_TYPE_DB_ONLY', + 'selected' => false, + ), + ); + } + $this->iohandler->add_user_form_group('UPDATE_TYPE', array( 'update_type' => array( 'label' => 'UPDATE_TYPE', 'type' => 'radio', - 'options' => array( - array( - 'value' => 'all', - 'label' => 'UPDATE_TYPE_ALL', - 'selected' => true, - ), - array( - 'value' => 'db_only', - 'label' => 'UPDATE_TYPE_DB_ONLY', - 'selected' => false, - ), - ), + 'options' => $options, ), 'submit_update' => array( 'label' => 'SUBMIT', @@ -80,7 +93,6 @@ class obtain_update_settings extends task_base ), )); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php b/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php index 26593e6777..121b4ff4e5 100644 --- a/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php +++ b/phpBB/phpbb/install/module/requirements/abstract_requirements_module.php @@ -13,7 +13,6 @@ namespace phpbb\install\module\requirements; -use phpbb\install\exception\resource_limit_reached_exception; use phpbb\install\exception\user_interaction_required_exception; use phpbb\install\module_base; @@ -25,41 +24,8 @@ abstract class abstract_requirements_module extends module_base public function run() { $tests_passed = true; - - // Recover install progress - $task_name = $this->recover_progress(); - $task_found = false; - - /** - * @var string $name ID of the service - * @var \phpbb\install\task_interface $task Task object - */ foreach ($this->task_collection as $name => $task) { - // Run until there are available resources - if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) - { - throw new resource_limit_reached_exception(); - } - - // Skip forward until the next task is reached - if (!$task_found) - { - if ($name === $task_name || empty($task_name)) - { - $task_found = true; - - if ($name === $task_name) - { - continue; - } - } - else - { - continue; - } - } - // Check if we can run the task if (!$task->is_essential() && !$task->check_requirements()) { @@ -76,7 +42,7 @@ abstract class abstract_requirements_module extends module_base } // Module finished, so clear task progress - $this->install_config->set_finished_task(''); + $this->install_config->set_finished_task(0); // Check if tests have failed if (!$tests_passed) @@ -91,7 +57,6 @@ abstract class abstract_requirements_module extends module_base )); // Send the response and quit - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/requirements/task/check_update.php b/phpBB/phpbb/install/module/requirements/task/check_update.php index c986c76810..4e9124ff47 100644 --- a/phpBB/phpbb/install/module/requirements/task/check_update.php +++ b/phpBB/phpbb/install/module/requirements/task/check_update.php @@ -14,6 +14,7 @@ namespace phpbb\install\module\requirements\task; use phpbb\filesystem\filesystem; +use phpbb\install\helper\config; use phpbb\install\helper\container_factory; use phpbb\install\helper\iohandler\iohandler_interface; use phpbb\install\helper\update_helper; @@ -35,6 +36,11 @@ class check_update extends task_base protected $filesystem; /** + * @var config + */ + protected $installer_config; + + /** * @var iohandler_interface */ protected $iohandler; @@ -69,14 +75,16 @@ class check_update extends task_base * * @param container_factory $container * @param filesystem $filesystem + * @param config $config * @param iohandler_interface $iohandler * @param update_helper $update_helper * @param string $phpbb_root_path * @param string $php_ext */ - public function __construct(container_factory $container, filesystem $filesystem, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path, $php_ext) + public function __construct(container_factory $container, filesystem $filesystem, config $config, iohandler_interface $iohandler, update_helper $update_helper, $phpbb_root_path, $php_ext) { $this->filesystem = $filesystem; + $this->installer_config = $config; $this->iohandler = $iohandler; $this->update_helper = $update_helper; $this->phpbb_root_path = $phpbb_root_path; @@ -117,8 +125,10 @@ class check_update extends task_base $this->iohandler->add_error_message('UPDATE_FILES_NOT_FOUND'); $this->set_test_passed(false); - // If there are no update files, we can't check the version - return false; + // If there are no update files, we can't check the version etc + // However, we can let the users run migrations if they really want to... + $this->installer_config->set('disable_filesystem_update', true); + return true; } // Recover version numbers diff --git a/phpBB/phpbb/install/module/update_database/task/update.php b/phpBB/phpbb/install/module/update_database/task/update.php index 84ec6f73f5..4b2baf2c23 100644 --- a/phpBB/phpbb/install/module/update_database/task/update.php +++ b/phpBB/phpbb/install/module/update_database/task/update.php @@ -140,7 +140,7 @@ class update extends task_base ->get_classes(); $this->migrator->set_migrations($migrations); - $migration_count = count($migrations); + $migration_count = count($this->migrator->get_migrations()); $this->iohandler->set_task_count($migration_count, true); $progress_count = $this->installer_config->get('database_update_count', 0); diff --git a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php index 9271e8fd50..f911b7ac62 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php @@ -101,7 +101,6 @@ class download_updated_files extends task_base ), )); - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } } diff --git a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php index e712b8ad6a..c46c05500a 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/show_file_status.php @@ -136,7 +136,6 @@ class show_file_status extends task_base )); // Show results to the user - $this->iohandler->send_response(); throw new user_interaction_required_exception(); } else diff --git a/phpBB/phpbb/install/module_base.php b/phpBB/phpbb/install/module_base.php index fb68c3aca2..527447b4a1 100644 --- a/phpBB/phpbb/install/module_base.php +++ b/phpBB/phpbb/install/module_base.php @@ -105,47 +105,23 @@ abstract class module_base implements module_interface public function run() { // Recover install progress - $task_name = $this->recover_progress(); - $task_found = false; - - /** - * @var string $name ID of the service - * @var \phpbb\install\task_interface $task Task object - */ - foreach ($this->task_collection as $name => $task) - { - // Run until there are available resources - if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) - { - throw new resource_limit_reached_exception(); - } + $task_index = $this->recover_progress(); + $iterator = $this->task_collection->getIterator(); - // Skip forward until the next task is reached - if (!$task_found) - { - if ($name === $task_name || empty($task_name)) - { - $task_found = true; - - if ($name === $task_name) - { - continue; - } - } - else - { - continue; - } - } + if ($task_index < $iterator->count()) + { + $iterator->seek($task_index); + } + else + { + $this->install_config->set_finished_task(0); + return; + } - // Send progress information - if ($this->allow_progress_bar) - { - $this->iohandler->set_progress( - $task->get_task_lang_name(), - $this->install_config->get_current_task_progress() - ); - } + while ($iterator->valid()) + { + $task = $iterator->current(); + $name = $iterator->key(); // Check if we can run the task if (!$task->is_essential() && !$task->check_requirements()) @@ -156,20 +132,33 @@ abstract class module_base implements module_interface )); $this->install_config->increment_current_task_progress($this->task_step_count[$name]); - continue; } - - if ($this->allow_progress_bar) + else { - // Only increment progress by one, as if a task has more than one steps - // then that should be incremented in the task itself - $this->install_config->increment_current_task_progress(); - } + // Send progress information + if ($this->allow_progress_bar) + { + $this->iohandler->set_progress( + $task->get_task_lang_name(), + $this->install_config->get_current_task_progress() + ); + + $this->iohandler->send_response(); + } + + $task->run(); - $task->run(); + if ($this->allow_progress_bar) + { + // Only increment progress by one, as if a task has more than one steps + // then that should be incremented in the task itself + $this->install_config->increment_current_task_progress(); + } + } - // Log install progress - $this->install_config->set_finished_task($name); + $task_index++; + $this->install_config->set_finished_task($task_index); + $iterator->next(); // Send progress information if ($this->allow_progress_bar) @@ -181,10 +170,16 @@ abstract class module_base implements module_interface } $this->iohandler->send_response(); + + // Stop execution if resource limit is reached + if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) + { + throw new resource_limit_reached_exception(); + } } // Module finished, so clear task progress - $this->install_config->set_finished_task(''); + $this->install_config->set_finished_task(0); } /** @@ -195,7 +190,7 @@ abstract class module_base implements module_interface protected function recover_progress() { $progress_array = $this->install_config->get_progress_data(); - return $progress_array['last_task_name']; + return $progress_array['last_task_index']; } /** diff --git a/phpBB/phpbb/language/language.php b/phpBB/phpbb/language/language.php index 382d4db89e..42429c2c07 100644 --- a/phpBB/phpbb/language/language.php +++ b/phpBB/phpbb/language/language.php @@ -246,14 +246,14 @@ class language } /** - * Act like lang() but takes a key and an array of parameters instead of using variadic + * Returns the raw value associated to a language key or the language key no translation is available. + * No parameter substitution is performed, can be a string or an array. * * @param string|array $key Language key - * @param array $args Parameters * * @return array|string */ - public function lang_array($key, $args = array()) + public function lang_raw($key) { // Load common language files if they not loaded yet if (!$this->common_language_files_loaded) @@ -281,6 +281,26 @@ class language return $key; } + return $lang; + } + + /** + * Act like lang() but takes a key and an array of parameters instead of using variadic + * + * @param string|array $key Language key + * @param array $args Parameters + * + * @return string + */ + public function lang_array($key, $args = array()) + { + $lang = $this->lang_raw($key); + + if ($lang === $key) + { + return $key; + } + // If the language entry is a string, we simply mimic sprintf() behaviour if (is_string($lang)) { diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php index 7b0d6f0fba..154361ef64 100644 --- a/phpBB/phpbb/path_helper.php +++ b/phpBB/phpbb/path_helper.php @@ -100,11 +100,18 @@ class path_helper */ public function update_web_root_path($path) { + $web_root_path = $this->get_web_root_path(); + + // Removes the web root path if it is already present + if (strpos($path, $web_root_path) === 0) + { + $path = $this->phpbb_root_path . substr($path, strlen($web_root_path)); + } + if (strpos($path, $this->phpbb_root_path) === 0) { $path = substr($path, strlen($this->phpbb_root_path)); - $web_root_path = $this->get_web_root_path(); if (substr($web_root_path, -8) === 'app.php/' && substr($path, 0, 7) === 'app.php') { $path = substr($path, 8); diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php index 3f7146c59b..12031bda03 100644 --- a/phpBB/phpbb/session.php +++ b/phpBB/phpbb/session.php @@ -1600,6 +1600,8 @@ class session $db->sql_return_on_error(false); + $this->data = array_merge($this->data, $sql_ary); + if ($this->data['user_id'] != ANONYMOUS && !empty($config['new_member_post_limit']) && $this->data['user_new'] && $config['new_member_post_limit'] <= $this->data['user_posts']) { $this->leave_newly_registered(); diff --git a/phpBB/phpbb/template/assets_bag.php b/phpBB/phpbb/template/assets_bag.php new file mode 100644 index 0000000000..9013061b96 --- /dev/null +++ b/phpBB/phpbb/template/assets_bag.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\template; + +class assets_bag +{ + /** @var asset[] */ + protected $stylesheets = []; + + /** @var asset[] */ + protected $scripts = []; + + /** + * Add a css asset to the bag + * + * @param asset $asset + */ + public function add_stylesheet(asset $asset) + { + $this->stylesheets[] = $asset; + } + + /** + * Add a js script asset to the bag + * + * @param asset $asset + */ + public function add_script(asset $asset) + { + $this->scripts[] = $asset; + } + + /** + * Returns all css assets + * + * @return asset[] + */ + public function get_stylesheets() + { + return $this->stylesheets; + } + + /** + * Returns all js assets + * + * @return asset[] + */ + public function get_scripts() + { + return $this->scripts; + } + + /** + * Returns the HTML code to includes all css assets + * + * @return string + */ + public function get_stylesheets_content() + { + $output = ''; + foreach ($this->stylesheets as $stylesheet) + { + $output .= "<link href=\"{$stylesheet->get_url()}\" rel=\"stylesheet\" type=\"text/css\" media=\"screen\" />\n"; + } + + return $output; + } + + /** + * Returns the HTML code to includes all js assets + * + * @return string + */ + public function get_scripts_content() + { + $output = ''; + foreach ($this->scripts as $script) + { + $output .= "<script type=\"text/javascript\" src=\"{$script->get_url()}\"></script>\n"; + } + + return $output; + } +} diff --git a/phpBB/phpbb/template/twig/definition.php b/phpBB/phpbb/template/twig/definition.php index cb3c953692..205f0e68ee 100644 --- a/phpBB/phpbb/template/twig/definition.php +++ b/phpBB/phpbb/template/twig/definition.php @@ -19,7 +19,10 @@ namespace phpbb\template\twig; class definition { /** @var array **/ - protected $definitions = array(); + protected $definitions = array( + 'SCRIPTS' => '__SCRIPTS_PLACEHOLDER__', + 'STYLESHEETS' => '__STYLESHEETS_PLACEHOLDER__' + ); /** * Get a DEFINE'd variable diff --git a/phpBB/phpbb/template/twig/environment.php b/phpBB/phpbb/template/twig/environment.php index 6e75403159..5660ddc3a4 100644 --- a/phpBB/phpbb/template/twig/environment.php +++ b/phpBB/phpbb/template/twig/environment.php @@ -13,6 +13,8 @@ namespace phpbb\template\twig; +use phpbb\template\assets_bag; + class environment extends \Twig_Environment { /** @var \phpbb\config\config */ @@ -39,6 +41,9 @@ class environment extends \Twig_Environment /** @var array **/ protected $namespace_look_up_order = array('__main__'); + /** @var assets_bag */ + protected $assets_bag; + /** * Constructor * @@ -63,6 +68,8 @@ class environment extends \Twig_Environment $this->phpbb_root_path = $this->phpbb_path_helper->get_phpbb_root_path(); $this->web_root_path = $this->phpbb_path_helper->get_web_root_path(); + $this->assets_bag = new assets_bag(); + $options = array_merge(array( 'cache' => (defined('IN_INSTALL')) ? false : $cache_path, 'debug' => false, @@ -151,6 +158,16 @@ class environment extends \Twig_Environment } /** + * Gets the assets bag + * + * @return assets_bag + */ + public function get_assets_bag() + { + return $this->assets_bag; + } + + /** * Get the namespace look up order * * @return array @@ -174,6 +191,58 @@ class environment extends \Twig_Environment } /** + * {@inheritdoc} + */ + public function render($name, array $context = []) + { + $output = parent::render($name, $context); + + return $this->inject_assets($output); + } + + /** + * {@inheritdoc} + */ + public function display($name, array $context = []) + { + $level = ob_get_level(); + ob_start(); + + try + { + parent::display($name, $context); + } + catch (\Exception $e) + { + while (ob_get_level() > $level) + { + ob_end_clean(); + } + + throw $e; + } + + $output = ob_get_clean(); + + echo $this->inject_assets($output); + } + + /** + * Injects the assets (from INCLUDECSS/JS) in the output. + * + * @param string $output + * + * @return string + */ + private function inject_assets($output) + { + $output = str_replace('__STYLESHEETS_PLACEHOLDER__', $this->assets_bag->get_stylesheets_content(), $output); + $output = str_replace('__SCRIPTS_PLACEHOLDER__', $this->assets_bag->get_scripts_content(), $output); + + return $output; + } + + /** * Loads a template by name. * * @param string $name The template name diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php index 324823b8d7..6d50eafc9d 100644 --- a/phpBB/phpbb/template/twig/node/includeasset.php +++ b/phpBB/phpbb/template/twig/node/includeasset.php @@ -49,33 +49,18 @@ abstract class includeasset extends \Twig_Node ->write("\$local_file = \$this->getEnvironment()->findTemplate(\$asset_path);\n") ->write("\$asset->set_path(\$local_file, true);\n") ->outdent() - ->write("\$asset->add_assets_version('{$config['assets_version']}');\n") - ->write("\$asset_file = \$asset->get_url();\n") ->write("}\n") + ->write("\$asset->add_assets_version('{$config['assets_version']}');\n") ->outdent() ->write("}\n") - ->write("\$context['definition']->append('{$this->get_definition_name()}', '") - ; - - $this->append_asset($compiler); - - $compiler - ->raw("\n');\n") + ->write("\$this->getEnvironment()->get_assets_bag()->add_{$this->get_setters_name()}(\$asset);") ; } /** - * Get the definition name + * Get the name of the assets bag setter * - * @return string (e.g. 'SCRIPTS') - */ - abstract public function get_definition_name(); - - /** - * Append the output code for the asset - * - * @param \Twig_Compiler A Twig_Compiler instance - * @return null + * @return string (e.g. 'script') */ - abstract protected function append_asset(\Twig_Compiler $compiler); + abstract public function get_setters_name(); } diff --git a/phpBB/phpbb/template/twig/node/includecss.php b/phpBB/phpbb/template/twig/node/includecss.php index 2dac154036..2e97d4972d 100644 --- a/phpBB/phpbb/template/twig/node/includecss.php +++ b/phpBB/phpbb/template/twig/node/includecss.php @@ -18,20 +18,8 @@ class includecss extends \phpbb\template\twig\node\includeasset /** * {@inheritdoc} */ - public function get_definition_name() + public function get_setters_name() { - return 'STYLESHEETS'; - } - - /** - * {@inheritdoc} - */ - public function append_asset(\Twig_Compiler $compiler) - { - $compiler - ->raw("<link href=\"' . ") - ->raw("\$asset_file . '\"") - ->raw(' rel="stylesheet" type="text/css" media="screen" />') - ; + return 'stylesheet'; } } diff --git a/phpBB/phpbb/template/twig/node/includejs.php b/phpBB/phpbb/template/twig/node/includejs.php index e77f2afeed..505b49757b 100644 --- a/phpBB/phpbb/template/twig/node/includejs.php +++ b/phpBB/phpbb/template/twig/node/includejs.php @@ -18,20 +18,8 @@ class includejs extends \phpbb\template\twig\node\includeasset /** * {@inheritdoc} */ - public function get_definition_name() + public function get_setters_name() { - return 'SCRIPTS'; - } - - /** - * {@inheritdoc} - */ - protected function append_asset(\Twig_Compiler $compiler) - { - $compiler - ->raw("<script type=\"text/javascript\" src=\"' . ") - ->raw("\$asset_file") - ->raw(". '\"></script>\n") - ; + return 'script'; } } |