/**
  * Open file for logging
  *
  * @param string $file File to open
  */
 protected function file_open($file)
 {
     if ($this->filesystem->is_writable(dirname($file))) {
         $this->file_handle = fopen($file, 'w');
     } else {
         throw new \RuntimeException('Unable to write to migrator log file');
     }
 }
Exemplo n.º 2
0
 /**
  * {@inheritdoc}
  */
 public function locate_resources()
 {
     if ($this->filesystem->exists($this->phpbb_root_path . 'install/update/new/config')) {
         $resources = array(array('install/update/new/config/' . $this->environment . '/routing/environment.yml', 'yaml'));
     } else {
         $resources = array(array('config/' . $this->environment . '/routing/environment.yml', 'yaml'));
     }
     return $resources;
 }
Exemplo n.º 3
0
 public function __construct(filesystem_interface $filesystem, $paths = [])
 {
     $paths = (array) $paths;
     $absolute_paths = [];
     foreach ($paths as $path) {
         $absolute_paths[] = $filesystem->realpath($path);
     }
     parent::__construct($absolute_paths);
 }
Exemplo n.º 4
0
 /**
  * Test Settings
  */
 function test_upload(&$error, $upload_dir, $create_directory = false)
 {
     global $user, $phpbb_root_path;
     // Does the target directory exist, is it a directory and writable.
     if ($create_directory) {
         if (!file_exists($phpbb_root_path . $upload_dir)) {
             @mkdir($phpbb_root_path . $upload_dir, 0777);
             try {
                 $this->filesystem->phpbb_chmod($phpbb_root_path . $upload_dir, CHMOD_READ | CHMOD_WRITE);
             } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
                 // Do nothing
             }
         }
     }
     if (!file_exists($phpbb_root_path . $upload_dir)) {
         $error[] = sprintf($user->lang['NO_UPLOAD_DIR'], $upload_dir);
         return;
     }
     if (!is_dir($phpbb_root_path . $upload_dir)) {
         $error[] = sprintf($user->lang['UPLOAD_NOT_DIR'], $upload_dir);
         return;
     }
     if (!$this->filesystem->is_writable($phpbb_root_path . $upload_dir)) {
         $error[] = sprintf($user->lang['NO_WRITE_UPLOAD'], $upload_dir);
         return;
     }
 }
Exemplo n.º 5
0
 /**
  * Check if the avatar directory is writable and disable avatars
  * if it isn't writable.
  */
 function disable_avatars_if_unwritable()
 {
     global $config, $phpbb_root_path;
     if (!$this->filesystem->is_writable($phpbb_root_path . 'images/avatars/upload/')) {
         $config->set('allow_avatar', 0);
         $config->set('allow_avatar_upload', 0);
     }
 }
Exemplo n.º 6
0
 /**
  * Find a list of controllers
  *
  * @param string $base_path Base path to prepend to file paths
  * @return router
  */
 public function find($base_path = '')
 {
     if ($this->route_collection === null || $this->route_collection->count() === 0) {
         $this->route_collection = new RouteCollection();
         foreach ($this->routing_files as $file_path) {
             $loader = new YamlFileLoader(new FileLocator($this->filesystem->realpath($base_path)));
             $this->route_collection->addCollection($loader->load($file_path));
         }
     }
     return $this;
 }
Exemplo n.º 7
0
 /**
  * {@inheritdoc}
  */
 public function run()
 {
     $this->db->sql_return_on_error(true);
     $server_name = $this->install_config->get('server_name');
     $current_time = time();
     $user_ip = phpbb_ip_normalise($this->iohandler->get_server_variable('REMOTE_ADDR'));
     $user_ip = $user_ip === false ? '' : $user_ip;
     $referer = $this->iohandler->get_server_variable('REFERER');
     // Calculate cookie domain
     $cookie_domain = $server_name;
     if (strpos($cookie_domain, 'www.') === 0) {
         $cookie_domain = substr($cookie_domain, 3);
     }
     // Set default config and post data, this applies to all DB's
     $sql_ary = array('INSERT INTO ' . $this->config_table . " (config_name, config_value)\n\t\t\t\tVALUES ('board_startdate', '{$current_time}')", 'INSERT INTO ' . $this->config_table . " (config_name, config_value)\n\t\t\t\tVALUES ('default_lang', '" . $this->db->sql_escape($this->install_config->get('default_lang')) . "')", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('img_imagick')) . "'\n\t\t\t\tWHERE config_name = 'img_imagick'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('server_name')) . "'\n\t\t\t\tWHERE config_name = 'server_name'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('server_port')) . "'\n\t\t\t\tWHERE config_name = 'server_port'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('board_email')) . "'\n\t\t\t\tWHERE config_name = 'board_email'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('board_email')) . "'\n\t\t\t\tWHERE config_name = 'board_contact'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($cookie_domain) . "'\n\t\t\t\tWHERE config_name = 'cookie_domain'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->language->lang('default_dateformat')) . "'\n\t\t\t\tWHERE config_name = 'default_dateformat'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('email_enable')) . "'\n\t\t\t\tWHERE config_name = 'email_enable'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_delivery')) . "'\n\t\t\t\tWHERE config_name = 'smtp_delivery'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_host')) . "'\n\t\t\t\tWHERE config_name = 'smtp_host'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_port')) . "'\n\t\t\t\tWHERE config_name = 'smtp_port'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_auth')) . "'\n\t\t\t\tWHERE config_name = 'smtp_auth_method'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_user')) . "'\n\t\t\t\tWHERE config_name = 'smtp_username'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_pass')) . "'\n\t\t\t\tWHERE config_name = 'smtp_password'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('cookie_secure')) . "'\n\t\t\t\tWHERE config_name = 'cookie_secure'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('force_server_vars')) . "'\n\t\t\t\tWHERE config_name = 'force_server_vars'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('script_path')) . "'\n\t\t\t\tWHERE config_name = 'script_path'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('server_protocol')) . "'\n\t\t\t\tWHERE config_name = 'server_protocol'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "'\n\t\t\t\tWHERE config_name = 'newest_username'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . md5(mt_rand()) . "'\n\t\t\t\tWHERE config_name = 'avatar_salt'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . md5(mt_rand()) . "'\n\t\t\t\tWHERE config_name = 'plupload_salt'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('board_name')) . "'\n\t\t\t\tWHERE config_name = 'sitename'", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->install_config->get('board_description')) . "'\n\t\t\t\tWHERE config_name = 'site_desc'", 'UPDATE ' . $this->user_table . "\n\t\t\t\tSET username = '******'admin_name')) . "',\n\t\t\t\t\tuser_password='******'admin_passwd')) . "',\n\t\t\t\t\tuser_ip = '" . $this->db->sql_escape($user_ip) . "',\n\t\t\t\t\tuser_lang = '" . $this->db->sql_escape($this->install_config->get('user_language', 'en')) . "',\n\t\t\t\t\tuser_email='" . $this->db->sql_escape($this->install_config->get('board_email')) . "',\n\t\t\t\t\tuser_dateformat='" . $this->db->sql_escape($this->language->lang('default_dateformat')) . "',\n\t\t\t\t\tuser_email_hash = " . $this->db->sql_escape(phpbb_email_hash($this->install_config->get('board_email'))) . ",\n\t\t\t\t\tusername_clean = '" . $this->db->sql_escape(utf8_clean_string($this->install_config->get('admin_name'))) . "'\n\t\t\t\tWHERE username = '******'", 'UPDATE ' . $this->moderator_cache_table . "\n\t\t\t\tSET username = '******'admin_name')) . "'\n\t\t\t\tWHERE username = '******'", 'UPDATE ' . $this->forums_table . "\n\t\t\t\tSET forum_last_poster_name = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "'\n\t\t\t\tWHERE forum_last_poster_name = 'Admin'", 'UPDATE ' . $this->topics_table . "\n\t\t\t\tSET topic_first_poster_name = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "',\n\t\t\t\ttopic_last_poster_name = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "'\n\t\t\t\tWHERE topic_first_poster_name = 'Admin'\n\t\t\t\t\tOR topic_last_poster_name = 'Admin'", 'UPDATE ' . $this->user_table . "\n\t\t\t\tSET user_regdate = {$current_time}", 'UPDATE ' . $this->posts_table . "\n\t\t\t\tSET post_time = {$current_time}, poster_ip = '" . $this->db->sql_escape($user_ip) . "'", 'UPDATE ' . $this->topics_table . "\n\t\t\t\tSET topic_time = {$current_time}, topic_last_post_time = {$current_time}", 'UPDATE ' . $this->forums_table . "\n\t\t\t\tSET forum_last_post_time = {$current_time}", 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '" . $this->db->sql_escape($this->db->sql_server_info(true)) . "'\n\t\t\t\tWHERE config_name = 'dbms_version'");
     if (@extension_loaded('gd')) {
         $sql_ary[] = 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = 'core.captcha.plugins.gd'\n\t\t\t\tWHERE config_name = 'captcha_plugin'";
         $sql_ary[] = 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '1'\n\t\t\t\tWHERE config_name = 'captcha_gd'";
     }
     $ref = substr($referer, strpos($referer, '://') + 3);
     if (!(stripos($ref, $server_name) === 0)) {
         $sql_ary[] = 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '0'\n\t\t\t\tWHERE config_name = 'referer_validation'";
     }
     // We set a (semi-)unique cookie name to bypass login issues related to the cookie name.
     $cookie_name = 'phpbb3_';
     $rand_str = md5(mt_rand());
     $rand_str = str_replace('0', 'z', base_convert($rand_str, 16, 35));
     $rand_str = substr($rand_str, 0, 5);
     $cookie_name .= strtolower($rand_str);
     $sql_ary[] = 'UPDATE ' . $this->config_table . "\n\t\t\tSET config_value = '" . $this->db->sql_escape($cookie_name) . "'\n\t\t\tWHERE config_name = 'cookie_name'";
     // Disable avatars if upload directory is not writable
     if (!$this->filesystem->is_writable($this->phpbb_root_path . 'images/avatars/upload/')) {
         $sql_ary[] = 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '0'\n\t\t\t\tWHERE config_name = 'allow_avatar'";
         $sql_ary[] = 'UPDATE ' . $this->config_table . "\n\t\t\t\tSET config_value = '0'\n\t\t\t\tWHERE config_name = 'allow_avatar_upload'";
     }
     $i = $this->install_config->get('add_config_settings_index', 0);
     $total = sizeof($sql_ary);
     $sql_ary = array_slice($sql_ary, $i);
     foreach ($sql_ary as $sql) {
         if (!$this->db->sql_query($sql)) {
             $error = $this->db->sql_error($this->db->get_sql_error_sql());
             $this->iohandler->add_error_message('INST_ERR_DB', $error['message']);
         }
         $i++;
         // Stop execution if resource limit is reached
         if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0) {
             break;
         }
     }
     if ($i < $total) {
         $this->install_config->set('add_config_settings_index', $i);
         throw new resource_limit_reached_exception();
     }
 }
