diff options
Diffstat (limited to 'phpBB/phpbb/install/installer.php')
| -rw-r--r-- | phpBB/phpbb/install/installer.php | 350 | 
1 files changed, 350 insertions, 0 deletions
| diff --git a/phpBB/phpbb/install/installer.php b/phpBB/phpbb/install/installer.php new file mode 100644 index 0000000000..e04e233a76 --- /dev/null +++ b/phpBB/phpbb/install/installer.php @@ -0,0 +1,350 @@ +<?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; + +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\ajax_iohandler; +use phpbb\install\helper\iohandler\cli_iohandler; +use phpbb\install\helper\iohandler\iohandler_interface; +use phpbb\path_helper; + +class installer +{ +	/** +	 * @var driver_interface +	 */ +	protected $cache; + +	/** +	 * @var container_factory +	 */ +	protected $container_factory; + +	/** +	 * @var config +	 */ +	protected $install_config; + +	/** +	 * @var ordered_service_collection +	 */ +	protected $installer_modules; + +	/** +	 * @var iohandler_interface +	 */ +	protected $iohandler; + +	/** +	 * @var string +	 */ +	protected $web_root; + +	/** +	 * Stores the number of steps that a given module has +	 * +	 * @var array +	 */ +	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, 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; +	} + +	/** +	 * Sets modules to execute +	 * +	 * Note: The installer will run modules in the order they are set in +	 * the array. +	 * +	 * @param ordered_service_collection	$modules	Service collection of module service names +	 */ +	public function set_modules(ordered_service_collection $modules) +	{ +		$this->installer_modules = $modules; +	} + +	/** +	 * Sets input-output handler objects +	 * +	 * @param iohandler_interface	$iohandler +	 */ +	public function set_iohandler(iohandler_interface $iohandler) +	{ +		$this->iohandler = $iohandler; +	} + +	/** +	 * 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() +	{ +		if ($this->iohandler instanceof ajax_iohandler) +		{ +			$this->iohandler->acquire_lock(); +		} + +		// 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_index = $this->recover_progress(); + +		// Variable used to check if the install process have been finished +		$install_finished	= false; +		$fail_cleanup		= false; +		$send_refresh		= false; + +		// We are installing something, so the introduction stage can go now... +		$this->install_config->set_finished_navigation_stage(array('install', 0, 'introduction')); +		$this->iohandler->set_finished_stage_menu(array('install', 0, 'introduction')); + +		if ($this->install_config->get_task_progress_count() === 0) +		{ +			// Count all tasks in the current installer modules +			$step_count = 0; + +			/** @var \phpbb\install\module_interface $module */ +			foreach ($this->installer_modules as $name => $module) +			{ +				$module_step_count = $module->get_step_count(); +				$step_count += $module_step_count; +				$this->module_step_count[$name] = $module_step_count; +			} + +			// Set task count +			$this->install_config->set_task_progress_count($step_count); +		} + +		// Set up progress information +		$this->iohandler->set_task_count( +			$this->install_config->get_task_progress_count() +		); + +		try +		{ +			$iterator = $this->installer_modules->getIterator(); + +			if ($module_index < $iterator->count()) +			{ +				$iterator->seek($module_index); +			} +			else +			{ +				$iterator->seek($module_index - 1); +				$iterator->next(); +			} + +			while ($iterator->valid()) +			{ +				$module	= $iterator->current(); +				$name	= $iterator->key(); + +				// Check if module should be executed +				if (!$module->is_essential() && !$module->check_requirements()) +				{ +					$this->install_config->set_finished_navigation_stage($module->get_navigation_stage_path()); +					$this->iohandler->set_finished_stage_menu($module->get_navigation_stage_path()); + +					$this->iohandler->add_log_message(array( +						'SKIP_MODULE', +						$name, +					)); +					$this->install_config->increment_current_task_progress($this->module_step_count[$name]); +				} +				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()); +				} + +				$module_index++; +				$iterator->next(); + +				// Save progress +				$this->install_config->set_active_module($name, $module_index); + +				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 +			$install_finished = true; + +			if ($this->iohandler instanceof cli_iohandler) +			{ +				$this->iohandler->add_success_message('INSTALLER_FINISHED'); +			} +			else +			{ +				// Start session if not installing and get user object +				// to allow redirecting to ACP +				$user = $this->container_factory->get('user'); +				if (!isset($module) || !($module instanceof \phpbb\install\module\install_finish\module)) +				{ +					$auth = $this->container_factory->get('auth'); + +					$user->session_begin(); +					$auth->acl($user->data); +					$user->setup(); +				} + +				$phpbb_root_path = $this->container_factory->get_parameter('core.root_path'); + +				$acp_url = append_sid($phpbb_root_path . 'adm/index.php', 'i=acp_help_phpbb&mode=help_phpbb', true, $user->session_id); +				$this->iohandler->add_success_message('INSTALLER_FINISHED', array( +					'ACP_LINK', +					$acp_url, +				)); +			} +		} +		catch (user_interaction_required_exception $e) +		{ +			$this->iohandler->send_response(true); +		} +		catch (resource_limit_reached_exception $e) +		{ +			$send_refresh = true; +		} +		catch (jump_to_restart_point_exception $e) +		{ +			$this->install_config->jump_to_restart_point($e->get_restart_point_name()); +			$send_refresh = true; +		} +		catch (\Exception $e) +		{ +			$this->iohandler->add_error_message($e->getMessage()); +			$this->iohandler->send_response(true); +			$fail_cleanup = true; +		} + +		if ($this->iohandler instanceof ajax_iohandler) +		{ +			$this->iohandler->release_lock(); +		} + +		if ($install_finished) +		{ +			// 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(true); +		} + +		// Save install progress +		try +		{ +			if ($install_finished || $fail_cleanup) +			{ +				$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 +			{ +				$this->install_config->save_config(); +			} +		} +		catch (installer_config_not_writable_exception $e) +		{ +			// It is allowed to fail this test during requirements testing +			$progress_data = $this->install_config->get_progress_data(); + +			if ($progress_data['last_task_module_name'] !== 'installer.module.requirements_install') +			{ +				$this->iohandler->add_error_message('INSTALLER_CONFIG_NOT_WRITABLE'); +			} +		} +	} + +	/** +	 * Recover install progress +	 * +	 * @return string	Index of the next installer module to execute +	 */ +	protected function recover_progress() +	{ +		$progress_array = $this->install_config->get_progress_data(); +		return $progress_array['last_task_module_index']; +	} +} | 
