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';  	}  } | 