Exemplo n.º 8
0
 /**
  * {@inheritdoc}
  */
 public function run()
 {
     $config_written = true;
     // Create config.php
     $path_to_config = $this->phpbb_root_path . 'config.' . $this->php_ext;
     $fp = @fopen($path_to_config, 'w');
     if (!$fp) {
         $config_written = false;
     }
     $config_content = $this->get_config_data();
     if (!@fwrite($fp, $config_content)) {
         $config_written = false;
     }
     @fclose($fp);
     // chmod config.php to be only readable
     if ($config_written) {
         try {
             $this->filesystem->phpbb_chmod($path_to_config, \phpbb\filesystem\filesystem_interface::CHMOD_READ);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing, the user will get a notice later
         }
     } else {
         $this->iohandler->add_error_message('UNABLE_TO_WRITE_CONFIG_FILE');
         $this->iohandler->send_response();
         throw new user_interaction_required_exception();
     }
     // Create a lock file to indicate that there is an install in progress
     $fp = @fopen($this->phpbb_root_path . 'cache/install_lock', 'wb');
     if ($fp === false) {
         // We were unable to create the lock file - abort
         $this->iohandler->add_error_message('UNABLE_TO_WRITE_LOCK');
         $this->iohandler->send_response();
         throw new user_interaction_required_exception();
     }
     @fclose($fp);
     try {
         $this->filesystem->phpbb_chmod($this->phpbb_root_path . 'cache/install_lock', 0777);
     } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
         // Do nothing, the user will get a notice later
     }
 }
