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