diff options
Diffstat (limited to 'phpBB/phpbb/install/helper')
14 files changed, 2373 insertions, 0 deletions
| diff --git a/phpBB/phpbb/install/helper/config.php b/phpBB/phpbb/install/helper/config.php new file mode 100644 index 0000000000..d5653f1924 --- /dev/null +++ b/phpBB/phpbb/install/helper/config.php @@ -0,0 +1,386 @@ +<?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; + +use phpbb\install\exception\installer_config_not_writable_exception; + +/** + * Stores common settings and installation status + */ +class config +{ +	/** +	 * @var \phpbb\filesystem\filesystem_interface +	 */ +	protected $filesystem; + +	/** +	 * Array which contains config settings for the installer +	 * +	 * The array will also store all the user input, as well as any +	 * data that is passed to other tasks by a task. +	 * +	 * @var array +	 */ +	protected $installer_config; + +	/** +	 * @var string +	 */ +	protected $install_config_file; + +	/** +	 * @var \bantu\IniGetWrapper\IniGetWrapper +	 */ +	protected $php_ini; + +	/** +	 * @var string +	 */ +	protected $phpbb_root_path; + +	/** +	 * Array containing progress information +	 * +	 * @var array +	 */ +	protected $progress_data; + +	/** +	 * Array containing system information +	 * +	 * The array contains run time and memory limitations. +	 * +	 * @var array +	 */ +	protected $system_data; + +	/** +	 * Array containing navigation bar information +	 * +	 * @var array +	 */ +	protected $navigation_data; + +	/** +	 * Flag indicating that config file should be cleaned up +	 * +	 * @var bool +	 */ +	protected $do_clean_up; + +	/** +	 * Constructor +	 */ +	public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, \bantu\IniGetWrapper\IniGetWrapper $php_ini, $phpbb_root_path) +	{ +		$this->filesystem		= $filesystem; +		$this->php_ini			= $php_ini; +		$this->phpbb_root_path	= $phpbb_root_path; +		$this->do_clean_up		= false; + +		// Set up data arrays +		$this->navigation_data	= array(); +		$this->installer_config	= array(); +		$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 +			'max_task_progress'			=> 0, +			'current_task_progress'		=> 0, +		); + +		$this->install_config_file = $this->phpbb_root_path . 'store/install_config.php'; + +		$this->setup_system_data(); +	} + +	/** +	 * Returns data for a specified parameter +	 * +	 * @param	string	$param_name	Name of the parameter to return +	 * @param	mixed	$default	Default value to return when the specified data +	 * 								does not exist. +	 * +	 * @return 	mixed	value of the specified parameter or the default value if the data +	 * 					cannot be recovered. +	 */ +	public function get($param_name, $default = false) +	{ +		return (isset($this->installer_config[$param_name])) ? $this->installer_config[$param_name] : $default; +	} + +	/** +	 * Sets a parameter in installer_config +	 * +	 * @param	string	$param_name	Name of the parameter +	 * @param	mixed	$value		Values to set the parameter +	 */ +	public function set($param_name, $value) +	{ +		$this->installer_config = array_merge($this->installer_config, array( +			$param_name => $value, +		)); +	} + +	/** +	 * Returns system parameter +	 * +	 * @param string	$param_name	Name of the parameter +	 * +	 * @return mixed	Returns system parameter if it is defined, false otherwise +	 */ +	public function system_get($param_name) +	{ +		return (isset($this->system_data[$param_name])) ? $this->system_data[$param_name] : false; +	} + +	/** +	 * Returns remaining time until the run time limit +	 * +	 * @return int	Remaining time until the run time limit in seconds +	 */ +	public function get_time_remaining() +	{ +		if ($this->system_data['max_execution_time'] <= 0) +		{ +			return 1; +		} + +		return ($this->system_data['start_time'] + $this->system_data['max_execution_time']) - time(); +	} + +	/** +	 * Returns remaining memory available for PHP +	 * +	 * @return int	Remaining memory until reaching the limit +	 */ +	public function get_memory_remaining() +	{ +		if ($this->system_data['memory_limit'] <= 0) +		{ +			return 1; +		} + +		if (function_exists('memory_get_usage')) +		{ +			return ($this->system_data['memory_limit'] - memory_get_usage()); +		} + +		// If we cannot get the information then just return a positive number (and cross fingers) +		return 1; +	} + +	/** +	 * Saves the latest executed task +	 * +	 * @param string	$task_service_name	Name of the installer task service +	 */ +	public function set_finished_task($task_service_name) +	{ +		$this->progress_data['last_task_name']	= $task_service_name; +	} + +	/** +	 * Set active module +	 * +	 * @param string	$module_service_name	Name of the installer module service +	 */ +	public function set_active_module($module_service_name) +	{ +		$this->progress_data['last_task_module_name']	= $module_service_name; +	} + +	/** +	 * Getter for progress data +	 * +	 * @return array +	 */ +	public function get_progress_data() +	{ +		return $this->progress_data; +	} + +	/** +	 * Recovers install configuration from file +	 */ +	public function load_config() +	{ +		if (!$this->filesystem->exists($this->install_config_file)) +		{ +			return; +		} + +		$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(); + +		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(); +		} +	} + +	/** +	 * Dumps install configuration to disk +	 */ +	public function save_config() +	{ +		if ($this->do_clean_up) +		{ +			@unlink($this->install_config_file); +			return; +		} + +		// Create array to save +		$save_array = array( +			'installer_config'	=> $this->installer_config, +			'progress_data'		=> $this->progress_data, +			'navigation_data'	=> $this->navigation_data, +		); + +		// Create file content +		$file_content = '<?php // '; +		$file_content .= json_encode($save_array); +		$file_content .= "\n"; + +		// Dump file_content to disk +		$fp = @fopen($this->install_config_file, 'w'); +		if (!$fp) +		{ +			throw new installer_config_not_writable_exception(); +		} + +		fwrite($fp, $file_content); +		fclose($fp); +	} + +	/** +	 * Increments the task progress +	 * +	 * @param int	$increment_by	The amount to increment by +	 */ +	public function increment_current_task_progress($increment_by = 1) +	{ +		$this->progress_data['current_task_progress'] += $increment_by; + +		if ($this->progress_data['current_task_progress'] > $this->progress_data['max_task_progress']) +		{ +			$this->progress_data['current_task_progress'] = $this->progress_data['max_task_progress']; +		} +	} + +	/** +	 * Sets the task progress to a specific number +	 * +	 * @param int	$task_progress	The task progress number to be set +	 */ +	public function set_current_task_progress($task_progress) +	{ +		$this->progress_data['current_task_progress'] = $task_progress; +	} + +	/** +	 * Sets the number of tasks belonging to the installer in the current mode. +	 * +	 * @param int	$task_progress_count	Number of tasks +	 */ +	public function set_task_progress_count($task_progress_count) +	{ +		$this->progress_data['max_task_progress'] = $task_progress_count; +	} + +	/** +	 * Returns the number of the current task being executed +	 * +	 * @return int +	 */ +	public function get_current_task_progress() +	{ +		return $this->progress_data['current_task_progress']; +	} + +	/** +	 * Returns the number of tasks belonging to the installer in the current mode. +	 * +	 * @return int +	 */ +	public function get_task_progress_count() +	{ +		return $this->progress_data['max_task_progress']; +	} + +	/** +	 * Marks stage as completed in the navigation bar +	 * +	 * @param array	$nav_path	Array to the navigation elem +	 */ +	public function set_finished_navigation_stage($nav_path) +	{ +		$this->navigation_data['finished'][] = $nav_path; +	} + +	/** +	 * Marks stage as active in the navigation bar +	 * +	 * @param array	$nav_path	Array to the navigation elem +	 */ +	public function set_active_navigation_stage($nav_path) +	{ +		$this->navigation_data['active'] = $nav_path; +	} + +	/** +	 * Returns navigation data +	 * +	 * @return array +	 */ +	public function get_navigation_data() +	{ +		return $this->navigation_data; +	} + +	/** +	 * Removes install config file +	 */ +	public function clean_up_config_file() +	{ +		$this->do_clean_up = true; +		@unlink($this->install_config_file); +	} + +	/** +	 * Filling up system_data array +	 */ +	protected function setup_system_data() +	{ +		// Query maximum runtime from php.ini +		$execution_time = $this->php_ini->getNumeric('max_execution_time'); +		$execution_time = min(15, $execution_time / 2); +		$this->system_data['max_execution_time'] = $execution_time; + +		// Set start time +		$this->system_data['start_time'] = time(); + +		// 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 new file mode 100644 index 0000000000..dc0eef6485 --- /dev/null +++ b/phpBB/phpbb/install/helper/container_factory.php @@ -0,0 +1,162 @@ +<?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; + +use phpbb\cache\driver\dummy; +use phpbb\install\exception\cannot_build_container_exception; + +class container_factory +{ +	/** +	 * @var string +	 */ +	protected $phpbb_root_path; + +	/** +	 * @var string +	 */ +	protected $php_ext; + +	/** +	 * @var \phpbb\request\request +	 */ +	protected $request; + +	/** +	 * The full phpBB container +	 * +	 * @var \Symfony\Component\DependencyInjection\ContainerInterface +	 */ +	protected $container; + +	/** +	 * Constructor +	 * +	 * @param \phpbb\request\request	$request			Request interface +	 * @param string					$phpbb_root_path	Path to phpBB's root +	 * @param string					$php_ext			Extension of PHP files +	 */ +	public function __construct(\phpbb\request\request $request, $phpbb_root_path, $php_ext) +	{ +		$this->request			= $request; +		$this->phpbb_root_path	= $phpbb_root_path; +		$this->php_ext			= $php_ext; +		$this->container		= null; +	} + +	/** +	 * Container getter +	 * +	 * @param null|string	$service_name	Name of the service to return +	 * +	 * @return \Symfony\Component\DependencyInjection\ContainerInterface|Object	phpBB's dependency injection container +	 * 																			or the service specified in $service_name +	 * +	 * @throws \phpbb\install\exception\cannot_build_container_exception							When container cannot be built +	 * @throws \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException			If the service is not defined +	 * @throws \Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException	When a circular reference is detected +	 * @throws \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException			When the service is not defined +	 */ +	public function get($service_name = null) +	{ +		// Check if container was built, if not try to build it +		if ($this->container === null) +		{ +			$this->build_container(); +		} + +		return ($service_name === null) ? $this->container : $this->container->get($service_name); +	} + +	/** +	 * Returns the specified parameter from the container +	 * +	 * @param string	$param_name +	 * +	 * @return mixed +	 * +	 * @throws \phpbb\install\exception\cannot_build_container_exception	When container cannot be built +	 */ +	public function get_parameter($param_name) +	{ +		// Check if container was built, if not try to build it +		if ($this->container === null) +		{ +			$this->build_container(); +		} + +		return $this->container->getParameter($param_name); +	} + +	/** +	 * Build dependency injection container +	 * +	 * @throws \phpbb\install\exception\cannot_build_container_exception	When container cannot be built +	 */ +	protected function build_container() +	{ +		// If the container has been already built just return. +		// Although this should never happen +		if ($this->container instanceof \Symfony\Component\DependencyInjection\ContainerInterface) +		{ +			return; +		} + +		// Check whether container can be built +		// We need config.php for that so let's check if it has been set up yet +		if (!filesize($this->phpbb_root_path . 'config.' . $this->php_ext)) +		{ +			throw new cannot_build_container_exception(); +		} + +		$phpbb_config_php_file = new \phpbb\config_php_file($this->phpbb_root_path, $this->php_ext); +		$phpbb_container_builder = new \phpbb\di\container_builder($this->phpbb_root_path, $this->php_ext); + +		// For BC with functions that we need during install +		global $phpbb_container; + +		$disable_super_globals = $this->request->super_globals_disabled(); + +		// This is needed because container_builder::get_env_parameters() uses $_SERVER +		if ($disable_super_globals) +		{ +			$this->request->enable_super_globals(); +		} + +		$this->container = $phpbb_container = $phpbb_container_builder +			->with_config($phpbb_config_php_file) +			->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); + +		// Replace cache service, as config gets cached, and we don't want that +		$this->container->register('cache.driver')->setSynthetic(true); +		$this->container->set('cache.driver', new dummy()); +		$this->container->compile(); + +		// Restore super globals to previous state +		if ($disable_super_globals) +		{ +			$this->request->disable_super_globals(); +		} + +		// Get compatibilty globals +		require ($this->phpbb_root_path . 'includes/compatibility_globals.' . $this->php_ext); +	} +} diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php new file mode 100644 index 0000000000..627e9ea9b0 --- /dev/null +++ b/phpBB/phpbb/install/helper/database.php @@ -0,0 +1,456 @@ +<?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; + +use phpbb\install\exception\invalid_dbms_exception; + +/** + * Database related general functionality for installer + */ +class database +{ +	/** +	 * @var \phpbb\filesystem\filesystem_interface +	 */ +	protected $filesystem; + +	/** +	 * @var string +	 */ +	protected $phpbb_root_path; + +	/** +	 * @var array +	 */ +	protected $supported_dbms = array( +		// Note: php 5.5 alpha 2 deprecated mysql. +		// Keep mysqli before mysql in this list. +		'mysqli'	=> array( +			'LABEL'			=> 'MySQL with MySQLi Extension', +			'SCHEMA'		=> 'mysql_41', +			'MODULE'		=> 'mysqli', +			'DELIM'			=> ';', +			'DRIVER'		=> 'phpbb\db\driver\mysqli', +			'AVAILABLE'		=> true, +			'2.0.x'			=> true, +		), +		'mysql'		=> array( +			'LABEL'			=> 'MySQL', +			'SCHEMA'		=> 'mysql', +			'MODULE'		=> 'mysql', +			'DELIM'			=> ';', +			'DRIVER'		=> 'phpbb\db\driver\mysql', +			'AVAILABLE'		=> true, +			'2.0.x'			=> true, +		), +		'mssql'		=> array( +			'LABEL'			=> 'MS SQL Server 2000+', +			'SCHEMA'		=> 'mssql', +			'MODULE'		=> 'mssql', +			'DELIM'			=> 'GO', +			'DRIVER'		=> 'phpbb\db\driver\mssql', +			'AVAILABLE'		=> true, +			'2.0.x'			=> true, +		), +		'mssql_odbc'=>	array( +			'LABEL'			=> 'MS SQL Server [ ODBC ]', +			'SCHEMA'		=> 'mssql', +			'MODULE'		=> 'odbc', +			'DELIM'			=> 'GO', +			'DRIVER'		=> 'phpbb\db\driver\mssql_odbc', +			'AVAILABLE'		=> true, +			'2.0.x'			=> true, +		), +		'mssqlnative'		=> array( +			'LABEL'			=> 'MS SQL Server 2005+ [ Native ]', +			'SCHEMA'		=> 'mssql', +			'MODULE'		=> 'sqlsrv', +			'DELIM'			=> 'GO', +			'DRIVER'		=> 'phpbb\db\driver\mssqlnative', +			'AVAILABLE'		=> true, +			'2.0.x'			=> false, +		), +		'oracle'	=>	array( +			'LABEL'			=> 'Oracle', +			'SCHEMA'		=> 'oracle', +			'MODULE'		=> 'oci8', +			'DELIM'			=> '/', +			'DRIVER'		=> 'phpbb\db\driver\oracle', +			'AVAILABLE'		=> true, +			'2.0.x'			=> false, +		), +		'postgres' => array( +			'LABEL'			=> 'PostgreSQL 8.3+', +			'SCHEMA'		=> 'postgres', +			'MODULE'		=> 'pgsql', +			'DELIM'			=> ';', +			'DRIVER'		=> 'phpbb\db\driver\postgres', +			'AVAILABLE'		=> true, +			'2.0.x'			=> true, +		), +		'sqlite'		=> array( +			'LABEL'			=> 'SQLite', +			'SCHEMA'		=> 'sqlite', +			'MODULE'		=> 'sqlite', +			'DELIM'			=> ';', +			'DRIVER'		=> 'phpbb\db\driver\sqlite', +			'AVAILABLE'		=> true, +			'2.0.x'			=> false, +		), +		'sqlite3'		=> array( +			'LABEL'			=> 'SQLite3', +			'SCHEMA'		=> 'sqlite', +			'MODULE'		=> 'sqlite3', +			'DELIM'			=> ';', +			'DRIVER'		=> 'phpbb\db\driver\sqlite3', +			'AVAILABLE'		=> true, +			'2.0.x'			=> false, +		), +	); + +	/** +	 * Constructor +	 * +	 * @param \phpbb\filesystem\filesystem_interface	$filesystem			Filesystem interface +	 * @param string									$phpbb_root_path	Path to phpBB's root +	 */ +	public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path) +	{ +		$this->filesystem		= $filesystem; +		$this->phpbb_root_path	= $phpbb_root_path; +	} + +	/** +	 * Returns an array of available DBMS supported by phpBB +	 * +	 * If a DBMS is specified it will only return data for that DBMS +	 * and will load its extension if necessary. +	 * +	 * @param	mixed	$dbms				name of the DBMS that's info is required or false for all DBMS info +	 * @param	bool	$return_unavailable	set it to true if you expect unavailable but supported DBMS +	 * 										returned as well +	 * @param	bool	$only_20x_options	set it to true if you only want to recover 2.0.x options +	 * +	 * @return	array	Array of available and supported DBMS +	 */ +	public function get_available_dbms($dbms = false, $return_unavailable = false, $only_20x_options = false) +	{ +		$available_dbms = $this->supported_dbms; + +		if ($dbms) +		{ +			if (isset($this->supported_dbms[$dbms])) +			{ +				$available_dbms = array($dbms => $this->supported_dbms[$dbms]); +			} +			else +			{ +				return array(); +			} +		} + +		$any_dbms_available = false; +		foreach ($available_dbms as $db_name => $db_array) +		{ +			if ($only_20x_options && !$db_array['2.0.x']) +			{ +				if ($return_unavailable) +				{ +					$available_dbms[$db_name]['AVAILABLE'] = false; +				} +				else +				{ +					unset($available_dbms[$db_name]); +				} + +				continue; +			} + +			$dll = $db_array['MODULE']; +			if (!@extension_loaded($dll)) +			{ +				if ($return_unavailable) +				{ +					$available_dbms[$db_name]['AVAILABLE'] = false; +				} +				else +				{ +					unset($available_dbms[$db_name]); +				} + +				continue; +			} + +			$any_dbms_available = true; +		} + +		if ($return_unavailable) +		{ +			$available_dbms['ANY_DB_SUPPORT'] = $any_dbms_available; +		} + +		return $available_dbms; +	} + +	/** +	 * Removes "/* style" as well as "# style" comments from $input. +	 * +	 * @param string $sql_query	Input string +	 * +	 * @return string Input string with comments removed +	 */ +	public function remove_comments($sql_query) +	{ +		// Remove /* */ comments (http://ostermiller.org/findcomment.html) +		$sql_query = preg_replace('#/\*(.|[\r\n])*?\*/#', "\n", $sql_query); + +		// Remove # style comments +		$sql_query = preg_replace('/\n{2,}/', "\n", preg_replace('/^#.*$/m', "\n", $sql_query)); + +		return $sql_query; +	} + +	/** +	 * split_sql_file() will split an uploaded sql file into single sql statements. +	 * +	 * Note: expects trim() to have already been run on $sql. +	 * +	 * @param	string	$sql		SQL statements +	 * @param	string	$delimiter	Delimiter between sql statements +	 * +	 * @return array Array of sql statements +	 */ +	public function split_sql_file($sql, $delimiter) +	{ +		$sql = str_replace("\r" , '', $sql); +		$data = preg_split('/' . preg_quote($delimiter, '/') . '$/m', $sql); + +		$data = array_map('trim', $data); + +		// The empty case +		$end_data = end($data); + +		if (empty($end_data)) +		{ +			unset($data[key($data)]); +		} + +		return $data; +	} + +	/** +	 * Validates table prefix +	 * +	 * @param string	$dbms			The selected dbms +	 * @param string	$table_prefix	The table prefix to validate +	 * +	 * @return bool|array	true if table prefix is valid, array of errors otherwise +	 * +	 * @throws \phpbb\install\exception\invalid_dbms_exception When $dbms is not a valid +	 */ +	public function validate_table_prefix($dbms, $table_prefix) +	{ +		$errors = array(); + +		if (!preg_match('#^[a-zA-Z][a-zA-Z0-9_]*$#', $table_prefix)) +		{ +			$errors[] = array( +				'title' => 'INST_ERR_DB_INVALID_PREFIX', +			); +		} + +		// Do dbms specific checks +		$dbms_info = $this->get_available_dbms($dbms); +		switch ($dbms_info[$dbms]['SCHEMA']) +		{ +			case 'mysql': +			case 'mysql_41': +				$prefix_length = 36; +			break; +			case 'mssql': +				$prefix_length = 90; +			break; +			case 'oracle': +				$prefix_length = 6; +			break; +			case 'postgres': +				$prefix_length = 36; +			break; +			case 'sqlite': +				$prefix_length = 200; +			break; +			default: +				throw new invalid_dbms_exception(); +			break; +		} + +		// Check the prefix length to ensure that index names are not too long +		if (strlen($table_prefix) > $prefix_length) +		{ +			$errors[] = array( +				'title' => array('INST_ERR_PREFIX_TOO_LONG', $prefix_length), +			); +		} + +		return (empty($errors)) ? true : $errors; +	} + +	/** +	 * Check if the user provided database parameters are correct +	 * +	 * This function checks the database connection data and also checks for +	 * any other problems that could cause an error during the installation +	 * such as if there is any database table names conflicting. +	 * +	 * Note: The function assumes that $table_prefix has been already validated +	 * with validate_table_prefix(). +	 * +	 * @param string	$dbms			Selected database type +	 * @param string	$dbhost			Database host address +	 * @param int		$dbport			Database port number +	 * @param string	$dbuser			Database username +	 * @param string	$dbpass			Database password +	 * @param string	$dbname			Database name +	 * @param string	$table_prefix	Database table prefix +	 * +	 * @return array|bool	Returns true if test is successful, array of errors otherwise +	 */ +	public function check_database_connection($dbms, $dbhost, $dbport, $dbuser, $dbpass, $dbname, $table_prefix) +	{ +		$dbms_info = $this->get_available_dbms($dbms); +		$dbms_info = $dbms_info[$dbms]; +		$errors = array(); + +		// Instantiate it and set return on error true +		/** @var \phpbb\db\driver\driver_interface $db */ +		$db = new $dbms_info['DRIVER']; +		$db->sql_return_on_error(true); + +		// Check that we actually have a database name before going any further +		if (!in_array($dbms_info['SCHEMA'], array('sqlite', 'oracle')) && $dbname === '') +		{ +			$errors[] = array( +				'title' => 'INST_ERR_DB_NO_NAME', +			); +		} + +		// Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea +		if ($dbms_info['SCHEMA'] === 'sqlite' +			&& stripos($this->filesystem->realpath($dbhost), $this->filesystem->realpath($this->phpbb_root_path) === 0)) +		{ +			$errors[] = array( +				'title' =>'INST_ERR_DB_FORUM_PATH', +			); +		} + +		// Try to connect to db +		if (is_array($db->sql_connect($dbhost, $dbuser, $dbpass, $dbname, $dbport, false, true))) +		{ +			$db_error = $db->sql_error(); +			$errors[] = array( +				'title' => 'INST_ERR_DB_CONNECT', +				'description' => ($db_error['message']) ? utf8_convert_message($db_error['message']) : 'INST_ERR_DB_NO_ERROR', +			); +		} +		else +		{ +			// Check if there is any table name collisions +			$temp_prefix = strtolower($table_prefix); +			$table_ary = array( +				$temp_prefix . 'attachments', +				$temp_prefix . 'config', +				$temp_prefix . 'sessions', +				$temp_prefix . 'topics', +				$temp_prefix . 'users', +			); + +			$db_tools_factory = new \phpbb\db\tools\factory(); +			$db_tools = $db_tools_factory->get($db); +			$tables = $db_tools->sql_list_tables(); +			$tables = array_map('strtolower', $tables); +			$table_intersect = array_intersect($tables, $table_ary); + +			if (sizeof($table_intersect)) +			{ +				$errors[] = array( +					'title' => 'INST_ERR_PREFIX', +				); +			} + +			// Check if database version is supported +			switch ($dbms) +			{ +				case 'mysqli': +					if (version_compare($db->sql_server_info(true), '4.1.3', '<')) +					{ +						$errors[] = array( +							'title' => 'INST_ERR_DB_NO_MYSQLI', +						); +					} +				break; +				case 'sqlite': +					if (version_compare($db->sql_server_info(true), '2.8.2', '<')) +					{ +						$errors[] = array( +							'title' => 'INST_ERR_DB_NO_SQLITE', +						); +					} +				break; +				case 'sqlite3': +					if (version_compare($db->sql_server_info(true), '3.6.15', '<')) +					{ +						$errors[] = array( +							'title' => 'INST_ERR_DB_NO_SQLITE3', +						); +					} +				break; +				case 'oracle': +					$sql = "SELECT * +						FROM NLS_DATABASE_PARAMETERS +						WHERE PARAMETER = 'NLS_RDBMS_VERSION' +							OR PARAMETER = 'NLS_CHARACTERSET'"; +					$result = $db->sql_query($sql); + +					while ($row = $db->sql_fetchrow($result)) +					{ +						$stats[$row['parameter']] = $row['value']; +					} +					$db->sql_freeresult($result); + +					if (version_compare($stats['NLS_RDBMS_VERSION'], '9.2', '<') && $stats['NLS_CHARACTERSET'] !== 'UTF8') +					{ +						$errors[] = array( +							'title' => 'INST_ERR_DB_NO_ORACLE', +						); +					} +				break; +				case 'postgres': +					$sql = "SHOW server_encoding;"; +					$result = $db->sql_query($sql); +					$row = $db->sql_fetchrow($result); +					$db->sql_freeresult($result); + +					if ($row['server_encoding'] !== 'UNICODE' && $row['server_encoding'] !== 'UTF8') +					{ +						$errors[] = array( +							'title' => 'INST_ERR_DB_NO_POSTGRES', +						); +					} +				break; +			} +		} + +		return (empty($errors)) ? true : $errors; +	} +} diff --git a/phpBB/phpbb/install/helper/install_helper.php b/phpBB/phpbb/install/helper/install_helper.php new file mode 100644 index 0000000000..ffe36cd645 --- /dev/null +++ b/phpBB/phpbb/install/helper/install_helper.php @@ -0,0 +1,60 @@ +<?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; + +/** + * General helper functionality for the installer + */ +class install_helper +{ +	/** +	 * @var string +	 */ +	protected $php_ext; + +	/** +	 * @var string +	 */ +	protected $phpbb_root_path; + +	/** +	 * Constructor +	 * +	 * @param string	$phpbb_root_path	path to phpBB's root +	 * @param string	$php_ext			Extension of PHP files +	 */ +	public function __construct($phpbb_root_path, $php_ext) +	{ +		$this->phpbb_root_path	= $phpbb_root_path; +		$this->php_ext			= $php_ext; +	} + +	/** +	 * Check whether phpBB is installed. +	 * +	 * @return bool +	 */ +	public function is_phpbb_installed() +	{ +		$config_path = $this->phpbb_root_path . 'config.' . $this->php_ext; +		$install_lock_path = $this->phpbb_root_path . 'cache/install_lock'; + +		if (file_exists($config_path) && !file_exists($install_lock_path) && filesize($config_path)) +		{ +			return true; +		} + +		return false; +	} +} diff --git a/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php new file mode 100644 index 0000000000..fa628f3365 --- /dev/null +++ b/phpBB/phpbb/install/helper/iohandler/ajax_iohandler.php @@ -0,0 +1,293 @@ +<?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\iohandler; + +/** + * Input-Output handler for the AJAX frontend + */ +class ajax_iohandler extends iohandler_base +{ +	/** +	 * @var \phpbb\request\request_interface +	 */ +	protected $request; + +	/** +	 * @var \phpbb\template\template +	 */ +	protected $template; + +	/** +	 * @var string +	 */ +	protected $form; + +	/** +	 * @var bool +	 */ +	protected $request_client_refresh; + +	/** +	 * @var array +	 */ +	protected $nav_data; + +	/** +	 * @var array +	 */ +	protected $cookies; + +	/** +	 * Constructor +	 * +	 * @param \phpbb\request\request_interface	$request	HTTP request interface +	 * @param \phpbb\template\template			$template	Template engine +	 */ +	public function __construct(\phpbb\request\request_interface $request, \phpbb\template\template $template) +	{ +		$this->request	= $request; +		$this->template	= $template; +		$this->form		= ''; +		$this->nav_data	= array(); +		$this->cookies	= array(); + +		parent::__construct(); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function get_input($name, $default, $multibyte = false) +	{ +		return $this->request->variable($name, $default, $multibyte); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function get_server_variable($name, $default = '') +	{ +		return $this->request->server($name, $default); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function get_header_variable($name, $default = '') +	{ +		return $this->request->header($name, $default); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function is_secure() +	{ +		return $this->request->is_secure(); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function add_user_form_group($title, $form) +	{ +		$this->template->assign_var('S_FORM_ELEM_COUNT', sizeof($form)); + +		$this->template->assign_block_vars('options', array( +			'LEGEND'	=> $this->language->lang($title), +			'S_LEGEND'	=> true, +		)); + +		foreach ($form as $input_name => $input_options) +		{ +			if (!isset($input_options['type'])) +			{ +				continue; +			} + +			$tpl_ary = array(); + +			$tpl_ary['TYPE'] = $input_options['type']; +			$tpl_ary['TITLE'] = $this->language->lang($input_options['label']); +			$tpl_ary['KEY'] = $input_name; +			$tpl_ary['S_EXPLAIN'] = false; + +			if (isset($input_options['default'])) +			{ +				$default = $input_options['default']; +				$default = preg_replace_callback('#\{L_([A-Z0-9\-_]*)\}#s', array($this, 'lang_replace_callback'), $default); +				$tpl_ary['DEFAULT'] = $default; +			} + +			if (isset($input_options['description'])) +			{ +				$tpl_ary['TITLE_EXPLAIN'] = $this->language->lang($input_options['description']); +				$tpl_ary['S_EXPLAIN'] = true; +			} + +			if (in_array($input_options['type'], array('select', 'radio'))) +			{ +				for ($i = 0, $total = sizeof($input_options['options']); $i < $total; $i++) +				{ +					if (isset($input_options['options'][$i]['label'])) +					{ +						$input_options['options'][$i]['label'] = $this->language->lang($input_options['options'][$i]['label']); +					} +				} + +				$tpl_ary['OPTIONS'] = $input_options['options']; +			} + +			$this->template->assign_block_vars('options', $tpl_ary); +		} + +		$this->template->set_filenames(array( +			'form_install' => 'installer_form.html', +		)); + +		$this->form = $this->template->assign_display('form_install'); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function send_response() +	{ +		$json_data_array = $this->prepare_json_array(); +		$json_data = json_encode($json_data_array); + +		// Try to push content to the browser +		print(str_pad(' ', 4096) . "\n"); +		print($json_data . "\n\n"); +		flush(); +	} + +	/** +	 * Prepares iohandler's data to be sent out to the client. +	 * +	 * @return array +	 */ +	protected function prepare_json_array() +	{ +		$json_array = array( +			'errors' => $this->errors, +			'warnings' => $this->warnings, +			'logs' => $this->logs, +			'success' => $this->success, +		); + +		if (!empty($this->form)) +		{ +			$json_array['form'] = $this->form; +			$this->form = ''; +		} + +		// If current task name is set, we push progress message to the client side +		if (!empty($this->current_task_name)) +		{ +			$json_array['progress'] = array( +				'task_name'		=> $this->current_task_name, +				'task_num'		=> $this->current_task_progress, +				'task_count'	=> $this->task_progress_count, +			); +		} + +		if (!empty($this->nav_data)) +		{ +			$json_array['nav'] = $this->nav_data; +		} + +		$this->errors = array(); +		$this->warnings = array(); +		$this->logs = array(); +		$this->success = array(); +		$this->nav_data = array(); + +		if ($this->request_client_refresh) +		{ +			$json_array['refresh'] = true; +			$this->request_client_refresh = false; +		} + +		if (!empty($this->cookies)) +		{ +			$json_array['cookies'] = $this->cookies; +			$this->cookies = array(); +		} + +		return $json_array; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function set_progress($task_lang_key, $task_number) +	{ +		parent::set_progress($task_lang_key, $task_number); +		$this->send_response(); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function request_refresh() +	{ +		$this->request_client_refresh = true; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function set_active_stage_menu($menu_path) +	{ +		$this->nav_data['active'] = $menu_path[sizeof($menu_path) - 1]; +		$this->send_response(); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function set_finished_stage_menu($menu_path) +	{ +		$this->nav_data['finished'][] = $menu_path[sizeof($menu_path) - 1]; +		$this->send_response(); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function set_cookie($cookie_name, $cookie_value) +	{ +		$this->cookies[] = array( +			'name' => $cookie_name, +			'value' => $cookie_value +		); +	} + +	/** +	 * Callback function for language replacing +	 * +	 * @param array	$matches +	 * @return string +	 */ +	public function lang_replace_callback($matches) +	{ +		if (!empty($matches[1])) +		{ +			return $this->language->lang($matches[1]); +		} + +		return ''; +	} +} diff --git a/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php new file mode 100644 index 0000000000..c5b2bb06bc --- /dev/null +++ b/phpBB/phpbb/install/helper/iohandler/cli_iohandler.php @@ -0,0 +1,265 @@ +<?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\iohandler; + +use phpbb\install\exception\installer_exception; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\OutputStyle; + +/** + * Input-Output handler for the CLI frontend + */ +class cli_iohandler extends iohandler_base +{ +	/** +	 * @var OutputInterface +	 */ +	protected $output; + +	/** +	 * @var OutputStyle +	 */ +	protected $io; + +	/** +	 * @var array +	 */ +	protected $input_values = array(); + +	/** +	 * @var \Symfony\Component\Console\Helper\ProgressBar +	 */ +	protected $progress_bar; + +	/** +	 * Set the style and output used to display feedback; +	 * +	 * @param OutputStyle 		$style +	 * @param OutputInterface	$output +	 */ +	public function set_style(OutputStyle $style, OutputInterface $output) +	{ +		$this->io = $style; +		$this->output = $output; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function get_input($name, $default, $multibyte = false) +	{ +		$result = $default; + +		if (isset($this->input_values[$name])) +		{ +			$result = $this->input_values[$name]; +		} + +		if ($multibyte) +		{ +			return utf8_normalize_nfc($result); +		} + +		return $result; +	} + +	public function set_input($name, $value) +	{ +		$this->input_values[$name] = $value; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function get_server_variable($name, $default = '') +	{ +		return $default; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function get_header_variable($name, $default = '') +	{ +		return $default; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function is_secure() +	{ +		return false; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function add_user_form_group($title, $form) +	{ +		throw new installer_exception('MISSING_DATA'); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function send_response() +	{ +	} + +	/** +	 * {@inheritdoc +	 */ +	public function add_error_message($error_title, $error_description = false) +	{ +		$this->io->newLine(); + +		$message = $this->translate_message($error_title, $error_description); +		$this->io->error($message['title'] . "\n" . $message['description']); + +		if ($this->progress_bar !== null) +		{ +			$this->io->newLine(2); +			$this->progress_bar->display(); +		} +	} + +	/** +	 * {@inheritdoc +	 */ +	public function add_warning_message($warning_title, $warning_description = false) +	{ +		$this->io->newLine(); + +		$message = $this->translate_message($warning_title, $warning_description); +		$this->io->warning($message['title'] . "\n" . $message['description']); + +		if ($this->progress_bar !== null) +		{ +			$this->io->newLine(2); +			$this->progress_bar->display(); +		} +	} + +	/** +	 * {@inheritdoc +	 */ +	public function add_log_message($log_title, $log_description = false) +	{ +		if ($this->output->getVerbosity() > OutputInterface::VERBOSITY_NORMAL) +		{ +			$message = $this->translate_message($log_title, $log_description); +			$this->output->writeln(sprintf('[%3d/%-3d] ---- %s', $this->current_task_progress, $this->task_progress_count, $message['title'])); +		} +	} + +	/** +	 * {@inheritdoc +	 */ +	public function add_success_message($error_title, $error_description = false) +	{ +		$this->io->newLine(); + +		$message = $this->translate_message($error_title, $error_description); +		$this->io->success($message['title'] . "\n" . $message['description']); + +		if ($this->progress_bar !== null) +		{ +			$this->io->newLine(2); +			$this->progress_bar->display(); +		} +	} + +	public function set_task_count($task_count) +	{ +		parent::set_task_count($task_count); + +		if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_NORMAL) +		{ +			$this->progress_bar = $this->io->createProgressBar($task_count); +			$this->progress_bar->setFormat( +				"    %current:3s%/%max:-3s% %bar%  %percent:3s%%\n" . +				"             %message%\n"); +			$this->progress_bar->setBarWidth(60); + +			if (!defined('PHP_WINDOWS_VERSION_BUILD')) +			{ +				$this->progress_bar->setEmptyBarCharacter('░'); // light shade character \u2591 +				$this->progress_bar->setProgressCharacter(''); +				$this->progress_bar->setBarCharacter('▓'); // dark shade character \u2593 +			} + +			$this->progress_bar->setMessage(''); +			$this->io->newLine(2); +			$this->progress_bar->start(); +		} +	} + +	public function set_progress($task_lang_key, $task_number) +	{ +		parent::set_progress($task_lang_key, $task_number); + +		if ($this->progress_bar !== null) +		{ +			$this->progress_bar->setProgress($this->current_task_progress); +			$this->progress_bar->setMessage($this->current_task_name); +		} +		else +		{ +			$this->output->writeln(sprintf('[%3d/%-3d] %s', $this->current_task_progress, $this->task_progress_count, $this->current_task_name)); +		} +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function finish_progress($message_lang_key) +	{ +		parent::finish_progress($message_lang_key); + +		if ($this->progress_bar !== null) +		{ +			$this->progress_bar->finish(); +			$this->progress_bar = null; +		} +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function request_refresh() +	{ +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function set_active_stage_menu($menu_path) +	{ +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function set_finished_stage_menu($menu_path) +	{ +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function set_cookie($cookie_name, $cookie_value) +	{ +	} +} diff --git a/phpBB/phpbb/install/helper/iohandler/exception/iohandler_not_implemented_exception.php b/phpBB/phpbb/install/helper/iohandler/exception/iohandler_not_implemented_exception.php new file mode 100644 index 0000000000..f2ddeda6f7 --- /dev/null +++ b/phpBB/phpbb/install/helper/iohandler/exception/iohandler_not_implemented_exception.php @@ -0,0 +1,19 @@ +<?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\iohandler\exception; + +class iohandler_not_implemented_exception extends \Exception +{ + +} diff --git a/phpBB/phpbb/install/helper/iohandler/factory.php b/phpBB/phpbb/install/helper/iohandler/factory.php new file mode 100644 index 0000000000..52d24e49b2 --- /dev/null +++ b/phpBB/phpbb/install/helper/iohandler/factory.php @@ -0,0 +1,81 @@ +<?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\iohandler; + +use phpbb\install\helper\iohandler\exception\iohandler_not_implemented_exception; + +/** + * Input-output handler factory + */ +class factory +{ +	/** +	 * @var \Symfony\Component\DependencyInjection\ContainerInterface +	 */ +	protected $container; + +	/** +	 * @var string +	 */ +	protected $environment; + +	/** +	 * Constructor +	 * +	 * @param \Symfony\Component\DependencyInjection\ContainerInterface $container Dependency injection container +	 */ +	public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container) +	{ +		$this->container	= $container; +		$this->environment	= null; +	} + +	/** +	 * @param string	$environment	The name of the input-output handler to use +	 */ +	public function set_environment($environment) +	{ +		$this->environment = $environment; +	} + +	/** +	 * Factory getter for iohandler +	 * +	 * @return \phpbb\install\helper\iohandler\iohandler_interface +	 * +	 * @throws \phpbb\install\helper\iohandler\exception\iohandler_not_implemented_exception +	 * 		When the specified iohandler_interface does not exists +	 */ +	public function get() +	{ +		switch ($this->environment) +		{ +			case 'ajax': +				return $this->container->get('installer.helper.iohandler_ajax'); +			break; +			case 'nojs': +				// @todo replace this +				return $this->container->get('installer.helper.iohandler_ajax'); +			break; +			case 'cli': +				return $this->container->get('installer.helper.iohandler_cli'); +			break; +			default: +				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 new file mode 100644 index 0000000000..006411f1e3 --- /dev/null +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_base.php @@ -0,0 +1,190 @@ +<?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\iohandler; + +/** + * Base class for installer input-output handlers + */ +abstract class iohandler_base implements iohandler_interface +{ +	/** +	 * Array of errors +	 * +	 * Errors should be added, when the installation cannot continue without +	 * user interaction. If the aim is to notify the user about something, please +	 * use a warning instead. +	 * +	 * @var array +	 */ +	protected $errors; + +	/** +	 * Array of warnings +	 * +	 * @var array +	 */ +	protected $warnings; + +	/** +	 * Array of logs +	 * +	 * @var array +	 */ +	protected $logs; + +	/** +	 * Array of success messages +	 * +	 * @var array +	 */ +	protected $success; + +	/** +	 * @var \phpbb\language\language +	 */ +	protected $language; + +	/** +	 * @var int +	 */ +	protected $task_progress_count; + +	/** +	 * @var int +	 */ +	protected $current_task_progress; + +	/** +	 * @var string +	 */ +	protected $current_task_name; + +	/** +	 * Constructor +	 */ +	public function __construct() +	{ +		$this->errors	= array(); +		$this->warnings	= array(); +		$this->logs		= array(); +		$this->success	= array(); + +		$this->task_progress_count		= 0; +		$this->current_task_progress	= 0; +		$this->current_task_name		= ''; +	} + +	/** +	 * Set language service +	 * +	 * @param \phpbb\language\language $language +	 */ +	public function set_language(\phpbb\language\language $language) +	{ +		$this->language = $language; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function add_error_message($error_title, $error_description = false) +	{ +		$this->errors[] = $this->translate_message($error_title, $error_description); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function add_warning_message($warning_title, $warning_description = false) +	{ +		$this->warnings[] = $this->translate_message($warning_title, $warning_description); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function add_log_message($log_title, $log_description = false) +	{ +		$this->logs[] = $this->translate_message($log_title, $log_description); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function add_success_message($success_title, $success_description = false) +	{ +		$this->success[] = $this->translate_message($success_title, $success_description); +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function set_task_count($task_count) +	{ +		$this->task_progress_count = $task_count; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function set_progress($task_lang_key, $task_number) +	{ +		$this->current_task_name = ''; + +		if (!empty($task_lang_key)) +		{ +			$this->current_task_name = $this->language->lang($task_lang_key); +		} + +		$this->current_task_progress = $task_number; +	} + +	/** +	 * {@inheritdoc} +	 */ +	public function finish_progress($message_lang_key) +	{ +		if (!empty($message_lang_key)) +		{ +			$this->current_task_name = $this->language->lang($message_lang_key); +		} + +		$this->current_task_progress = $this->task_progress_count; +	} + +	/** +	 * Localize message. +	 * +	 * Note: When an array is passed into the parameters below, it will be +	 * resolved as printf($param[0], $param[1], ...). +	 * +	 * @param array|string		$title			Title of the message +	 * @param array|string|bool	$description	Description of the message +	 * +	 * @return array	Localized message in an array +	 */ +	protected function translate_message($title, $description) +	{ +		$message_array = array(); + +		$message_array['title'] = call_user_func_array(array($this->language, 'lang'), (array) $title); + +		if ($description !== false) +		{ +			$message_array['description'] = call_user_func_array(array($this->language, 'lang'), (array) $description); +		} + +		return $message_array; +	} +} diff --git a/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php new file mode 100644 index 0000000000..5f5f8499d6 --- /dev/null +++ b/phpBB/phpbb/install/helper/iohandler/iohandler_interface.php @@ -0,0 +1,174 @@ +<?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\iohandler; + +/** + * Input-Output handler interface for the installer + */ +interface iohandler_interface +{ +	/** +	 * Renders or returns response message +	 */ +	public function send_response(); + +	/** +	 * Returns input variable +	 * +	 * @param string	$name		Name of the input variable to obtain +	 * @param mixed		$default	A default value that is returned if the variable was not set. +	 * 								This function will always return a value of the same type as the default. +	 * @param bool		$multibyte	If $default is a string this paramater has to be true if the variable may contain any UTF-8 characters +	 *								Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks +	 * +	 * @return mixed	Value of the input variable +	 */ +	public function get_input($name, $default, $multibyte = false); + +	/** +	 * Returns server variable +	 * +	 * This function should work the same as request_interterface::server(). +	 * +	 * @param string	$name		Name of the server variable +	 * @param mixed		$default	Default value to return when the requested variable does not exist +	 * +	 * @return mixed	Value of the server variable +	 */ +	public function get_server_variable($name, $default = ''); + +	/** +	 * Wrapper function for request_interterface::header() +	 * +	 * @param string	$name		Name of the request header variable +	 * @param mixed		$default	Default value to return when the requested variable does not exist +	 * +	 * @return mixed +	 */ +	public function get_header_variable($name, $default = ''); + +	/** +	 * Returns true if the connection is encrypted +	 * +	 * @return bool +	 */ +	public function is_secure(); + +	/** +	 * Adds an error message to the rendering queue +	 * +	 * Note: When an array is passed into the parameters below, it will be +	 * resolved as printf($param[0], $param[1], ...). +	 * +	 * @param string|array		$error_title		Title of the error message. +	 * @param string|bool|array	$error_description	Description of the error (and possibly guidelines to resolve it), +	 * 												or false if the error description is not available. +	 */ +	public function add_error_message($error_title, $error_description = false); + +	/** +	 * Adds a warning message to the rendering queue +	 * +	 * Note: When an array is passed into the parameters below, it will be +	 * resolved as printf($param[0], $param[1], ...). +	 * +	 * @param string|array		$warning_title			Title of the warning message +	 * @param string|bool|array	$warning_description	Description of the warning (and possibly guidelines to resolve it), +	 * 													or false if the warning description is not available +	 */ +	public function add_warning_message($warning_title, $warning_description = false); + +	/** +	 * Adds a log message to the rendering queue +	 * +	 * Note: When an array is passed into the parameters below, it will be +	 * resolved as printf($param[0], $param[1], ...). +	 * +	 * @param string|array		$log_title			Title of the log message +	 * @param string|bool|array	$log_description	Description of the log, +	 * 												or false if the log description is not available +	 */ +	public function add_log_message($log_title, $log_description = false); + +	/** +	 * Adds a success message to the rendering queue +	 * +	 * Note: When an array is passed into the parameters below, it will be +	 * resolved as printf($param[0], $param[1], ...). +	 * +	 * @param string|array		$success_title			Title of the success message +	 * @param string|bool|array	$success_description	Description of the success, +	 * 													or false if the success description is not available +	 * +	 * @return null +	 */ +	public function add_success_message($success_title, $success_description = false); + +	/** +	 * Adds a requested data group to the rendering queue +	 * +	 * @param string	$title	Language variable with the title of the form +	 * @param array		$form	An array describing the required data (options etc) +	 */ +	public function add_user_form_group($title, $form); + +	/** +	 * Sets the number of tasks belonging to the installer in the current mode. +	 * +	 * @param int	$task_count	Number of tasks +	 */ +	public function set_task_count($task_count); + +	/** +	 * Sets the progress information +	 * +	 * @param string	$task_lang_key	Language key for the name of the task +	 * @param int		$task_number	Position of the current task in the task queue +	 */ +	public function set_progress($task_lang_key, $task_number); + +	/** +	 * Sends refresh request to the client +	 */ +	public function request_refresh(); + +	/** +	 * Marks stage as active in the navigation bar +	 * +	 * @param array	$menu_path	Array to the navigation elem +	 */ +	public function set_active_stage_menu($menu_path); + +	/** +	 * Marks stage as completed in the navigation bar +	 * +	 * @param array	$menu_path	Array to the navigation elem +	 */ +	public function set_finished_stage_menu($menu_path); + +	/** +	 * Finish the progress bar +	 * +	 * @param string	$message_lang_key	Language key for the message +	 */ +	public function finish_progress($message_lang_key); + +	/** +	 * Sends and sets cookies +	 * +	 * @param string	$cookie_name	Name of the cookie to set +	 * @param string	$cookie_value	Value of the cookie to set +	 */ +	public function set_cookie($cookie_name, $cookie_value); +} diff --git a/phpBB/phpbb/install/helper/navigation/install_navigation.php b/phpBB/phpbb/install/helper/navigation/install_navigation.php new file mode 100644 index 0000000000..f690f8de76 --- /dev/null +++ b/phpBB/phpbb/install/helper/navigation/install_navigation.php @@ -0,0 +1,75 @@ +<?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 install_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( +			'install'	=> array( +				'label'	=> 'INSTALL', +				'route'	=> 'phpbb_installer_install', +				'order'	=> 1, +				array( +					'introduction'	=> array( +						'label'	=> 'INTRODUCTION_TITLE', +						'stage'	=> true, +						'order'	=> 0, +					), +					'requirements'	=> array( +						'label'	=> 'STAGE_REQUIREMENTS', +						'stage'	=> true, +						'order'	=> 1, +					), +					'obtain_data'	=> array( +						'label'	=> 'STAGE_OBTAIN_DATA', +						'stage'	=> true, +						'order'	=> 2, +					), +					'install'	=> array( +						'label'	=> 'STAGE_INSTALL', +						'stage'	=> true, +						'order'	=> 3, +					), +				), +			), +		); +	} +} diff --git a/phpBB/phpbb/install/helper/navigation/main_navigation.php b/phpBB/phpbb/install/helper/navigation/main_navigation.php new file mode 100644 index 0000000000..214bb04963 --- /dev/null +++ b/phpBB/phpbb/install/helper/navigation/main_navigation.php @@ -0,0 +1,48 @@ +<?php +/** + * + * This file is part of the phpBB Forum Software package. + * + * @copyright (c) phpBB Limited <https://www.phpbb.com> + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +namespace phpbb\install\helper\navigation; + +class main_navigation implements navigation_interface +{ +	/** +	 * {@inheritdoc} +	 */ +	public function get() +	{ +		return array( +			'overview'	=> array( +				'label'	=> 'MENU_OVERVIEW', +				'route'	=> 'phpbb_installer_index', +				'order'	=> 0, +				array( +					'introduction'	=> array( +						'label'	=> 'MENU_INTRO', +						'route'	=> 'phpbb_installer_index', +						'order'	=> 0, +					), +					'support'	=> array( +						'label'	=> 'MENU_SUPPORT', +						'route'	=> 'phpbb_installer_support', +						'order'	=> 1, +					), +					'license'	=> array( +						'label'	=> 'MENU_LICENSE', +						'route'	=> 'phpbb_installer_license', +						'order'	=> 2, +					), +				), +			), +		); +	} +} diff --git a/phpBB/phpbb/install/helper/navigation/navigation_interface.php b/phpBB/phpbb/install/helper/navigation/navigation_interface.php new file mode 100644 index 0000000000..eebdbe923f --- /dev/null +++ b/phpBB/phpbb/install/helper/navigation/navigation_interface.php @@ -0,0 +1,43 @@ +<?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; + +/** + * Interface for installer's navigation defining services + */ +interface navigation_interface +{ +	/** +	 * Returns an array with the navigation items +	 * +	 * The returned array should have the following format: +	 * <code> +	 * array( +	 * 	'parent_nav_name' => array( +	 * 		'nav_name' => array( +	 * 			'label' => 'MY_MENU', +	 * 			'route' => 'phpbb_route_name', +	 * 		) +	 * 	) +	 * ) +	 * </code> +	 * +	 * Navigation item setting options: +	 * 	- label: The language variable name +	 * 	- route: Name of the route which it is belongs to +	 * +	 * @return array +	 */ +	public function get(); +} diff --git a/phpBB/phpbb/install/helper/navigation/navigation_provider.php b/phpBB/phpbb/install/helper/navigation/navigation_provider.php new file mode 100644 index 0000000000..d52aec8999 --- /dev/null +++ b/phpBB/phpbb/install/helper/navigation/navigation_provider.php @@ -0,0 +1,121 @@ +<?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\di\service_collection; + +/** + * Installers navigation provider + */ +class navigation_provider +{ +	/** +	 * @var array +	 */ +	private $menu_collection; + +	/** +	 * Constructor +	 * +	 * @param service_collection		$plugins +	 */ +	public function __construct(service_collection $plugins) +	{ +		$this->menu_collection	= array(); + +		foreach ($plugins as $plugin => $plugin_instance) +		{ +			$this->register($plugin_instance); +		} +	} + +	/** +	 * Returns navigation array +	 * +	 * @return array +	 */ +	public function get() +	{ +		return $this->menu_collection; +	} + +	/** +	 * Registers a navigation provider's navigation items +	 * +	 * @param navigation_interface	$navigation +	 */ +	public function register(navigation_interface $navigation) +	{ +		$nav_arry = $navigation->get(); +		$this->menu_collection = $this->merge($nav_arry, $this->menu_collection); +	} + +	/** +	 * Set a property in the navigation array +	 * +	 * @param array	$nav_element	Array to the navigation elem +	 * @param array	$property_array	Array with the properties to set +	 */ +	public function set_nav_property($nav_element, $property_array) +	{ +		$array_pointer = array(); +		$array_root_pointer = &$array_pointer; +		foreach ($nav_element as $array_path) +		{ +			$array_pointer[$array_path] = array(); +			$array_pointer = &$array_pointer[$array_path]; +		} + +		$array_pointer = $property_array; + +		$this->menu_collection = $this->merge($array_root_pointer, $this->menu_collection); +	} + +	/** +	 * Recursive array merge +	 * +	 * This function is necessary to be able to replace the options of +	 * already set navigation items. +	 * +	 * @param array	$array_to_merge +	 * @param array	$array_to_merge_into +	 * +	 * @return array	Merged array +	 */ +	private function merge($array_to_merge, $array_to_merge_into) +	{ +		$merged_array = $array_to_merge_into; + +		foreach ($array_to_merge as $key => $value) +		{ +			if (isset($array_to_merge_into[$key])) +			{ +				if (is_array($array_to_merge_into[$key]) && is_array($value)) +				{ +					$merged_array[$key] = $this->merge($value, $array_to_merge_into[$key]); +				} +				else +				{ +					$merged_array[$key] = $value; +				} +			} +			else +			{ +				$merged_array[$key] = $value; +			} +		} + +		return $merged_array; +	} +} | 