Exemplo n.º 9
0
 /**
  * Write cache data to a specified file
  *
  * 'data_global' is a special case and the generated format is different for this file:
  * <code>
  * <?php exit; ?>
  * (expiration)
  * (length of var and serialised data)
  * (var)
  * (serialised data)
  * ... (repeat)
  * </code>
  *
  * The other files have a similar format:
  * <code>
  * <?php exit; ?>
  * (expiration)
  * (query) [SQL files only]
  * (length of serialised data)
  * (serialised data)
  * </code>
  *
  * @access private
  * @param string $filename Filename to write
  * @param mixed $data Data to store
  * @param int $expires Timestamp when the data expires
  * @param string $query Query when caching SQL queries
  * @return bool True if the file was successfully created, otherwise false
  */
 function _write($filename, $data = null, $expires = 0, $query = '')
 {
     global $phpEx;
     $filename = $this->clean_varname($filename);
     $file = "{$this->cache_dir}{$filename}.{$phpEx}";
     $lock = new \phpbb\lock\flock($file);
     $lock->acquire();
     if ($handle = @fopen($file, 'wb')) {
         // File header
         fwrite($handle, '<' . '?php exit; ?' . '>');
         if ($filename == 'data_global') {
             // Global data is a different format
             foreach ($this->vars as $var => $data) {
                 if (strpos($var, "\r") !== false || strpos($var, "\n") !== false) {
                     // CR/LF would cause fgets() to read the cache file incorrectly
                     // do not cache test entries, they probably won't be read back
                     // the cache keys should really be alphanumeric with a few symbols.
                     continue;
                 }
                 $data = serialize($data);
                 // Write out the expiration time
                 fwrite($handle, "\n" . $this->var_expires[$var] . "\n");
                 // Length of the remaining data for this var (ignoring two LF's)
                 fwrite($handle, strlen($data . $var) . "\n");
                 fwrite($handle, $var . "\n");
                 fwrite($handle, $data);
             }
         } else {
             fwrite($handle, "\n" . $expires . "\n");
             if (strpos($filename, 'sql_') === 0) {
                 fwrite($handle, $query . "\n");
             }
             $data = serialize($data);
             fwrite($handle, strlen($data) . "\n");
             fwrite($handle, $data);
         }
         fclose($handle);
         if (function_exists('opcache_invalidate')) {
             @opcache_invalidate($this->cache_file);
         }
         try {
             $this->filesystem->phpbb_chmod($file, CHMOD_READ | CHMOD_WRITE);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
         $return_value = true;
     } else {
         $return_value = false;
     }
     $lock->release();
     return $return_value;
 }
Exemplo n.º 10
0
 /**
  * Eliminates useless . and .. components from specified URL
  *
  * @param string $url URL to clean
  *
  * @return string Cleaned URL
  */
 public function clean_url($url)
 {
     $delimiter_position = strpos($url, '://');
     // URL should contain :// but it shouldn't start with it.
     // Do not clean URLs that do not fit these constraints.
     if (empty($delimiter_position)) {
         return $url;
     }
     $scheme = substr($url, 0, $delimiter_position) . '://';
     // Add length of URL delimiter to position
     $path = substr($url, $delimiter_position + 3);
     return $scheme . $this->filesystem->clean_path($path);
 }
Exemplo n.º 11
0
 /**
  * {@inheritdoc}
  */
 public function run()
 {
     // Generate database schema
     if ($this->filesystem->exists($this->phpbb_root_path . 'install/schemas/schema.json')) {
         $db_table_schema = @file_get_contents($this->phpbb_root_path . 'install/schemas/schema.json');
         $this->config->set('change_table_prefix', true);
     } else {
         global $table_prefix;
         // As this task may take a large amount of time to complete refreshing the page might be necessary for some
         // server configurations with limited resources
         if (!$this->config->get('pre_schema_forced_refresh', false)) {
             if ($this->config->get_time_remaining() < 5) {
                 $this->config->set('pre_schema_forced_refresh', true);
                 throw new resource_limit_reached_exception();
             }
         }
         $table_prefix = $this->config->get('table_prefix');
         if (!defined('CONFIG_TABLE')) {
             // We need to include the constants file for the table constants
             // when we generate the schema from the migration files.
             include $this->phpbb_root_path . 'includes/constants.' . $this->php_ext;
         }
         $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, null, $this->php_ext);
         $migrator_classes = $finder->core_path('phpbb/db/migration/data/')->get_classes();
         $factory = new \phpbb\db\tools\factory();
         $db_tools = $factory->get($this->db, true);
         $schema_generator = new \phpbb\db\migration\schema_generator($migrator_classes, new \phpbb\config\config(array()), $this->db, $db_tools, $this->phpbb_root_path, $this->php_ext, $table_prefix);
         $db_table_schema = $schema_generator->get_schema();
         $db_table_schema = json_encode($db_table_schema, JSON_PRETTY_PRINT);
         $this->config->set('change_table_prefix', false);
     }
     $fp = @fopen($this->phpbb_root_path . 'store/schema.json', 'wb');
     if (!$fp) {
         throw new \Exception('INST_SCHEMA_FILE_NOT_WRITABLE');
     }
     fwrite($fp, $db_table_schema);
     fclose($fp);
 }
Exemplo n.º 12
0
 /**
  * {@inheritdoc}
  */
 public function check_requirements()
 {
     $dbms = $this->config->get('dbms');
     $dbms_info = $this->database_helper->get_available_dbms($dbms);
     $schema_name = $dbms_info[$dbms]['SCHEMA'];
     if ($dbms === 'mysql') {
         if (version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) {
             $schema_name .= '_41';
         } else {
             $schema_name .= '_40';
         }
     }
     $this->schema_file_path = $this->phpbb_root_path . 'install/schemas/' . $schema_name . '_schema.sql';
     return $this->filesystem->exists($this->schema_file_path);
 }
Exemplo n.º 13
0
 /**
  * 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();
     }
 }
Exemplo n.º 14
0
 /**
  * Find the template
  *
  * Override for Twig_Loader_Filesystem::findTemplate to add support
  *	for loading from safe directories.
  */
 protected function findTemplate($name)
 {
     $name = (string) $name;
     // normalize name
     $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/'));
     // If this is in the cache we can skip the entire process below
     //	as it should have already been validated
     if (isset($this->cache[$name])) {
         return $this->cache[$name];
     }
     // First, find the template name. The override above of validateName
     //	causes the validateName process to be skipped for this call
     $file = parent::findTemplate($name);
     try {
         // Try validating the name (which may throw an exception)
         parent::validateName($name);
     } catch (\Twig_Error_Loader $e) {
         if (strpos($e->getRawMessage(), 'Looks like you try to load a template outside configured directories') === 0) {
             // Ok, so outside of the configured template directories, we
             //	can now check if we're within a "safe" directory
             // Find the real path of the directory the file is in
             $directory = $this->filesystem->realpath(dirname($file));
             if ($directory === false) {
                 // Some sort of error finding the actual path, must throw the exception
                 throw $e;
             }
             foreach ($this->safe_directories as $safe_directory) {
                 if (strpos($directory, $safe_directory) === 0) {
                     // The directory being loaded is below a directory
                     // that is "safe". We're good to load it!
                     return $file;
                 }
             }
         }
         // Not within any safe directories
         throw $e;
     }
     // No exception from validateName, safe to load.
     return $file;
 }
Exemplo n.º 15
0
 /**
  * Check if a directory is readable and writable
  *
  * @param string	$dir		Filename
  * @param bool		$failable	Whether failing test should abort the installation process
  */
 protected function check_dir($dir, $failable = false)
 {
     $path = $this->phpbb_root_path . $dir;
     $exists = $writable = false;
     // Try to create the directory if it does not exist
     if (!file_exists($path)) {
         try {
             $this->filesystem->mkdir($path, 0777);
             $this->filesystem->phpbb_chmod($path, \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE);
             $exists = true;
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
     }
     // Now really check
     if (file_exists($path) && is_dir($path)) {
         try {
             $exists = true;
             $this->filesystem->phpbb_chmod($path, \phpbb\filesystem\filesystem_interface::CHMOD_READ | \phpbb\filesystem\filesystem_interface::CHMOD_WRITE);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
     }
     if ($this->filesystem->is_writable($path)) {
         $writable = true;
     }
     $this->set_test_passed($exists && $writable || $failable);
     if (!($exists && $writable)) {
         $title = $exists ? 'DIRECTORY_NOT_WRITABLE' : 'DIRECTORY_NOT_EXISTS';
         $lang_suffix = '_EXPLAIN';
         $lang_suffix .= $failable ? '_OPTIONAL' : '';
         $description = array($title . $lang_suffix, $dir);
         if ($failable) {
             $this->response->add_warning_message($title, $description);
         } else {
             $this->response->add_error_message($title, $description);
         }
     }
 }
Exemplo n.º 16
0
 /**
  * @dataProvider is_absolute_data
  */
 public function test_is_absolute($path, $expected)
 {
     $this->assertEquals($expected, $this->filesystem->is_absolute_path($path));
 }
Exemplo n.º 17
0
 /**
  * The function which does the actual work (or dispatches it to the relevant places)
  */
 function convert_data($sub)
 {
     global $template, $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache, $auth;
     global $convert, $convert_row, $message_parser, $skip_rows, $language;
     global $request, $phpbb_config_php_file, $phpbb_dispatcher;
     extract($phpbb_config_php_file->get_all());
     require $phpbb_root_path . 'includes/constants.' . $phpEx;
     require $phpbb_root_path . 'includes/functions_convert.' . $phpEx;
     $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
     $db = new $dbms();
     $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, true);
     unset($dbpasswd);
     // We need to fill the config to let internal functions correctly work
     $config = new \phpbb\config\db($db, new \phpbb\cache\driver\dummy(), CONFIG_TABLE);
     // Override a couple of config variables for the duration
     $config['max_quote_depth'] = 0;
     // @todo Need to confirm that max post length in source is <= max post length in destination or there may be interesting formatting issues
     $config['max_post_chars'] = $config['min_post_chars'] = 0;
     // Set up a user as well. We _should_ have enough of a database here at this point to do this
     // and it helps for any core code we call
     $user->session_begin();
     $user->page = $user->extract_current_page($phpbb_root_path);
     // This is a little bit of a fudge, but it allows the language entries to be available to the
     // core code without us loading them again
     $user->lang =& $lang;
     $this->page_title = $user->lang['STAGE_IN_PROGRESS'];
     $convert->options = array();
     if (isset($config['convert_progress'])) {
         $convert->options = unserialize($config['convert_progress']);
         $convert->options = array_merge($convert->options, unserialize($config['convert_db_server']), unserialize($config['convert_db_user']), unserialize($config['convert_options']));
     }
     // This information should have already been checked once, but do it again for safety
     if (empty($convert->options) || empty($convert->options['tag']) || !isset($convert->options['dbms']) || !isset($convert->options['dbhost']) || !isset($convert->options['dbport']) || !isset($convert->options['dbuser']) || !isset($convert->options['dbpasswd']) || !isset($convert->options['dbname']) || !isset($convert->options['table_prefix'])) {
         $this->p_master->error($user->lang['NO_CONVERT_SPECIFIED'], __LINE__, __FILE__);
     }
     // Make some short variables accessible, for easier referencing
     $convert->convertor_tag = basename($convert->options['tag']);
     $convert->src_dbms = $convert->options['dbms'];
     $convert->src_dbhost = $convert->options['dbhost'];
     $convert->src_dbport = $convert->options['dbport'];
     $convert->src_dbuser = $convert->options['dbuser'];
     $convert->src_dbpasswd = $convert->options['dbpasswd'];
     $convert->src_dbname = $convert->options['dbname'];
     $convert->src_table_prefix = $convert->options['table_prefix'];
     // initiate database connection to old db if old and new db differ
     global $src_db, $same_db;
     $src_db = $same_db = null;
     if ($convert->src_dbms != $dbms || $convert->src_dbhost != $dbhost || $convert->src_dbport != $dbport || $convert->src_dbname != $dbname || $convert->src_dbuser != $dbuser) {
         $dbms = $convert->src_dbms;
         $src_db = new $dbms();
         $src_db->sql_connect($convert->src_dbhost, $convert->src_dbuser, htmlspecialchars_decode($convert->src_dbpasswd), $convert->src_dbname, $convert->src_dbport, false, true);
         $same_db = false;
     } else {
         $src_db = $db;
         $same_db = true;
     }
     $convert->mysql_convert = false;
     switch ($src_db->sql_layer) {
         case 'sqlite':
         case 'sqlite3':
             $convert->src_truncate_statement = 'DELETE FROM ';
             break;
             // Thanks MySQL, for silently converting...
         // Thanks MySQL, for silently converting...
         case 'mysql':
         case 'mysql4':
             if (version_compare($src_db->sql_server_info(true, false), '4.1.3', '>=')) {
                 $convert->mysql_convert = true;
             }
             $convert->src_truncate_statement = 'TRUNCATE TABLE ';
             break;
         case 'mysqli':
             $convert->mysql_convert = true;
             $convert->src_truncate_statement = 'TRUNCATE TABLE ';
             break;
         default:
             $convert->src_truncate_statement = 'TRUNCATE TABLE ';
             break;
     }
     if ($convert->mysql_convert && !$same_db) {
         $src_db->sql_query("SET NAMES 'binary'");
     }
     switch ($db->get_sql_layer()) {
         case 'sqlite':
         case 'sqlite3':
             $convert->truncate_statement = 'DELETE FROM ';
             break;
         default:
             $convert->truncate_statement = 'TRUNCATE TABLE ';
             break;
     }
     $get_info = false;
     // check security implications of direct inclusion
     if (!file_exists('./convertors/convert_' . $convert->convertor_tag . '.' . $phpEx)) {
         $this->p_master->error($user->lang['CONVERT_NOT_EXIST'], __LINE__, __FILE__);
     }
     if (file_exists('./convertors/functions_' . $convert->convertor_tag . '.' . $phpEx)) {
         include './convertors/functions_' . $convert->convertor_tag . '.' . $phpEx;
     }
     $get_info = true;
     include './convertors/convert_' . $convert->convertor_tag . '.' . $phpEx;
     // Map some variables...
     $convert->convertor_data = $convertor_data;
     $convert->tables = $tables;
     $convert->config_schema = $config_schema;
     // Now include the real data
     $get_info = false;
     include './convertors/convert_' . $convert->convertor_tag . '.' . $phpEx;
     $convert->convertor_data = $convertor_data;
     $convert->tables = $tables;
     $convert->config_schema = $config_schema;
     $convert->convertor = $convertor;
     // The test_file is a file that should be present in the location of the old board.
     if (!file_exists($convert->options['forum_path'] . '/' . $test_file)) {
         $this->p_master->error(sprintf($user->lang['COULD_NOT_FIND_PATH'], $convert->options['forum_path']), __LINE__, __FILE__);
     }
     $search_type = $config['search_type'];
     // For conversions we are a bit less strict and set to a search backend we know exist...
     if (!class_exists($search_type)) {
         $search_type = '\\phpbb\\search\\fulltext_native';
         $config->set('search_type', $search_type);
     }
     if (!class_exists($search_type)) {
         trigger_error('NO_SUCH_SEARCH_MODULE');
     }
     $error = false;
     $convert->fulltext_search = new $search_type($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher);
     if ($error) {
         trigger_error($error);
     }
     include $phpbb_root_path . 'includes/message_parser.' . $phpEx;
     $message_parser = new parse_message();
     $jump = $request->variable('jump', 0);
     $final_jump = $request->variable('final_jump', 0);
     $sync_batch = $request->variable('sync_batch', -1);
     $last_statement = $request->variable('last', 0);
     // We are running sync...
     if ($sync_batch >= 0) {
         $this->sync_forums($sync_batch);
         return;
     }
     if ($jump) {
         $this->jump($jump, $last_statement);
         return;
     }
     if ($final_jump) {
         $this->final_jump($final_jump);
         return;
     }
     $current_table = $request->variable('current_table', 0);
     $old_current_table = min(-1, $current_table - 1);
     $skip_rows = $request->variable('skip_rows', 0);
     if (!$current_table && !$skip_rows) {
         if (!$request->variable('confirm', false)) {
             // If avatars / ranks / smilies folders are specified make sure they are writable
             $bad_folders = array();
             $local_paths = array('avatar_path' => path($config['avatar_path']), 'avatar_gallery_path' => path($config['avatar_gallery_path']), 'icons_path' => path($config['icons_path']), 'ranks_path' => path($config['ranks_path']), 'smilies_path' => path($config['smilies_path']));
             foreach ($local_paths as $folder => $local_path) {
                 if (isset($convert->convertor[$folder])) {
                     if (empty($convert->convertor['test_file'])) {
                         // test_file is mandantory at the moment so this should never be reached, but just in case...
                         $this->p_master->error($user->lang['DEV_NO_TEST_FILE'], __LINE__, __FILE__);
                     }
                     if (!$local_path || !$this->filesystem->is_writable($phpbb_root_path . $local_path)) {
                         if (!$local_path) {
                             $bad_folders[] = sprintf($user->lang['CONFIG_PHPBB_EMPTY'], $folder);
                         } else {
                             $bad_folders[] = $local_path;
                         }
                     }
                 }
             }
             if (sizeof($bad_folders)) {
                 $msg = sizeof($bad_folders) == 1 ? $user->lang['MAKE_FOLDER_WRITABLE'] : $user->lang['MAKE_FOLDERS_WRITABLE'];
                 sort($bad_folders);
                 $this->p_master->error(sprintf($msg, implode('<br />', $bad_folders)), __LINE__, __FILE__, true);
                 $template->assign_vars(array('L_SUBMIT' => $user->lang['INSTALL_TEST'], 'U_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&amp;sub=in_progress&amp;tag={$convert->convertor_tag}&amp;language={$language}"));
                 return;
             }
             // Grab all the tables used in convertor
             $missing_tables = $tables_list = $aliases = array();
             foreach ($convert->convertor['schema'] as $schema) {
                 // Skip those not used (because of addons/plugins not detected)
                 if (!$schema['target']) {
                     continue;
                 }
                 foreach ($schema as $key => $val) {
                     // we're dealing with an array like:
                     // array('forum_status',			'forums.forum_status',				'is_item_locked')
                     if (is_int($key) && !empty($val[1])) {
                         $temp_data = $val[1];
                         if (!is_array($temp_data)) {
                             $temp_data = array($temp_data);
                         }
                         foreach ($temp_data as $val) {
                             if (preg_match('/([a-z0-9_]+)\\.([a-z0-9_]+)\\)* ?A?S? ?([a-z0-9_]*?)\\.?([a-z0-9_]*)$/i', $val, $m)) {
                                 $table = $convert->src_table_prefix . $m[1];
                                 $tables_list[$table] = $table;
                                 if (!empty($m[3])) {
                                     $aliases[] = $convert->src_table_prefix . $m[3];
                                 }
                             }
                         }
                     } else {
                         if ($key == 'left_join') {
                             // Convert the value if it wasn't an array already.
                             if (!is_array($val)) {
                                 $val = array($val);
                             }
                             for ($j = 0; $j < sizeof($val); ++$j) {
                                 if (preg_match('/LEFT JOIN ([a-z0-9_]+) AS ([a-z0-9_]+)/i', $val[$j], $m)) {
                                     $table = $convert->src_table_prefix . $m[1];
                                     $tables_list[$table] = $table;
                                     if (!empty($m[2])) {
                                         $aliases[] = $convert->src_table_prefix . $m[2];
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             // Remove aliased tables from $tables_list
             foreach ($aliases as $alias) {
                 unset($tables_list[$alias]);
             }
             // Check if the tables that we need exist
             $src_db->sql_return_on_error(true);
             foreach ($tables_list as $table => $null) {
                 $sql = 'SELECT 1 FROM ' . $table;
                 $_result = $src_db->sql_query_limit($sql, 1);
                 if (!$_result) {
                     $missing_tables[] = $table;
                 }
                 $src_db->sql_freeresult($_result);
             }
             $src_db->sql_return_on_error(false);
             // Throw an error if some tables are missing
             // We used to do some guessing here, but since we have a suggestion of possible values earlier, I don't see it adding anything here to do it again
             if (sizeof($missing_tables) == sizeof($tables_list)) {
                 $this->p_master->error($user->lang['NO_TABLES_FOUND'] . ' ' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__);
             } else {
                 if (sizeof($missing_tables)) {
                     $this->p_master->error(sprintf($user->lang['TABLES_MISSING'], implode($user->lang['COMMA_SEPARATOR'], $missing_tables)) . '<br /><br />' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__);
                 }
             }
             $url = $this->save_convert_progress('&amp;confirm=1');
             $msg = $user->lang['PRE_CONVERT_COMPLETE'];
             if ($convert->convertor_data['author_notes']) {
                 $msg .= '</p><p>' . sprintf($user->lang['AUTHOR_NOTES'], $convert->convertor_data['author_notes']);
             }
             $template->assign_vars(array('L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], 'L_MESSAGE' => $msg, 'U_ACTION' => $url));
             return;
         }
         // if (!$request->variable('confirm', false)))
         $template->assign_block_vars('checks', array('S_LEGEND' => true, 'LEGEND' => $user->lang['STARTING_CONVERT']));
         // Convert the config table and load the settings of the old board
         if (!empty($convert->config_schema)) {
             restore_config($convert->config_schema);
             // Override a couple of config variables for the duration
             $config['max_quote_depth'] = 0;
             // @todo Need to confirm that max post length in source is <= max post length in destination or there may be interesting formatting issues
             $config['max_post_chars'] = $config['min_post_chars'] = 0;
         }
         $template->assign_block_vars('checks', array('TITLE' => $user->lang['CONFIG_CONVERT'], 'RESULT' => $user->lang['DONE']));
         // Now process queries and execute functions that have to be executed prior to the conversion
         if (!empty($convert->convertor['execute_first'])) {
             // @codingStandardsIgnoreStart
             eval($convert->convertor['execute_first']);
             // @codingStandardsIgnoreEnd
         }
         if (!empty($convert->convertor['query_first'])) {
             if (!is_array($convert->convertor['query_first'])) {
                 $convert->convertor['query_first'] = array('target', array($convert->convertor['query_first']));
             } else {
                 if (!is_array($convert->convertor['query_first'][0])) {
                     $convert->convertor['query_first'] = array(array($convert->convertor['query_first'][0], $convert->convertor['query_first'][1]));
                 }
             }
             foreach ($convert->convertor['query_first'] as $query_first) {
                 if ($query_first[0] == 'src') {
                     if ($convert->mysql_convert && $same_db) {
                         $src_db->sql_query("SET NAMES 'binary'");
                     }
                     $src_db->sql_query($query_first[1]);
                     if ($convert->mysql_convert && $same_db) {
                         $src_db->sql_query("SET NAMES 'utf8'");
                     }
                 } else {
                     $db->sql_query($query_first[1]);
                 }
             }
         }
         $template->assign_block_vars('checks', array('TITLE' => $user->lang['PREPROCESS_STEP'], 'RESULT' => $user->lang['DONE']));
     }
     // if (!$current_table && !$skip_rows)
     $template->assign_block_vars('checks', array('S_LEGEND' => true, 'LEGEND' => $user->lang['FILLING_TABLES']));
     // This loop takes one target table and processes it
     while ($current_table < sizeof($convert->convertor['schema'])) {
         $schema = $convert->convertor['schema'][$current_table];
         // The target table isn't set, this can be because a module (for example the attachement mod) is taking care of this.
         if (empty($schema['target'])) {
             $current_table++;
             continue;
         }
         $template->assign_block_vars('checks', array('TITLE' => sprintf($user->lang['FILLING_TABLE'], $schema['target'])));
         // This is only the case when we first start working on the tables.
         if (!$skip_rows) {
             // process execute_first and query_first for this table...
             if (!empty($schema['execute_first'])) {
                 // @codingStandardsIgnoreStart
                 eval($schema['execute_first']);
                 // @codingStandardsIgnoreEnd
             }
             if (!empty($schema['query_first'])) {
                 if (!is_array($schema['query_first'])) {
                     $schema['query_first'] = array('target', array($schema['query_first']));
                 } else {
                     if (!is_array($schema['query_first'][0])) {
                         $schema['query_first'] = array(array($schema['query_first'][0], $schema['query_first'][1]));
                     }
                 }
                 foreach ($schema['query_first'] as $query_first) {
                     if ($query_first[0] == 'src') {
                         if ($convert->mysql_convert && $same_db) {
                             $src_db->sql_query("SET NAMES 'binary'");
                         }
                         $src_db->sql_query($query_first[1]);
                         if ($convert->mysql_convert && $same_db) {
                             $src_db->sql_query("SET NAMES 'utf8'");
                         }
                     } else {
                         $db->sql_query($query_first[1]);
                     }
                 }
             }
             if (!empty($schema['autoincrement'])) {
                 switch ($db->get_sql_layer()) {
                     case 'postgres':
                         $db->sql_query("SELECT SETVAL('" . $schema['target'] . "_seq',(select case when max(" . $schema['autoincrement'] . ")>0 then max(" . $schema['autoincrement'] . ")+1 else 1 end from " . $schema['target'] . '));');
                         break;
                     case 'oracle':
                         $result = $db->sql_query('SELECT MAX(' . $schema['autoincrement'] . ') as max_id FROM ' . $schema['target']);
                         $row = $db->sql_fetchrow($result);
                         $db->sql_freeresult($result);
                         $largest_id = (int) $row['max_id'];
                         if ($largest_id) {
                             $db->sql_query('DROP SEQUENCE ' . $schema['target'] . '_seq');
                             $db->sql_query('CREATE SEQUENCE ' . $schema['target'] . '_seq START WITH ' . ($largest_id + 1));
                         }
                         break;
                 }
             }
         }
         // Process execute_always for this table
         // This is for code which needs to be executed on every pass of this table if
         // it gets split because of time restrictions
         if (!empty($schema['execute_always'])) {
             // @codingStandardsIgnoreStart
             eval($schema['execute_always']);
             // @codingStandardsIgnoreEnd
         }
         //
         // Set up some variables
         //
         // $waiting_rows	holds rows for multirows insertion (MySQL only)
         // $src_tables		holds unique tables with aliases to select from
         // $src_fields		will quickly refer source fields (or aliases) corresponding to the current index
         // $select_fields	holds the names of the fields to retrieve
         //
         $sql_data = array('source_fields' => array(), 'target_fields' => array(), 'source_tables' => array(), 'select_fields' => array());
         // This statement is building the keys for later insertion.
         $insert_query = $this->build_insert_query($schema, $sql_data, $current_table);
         // If no source table is affected, we skip the table
         if (empty($sql_data['source_tables'])) {
             $skip_rows = 0;
             $current_table++;
             continue;
         }
         $distinct = !empty($schema['distinct']) ? 'DISTINCT ' : '';
         $sql = 'SELECT ' . $distinct . implode(', ', $sql_data['select_fields']) . " \nFROM " . implode(', ', $sql_data['source_tables']);
         // Where
         $sql .= !empty($schema['where']) ? "\nWHERE (" . $schema['where'] . ')' : '';
         // Group By
         if (!empty($schema['group_by'])) {
             $schema['group_by'] = array($schema['group_by']);
             foreach ($sql_data['select_fields'] as $select) {
                 $alias = strpos(strtolower($select), ' as ');
                 $select = $alias ? substr($select, 0, $alias) : $select;
                 if (!in_array($select, $schema['group_by'])) {
                     $schema['group_by'][] = $select;
                 }
             }
         }
         $sql .= !empty($schema['group_by']) ? "\nGROUP BY " . implode(', ', $schema['group_by']) : '';
         // Having
         $sql .= !empty($schema['having']) ? "\nHAVING " . $schema['having'] : '';
         // Order By
         if (empty($schema['order_by']) && !empty($schema['primary'])) {
             $schema['order_by'] = $schema['primary'];
         }
         $sql .= !empty($schema['order_by']) ? "\nORDER BY " . $schema['order_by'] : '';
         // Counting basically holds the amount of rows processed.
         $counting = -1;
         $batch_time = 0;
         while ($counting === -1 || $counting >= $convert->batch_size && still_on_time()) {
             $old_current_table = $current_table;
             $rows = '';
             $waiting_rows = array();
             if (!empty($batch_time)) {
                 $mtime = explode(' ', microtime());
                 $mtime = $mtime[0] + $mtime[1];
                 $rows = ceil($counting / ($mtime - $batch_time)) . " rows/s ({$counting} rows) | ";
             }
             $template->assign_block_vars('checks', array('TITLE' => "skip_rows = {$skip_rows}", 'RESULT' => $rows . (defined('DEBUG') && function_exists('memory_get_usage') ? ceil(memory_get_usage() / 1024) . ' ' . $user->lang['KIB'] : '')));
             $mtime = explode(' ', microtime());
             $batch_time = $mtime[0] + $mtime[1];
             if ($convert->mysql_convert && $same_db) {
                 $src_db->sql_query("SET NAMES 'binary'");
             }
             // Take skip rows into account and only fetch batch_size amount of rows
             $___result = $src_db->sql_query_limit($sql, $convert->batch_size, $skip_rows);
             if ($convert->mysql_convert && $same_db) {
                 $src_db->sql_query("SET NAMES 'utf8'");
             }
             // This loop processes each row
             $counting = 0;
             $convert->row = $convert_row = array();
             if (!empty($schema['autoincrement'])) {
                 switch ($db->get_sql_layer()) {
                     case 'mssql':
                     case 'mssql_odbc':
                     case 'mssqlnative':
                         $db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' ON');
                         break;
                 }
             }
             // Now handle the rows until time is over or no more rows to process...
             while ($counting === 0 || still_on_time()) {
                 $convert_row = $src_db->sql_fetchrow($___result);
                 if (!$convert_row) {
                     // move to the next batch or table
                     break;
                 }
                 // With this we are able to always save the last state
                 $convert->row = $convert_row;
                 // Increment the counting variable, it stores the number of rows we have processed
                 $counting++;
                 $insert_values = array();
                 $sql_flag = $this->process_row($schema, $sql_data, $insert_values);
                 if ($sql_flag === true) {
                     switch ($db->get_sql_layer()) {
                         // If MySQL, we'll wait to have num_wait_rows rows to submit at once
                         case 'mysql':
                         case 'mysql4':
                         case 'mysqli':
                             $waiting_rows[] = '(' . implode(', ', $insert_values) . ')';
                             if (sizeof($waiting_rows) >= $convert->num_wait_rows) {
                                 $errored = false;
                                 $db->sql_return_on_error(true);
                                 if (!$db->sql_query($insert_query . implode(', ', $waiting_rows))) {
                                     $errored = true;
                                 }
                                 $db->sql_return_on_error(false);
                                 if ($errored) {
                                     $db->sql_return_on_error(true);
                                     // Because it errored out we will try to insert the rows one by one... most of the time this
                                     // is caused by duplicate entries - but we also do not want to miss one...
                                     foreach ($waiting_rows as $waiting_sql) {
                                         if (!$db->sql_query($insert_query . $waiting_sql)) {
                                             $this->p_master->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_query . $waiting_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true);
                                         }
                                     }
                                     $db->sql_return_on_error(false);
                                 }
                                 $waiting_rows = array();
                             }
                             break;
                         default:
                             $insert_sql = $insert_query . '(' . implode(', ', $insert_values) . ')';
                             $db->sql_return_on_error(true);
                             if (!$db->sql_query($insert_sql)) {
                                 $this->p_master->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true);
                             }
                             $db->sql_return_on_error(false);
                             $waiting_rows = array();
                             break;
                     }
                 }
                 $skip_rows++;
             }
             $src_db->sql_freeresult($___result);
             // We might still have some rows waiting
             if (sizeof($waiting_rows)) {
                 $errored = false;
                 $db->sql_return_on_error(true);
                 if (!$db->sql_query($insert_query . implode(', ', $waiting_rows))) {
                     $errored = true;
                 }
                 $db->sql_return_on_error(false);
                 if ($errored) {
                     $db->sql_return_on_error(true);
                     // Because it errored out we will try to insert the rows one by one... most of the time this
                     // is caused by duplicate entries - but we also do not want to miss one...
                     foreach ($waiting_rows as $waiting_sql) {
                         $db->sql_query($insert_query . $waiting_sql);
                         $this->p_master->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_query . $waiting_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true);
                     }
                     $db->sql_return_on_error(false);
                 }
                 $waiting_rows = array();
             }
             if (!empty($schema['autoincrement'])) {
                 switch ($db->get_sql_layer()) {
                     case 'mssql':
                     case 'mssql_odbc':
                     case 'mssqlnative':
                         $db->sql_query('SET IDENTITY_INSERT ' . $schema['target'] . ' OFF');
                         break;
                     case 'postgres':
                         $db->sql_query("SELECT SETVAL('" . $schema['target'] . "_seq',(select case when max(" . $schema['autoincrement'] . ")>0 then max(" . $schema['autoincrement'] . ")+1 else 1 end from " . $schema['target'] . '));');
                         break;
                     case 'oracle':
                         $result = $db->sql_query('SELECT MAX(' . $schema['autoincrement'] . ') as max_id FROM ' . $schema['target']);
                         $row = $db->sql_fetchrow($result);
                         $db->sql_freeresult($result);
                         $largest_id = (int) $row['max_id'];
                         if ($largest_id) {
                             $db->sql_query('DROP SEQUENCE ' . $schema['target'] . '_seq');
                             $db->sql_query('CREATE SEQUENCE ' . $schema['target'] . '_seq START WITH ' . ($largest_id + 1));
                         }
                         break;
                 }
             }
         }
         // When we reach this point, either the current table has been processed or we're running out of time.
         if (still_on_time() && $counting < $convert->batch_size) {
             $skip_rows = 0;
             $current_table++;
         } else {
             /*
             				if (still_on_time() && $counting < $convert->batch_size)
             				{
             					$skip_rows = 0;
             					$current_table++;
             				}*/
             // Looks like we ran out of time.
             $url = $this->save_convert_progress('&amp;current_table=' . $current_table . '&amp;skip_rows=' . $skip_rows);
             $current_table++;
             //				$percentage = ($skip_rows == 0) ? 0 : floor(100 / ($total_rows / $skip_rows));
             $msg = sprintf($user->lang['STEP_PERCENT_COMPLETED'], $current_table, sizeof($convert->convertor['schema']));
             $template->assign_vars(array('L_MESSAGE' => $msg, 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], 'U_ACTION' => $url));
             $this->meta_refresh($url);
             return;
         }
     }
     // Process execute_last then we'll be done
     $url = $this->save_convert_progress('&amp;jump=1');
     $template->assign_vars(array('L_SUBMIT' => $user->lang['FINAL_STEP'], 'U_ACTION' => $url));
     $this->meta_refresh($url);
     return;
 }
Exemplo n.º 18
0
 /**
  * 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'), true) && $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 *\n\t\t\t\t\t\tFROM NLS_DATABASE_PARAMETERS\n\t\t\t\t\t\tWHERE PARAMETER = 'NLS_RDBMS_VERSION'\n\t\t\t\t\t\t\tOR 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;
 }
Exemplo n.º 19
0
 /**
  * Move file to destination folder
  * The phpbb_root_path variable will be applied to the destination path
  *
  * @param string $destination Destination path, for example $config['avatar_path']
  * @param bool $overwrite If set to true, an already existing file will be overwritten
  * @param bool $skip_image_check If set to true, the check for the file to be a valid image is skipped
  * @param string $chmod Permission mask for chmodding the file after a successful move. The mode entered here reflects the mode defined by {@link phpbb_chmod()}
  *
  * @access public
  */
 function move_file($destination, $overwrite = false, $skip_image_check = false, $chmod = false)
 {
     global $user, $phpbb_root_path;
     if (sizeof($this->error)) {
         return false;
     }
     $chmod = $chmod === false ? CHMOD_READ | CHMOD_WRITE : $chmod;
     // We need to trust the admin in specifying valid upload directories and an attacker not being able to overwrite it...
     $this->destination_path = $phpbb_root_path . $destination;
     // Check if the destination path exist...
     if (!file_exists($this->destination_path)) {
         @unlink($this->filename);
         return false;
     }
     $upload_mode = @ini_get('open_basedir') || @ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'on' ? 'move' : 'copy';
     $upload_mode = $this->local ? 'local' : $upload_mode;
     $this->destination_file = $this->destination_path . '/' . utf8_basename($this->realname);
     // Check if the file already exist, else there is something wrong...
     if (file_exists($this->destination_file) && !$overwrite) {
         @unlink($this->filename);
         $this->error[] = $user->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file);
         $this->file_moved = false;
         return false;
     } else {
         if (file_exists($this->destination_file)) {
             @unlink($this->destination_file);
         }
         switch ($upload_mode) {
             case 'copy':
                 if (!@copy($this->filename, $this->destination_file)) {
                     if (!@move_uploaded_file($this->filename, $this->destination_file)) {
                         $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
                     }
                 }
                 break;
             case 'move':
                 if (!@move_uploaded_file($this->filename, $this->destination_file)) {
                     if (!@copy($this->filename, $this->destination_file)) {
                         $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
                     }
                 }
                 break;
             case 'local':
                 if (!@copy($this->filename, $this->destination_file)) {
                     $this->error[] = sprintf($user->lang[$this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR'], $this->destination_file);
                 }
                 break;
         }
         // Remove temporary filename
         @unlink($this->filename);
         if (sizeof($this->error)) {
             return false;
         }
         try {
             $this->filesystem->phpbb_chmod($this->destination_file, $chmod);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
     }
     // Try to get real filesize from destination folder
     $this->filesize = @filesize($this->destination_file) ? @filesize($this->destination_file) : $this->filesize;
     // Get mimetype of supplied file
     $this->mimetype = $this->get_mimetype($this->destination_file);
     if ($this->is_image() && !$skip_image_check) {
         $this->width = $this->height = 0;
         // Get imagesize class
         $imagesize = new \fastImageSize\fastImageSize();
         $this->image_info = $imagesize->getImageSize($this->destination_file, $this->mimetype);
         if ($this->image_info !== false) {
             $this->width = $this->image_info['width'];
             $this->height = $this->image_info['height'];
             // Check image type
             $types = fileupload::image_types();
             if (!isset($types[$this->image_info['type']]) || !in_array($this->extension, $types[$this->image_info['type']])) {
                 if (!isset($types[$this->image_info['type']])) {
                     $this->error[] = $user->lang('IMAGE_FILETYPE_INVALID', $this->image_info['type'], $this->mimetype);
                 } else {
                     $this->error[] = $user->lang('IMAGE_FILETYPE_MISMATCH', $types[$this->image_info['type']][0], $this->extension);
                 }
             }
             // Make sure the dimensions match a valid image
             if (empty($this->width) || empty($this->height)) {
                 $this->error[] = $user->lang['ATTACHED_IMAGE_NOT_IMAGE'];
             }
         } else {
             $this->error[] = $user->lang['UNABLE_GET_IMAGE_SIZE'];
         }
     }
     $this->file_moved = true;
     $this->additional_checks();
     unset($this->upload);
     return true;
 }
Exemplo n.º 20
0
 /**
  * Save queue
  */
 function save()
 {
     if (!sizeof($this->data)) {
         return;
     }
     $lock = new \phpbb\lock\flock($this->cache_file);
     $lock->acquire();
     if (file_exists($this->cache_file)) {
         include $this->cache_file;
         foreach ($this->queue_data as $object => $data_ary) {
             if (isset($this->data[$object]) && sizeof($this->data[$object])) {
                 $this->data[$object]['data'] = array_merge($data_ary['data'], $this->data[$object]['data']);
             } else {
                 $this->data[$object]['data'] = $data_ary['data'];
             }
         }
     }
     if ($fp = @fopen($this->cache_file, 'w')) {
         fwrite($fp, "<?php\nif (!defined('IN_PHPBB')) exit;\n\$this->queue_data = unserialize(" . var_export(serialize($this->data), true) . ");\n\n?>");
         fclose($fp);
         try {
             $this->filesystem->phpbb_chmod($this->cache_file, CHMOD_READ | CHMOD_WRITE);
         } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
             // Do nothing
         }
         $this->data = array();
     }
     $lock->release();
 }
Exemplo n.º 21
0
 /**
  * {@inheritdoc}
  */
 public function run()
 {
     $this->db->sql_return_on_error(true);
     $dbms = $this->config->get('dbms');
     $dbms_info = $this->database_helper->get_available_dbms($dbms);
     $schema_name = $dbms_info[$dbms]['SCHEMA'];
     $delimiter = $dbms_info[$dbms]['DELIM'];
     $table_prefix = $this->config->get('table_prefix');
     if ($dbms === 'mysql') {
         if (version_compare($this->db->sql_server_info(true), '4.1.3', '>=')) {
             $schema_name .= '_41';
         } else {
             $schema_name .= '_40';
         }
     }
     $db_schema_path = $this->phpbb_root_path . 'install/schemas/' . $schema_name . '_schema.sql';
     // Load database vendor specific code if there is any
     if ($this->filesystem->exists($db_schema_path)) {
         $sql_query = @file_get_contents($db_schema_path);
         $sql_query = preg_replace('#phpbb_#i', $table_prefix, $sql_query);
         $sql_query = $this->database_helper->remove_comments($sql_query);
         $sql_query = $this->database_helper->split_sql_file($sql_query, $delimiter);
         foreach ($sql_query as $sql) {
             if (!$this->db->sql_query($sql)) {
                 $error = $this->db->sql_error($this->db->get_sql_error_sql());
                 $this->iohandler->add_error_message('INST_ERR_DB', $error['message']);
             }
         }
         unset($sql_query);
     }
     $change_prefix = false;
     // Generate database schema
     if ($this->filesystem->exists($this->phpbb_root_path . 'install/schemas/schema.json')) {
         $db_table_schema = @file_get_contents($this->phpbb_root_path . 'install/schemas/schema.json');
         $db_table_schema = json_decode($db_table_schema, true);
         $change_prefix = true;
     } else {
         global $table_prefix;
         $table_prefix = $this->config->get('table_prefix');
         if (!defined('CONFIG_TABLE')) {
             // We need to include the constants file for the table constants
             // when we generate the schema from the migration files.
             include $this->phpbb_root_path . 'includes/constants.' . $this->php_ext;
         }
         $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, null, $this->php_ext);
         $migrator_classes = $finder->core_path('phpbb/db/migration/data/')->get_classes();
         $factory = new \phpbb\db\tools\factory();
         $db_tools = $factory->get($this->db, true);
         $schema_generator = new \phpbb\db\migration\schema_generator($migrator_classes, new \phpbb\config\config(array()), $this->db, $db_tools, $this->phpbb_root_path, $this->php_ext, $table_prefix);
         $db_table_schema = $schema_generator->get_schema();
     }
     if (!defined('CONFIG_TABLE')) {
         // CONFIG_TABLE is required by sql_create_index() to check the
         // length of index names. However table_prefix is not defined
         // here yet, so we need to create the constant ourselves.
         define('CONFIG_TABLE', $table_prefix . 'config');
     }
     foreach ($db_table_schema as $table_name => $table_data) {
         $this->db_tools->sql_create_table($change_prefix ? $table_prefix . substr($table_name, 6) : $table_name, $table_data);
     }
 }
Exemplo n.º 22
0
 /**
  * Extract archive
  */
 function extract($dst)
 {
     $fzread = $this->isbz && function_exists('bzread') ? 'bzread' : ($this->isgz && @extension_loaded('zlib') ? 'gzread' : 'fread');
     // Run through the file and grab directory entries
     while ($buffer = $fzread($this->fp, 512)) {
         $tmp = unpack('A6magic', substr($buffer, 257, 6));
         if (trim($tmp['magic']) == 'ustar') {
             $tmp = unpack('A100name', $buffer);
             $filename = trim($tmp['name']);
             $tmp = unpack('Atype', substr($buffer, 156, 1));
             $filetype = (int) trim($tmp['type']);
             $tmp = unpack('A12size', substr($buffer, 124, 12));
             $filesize = octdec((int) trim($tmp['size']));
             $target_filename = "{$dst}{$filename}";
             if ($filetype == 5) {
                 if (!is_dir($target_filename)) {
                     $str = '';
                     $folders = explode('/', $target_filename);
                     // Create and folders and subfolders if they do not exist
                     foreach ($folders as $folder) {
                         $folder = trim($folder);
                         if (!$folder) {
                             continue;
                         }
                         $str = !empty($str) ? $str . '/' . $folder : $folder;
                         if (!is_dir($str)) {
                             if (!@mkdir($str, 0777)) {
                                 trigger_error("Could not create directory {$folder}");
                             }
                             try {
                                 $this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
                             } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
                                 // Do nothing
                             }
                         }
                     }
                 }
             } else {
                 if ($filesize >= 0 && ($filetype == 0 || $filetype == "")) {
                     // Some archivers are punks, they don't properly order the folders in their archives!
                     $str = '';
                     $folders = explode('/', pathinfo($target_filename, PATHINFO_DIRNAME));
                     // Create and folders and subfolders if they do not exist
                     foreach ($folders as $folder) {
                         $folder = trim($folder);
                         if (!$folder) {
                             continue;
                         }
                         $str = !empty($str) ? $str . '/' . $folder : $folder;
                         if (!is_dir($str)) {
                             if (!@mkdir($str, 0777)) {
                                 trigger_error("Could not create directory {$folder}");
                             }
                             try {
                                 $this->filesystem->phpbb_chmod($str, CHMOD_READ | CHMOD_WRITE);
                             } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
                                 // Do nothing
                             }
                         }
                     }
                     // Write out the files
                     if (!($fp = fopen($target_filename, 'wb'))) {
                         trigger_error("Couldn't create file {$filename}");
                     }
                     try {
                         $this->filesystem->phpbb_chmod($target_filename, CHMOD_READ);
                     } catch (\phpbb\filesystem\exception\filesystem_exception $e) {
                         // Do nothing
                     }
                     // Grab the file contents
                     fwrite($fp, $filesize ? $fzread($this->fp, $filesize + 511 & ~511) : '', $filesize);
                     fclose($fp);
                 }
             }
         }
     }
 }
Exemplo n.º 23
0
 /**
  * Check if user is able to upload an avatar
  *
  * @return bool True if user can upload, false if not
  */
 protected function can_upload()
 {
     return file_exists($this->phpbb_root_path . $this->config['avatar_path']) && $this->filesystem->is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on');
 }