From 10f6716566fce9d9c38f3dd99419595b2a1cba4c Mon Sep 17 00:00:00 2001 From: Mate Bartus Date: Tue, 30 Jun 2015 16:36:34 +0200 Subject: [ticket/13740] Restore original install folder This reverts commit 934e2821f1cef5e2e21ad6d96f7beb45647ed81c. PHPBB3-13740 --- phpBB/common.php | 2 +- phpBB/install/app.php | 79 - phpBB/install/convertors/convert_phpbb20.php | 975 ++++++++ phpBB/install/convertors/functions_phpbb20.php | 1984 ++++++++++++++++ phpBB/install/data/confusables.php | 645 ++++++ phpBB/install/database_update.php | 267 +++ phpBB/install/index.php | 867 +++++++ phpBB/install/install_convert.php | 2153 ++++++++++++++++++ phpBB/install/install_install.php | 2368 ++++++++++++++++++++ phpBB/install/install_main.php | 78 + phpBB/install/install_update.php | 1790 +++++++++++++++ phpBB/install/phpbbcli.php | 68 - phpBB/install/phpinfo.php | 14 + phpBB/install/schemas/index.htm | 10 + phpBB/install/schemas/oracle_schema.sql | 37 + phpBB/install/schemas/postgres_schema.sql | 80 + phpBB/install/schemas/schema_data.sql | 821 +++++++ phpBB/install_new/app.php | 79 + phpBB/install_new/phpbbcli.php | 68 + phpBB/install_old/convertors/convert_phpbb20.php | 975 -------- phpBB/install_old/convertors/functions_phpbb20.php | 1984 ---------------- phpBB/install_old/data/confusables.php | 645 ------ phpBB/install_old/database_update.php | 267 --- phpBB/install_old/index.php | 867 ------- phpBB/install_old/install_convert.php | 2153 ------------------ phpBB/install_old/install_update.php | 1790 --------------- phpBB/install_old/phpinfo.php | 14 - 27 files changed, 12237 insertions(+), 8843 deletions(-) delete mode 100644 phpBB/install/app.php create mode 100644 phpBB/install/convertors/convert_phpbb20.php create mode 100644 phpBB/install/convertors/functions_phpbb20.php create mode 100644 phpBB/install/data/confusables.php create mode 100644 phpBB/install/database_update.php create mode 100644 phpBB/install/index.php create mode 100644 phpBB/install/install_convert.php create mode 100644 phpBB/install/install_install.php create mode 100644 phpBB/install/install_main.php create mode 100644 phpBB/install/install_update.php delete mode 100755 phpBB/install/phpbbcli.php create mode 100644 phpBB/install/phpinfo.php create mode 100644 phpBB/install/schemas/index.htm create mode 100644 phpBB/install/schemas/oracle_schema.sql create mode 100644 phpBB/install/schemas/postgres_schema.sql create mode 100644 phpBB/install/schemas/schema_data.sql create mode 100644 phpBB/install_new/app.php create mode 100644 phpBB/install_new/phpbbcli.php delete mode 100644 phpBB/install_old/convertors/convert_phpbb20.php delete mode 100644 phpBB/install_old/convertors/functions_phpbb20.php delete mode 100644 phpBB/install_old/data/confusables.php delete mode 100644 phpBB/install_old/database_update.php delete mode 100644 phpBB/install_old/index.php delete mode 100644 phpBB/install_old/install_convert.php delete mode 100644 phpBB/install_old/install_update.php delete mode 100644 phpBB/install_old/phpinfo.php diff --git a/phpBB/common.php b/phpBB/common.php index 38761cfadc..0b898d9553 100644 --- a/phpBB/common.php +++ b/phpBB/common.php @@ -52,7 +52,7 @@ if (!defined('PHPBB_INSTALLED')) } // $phpbb_root_path accounts for redirects from e.g. /adm - $script_path = trim(dirname($script_name)) . '/' . $phpbb_root_path . 'install/app.' . $phpEx; + $script_path = trim(dirname($script_name)) . '/' . $phpbb_root_path . 'install/index.' . $phpEx; // Replace any number of consecutive backslashes and/or slashes with a single slash // (could happen on some proxy setups and/or Windows servers) $script_path = preg_replace('#[\\\\/]{2,}#', '/', $script_path); diff --git a/phpBB/install/app.php b/phpBB/install/app.php deleted file mode 100644 index 75b28fa092..0000000000 --- a/phpBB/install/app.php +++ /dev/null @@ -1,79 +0,0 @@ - - * @license GNU General Public License, version 2 (GPL-2.0) - * - * For full copyright and license information, please see - * the docs/CREDITS.txt file. - * - */ - -/** - * @ignore - */ -define('IN_PHPBB', true); -define('IN_INSTALL', true); -define('PHPBB_ENVIRONMENT', 'production'); -$phpbb_root_path = '../'; -$phpEx = substr(strrchr(__FILE__, '.'), 1); - -// -// Let's do the common.php logic -// -require($phpbb_root_path . 'includes/startup.' . $phpEx); -require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx); - -$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); -$phpbb_class_loader->register(); - -// In case $phpbb_adm_relative_path is not set (in case of an update), use the default. -$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/'; -$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path; - -// Include files -require($phpbb_root_path . 'includes/functions.' . $phpEx); -require($phpbb_root_path . 'includes/functions_content.' . $phpEx); -include($phpbb_root_path . 'includes/functions_compatibility.' . $phpEx); -require($phpbb_root_path . 'includes/functions_user.' . $phpEx); -require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); - -// Set PHP error handler to ours -set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); - -$phpbb_installer_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); -$phpbb_installer_container = $phpbb_installer_container_builder - ->with_environment('installer') - ->without_extensions() - ->get_container(); - -// Path to templates -$paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style'); -$paths = array_filter($paths, 'is_dir'); - -/** @var \phpbb\filesystem\filesystem $phpbb_filesystem */ -$phpbb_filesystem = $phpbb_installer_container->get('filesystem'); - -/** @var \phpbb\template\template $template */ -$template = $phpbb_installer_container->get('template'); -$template->set_custom_style(array( - array( - 'name' => 'adm', - 'ext_path' => 'adm/style/', - ), -), $paths); - -/** @var \phpbb\language\language $language */ -$language = $phpbb_installer_container->get('language'); -$language->add_lang(array('common', 'acp/common', 'acp/board', 'install', 'posting')); - -/* @var $http_kernel \Symfony\Component\HttpKernel\HttpKernel */ -$http_kernel = $phpbb_installer_container->get('http_kernel'); - -/* @var $symfony_request \phpbb\symfony_request */ -$symfony_request = $phpbb_installer_container->get('symfony_request'); -$response = $http_kernel->handle($symfony_request); -$response->send(); -$http_kernel->terminate($symfony_request, $response); diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php new file mode 100644 index 0000000000..a19bb2504b --- /dev/null +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -0,0 +1,975 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +* NOTE to potential convertor authors. Please use this file to get +* familiar with the structure since we added some bare explanations here. +* +* Since this file gets included more than once on one page you are not able to add functions to it. +* Instead use a functions_ file. +* +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +$phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx); +extract($phpbb_config_php_file->get_all()); +unset($dbpasswd); + +$dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms); + +/** +* $convertor_data provides some basic information about this convertor which is +* used on the initial list of convertors and to populate the default settings +*/ +$convertor_data = array( + 'forum_name' => 'phpBB 2.0.x', + 'version' => '1.0.3', + 'phpbb_version' => '3.1.5', + 'author' => 'phpBB Limited', + 'dbms' => $dbms, + 'dbhost' => $dbhost, + 'dbport' => $dbport, + 'dbuser' => $dbuser, + 'dbpasswd' => '', + 'dbname' => $dbname, + 'table_prefix' => 'phpbb_', + 'forum_path' => '../forums', + 'author_notes' => '', +); + +/** +* $tables is a list of the tables (minus prefix) which we expect to find in the +* source forum. It is used to guess the prefix if the specified prefix is incorrect +*/ +$tables = array( + 'auth_access', + 'banlist', + 'categories', + 'disallow', + 'forum_prune', + 'forums', + 'groups', + 'posts', + 'posts_text', + 'privmsgs', + 'privmsgs_text', + 'ranks', + 'smilies', + 'topics', + 'topics_watch', + 'user_group', + 'users', + 'vote_desc', + 'vote_results', + 'vote_voters', + 'words' +); + +/** +* $config_schema details how the board configuration information is stored in the source forum. +* +* 'table_format' can take the value 'file' to indicate a config file. In this case array_name +* is set to indicate the name of the array the config values are stored in +* Example of using a file: +* $config_schema = array( +* 'table_format' => 'file', +* 'filename' => 'NAME OF FILE', // If the file is not in the root directory, the path needs to be added with no leading slash +* 'array_name' => 'NAME OF ARRAY', // Only used if the configuration file stores the setting in an array. +* 'settings' => array( +* 'board_email' => 'SUPPORT_EMAIL', // target config name => source target name +* ) +* ); +* 'table_format' can be an array if the values are stored in a table which is an assosciative array +* (as per phpBB 2.0.x) +* If left empty, values are assumed to be stored in a table where each config setting is +* a column (as per phpBB 1.x) +* +* In either of the latter cases 'table_name' indicates the name of the table in the database +* +* 'settings' is an array which maps the name of the config directive in the source forum +* to the config directive in phpBB3. It can either be a direct mapping or use a function. +* Please note that the contents of the old config value are passed to the function, therefore +* an in-built function requiring the variable passed by reference is not able to be used. Since +* empty() is such a function we created the function is_empty() to be used instead. +*/ +$config_schema = array( + 'table_name' => 'config', + 'table_format' => array('config_name' => 'config_value'), + 'settings' => array( + 'allow_bbcode' => 'allow_bbcode', + 'allow_smilies' => 'allow_smilies', + 'allow_sig' => 'allow_sig', + 'allow_namechange' => 'allow_namechange', + 'allow_avatar_local' => 'allow_avatar_local', + 'allow_avatar_remote' => 'allow_avatar_remote', + 'allow_avatar_upload' => 'allow_avatar_upload', + 'board_disable' => 'board_disable', + 'sitename' => 'phpbb_set_encoding(sitename)', + 'site_desc' => 'phpbb_set_encoding(site_desc)', + 'session_length' => 'session_length', + 'board_email_sig' => 'phpbb_set_encoding(board_email_sig)', + 'posts_per_page' => 'posts_per_page', + 'topics_per_page' => 'topics_per_page', + 'enable_confirm' => 'enable_confirm', + 'board_email_form' => 'board_email_form', + 'override_user_style' => 'override_user_style', + 'hot_threshold' => 'hot_threshold', + 'max_poll_options' => 'max_poll_options', + 'max_sig_chars' => 'max_sig_chars', + 'pm_max_msgs' => 'max_inbox_privmsgs', + 'smtp_delivery' => 'smtp_delivery', + 'smtp_host' => 'smtp_host', + 'smtp_username' => 'smtp_username', + 'smtp_password' => 'smtp_password', + 'require_activation' => 'require_activation', + 'flood_interval' => 'flood_interval', + 'avatar_filesize' => 'avatar_filesize', + 'avatar_max_width' => 'avatar_max_width', + 'avatar_max_height' => 'avatar_max_height', + 'default_dateformat' => 'phpbb_set_encoding(default_dateformat)', + 'board_timezone' => 'phpbb_convert_timezone(board_timezone)', + 'allow_privmsg' => 'not(privmsg_disable)', + 'gzip_compress' => 'gzip_compress', + 'coppa_enable' => '!is_empty(coppa_mail)', + 'coppa_fax' => 'coppa_fax', + 'coppa_mail' => 'coppa_mail', + 'record_online_users' => 'record_online_users', + 'record_online_date' => 'record_online_date', + 'board_startdate' => 'board_startdate', + ) +); + +/** +* $test_file is the name of a file which is present on the source +* forum which can be used to check that the path specified by the +* user was correct +*/ +$test_file = 'modcp.php'; + +/** +* If this is set then we are not generating the first page of information but getting the conversion information. +*/ +if (!$get_info) +{ + // Test to see if the birthday MOD is installed on the source forum + // Niels' birthday mod + if (get_config_value('birthday_required') !== false || get_config_value('bday_require') !== false) + { + define('MOD_BIRTHDAY', true); + } + + // TerraFrost's validated birthday mod + if (get_config_value('bday_require') !== false) + { + define('MOD_BIRTHDAY_TERRA', true); + } + + // Test to see if the attachment MOD is installed on the source forum + // If it is, we will convert this data as well + $src_db->sql_return_on_error(true); + + $sql = "SELECT config_value + FROM {$convert->src_table_prefix}attachments_config + WHERE config_name = 'upload_dir'"; + $result = $src_db->sql_query($sql); + + if ($result && $row = $src_db->sql_fetchrow($result)) + { + // Here the constant is defined + define('MOD_ATTACHMENT', true); + + // Here i add more tables to be checked in the old forum + $tables += array( + 'attachments', + 'attachments_desc', + 'extensions', + 'extension_groups' + ); + + $src_db->sql_freeresult($result); + } + else if ($result) + { + $src_db->sql_freeresult($result); + } + + + /** + * Tests for further MODs can be included here. + * Please use constants for this, prefixing them with MOD_ + */ + + $src_db->sql_return_on_error(false); + + // Now let us set a temporary config variable for user id incrementing + $sql = "SELECT user_id + FROM {$convert->src_table_prefix}users + WHERE user_id = 1"; + $result = $src_db->sql_query($sql); + $user_id = (int) $src_db->sql_fetchfield('user_id'); + $src_db->sql_freeresult($result); + + // If there is a user id 1, we need to increment user ids. :/ + if ($user_id === 1) + { + // Try to get the maximum user id possible... + $sql = "SELECT MAX(user_id) AS max_user_id + FROM {$convert->src_table_prefix}users"; + $result = $src_db->sql_query($sql); + $user_id = (int) $src_db->sql_fetchfield('max_user_id'); + $src_db->sql_freeresult($result); + + $config->set('increment_user_id', ($user_id + 1), false); + } + else + { + $config->set('increment_user_id', 0, false); + } + + // Overwrite maximum avatar width/height + @define('DEFAULT_AVATAR_X_CUSTOM', get_config_value('avatar_max_width')); + @define('DEFAULT_AVATAR_Y_CUSTOM', get_config_value('avatar_max_height')); + + // additional table used only during conversion + @define('USERCONV_TABLE', $table_prefix . 'userconv'); + +/** +* Description on how to use the convertor framework. +* +* 'schema' Syntax Description +* -> 'target' => Target Table. If not specified the next table will be handled +* -> 'primary' => Primary Key. If this is specified then this table is processed in batches +* -> 'query_first' => array('target' or 'src', Query to execute before beginning the process +* (if more than one then specified as array)) +* -> 'function_first' => Function to execute before beginning the process (if more than one then specified as array) +* (This is mostly useful if variables need to be given to the converting process) +* -> 'test_file' => This is not used at the moment but should be filled with a file from the old installation +* +* // DB Functions +* 'distinct' => Add DISTINCT to the select query +* 'where' => Add WHERE to the select query +* 'group_by' => Add GROUP BY to the select query +* 'left_join' => Add LEFT JOIN to the select query (if more than one joins specified as array) +* 'having' => Add HAVING to the select query +* +* // DB INSERT array +* This one consist of three parameters +* First Parameter: +* The key need to be filled within the target table +* If this is empty, the target table gets not assigned the source value +* Second Parameter: +* Source value. If the first parameter is specified, it will be assigned this value. +* If the first parameter is empty, this only gets added to the select query +* Third Parameter: +* Custom Function. Function to execute while storing source value into target table. +* The functions return value get stored. +* The function parameter consist of the value of the second parameter. +* +* types: +* - empty string == execute nothing +* - string == function to execute +* - array == complex execution instructions +* +* Complex execution instructions: +* @todo test complex execution instructions - in theory they will work fine +* +* By defining an array as the third parameter you are able to define some statements to be executed. The key +* is defining what to execute, numbers can be appended... +* +* 'function' => execute function +* 'execute' => run code, whereby all occurrences of {VALUE} get replaced by the last returned value. +* The result *must* be assigned/stored to {RESULT}. +* 'typecast' => typecast value +* +* The returned variables will be made always available to the next function to continue to work with. +* +* example (variable inputted is an integer of 1): +* +* array( +* 'function1' => 'increment_by_one', // returned variable is 2 +* 'typecast' => 'string', // typecast variable to be a string +* 'execute' => '{RESULT} = {VALUE} . ' is good';', // returned variable is '2 is good' +* 'function2' => 'replace_good_with_bad', // returned variable is '2 is bad' +* ), +* +*/ + + $convertor = array( + 'test_file' => 'viewtopic.php', + + 'avatar_path' => get_config_value('avatar_path') . '/', + 'avatar_gallery_path' => get_config_value('avatar_gallery_path') . '/', + 'smilies_path' => get_config_value('smilies_path') . '/', + 'upload_path' => (defined('MOD_ATTACHMENT')) ? phpbb_get_files_dir() . '/' : '', + 'thumbnails' => (defined('MOD_ATTACHMENT')) ? array('thumbs/', 't_') : '', + 'ranks_path' => false, // phpBB 2.0.x had no config value for a ranks path + + // We empty some tables to have clean data available + 'query_first' => array( + array('target', $convert->truncate_statement . SEARCH_RESULTS_TABLE), + array('target', $convert->truncate_statement . SEARCH_WORDLIST_TABLE), + array('target', $convert->truncate_statement . SEARCH_WORDMATCH_TABLE), + array('target', $convert->truncate_statement . LOG_TABLE), + ), + +// with this you are able to import all attachment files on the fly. For large boards this is not an option, therefore commented out by default. +// Instead every file gets copied while processing the corresponding attachment entry. +// if (defined("MOD_ATTACHMENT")) { import_attachment_files(); phpbb_copy_thumbnails(); } + + // phpBB2 allowed some similar usernames to coexist which would have the same + // username_clean in phpBB3 which is not possible, so we'll give the admin a list + // of user ids and usernames and let him deicde what he wants to do with them + 'execute_first' => ' + phpbb_create_userconv_table(); + import_avatar_gallery(); + if (defined("MOD_ATTACHMENT")) phpbb_import_attach_config(); + phpbb_insert_forums(); + ', + + 'execute_last' => array(' + add_bots(); + ', ' + update_folder_pm_count(); + ', ' + update_unread_count(); + ', (defined('MOD_ATTACHMENT')) ? ' + phpbb_attachment_extension_group_name(); + ' : ' + ', ' + phpbb_convert_authentication(\'start\'); + ', ' + phpbb_convert_authentication(\'first\'); + ', ' + phpbb_convert_authentication(\'second\'); + ', ' + phpbb_convert_authentication(\'third\'); + '), + + 'schema' => array( + array( + 'target' => USERCONV_TABLE, + 'query_first' => array('target', $convert->truncate_statement . USERCONV_TABLE), + + + array('user_id', 'users.user_id', ''), + array('username_clean', 'users.username', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_clean_string')), + ), + + array( + 'target' => (defined('MOD_ATTACHMENT')) ? ATTACHMENTS_TABLE : '', + 'primary' => 'attachments.attach_id', + 'query_first' => (defined('MOD_ATTACHMENT')) ? array('target', $convert->truncate_statement . ATTACHMENTS_TABLE) : '', + 'autoincrement' => 'attach_id', + + array('attach_id', 'attachments.attach_id', ''), + array('post_msg_id', 'attachments.post_id', ''), + array('topic_id', 'posts.topic_id', ''), + array('in_message', 0, ''), + array('is_orphan', 0, ''), + array('poster_id', 'attachments.user_id_1 AS poster_id', 'phpbb_user_id'), + array('physical_filename', 'attachments_desc.physical_filename', 'import_attachment'), + array('real_filename', 'attachments_desc.real_filename', 'phpbb_set_encoding'), + array('download_count', 'attachments_desc.download_count', ''), + array('attach_comment', 'attachments_desc.comment', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), + array('extension', 'attachments_desc.extension', ''), + array('mimetype', 'attachments_desc.mimetype', ''), + array('filesize', 'attachments_desc.filesize', ''), + array('filetime', 'attachments_desc.filetime', ''), + array('thumbnail', 'attachments_desc.thumbnail', ''), + + 'where' => 'attachments_desc.attach_id = attachments.attach_id AND attachments.privmsgs_id = 0 AND posts.post_id = attachments.post_id', + 'group_by' => 'attachments.attach_id' + ), + + array( + 'target' => (defined('MOD_ATTACHMENT')) ? ATTACHMENTS_TABLE : '', + 'primary' => 'attachments.attach_id', + 'autoincrement' => 'attach_id', + + array('attach_id', 'attachments.attach_id', ''), + array('post_msg_id', 'attachments.privmsgs_id', ''), + array('topic_id', 0, ''), + array('in_message', 1, ''), + array('is_orphan', 0, ''), + array('poster_id', 'attachments.user_id_1 AS poster_id', 'phpbb_user_id'), + array('physical_filename', 'attachments_desc.physical_filename', 'import_attachment'), + array('real_filename', 'attachments_desc.real_filename', 'phpbb_set_encoding'), + array('download_count', 'attachments_desc.download_count', ''), + array('attach_comment', 'attachments_desc.comment', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), + array('extension', 'attachments_desc.extension', ''), + array('mimetype', 'attachments_desc.mimetype', ''), + array('filesize', 'attachments_desc.filesize', ''), + array('filetime', 'attachments_desc.filetime', ''), + array('thumbnail', 'attachments_desc.thumbnail', ''), + + 'where' => 'attachments_desc.attach_id = attachments.attach_id AND attachments.post_id = 0', + 'group_by' => 'attachments.attach_id' + ), + + array( + 'target' => (defined('MOD_ATTACHMENT')) ? EXTENSIONS_TABLE : '', + 'query_first' => (defined('MOD_ATTACHMENT')) ? array('target', $convert->truncate_statement . EXTENSIONS_TABLE) : '', + 'autoincrement' => 'extension_id', + + array('extension_id', 'extensions.ext_id', ''), + array('group_id', 'extensions.group_id', ''), + array('extension', 'extensions.extension', ''), + ), + + array( + 'target' => (defined('MOD_ATTACHMENT')) ? EXTENSION_GROUPS_TABLE : '', + 'query_first' => (defined('MOD_ATTACHMENT')) ? array('target', $convert->truncate_statement . EXTENSION_GROUPS_TABLE) : '', + 'autoincrement' => 'group_id', + + array('group_id', 'extension_groups.group_id', ''), + array('group_name', 'extension_groups.group_name', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), + array('cat_id', 'extension_groups.cat_id', 'phpbb_attachment_category'), + array('allow_group', 'extension_groups.allow_group', ''), + array('download_mode', 1, ''), + array('upload_icon', '', ''), + array('max_filesize', 'extension_groups.max_filesize', ''), + array('allowed_forums', 'extension_groups.forum_permissions', 'phpbb_attachment_forum_perms'), + array('allow_in_pm', 1, ''), + ), + + array( + 'target' => BANLIST_TABLE, + 'execute_first' => 'phpbb_check_username_collisions();', + 'query_first' => array('target', $convert->truncate_statement . BANLIST_TABLE), + + array('ban_ip', 'banlist.ban_ip', 'decode_ban_ip'), + array('ban_userid', 'banlist.ban_userid', 'phpbb_user_id'), + array('ban_email', 'banlist.ban_email', ''), + array('ban_reason', '', ''), + array('ban_give_reason', '', ''), + + 'where' => "banlist.ban_ip NOT LIKE '%.%'", + ), + + array( + 'target' => BANLIST_TABLE, + + array('ban_ip', 'banlist.ban_ip', ''), + array('ban_userid', 0, ''), + array('ban_email', '', ''), + array('ban_reason', '', ''), + array('ban_give_reason', '', ''), + + 'where' => "banlist.ban_ip LIKE '%.%'", + ), + + array( + 'target' => DISALLOW_TABLE, + 'query_first' => array('target', $convert->truncate_statement . DISALLOW_TABLE), + + array('disallow_username', 'disallow.disallow_username', 'phpbb_disallowed_username'), + ), + + array( + 'target' => RANKS_TABLE, + 'query_first' => array('target', $convert->truncate_statement . RANKS_TABLE), + 'autoincrement' => 'rank_id', + + array('rank_id', 'ranks.rank_id', ''), + array('rank_title', 'ranks.rank_title', array('function1' => 'phpbb_set_default_encoding', 'function2' => 'utf8_htmlspecialchars')), + array('rank_min', 'ranks.rank_min', array('typecast' => 'int', 'execute' => '{RESULT} = ({VALUE}[0] < 0) ? 0 : {VALUE}[0];')), + array('rank_special', 'ranks.rank_special', ''), + array('rank_image', 'ranks.rank_image', 'import_rank'), + ), + + array( + 'target' => TOPICS_TABLE, + 'query_first' => array('target', $convert->truncate_statement . TOPICS_TABLE), + 'primary' => 'topics.topic_id', + 'autoincrement' => 'topic_id', + + array('topic_id', 'topics.topic_id', ''), + array('forum_id', 'topics.forum_id', ''), + array('icon_id', 0, ''), + array('topic_poster', 'topics.topic_poster AS poster_id', 'phpbb_user_id'), + array('topic_attachment', ((defined('MOD_ATTACHMENT')) ? 'topics.topic_attachment' : 0), ''), + array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'), + array('topic_time', 'topics.topic_time', ''), + array('topic_views', 'topics.topic_views', ''), + array('topic_posts_approved', 'topics.topic_replies', 'phpbb_topic_replies_to_posts'), + array('topic_posts_unapproved', 0, ''), + array('topic_posts_softdeleted',0, ''), + array('topic_last_post_id', 'topics.topic_last_post_id', ''), + array('topic_status', 'topics.topic_status', 'is_topic_locked'), + array('topic_moved_id', 0, ''), + array('topic_type', 'topics.topic_type', 'phpbb_convert_topic_type'), + array('topic_first_post_id', 'topics.topic_first_post_id', ''), + array('topic_last_view_time', 'posts.post_time', 'intval'), + array('topic_visibility', ITEM_APPROVED, ''), + + array('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => 'htmlspecialchars_decode', 'function4' => 'utf8_htmlspecialchars')), + array('poll_start', 'vote_desc.vote_start', 'null_to_zero'), + array('poll_length', 'vote_desc.vote_length', 'null_to_zero'), + array('poll_max_options', 1, ''), + array('poll_vote_change', 0, ''), + + 'left_join' => array ( 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1', + 'topics LEFT JOIN posts ON topics.topic_last_post_id = posts.post_id', + ), + 'where' => 'topics.topic_moved_id = 0', + ), + + array( + 'target' => TOPICS_TABLE, + 'primary' => 'topics.topic_id', + 'autoincrement' => 'topic_id', + + array('topic_id', 'topics.topic_id', ''), + array('forum_id', 'topics.forum_id', ''), + array('icon_id', 0, ''), + array('topic_poster', 'topics.topic_poster AS poster_id', 'phpbb_user_id'), + array('topic_attachment', ((defined('MOD_ATTACHMENT')) ? 'topics.topic_attachment' : 0), ''), + array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'), + array('topic_time', 'topics.topic_time', ''), + array('topic_views', 'topics.topic_views', ''), + array('topic_posts_approved', 'topics.topic_replies', 'phpbb_topic_replies_to_posts'), + array('topic_posts_unapproved', 0, ''), + array('topic_posts_softdeleted',0, ''), + array('topic_last_post_id', 'topics.topic_last_post_id', ''), + array('topic_status', ITEM_MOVED, ''), + array('topic_moved_id', 'topics.topic_moved_id', ''), + array('topic_type', 'topics.topic_type', 'phpbb_convert_topic_type'), + array('topic_first_post_id', 'topics.topic_first_post_id', ''), + array('topic_visibility', ITEM_APPROVED, ''), + + array('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => 'htmlspecialchars_decode', 'function4' => 'utf8_htmlspecialchars')), + array('poll_start', 'vote_desc.vote_start', 'null_to_zero'), + array('poll_length', 'vote_desc.vote_length', 'null_to_zero'), + array('poll_max_options', 1, ''), + array('poll_vote_change', 0, ''), + + 'left_join' => 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1', + 'where' => 'topics.topic_moved_id <> 0', + ), + + array( + 'target' => TOPICS_WATCH_TABLE, + 'primary' => 'topics_watch.topic_id', + 'query_first' => array('target', $convert->truncate_statement . TOPICS_WATCH_TABLE), + + array('topic_id', 'topics_watch.topic_id', ''), + array('user_id', 'topics_watch.user_id', 'phpbb_user_id'), + array('notify_status', 'topics_watch.notify_status', ''), + ), + + array( + 'target' => SMILIES_TABLE, + 'query_first' => array('target', $convert->truncate_statement . SMILIES_TABLE), + 'autoincrement' => 'smiley_id', + + array('smiley_id', 'smilies.smilies_id', ''), + array('code', 'smilies.code', array('function1' => 'phpbb_smilie_html_decode', 'function2' => 'phpbb_set_encoding', 'function3' => 'utf8_htmlspecialchars')), + array('emotion', 'smilies.emoticon', 'phpbb_set_encoding'), + array('smiley_url', 'smilies.smile_url', 'import_smiley'), + array('smiley_width', 'smilies.smile_url', 'get_smiley_width'), + array('smiley_height', 'smilies.smile_url', 'get_smiley_height'), + array('smiley_order', 'smilies.smilies_id', ''), + array('display_on_posting', 'smilies.smilies_id', 'get_smiley_display'), + + 'order_by' => 'smilies.smilies_id ASC', + ), + + array( + 'target' => POLL_OPTIONS_TABLE, + 'primary' => 'vote_results.vote_option_id', + 'query_first' => array('target', $convert->truncate_statement . POLL_OPTIONS_TABLE), + + array('poll_option_id', 'vote_results.vote_option_id', ''), + array('topic_id', 'vote_desc.topic_id', ''), + array('', 'topics.topic_poster AS poster_id', 'phpbb_user_id'), + array('poll_option_text', 'vote_results.vote_option_text', array('function1' => 'phpbb_set_encoding', 'function2' => 'htmlspecialchars_decode', 'function3' => 'utf8_htmlspecialchars')), + array('poll_option_total', 'vote_results.vote_result', ''), + + 'where' => 'vote_results.vote_id = vote_desc.vote_id', + 'left_join' => 'vote_desc LEFT JOIN topics ON topics.topic_id = vote_desc.topic_id', + ), + + array( + 'target' => POLL_VOTES_TABLE, + 'primary' => 'vote_desc.topic_id', + 'query_first' => array('target', $convert->truncate_statement . POLL_VOTES_TABLE), + + array('poll_option_id', VOTE_CONVERTED, ''), + array('topic_id', 'vote_desc.topic_id', ''), + array('vote_user_id', 'vote_voters.vote_user_id', 'phpbb_user_id'), + array('vote_user_ip', 'vote_voters.vote_user_ip', 'decode_ip'), + + 'where' => 'vote_voters.vote_id = vote_desc.vote_id', + ), + + array( + 'target' => WORDS_TABLE, + 'primary' => 'words.word_id', + 'query_first' => array('target', $convert->truncate_statement . WORDS_TABLE), + 'autoincrement' => 'word_id', + + array('word_id', 'words.word_id', ''), + array('word', 'words.word', 'phpbb_set_encoding'), + array('replacement', 'words.replacement', 'phpbb_set_encoding'), + ), + + array( + 'target' => POSTS_TABLE, + 'primary' => 'posts.post_id', + 'autoincrement' => 'post_id', + 'query_first' => array('target', $convert->truncate_statement . POSTS_TABLE), + 'execute_first' => ' + $config["max_post_chars"] = 0; + $config["min_post_chars"] = 0; + $config["max_quote_depth"] = 0; + ', + + array('post_id', 'posts.post_id', ''), + array('topic_id', 'posts.topic_id', ''), + array('forum_id', 'posts.forum_id', ''), + array('poster_id', 'posts.poster_id', 'phpbb_user_id'), + array('icon_id', 0, ''), + array('poster_ip', 'posts.poster_ip', 'decode_ip'), + array('post_time', 'posts.post_time', ''), + array('enable_bbcode', 'posts.enable_bbcode', ''), + array('', 'posts.enable_html', ''), + array('enable_smilies', 'posts.enable_smilies', ''), + array('enable_sig', 'posts.enable_sig', ''), + array('enable_magic_url', 1, ''), + array('post_username', 'posts.post_username', 'phpbb_set_encoding'), + array('post_subject', 'posts_text.post_subject', 'phpbb_set_encoding'), + array('post_attachment', ((defined('MOD_ATTACHMENT')) ? 'posts.post_attachment' : 0), ''), + array('post_edit_time', 'posts.post_edit_time', array('typecast' => 'int')), + array('post_edit_count', 'posts.post_edit_count', ''), + array('post_edit_reason', '', ''), + array('post_edit_user', '', 'phpbb_post_edit_user'), + array('post_visibility', ITEM_APPROVED, ''), + + array('bbcode_uid', 'posts.post_time', 'make_uid'), + array('post_text', 'posts_text.post_text', 'phpbb_prepare_message'), + array('', 'posts_text.bbcode_uid AS old_bbcode_uid', ''), + array('bbcode_bitfield', '', 'get_bbcode_bitfield'), + array('post_checksum', '', ''), + + // Commented out inline search indexing, this takes up a LOT of time. :D + // @todo We either need to enable this or call the rebuild search functionality post convert +/* array('', '', 'search_indexing'), + array('', 'posts_text.post_text AS message', ''), + array('', 'posts_text.post_subject AS title', ''),*/ + + 'where' => 'posts.post_id = posts_text.post_id' + ), + + array( + 'target' => PRIVMSGS_TABLE, + 'primary' => 'privmsgs.privmsgs_id', + 'autoincrement' => 'msg_id', + 'query_first' => array( + array('target', $convert->truncate_statement . PRIVMSGS_TABLE), + array('target', $convert->truncate_statement . PRIVMSGS_RULES_TABLE), + ), + + 'execute_first' => ' + $config["max_post_chars"] = 0; + $config["min_post_chars"] = 0; + $config["max_quote_depth"] = 0; + ', + + array('msg_id', 'privmsgs.privmsgs_id', ''), + array('root_level', 0, ''), + array('author_id', 'privmsgs.privmsgs_from_userid AS poster_id', 'phpbb_user_id'), + array('icon_id', 0, ''), + array('author_ip', 'privmsgs.privmsgs_ip', 'decode_ip'), + array('message_time', 'privmsgs.privmsgs_date', ''), + array('enable_bbcode', 'privmsgs.privmsgs_enable_bbcode AS enable_bbcode', ''), + array('', 'privmsgs.privmsgs_enable_html AS enable_html', ''), + array('enable_smilies', 'privmsgs.privmsgs_enable_smilies AS enable_smilies', ''), + array('enable_magic_url', 1, ''), + array('enable_sig', 'privmsgs.privmsgs_attach_sig', ''), + array('message_subject', 'privmsgs.privmsgs_subject', 'phpbb_set_encoding'), // Already specialchared in 2.0.x + array('message_attachment', ((defined('MOD_ATTACHMENT')) ? 'privmsgs.privmsgs_attachment' : 0), ''), + array('message_edit_reason', '', ''), + array('message_edit_user', 0, ''), + array('message_edit_time', 0, ''), + array('message_edit_count', 0, ''), + + array('bbcode_uid', 'privmsgs.privmsgs_date AS post_time', 'make_uid'), + array('message_text', 'privmsgs_text.privmsgs_text', 'phpbb_prepare_message'), + array('', 'privmsgs_text.privmsgs_bbcode_uid AS old_bbcode_uid', ''), + array('bbcode_bitfield', '', 'get_bbcode_bitfield'), + array('to_address', 'privmsgs.privmsgs_to_userid', 'phpbb_privmsgs_to_userid'), + array('bcc_address', '', ''), + + 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id' + ), + + array( + 'target' => PRIVMSGS_FOLDER_TABLE, + 'primary' => 'users.user_id', + 'query_first' => array('target', $convert->truncate_statement . PRIVMSGS_FOLDER_TABLE), + + array('user_id', 'users.user_id', 'phpbb_user_id'), + array('folder_name', $user->lang['CONV_SAVED_MESSAGES'], ''), + array('pm_count', 0, ''), + + 'where' => 'users.user_id <> -1', + ), + + // Inbox + array( + 'target' => PRIVMSGS_TO_TABLE, + 'primary' => 'privmsgs.privmsgs_id', + 'query_first' => array('target', $convert->truncate_statement . PRIVMSGS_TO_TABLE), + + array('msg_id', 'privmsgs.privmsgs_id', ''), + array('user_id', 'privmsgs.privmsgs_to_userid', 'phpbb_user_id'), + array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), + array('pm_deleted', 0, ''), + array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'), + array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'), + array('pm_replied', 0, ''), + array('pm_marked', 0, ''), + array('pm_forwarded', 0, ''), + array('folder_id', PRIVMSGS_INBOX, ''), + + 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id + AND (privmsgs.privmsgs_type = 0 OR privmsgs.privmsgs_type = 1 OR privmsgs.privmsgs_type = 5)', + ), + + // Outbox + array( + 'target' => PRIVMSGS_TO_TABLE, + 'primary' => 'privmsgs.privmsgs_id', + + array('msg_id', 'privmsgs.privmsgs_id', ''), + array('user_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), + array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), + array('pm_deleted', 0, ''), + array('pm_new', 0, ''), + array('pm_unread', 0, ''), + array('pm_replied', 0, ''), + array('pm_marked', 0, ''), + array('pm_forwarded', 0, ''), + array('folder_id', PRIVMSGS_OUTBOX, ''), + + 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id + AND (privmsgs.privmsgs_type = 1 OR privmsgs.privmsgs_type = 5)', + ), + + // Sentbox + array( + 'target' => PRIVMSGS_TO_TABLE, + 'primary' => 'privmsgs.privmsgs_id', + + array('msg_id', 'privmsgs.privmsgs_id', ''), + array('user_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), + array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), + array('pm_deleted', 0, ''), + array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'), + array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'), + array('pm_replied', 0, ''), + array('pm_marked', 0, ''), + array('pm_forwarded', 0, ''), + array('folder_id', PRIVMSGS_SENTBOX, ''), + + 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id + AND privmsgs.privmsgs_type = 2', + ), + + // Savebox (SAVED IN) + array( + 'target' => PRIVMSGS_TO_TABLE, + 'primary' => 'privmsgs.privmsgs_id', + + array('msg_id', 'privmsgs.privmsgs_id', ''), + array('user_id', 'privmsgs.privmsgs_to_userid', 'phpbb_user_id'), + array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), + array('pm_deleted', 0, ''), + array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'), + array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'), + array('pm_replied', 0, ''), + array('pm_marked', 0, ''), + array('pm_forwarded', 0, ''), + array('folder_id', 'privmsgs.privmsgs_to_userid', 'phpbb_get_savebox_id'), + + 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id + AND privmsgs.privmsgs_type = 3', + ), + + // Savebox (SAVED OUT) + array( + 'target' => PRIVMSGS_TO_TABLE, + 'primary' => 'privmsgs.privmsgs_id', + + array('msg_id', 'privmsgs.privmsgs_id', ''), + array('user_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), + array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), + array('pm_deleted', 0, ''), + array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'), + array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'), + array('pm_replied', 0, ''), + array('pm_marked', 0, ''), + array('pm_forwarded', 0, ''), + array('folder_id', 'privmsgs.privmsgs_from_userid', 'phpbb_get_savebox_id'), + + 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id + AND privmsgs.privmsgs_type = 4', + ), + + array( + 'target' => GROUPS_TABLE, + 'autoincrement' => 'group_id', + 'query_first' => array( + array('target', $convert->truncate_statement . GROUPS_TABLE), + array('target', $convert->truncate_statement . TEAMPAGE_TABLE), + ), + + array('group_id', 'groups.group_id', ''), + array('group_type', 'groups.group_type', 'phpbb_convert_group_type'), + array('group_display', 0, ''), + array('group_legend', 0, ''), + array('group_name', 'groups.group_name', 'phpbb_convert_group_name'), // phpbb_set_encoding called in phpbb_convert_group_name + array('group_desc', 'groups.group_description', 'phpbb_set_encoding'), + + 'where' => 'groups.group_single_user = 0', + ), + + array( + 'target' => USER_GROUP_TABLE, + 'query_first' => array('target', $convert->truncate_statement . USER_GROUP_TABLE), + 'execute_first' => ' + add_default_groups(); + add_groups_to_teampage(); + ', + + array('group_id', 'groups.group_id', ''), + array('user_id', 'groups.group_moderator', 'phpbb_user_id'), + array('group_leader', 1, ''), + array('user_pending', 0, ''), + + 'where' => 'groups.group_single_user = 0 AND groups.group_moderator <> 0', + ), + + array( + 'target' => USER_GROUP_TABLE, + + array('group_id', 'user_group.group_id', ''), + array('user_id', 'user_group.user_id', 'phpbb_user_id'), + array('group_leader', 0, ''), + array('user_pending', 'user_group.user_pending', ''), + + 'where' => 'user_group.group_id = groups.group_id AND groups.group_single_user = 0 AND groups.group_moderator <> user_group.user_id', + ), + + array( + 'target' => USERS_TABLE, + 'primary' => 'users.user_id', + 'autoincrement' => 'user_id', + 'query_first' => array( + array('target', 'DELETE FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS), + array('target', $convert->truncate_statement . BOTS_TABLE), + array('target', $convert->truncate_statement . USER_NOTIFICATIONS_TABLE), + ), + + 'execute_last' => ' + remove_invalid_users(); + ', + + array('user_id', 'users.user_id', 'phpbb_user_id'), + array('', 'users.user_id AS poster_id', 'phpbb_user_id'), + array('user_type', 'users.user_active', 'set_user_type'), + array('group_id', 'users.user_level', 'phpbb_set_primary_group'), + array('user_regdate', 'users.user_regdate', ''), + array('username', 'users.username', 'phpbb_set_default_encoding'), // recode to utf8 with default lang + array('username_clean', 'users.username', array('function1' => 'phpbb_set_default_encoding', 'function2' => 'utf8_clean_string')), + array('user_password', 'users.user_password', 'phpbb_convert_password_hash'), + array('user_posts', 'users.user_posts', 'intval'), + array('user_email', 'users.user_email', 'strtolower'), + array('user_email_hash', 'users.user_email', 'gen_email_hash'), + array('user_birthday', ((defined('MOD_BIRTHDAY')) ? 'users.user_birthday' : ''), 'phpbb_get_birthday'), + array('user_lastvisit', 'users.user_lastvisit', 'intval'), + array('user_lastmark', 'users.user_lastvisit', 'intval'), + array('user_lang', $config['default_lang'], ''), + array('', 'users.user_lang', ''), + array('user_timezone', 'users.user_timezone', 'phpbb_convert_timezone'), + array('user_dateformat', 'users.user_dateformat', array('function1' => 'phpbb_set_encoding', 'function2' => 'fill_dateformat')), + array('user_inactive_reason', '', 'phpbb_inactive_reason'), + array('user_inactive_time', '', 'phpbb_inactive_time'), + + array('user_jabber', '', ''), + array('user_rank', 'users.user_rank', 'intval'), + array('user_permissions', '', ''), + + array('user_avatar', 'users.user_avatar', 'phpbb_import_avatar'), + array('user_avatar_type', 'users.user_avatar_type', 'phpbb_avatar_type'), + array('user_avatar_width', 'users.user_avatar', 'phpbb_get_avatar_width'), + array('user_avatar_height', 'users.user_avatar', 'phpbb_get_avatar_height'), + + array('user_new_privmsg', 'users.user_new_privmsg', ''), + array('user_unread_privmsg', 0, ''), //'users.user_unread_privmsg' + array('user_last_privmsg', 'users.user_last_privmsg', 'intval'), + array('user_emailtime', 'users.user_emailtime', 'null_to_zero'), + array('user_notify', 'users.user_notify', 'intval'), + array('user_notify_pm', 'users.user_notify_pm', 'intval'), + array('user_notify_type', NOTIFY_EMAIL, ''), + array('user_allow_pm', 'users.user_allow_pm', 'intval'), + array('user_allow_viewonline', 'users.user_allow_viewonline', 'intval'), + array('user_allow_viewemail', 'users.user_viewemail', 'intval'), + array('user_actkey', 'users.user_actkey', ''), + array('user_newpasswd', '', ''), // Users need to re-request their password... + array('user_style', $config['default_style'], ''), + + array('user_options', '', 'set_user_options'), + array('', 'users.user_popup_pm AS popuppm', ''), + array('', 'users.user_allowhtml AS html', ''), + array('', 'users.user_allowbbcode AS bbcode', ''), + array('', 'users.user_allowsmile AS smile', ''), + array('', 'users.user_attachsig AS attachsig',''), + + array('user_sig_bbcode_uid', 'users.user_regdate', 'make_uid'), + array('user_sig', 'users.user_sig', 'phpbb_prepare_message'), + array('', 'users.user_sig_bbcode_uid AS old_bbcode_uid', ''), + array('user_sig_bbcode_bitfield', '', 'get_bbcode_bitfield'), + array('', 'users.user_regdate AS post_time', ''), + + array('', 'users.user_notify_pm', 'phpbb_add_notification_options'), + + 'where' => 'users.user_id <> -1', + ), + + array( + 'target' => PROFILE_FIELDS_DATA_TABLE, + 'primary' => 'users.user_id', + 'query_first' => array( + array('target', $convert->truncate_statement . PROFILE_FIELDS_DATA_TABLE), + ), + + array('user_id', 'users.user_id', 'phpbb_user_id'), + array('pf_phpbb_occupation', 'users.user_occ', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_interests', 'users.user_interests', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_location', 'users.user_from', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_icq', 'users.user_icq', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_wlm', 'users.user_msnm', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_yahoo', 'users.user_yim', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_aol', 'users.user_aim', array('function1' => 'phpbb_set_encoding')), + array('pf_phpbb_website', 'users.user_website', 'validate_website'), + + 'where' => 'users.user_id <> -1', + ), + ), + ); +} diff --git a/phpBB/install/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php new file mode 100644 index 0000000000..48cff426b8 --- /dev/null +++ b/phpBB/install/convertors/functions_phpbb20.php @@ -0,0 +1,1984 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +if (!defined('IN_PHPBB')) +{ + exit; +} + +/** +* Helper functions for phpBB 2.0.x to phpBB 3.1.x conversion +*/ + +/** +* Set forum flags - only prune old polls by default +*/ +function phpbb_forum_flags() +{ + // Set forum flags + $forum_flags = 0; + + // FORUM_FLAG_LINK_TRACK + $forum_flags += 0; + + // FORUM_FLAG_PRUNE_POLL + $forum_flags += FORUM_FLAG_PRUNE_POLL; + + // FORUM_FLAG_PRUNE_ANNOUNCE + $forum_flags += 0; + + // FORUM_FLAG_PRUNE_STICKY + $forum_flags += 0; + + // FORUM_FLAG_ACTIVE_TOPICS + $forum_flags += 0; + + // FORUM_FLAG_POST_REVIEW + $forum_flags += FORUM_FLAG_POST_REVIEW; + + return $forum_flags; +} + +/** +* Insert/Convert forums +*/ +function phpbb_insert_forums() +{ + global $db, $src_db, $same_db, $convert, $user, $config; + + $db->sql_query($convert->truncate_statement . FORUMS_TABLE); + + // Determine the highest id used within the old forums table (we add the categories after the forum ids) + $sql = 'SELECT MAX(forum_id) AS max_forum_id + FROM ' . $convert->src_table_prefix . 'forums'; + $result = $src_db->sql_query($sql); + $max_forum_id = (int) $src_db->sql_fetchfield('max_forum_id'); + $src_db->sql_freeresult($result); + + $max_forum_id++; + + // pruning disabled globally? + $sql = "SELECT config_value + FROM {$convert->src_table_prefix}config + WHERE config_name = 'prune_enable'"; + $result = $src_db->sql_query($sql); + $prune_enabled = (int) $src_db->sql_fetchfield('config_value'); + $src_db->sql_freeresult($result); + + // Insert categories + $sql = 'SELECT cat_id, cat_title + FROM ' . $convert->src_table_prefix . 'categories + ORDER BY cat_order'; + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'binary'"); + } + + $result = $src_db->sql_query($sql); + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'utf8'"); + } + + switch ($db->get_sql_layer()) + { + case 'mssql': + case 'mssql_odbc': + case 'mssqlnative': + $db->sql_query('SET IDENTITY_INSERT ' . FORUMS_TABLE . ' ON'); + break; + } + + $cats_added = array(); + while ($row = $src_db->sql_fetchrow($result)) + { + $sql_ary = array( + 'forum_id' => (int) $max_forum_id, + 'forum_name' => ($row['cat_title']) ? htmlspecialchars(phpbb_set_default_encoding($row['cat_title']), ENT_COMPAT, 'UTF-8') : $user->lang['CATEGORY'], + 'parent_id' => 0, + 'forum_parents' => '', + 'forum_desc' => '', + 'forum_type' => FORUM_CAT, + 'forum_status' => ITEM_UNLOCKED, + 'forum_rules' => '', + ); + + $sql = 'SELECT MAX(right_id) AS right_id + FROM ' . FORUMS_TABLE; + $_result = $db->sql_query($sql); + $cat_row = $db->sql_fetchrow($_result); + $db->sql_freeresult($_result); + + $sql_ary['left_id'] = (int) ($cat_row['right_id'] + 1); + $sql_ary['right_id'] = (int) ($cat_row['right_id'] + 2); + + $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); + $db->sql_query($sql); + + $cats_added[$row['cat_id']] = $max_forum_id; + $max_forum_id++; + } + $src_db->sql_freeresult($result); + + // There may be installations having forums with non-existant category ids. + // We try to catch them and add them to an "unknown" category instead of leaving them out. + $sql = 'SELECT cat_id + FROM ' . $convert->src_table_prefix . 'forums + GROUP BY cat_id'; + $result = $src_db->sql_query($sql); + + $unknown_cat_id = false; + while ($row = $src_db->sql_fetchrow($result)) + { + // Catch those categories not been added before + if (!isset($cats_added[$row['cat_id']])) + { + $unknown_cat_id = true; + } + } + $src_db->sql_freeresult($result); + + // Is there at least one category not known? + if ($unknown_cat_id === true) + { + $unknown_cat_id = 'ghost'; + + $sql_ary = array( + 'forum_id' => (int) $max_forum_id, + 'forum_name' => (string) $user->lang['CATEGORY'], + 'parent_id' => 0, + 'forum_parents' => '', + 'forum_desc' => '', + 'forum_type' => FORUM_CAT, + 'forum_status' => ITEM_UNLOCKED, + 'forum_rules' => '', + ); + + $sql = 'SELECT MAX(right_id) AS right_id + FROM ' . FORUMS_TABLE; + $_result = $db->sql_query($sql); + $cat_row = $db->sql_fetchrow($_result); + $db->sql_freeresult($_result); + + $sql_ary['left_id'] = (int) ($cat_row['right_id'] + 1); + $sql_ary['right_id'] = (int) ($cat_row['right_id'] + 2); + + $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); + $db->sql_query($sql); + + $cats_added[$unknown_cat_id] = $max_forum_id; + $max_forum_id++; + } + + // Now insert the forums + $sql = 'SELECT f.forum_id, f.forum_name, f.cat_id, f.forum_desc, f.forum_status, f.prune_enable, f.prune_next, fp.prune_days, fp.prune_freq FROM ' . $convert->src_table_prefix . 'forums f + LEFT JOIN ' . $convert->src_table_prefix . 'forum_prune fp ON f.forum_id = fp.forum_id + GROUP BY f.forum_id, f.forum_name, f.cat_id, f.forum_desc, f.forum_status, f.prune_enable, f.prune_next, f.forum_order, fp.prune_days, fp.prune_freq + ORDER BY f.cat_id, f.forum_order'; + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'binary'"); + } + + $result = $src_db->sql_query($sql); + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'utf8'"); + } + + while ($row = $src_db->sql_fetchrow($result)) + { + // Some might have forums here with an id not being "possible"... + // To be somewhat friendly we "change" the category id for those to a previously created ghost category + if (!isset($cats_added[$row['cat_id']]) && $unknown_cat_id !== false) + { + $row['cat_id'] = $unknown_cat_id; + } + + if (!isset($cats_added[$row['cat_id']])) + { + continue; + } + + // Define the new forums sql ary + $sql_ary = array( + 'forum_id' => (int) $row['forum_id'], + 'forum_name' => htmlspecialchars(phpbb_set_default_encoding($row['forum_name']), ENT_COMPAT, 'UTF-8'), + 'parent_id' => (int) $cats_added[$row['cat_id']], + 'forum_parents' => '', + 'forum_desc' => htmlspecialchars(phpbb_set_default_encoding($row['forum_desc']), ENT_COMPAT, 'UTF-8'), + 'forum_type' => FORUM_POST, + 'forum_status' => is_item_locked($row['forum_status']), + 'enable_prune' => ($prune_enabled) ? (int) $row['prune_enable'] : 0, + 'prune_next' => (int) null_to_zero($row['prune_next']), + 'prune_days' => (int) null_to_zero($row['prune_days']), + 'prune_viewed' => 0, + 'prune_freq' => (int) null_to_zero($row['prune_freq']), + + 'forum_flags' => phpbb_forum_flags(), + 'forum_options' => 0, + + // Default values + 'forum_desc_bitfield' => '', + 'forum_desc_options' => 7, + 'forum_desc_uid' => '', + 'forum_link' => '', + 'forum_password' => '', + 'forum_style' => 0, + 'forum_image' => '', + 'forum_rules' => '', + 'forum_rules_link' => '', + 'forum_rules_bitfield' => '', + 'forum_rules_options' => 7, + 'forum_rules_uid' => '', + 'forum_topics_per_page' => 0, + 'forum_posts_approved' => 0, + 'forum_posts_unapproved' => 0, + 'forum_posts_softdeleted' => 0, + 'forum_topics_approved' => 0, + 'forum_topics_unapproved' => 0, + 'forum_topics_softdeleted' => 0, + 'forum_last_post_id' => 0, + 'forum_last_poster_id' => 0, + 'forum_last_post_subject' => '', + 'forum_last_post_time' => 0, + 'forum_last_poster_name' => '', + 'forum_last_poster_colour' => '', + 'display_on_index' => 1, + 'enable_indexing' => 1, + 'enable_icons' => 0, + ); + + // Now add the forums with proper left/right ids + $sql = 'SELECT left_id, right_id + FROM ' . FORUMS_TABLE . ' + WHERE forum_id = ' . $cats_added[$row['cat_id']]; + $_result = $db->sql_query($sql); + $cat_row = $db->sql_fetchrow($_result); + $db->sql_freeresult($_result); + + $sql = 'UPDATE ' . FORUMS_TABLE . ' + SET left_id = left_id + 2, right_id = right_id + 2 + WHERE left_id > ' . $cat_row['right_id']; + $db->sql_query($sql); + + $sql = 'UPDATE ' . FORUMS_TABLE . ' + SET right_id = right_id + 2 + WHERE ' . $cat_row['left_id'] . ' BETWEEN left_id AND right_id'; + $db->sql_query($sql); + + $sql_ary['left_id'] = (int) $cat_row['right_id']; + $sql_ary['right_id'] = (int) ($cat_row['right_id'] + 1); + + $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); + $db->sql_query($sql); + } + $src_db->sql_freeresult($result); + + switch ($db->get_sql_layer()) + { + case 'postgres': + $db->sql_query("SELECT SETVAL('" . FORUMS_TABLE . "_seq',(select case when max(forum_id)>0 then max(forum_id)+1 else 1 end from " . FORUMS_TABLE . '));'); + break; + + case 'mssql': + case 'mssql_odbc': + case 'mssqlnative': + $db->sql_query('SET IDENTITY_INSERT ' . FORUMS_TABLE . ' OFF'); + break; + + case 'oracle': + $result = $db->sql_query('SELECT MAX(forum_id) as max_id FROM ' . FORUMS_TABLE); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $largest_id = (int) $row['max_id']; + + if ($largest_id) + { + $db->sql_query('DROP SEQUENCE ' . FORUMS_TABLE . '_seq'); + $db->sql_query('CREATE SEQUENCE ' . FORUMS_TABLE . '_seq START WITH ' . ($largest_id + 1)); + } + break; + } +} + +/** +* Function for recoding text with the default language +* +* @param string $text text to recode to utf8 +* @param bool $grab_user_lang if set to true the function tries to use $convert_row['user_lang'] (and falls back to $convert_row['poster_id']) instead of the boards default language +*/ +function phpbb_set_encoding($text, $grab_user_lang = true) +{ + global $lang_enc_array, $convert_row; + global $convert, $phpEx; + + /*static $lang_enc_array = array( + 'korean' => 'euc-kr', + 'serbian' => 'windows-1250', + 'polish' => 'iso-8859-2', + 'kurdish' => 'windows-1254', + 'slovak' => 'Windows-1250', + 'russian' => 'windows-1251', + 'estonian' => 'iso-8859-4', + 'chinese_simplified' => 'gb2312', + 'macedonian' => 'windows-1251', + 'azerbaijani' => 'UTF-8', + 'romanian' => 'iso-8859-2', + 'romanian_diacritice' => 'iso-8859-2', + 'lithuanian' => 'windows-1257', + 'turkish' => 'iso-8859-9', + 'ukrainian' => 'windows-1251', + 'japanese' => 'shift_jis', + 'hungarian' => 'ISO-8859-2', + 'romanian_no_diacritics' => 'iso-8859-2', + 'mongolian' => 'UTF-8', + 'slovenian' => 'windows-1250', + 'bosnian' => 'windows-1250', + 'czech' => 'Windows-1250', + 'farsi' => 'Windows-1256', + 'croatian' => 'windows-1250', + 'greek' => 'iso-8859-7', + 'russian_tu' => 'windows-1251', + 'sakha' => 'UTF-8', + 'serbian_cyrillic' => 'windows-1251', + 'bulgarian' => 'windows-1251', + 'chinese_traditional_taiwan' => 'big5', + 'chinese_traditional' => 'big5', + 'arabic' => 'windows-1256', + 'hebrew' => 'WINDOWS-1255', + 'thai' => 'windows-874', + //'chinese_traditional_taiwan' => 'utf-8' // custom modified, we may have to do an include :-( + );*/ + + if (empty($lang_enc_array)) + { + $lang_enc_array = array(); + } + + $get_lang = trim(get_config_value('default_lang')); + + // Do we need the users language encoding? + if ($grab_user_lang && !empty($convert_row)) + { + if (!empty($convert_row['user_lang'])) + { + $get_lang = trim($convert_row['user_lang']); + } + else if (!empty($convert_row['poster_id'])) + { + global $src_db, $same_db; + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'binary'"); + } + + $sql = 'SELECT user_lang + FROM ' . $convert->src_table_prefix . 'users + WHERE user_id = ' . (int) $convert_row['poster_id']; + $result = $src_db->sql_query($sql); + $get_lang = (string) $src_db->sql_fetchfield('user_lang'); + $src_db->sql_freeresult($result); + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'utf8'"); + } + + $get_lang = (!trim($get_lang)) ? trim(get_config_value('default_lang')) : trim($get_lang); + } + } + + if (!isset($lang_enc_array[$get_lang])) + { + $filename = $convert->options['forum_path'] . '/language/lang_' . $get_lang . '/lang_main.' . $phpEx; + + if (!file_exists($filename)) + { + $get_lang = trim(get_config_value('default_lang')); + } + + if (!isset($lang_enc_array[$get_lang])) + { + include($convert->options['forum_path'] . '/language/lang_' . $get_lang . '/lang_main.' . $phpEx); + $lang_enc_array[$get_lang] = $lang['ENCODING']; + unset($lang); + } + } + + $encoding = $lang_enc_array[$get_lang]; + + return utf8_recode($text, $lang_enc_array[$get_lang]); +} + +/** +* Same as phpbb_set_encoding, but forcing boards default language +*/ +function phpbb_set_default_encoding($text) +{ + return phpbb_set_encoding($text, false); +} + +/** +* Convert Birthday from Birthday MOD to phpBB Format +*/ +function phpbb_get_birthday($birthday = '') +{ + if (defined('MOD_BIRTHDAY_TERRA')) + { + $birthday = (string) $birthday; + + // stored as month, day, year + if (!$birthday) + { + return ' 0- 0- 0'; + } + + // We use the original mod code to retrieve the birthday (not ideal) + preg_match('/(..)(..)(....)/', sprintf('%08d', $birthday), $birthday_parts); + + $month = $birthday_parts[1]; + $day = $birthday_parts[2]; + $year = $birthday_parts[3]; + + return sprintf('%2d-%2d-%4d', $day, $month, $year); + } + else + { + $birthday = (int) $birthday; + + if (!$birthday || $birthday == 999999) + { + return ' 0- 0- 0'; + } + + // The birthday mod from niels is using this code to transform to day/month/year + return sprintf('%2d-%2d-%4d', gmdate('j', $birthday * 86400 + 1), gmdate('n', $birthday * 86400 + 1), gmdate('Y', $birthday * 86400 + 1)); + } +} + +/** +* Return correct user id value +* Everyone's id will be one higher to allow the guest/anonymous user to have a positive id as well +*/ +function phpbb_user_id($user_id) +{ + global $config; + + // Increment user id if the old forum is having a user with the id 1 + if (!isset($config['increment_user_id'])) + { + global $src_db, $same_db, $convert; + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'binary'"); + } + + // Now let us set a temporary config variable for user id incrementing + $sql = "SELECT user_id + FROM {$convert->src_table_prefix}users + WHERE user_id = 1"; + $result = $src_db->sql_query($sql); + $id = (int) $src_db->sql_fetchfield('user_id'); + $src_db->sql_freeresult($result); + + // Try to get the maximum user id possible... + $sql = "SELECT MAX(user_id) AS max_user_id + FROM {$convert->src_table_prefix}users"; + $result = $src_db->sql_query($sql); + $max_id = (int) $src_db->sql_fetchfield('max_user_id'); + $src_db->sql_freeresult($result); + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'utf8'"); + } + + // If there is a user id 1, we need to increment user ids. :/ + if ($id === 1) + { + $config->set('increment_user_id', ($max_id + 1), false); + $config['increment_user_id'] = $max_id + 1; + } + else + { + $config->set('increment_user_id', 0, false); + $config['increment_user_id'] = 0; + } + } + + // If the old user id is -1 in 2.0.x it is the anonymous user... + if ($user_id == -1) + { + return ANONYMOUS; + } + + if (!empty($config['increment_user_id']) && $user_id == 1) + { + return $config['increment_user_id']; + } + + // A user id of 0 can happen, for example within the ban table if no user is banned... + // Within the posts and topics table this can be "dangerous" but is the fault of the user + // having mods installed (a poster id of 0 is not possible in 2.0.x). + // Therefore, we return the user id "as is". + + return (int) $user_id; +} + +/** +* Return correct user id value +* Everyone's id will be one higher to allow the guest/anonymous user to have a positive id as well +*/ +function phpbb_topic_replies_to_posts($num_replies) +{ + return (int) $num_replies + 1; +} + +/* Copy additional table fields from old forum to new forum if user wants this (for Mod compatibility for example) +function phpbb_copy_table_fields() +{ +} +*/ + +/** +* Convert authentication +* user, group and forum table has to be filled in order to work +*/ +function phpbb_convert_authentication($mode) +{ + global $db, $src_db, $same_db, $convert, $user, $config, $cache; + + if ($mode == 'start') + { + $db->sql_query($convert->truncate_statement . ACL_USERS_TABLE); + $db->sql_query($convert->truncate_statement . ACL_GROUPS_TABLE); + + // What we will do is handling all 2.0.x admins as founder to replicate what is common in 2.0.x. + // After conversion the main admin need to make sure he is removing permissions and the founder status if wanted. + + // Grab user ids of users with user_level of ADMIN + $sql = "SELECT user_id + FROM {$convert->src_table_prefix}users + WHERE user_level = 1 + ORDER BY user_regdate ASC"; + $result = $src_db->sql_query($sql); + + while ($row = $src_db->sql_fetchrow($result)) + { + $user_id = (int) phpbb_user_id($row['user_id']); + // Set founder admin... + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_type = ' . USER_FOUNDER . " + WHERE user_id = $user_id"; + $db->sql_query($sql); + } + $src_db->sql_freeresult($result); + + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = '" . $db->sql_escape('BOTS') . "'"; + $result = $db->sql_query($sql); + $bot_group_id = (int) $db->sql_fetchfield('group_id'); + $db->sql_freeresult($result); + } + + // Grab forum auth information + $sql = "SELECT * + FROM {$convert->src_table_prefix}forums"; + $result = $src_db->sql_query($sql); + + $forum_access = array(); + while ($row = $src_db->sql_fetchrow($result)) + { + $forum_access[$row['forum_id']] = $row; + } + $src_db->sql_freeresult($result); + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'binary'"); + } + // Grab user auth information from 2.0.x board + $sql = "SELECT ug.user_id, aa.* + FROM {$convert->src_table_prefix}auth_access aa, {$convert->src_table_prefix}user_group ug, {$convert->src_table_prefix}groups g, {$convert->src_table_prefix}forums f + WHERE g.group_id = aa.group_id + AND g.group_single_user = 1 + AND ug.group_id = g.group_id + AND f.forum_id = aa.forum_id"; + $result = $src_db->sql_query($sql); + + $user_access = array(); + while ($row = $src_db->sql_fetchrow($result)) + { + $user_access[$row['forum_id']][] = $row; + } + $src_db->sql_freeresult($result); + + // Grab group auth information + $sql = "SELECT g.group_id, aa.* + FROM {$convert->src_table_prefix}auth_access aa, {$convert->src_table_prefix}groups g + WHERE g.group_id = aa.group_id + AND g.group_single_user <> 1"; + $result = $src_db->sql_query($sql); + + $group_access = array(); + while ($row = $src_db->sql_fetchrow($result)) + { + $group_access[$row['forum_id']][] = $row; + } + $src_db->sql_freeresult($result); + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'utf8'"); + } + + // Add Forum Access List + $auth_map = array( + 'auth_view' => array('f_', 'f_list'), + 'auth_read' => array('f_read', 'f_search'), + 'auth_post' => array('f_post', 'f_bbcode', 'f_smilies', 'f_img', 'f_sigs', 'f_postcount', 'f_report', 'f_subscribe', 'f_print', 'f_email'), + 'auth_reply' => 'f_reply', + 'auth_edit' => 'f_edit', + 'auth_delete' => 'f_delete', + 'auth_pollcreate' => 'f_poll', + 'auth_vote' => 'f_vote', + 'auth_announce' => 'f_announce', + 'auth_sticky' => 'f_sticky', + 'auth_attachments' => array('f_attach', 'f_download'), + 'auth_download' => 'f_download', + ); + + // Define the ACL constants used in 2.0 to make the code slightly more readable + define('AUTH_ALL', 0); + define('AUTH_REG', 1); + define('AUTH_ACL', 2); + define('AUTH_MOD', 3); + define('AUTH_ADMIN', 5); + + // A mapping of the simple permissions used by 2.0 + $simple_auth_ary = array( + 'public' => array( + 'auth_view' => AUTH_ALL, + 'auth_read' => AUTH_ALL, + 'auth_post' => AUTH_ALL, + 'auth_reply' => AUTH_ALL, + 'auth_edit' => AUTH_REG, + 'auth_delete' => AUTH_REG, + 'auth_sticky' => AUTH_MOD, + 'auth_announce' => AUTH_MOD, + 'auth_vote' => AUTH_REG, + 'auth_pollcreate' => AUTH_REG, + ), + 'registered' => array( + 'auth_view' => AUTH_ALL, + 'auth_read' => AUTH_ALL, + 'auth_post' => AUTH_REG, + 'auth_reply' => AUTH_REG, + 'auth_edit' => AUTH_REG, + 'auth_delete' => AUTH_REG, + 'auth_sticky' => AUTH_MOD, + 'auth_announce' => AUTH_MOD, + 'auth_vote' => AUTH_REG, + 'auth_pollcreate' => AUTH_REG, + ), + 'registered_hidden' => array( + 'auth_view' => AUTH_REG, + 'auth_read' => AUTH_REG, + 'auth_post' => AUTH_REG, + 'auth_reply' => AUTH_REG, + 'auth_edit' => AUTH_REG, + 'auth_delete' => AUTH_REG, + 'auth_sticky' => AUTH_MOD, + 'auth_announce' => AUTH_MOD, + 'auth_vote' => AUTH_REG, + 'auth_pollcreate' => AUTH_REG, + ), + 'private' => array( + 'auth_view' => AUTH_ALL, + 'auth_read' => AUTH_ACL, + 'auth_post' => AUTH_ACL, + 'auth_reply' => AUTH_ACL, + 'auth_edit' => AUTH_ACL, + 'auth_delete' => AUTH_ACL, + 'auth_sticky' => AUTH_ACL, + 'auth_announce' => AUTH_MOD, + 'auth_vote' => AUTH_ACL, + 'auth_pollcreate' => AUTH_ACL, + ), + 'private_hidden' => array( + 'auth_view' => AUTH_ACL, + 'auth_read' => AUTH_ACL, + 'auth_post' => AUTH_ACL, + 'auth_reply' => AUTH_ACL, + 'auth_edit' => AUTH_ACL, + 'auth_delete' => AUTH_ACL, + 'auth_sticky' => AUTH_ACL, + 'auth_announce' => AUTH_MOD, + 'auth_vote' => AUTH_ACL, + 'auth_pollcreate' => AUTH_ACL, + ), + 'moderator' => array( + 'auth_view' => AUTH_ALL, + 'auth_read' => AUTH_MOD, + 'auth_post' => AUTH_MOD, + 'auth_reply' => AUTH_MOD, + 'auth_edit' => AUTH_MOD, + 'auth_delete' => AUTH_MOD, + 'auth_sticky' => AUTH_MOD, + 'auth_announce' => AUTH_MOD, + 'auth_vote' => AUTH_MOD, + 'auth_pollcreate' => AUTH_MOD, + ), + 'moderator_hidden' => array( + 'auth_view' => AUTH_MOD, + 'auth_read' => AUTH_MOD, + 'auth_post' => AUTH_MOD, + 'auth_reply' => AUTH_MOD, + 'auth_edit' => AUTH_MOD, + 'auth_delete' => AUTH_MOD, + 'auth_sticky' => AUTH_MOD, + 'auth_announce' => AUTH_MOD, + 'auth_vote' => AUTH_MOD, + 'auth_pollcreate' => AUTH_MOD, + ), + ); + + if ($mode == 'start') + { + user_group_auth('guests', 'SELECT user_id, {GUESTS} FROM ' . USERS_TABLE . ' WHERE user_id = ' . ANONYMOUS, false); + user_group_auth('registered', 'SELECT user_id, {REGISTERED} FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS . " AND group_id <> $bot_group_id", false); + + // Selecting from old table + if (!empty($config['increment_user_id'])) + { + $auth_sql = 'SELECT user_id, {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id <> 1'; + user_group_auth('administrators', $auth_sql, true); + + $auth_sql = 'SELECT ' . $config['increment_user_id'] . ' as user_id, {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id = 1'; + user_group_auth('administrators', $auth_sql, true); + } + else + { + $auth_sql = 'SELECT user_id, {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1'; + user_group_auth('administrators', $auth_sql, true); + } + + if (!empty($config['increment_user_id'])) + { + $auth_sql = 'SELECT user_id, {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id <> 1'; + user_group_auth('global_moderators', $auth_sql, true); + + $auth_sql = 'SELECT ' . $config['increment_user_id'] . ' as user_id, {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id = 1'; + user_group_auth('global_moderators', $auth_sql, true); + } + else + { + $auth_sql = 'SELECT user_id, {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1'; + user_group_auth('global_moderators', $auth_sql, true); + } + } + else if ($mode == 'first') + { + // Go through all 2.0.x forums + foreach ($forum_access as $forum) + { + $new_forum_id = (int) $forum['forum_id']; + + // Administrators have full access to all forums whatever happens + mass_auth('group_role', $new_forum_id, 'administrators', 'FORUM_FULL'); + + $matched_type = ''; + foreach ($simple_auth_ary as $key => $auth_levels) + { + $matched = 1; + foreach ($auth_levels as $k => $level) + { + if ($forum[$k] != $auth_levels[$k]) + { + $matched = 0; + } + } + + if ($matched) + { + $matched_type = $key; + break; + } + } + + switch ($matched_type) + { + case 'public': + mass_auth('group_role', $new_forum_id, 'guests', 'FORUM_LIMITED'); + mass_auth('group_role', $new_forum_id, 'registered', 'FORUM_LIMITED_POLLS'); + mass_auth('group_role', $new_forum_id, 'bots', 'FORUM_BOT'); + break; + + case 'registered': + mass_auth('group_role', $new_forum_id, 'guests', 'FORUM_READONLY'); + mass_auth('group_role', $new_forum_id, 'bots', 'FORUM_BOT'); + + // no break; + + case 'registered_hidden': + mass_auth('group_role', $new_forum_id, 'registered', 'FORUM_POLLS'); + break; + + case 'private': + case 'private_hidden': + case 'moderator': + case 'moderator_hidden': + default: + // The permissions don't match a simple set, so we're going to have to map them directly + + // No post approval for all, in 2.0.x this feature does not exist + mass_auth('group', $new_forum_id, 'guests', 'f_noapprove', ACL_YES); + mass_auth('group', $new_forum_id, 'registered', 'f_noapprove', ACL_YES); + + // Go through authentication map + foreach ($auth_map as $old_auth_key => $new_acl) + { + // If old authentication key does not exist we continue + // This is helpful for mods adding additional authentication fields, we need to add them to the auth_map array + if (!isset($forum[$old_auth_key])) + { + continue; + } + + // Now set the new ACL correctly + switch ($forum[$old_auth_key]) + { + // AUTH_ALL + case AUTH_ALL: + mass_auth('group', $new_forum_id, 'guests', $new_acl, ACL_YES); + mass_auth('group', $new_forum_id, 'bots', $new_acl, ACL_YES); + mass_auth('group', $new_forum_id, 'registered', $new_acl, ACL_YES); + break; + + // AUTH_REG + case AUTH_REG: + mass_auth('group', $new_forum_id, 'registered', $new_acl, ACL_YES); + break; + + // AUTH_ACL + case AUTH_ACL: + // Go through the old group access list for this forum + if (isset($group_access[$forum['forum_id']])) + { + foreach ($group_access[$forum['forum_id']] as $index => $access) + { + // We only check for ACL_YES equivalence entry + if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1) + { + mass_auth('group', $new_forum_id, (int) $access['group_id'], $new_acl, ACL_YES); + } + } + } + + if (isset($user_access[$forum['forum_id']])) + { + foreach ($user_access[$forum['forum_id']] as $index => $access) + { + // We only check for ACL_YES equivalence entry + if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1) + { + mass_auth('user', $new_forum_id, (int) phpbb_user_id($access['user_id']), $new_acl, ACL_YES); + } + } + } + break; + + // AUTH_MOD + case AUTH_MOD: + if (isset($group_access[$forum['forum_id']])) + { + foreach ($group_access[$forum['forum_id']] as $index => $access) + { + // We only check for ACL_YES equivalence entry + if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1) + { + mass_auth('group', $new_forum_id, (int) $access['group_id'], $new_acl, ACL_YES); + } + } + } + + if (isset($user_access[$forum['forum_id']])) + { + foreach ($user_access[$forum['forum_id']] as $index => $access) + { + // We only check for ACL_YES equivalence entry + if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1) + { + mass_auth('user', $new_forum_id, (int) phpbb_user_id($access['user_id']), $new_acl, ACL_YES); + } + } + } + break; + } + } + break; + } + } + } + else if ($mode == 'second') + { + // Assign permission roles and other default permissions + + // guests having u_download and u_search ability + $db->sql_query('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) SELECT ' . get_group_id('guests') . ', 0, auth_option_id, 0, 1 FROM ' . ACL_OPTIONS_TABLE . " WHERE auth_option IN ('u_', 'u_download', 'u_search')"); + + // administrators/global mods having full user features + mass_auth('group_role', 0, 'administrators', 'USER_FULL'); + mass_auth('group_role', 0, 'global_moderators', 'USER_FULL'); + + // By default all converted administrators are given full access + mass_auth('group_role', 0, 'administrators', 'ADMIN_FULL'); + + // All registered users are assigned the standard user role + mass_auth('group_role', 0, 'registered', 'USER_STANDARD'); + mass_auth('group_role', 0, 'registered_coppa', 'USER_STANDARD'); + + // Instead of administrators being global moderators we give the MOD_FULL role to global mods (admins already assigned to this group) + mass_auth('group_role', 0, 'global_moderators', 'MOD_FULL'); + + // And now those who have had their avatar rights removed get assigned a more restrictive role + $sql = 'SELECT user_id FROM ' . $convert->src_table_prefix . 'users + WHERE user_allowavatar = 0 + AND user_id > 0'; + $result = $src_db->sql_query($sql); + + while ($row = $src_db->sql_fetchrow($result)) + { + mass_auth('user_role', 0, (int) phpbb_user_id($row['user_id']), 'USER_NOAVATAR'); + } + $src_db->sql_freeresult($result); + + // And the same for those who have had their PM rights removed + $sql = 'SELECT user_id FROM ' . $convert->src_table_prefix . 'users + WHERE user_allow_pm = 0 + AND user_id > 0'; + $result = $src_db->sql_query($sql); + + while ($row = $src_db->sql_fetchrow($result)) + { + mass_auth('user_role', 0, (int) phpbb_user_id($row['user_id']), 'USER_NOPM'); + } + $src_db->sql_freeresult($result); + } + else if ($mode == 'third') + { + // And now the moderators + // We make sure that they have at least standard access to the forums they moderate in addition to the moderating permissions + + $mod_post_map = array( + 'auth_announce' => 'f_announce', + 'auth_sticky' => 'f_sticky' + ); + + foreach ($user_access as $forum_id => $access_map) + { + $forum_id = (int) $forum_id; + + foreach ($access_map as $access) + { + if (isset($access['auth_mod']) && $access['auth_mod'] == 1) + { + mass_auth('user_role', $forum_id, (int) phpbb_user_id($access['user_id']), 'MOD_STANDARD'); + mass_auth('user_role', $forum_id, (int) phpbb_user_id($access['user_id']), 'FORUM_STANDARD'); + foreach ($mod_post_map as $old => $new) + { + if (isset($forum_access[$forum_id]) && isset($forum_access[$forum_id][$old]) && $forum_access[$forum_id][$old] == AUTH_MOD) + { + mass_auth('user', $forum_id, (int) phpbb_user_id($access['user_id']), $new, ACL_YES); + } + } + } + } + } + + foreach ($group_access as $forum_id => $access_map) + { + $forum_id = (int) $forum_id; + + foreach ($access_map as $access) + { + if (isset($access['auth_mod']) && $access['auth_mod'] == 1) + { + mass_auth('group_role', $forum_id, (int) $access['group_id'], 'MOD_STANDARD'); + mass_auth('group_role', $forum_id, (int) $access['group_id'], 'FORUM_STANDARD'); + foreach ($mod_post_map as $old => $new) + { + if (isset($forum_access[$forum_id]) && isset($forum_access[$forum_id][$old]) && $forum_access[$forum_id][$old] == AUTH_MOD) + { + mass_auth('group', $forum_id, (int) $access['group_id'], $new, ACL_YES); + } + } + } + } + } + + // We grant everyone readonly access to the categories to ensure that the forums are visible + $sql = 'SELECT forum_id, forum_name, parent_id, left_id, right_id + FROM ' . FORUMS_TABLE . ' + ORDER BY left_id ASC'; + $result = $db->sql_query($sql); + + $parent_forums = $forums = array(); + while ($row = $db->sql_fetchrow($result)) + { + if ($row['parent_id'] == 0) + { + mass_auth('group_role', $row['forum_id'], 'administrators', 'FORUM_FULL'); + mass_auth('group_role', $row['forum_id'], 'global_moderators', 'FORUM_FULL'); + $parent_forums[] = $row; + } + else + { + $forums[] = $row; + } + } + $db->sql_freeresult($result); + + global $auth; + + // Let us see which groups have access to these forums... + foreach ($parent_forums as $row) + { + // Get the children + $branch = $forum_ids = array(); + + foreach ($forums as $key => $_row) + { + if ($_row['left_id'] > $row['left_id'] && $_row['left_id'] < $row['right_id']) + { + $branch[] = $_row; + $forum_ids[] = $_row['forum_id']; + continue; + } + } + + if (sizeof($forum_ids)) + { + // Now make sure the user is able to read these forums + $hold_ary = $auth->acl_group_raw_data(false, 'f_list', $forum_ids); + + if (empty($hold_ary)) + { + continue; + } + + foreach ($hold_ary as $g_id => $f_id_ary) + { + $set_group = false; + + foreach ($f_id_ary as $f_id => $auth_ary) + { + foreach ($auth_ary as $auth_option => $setting) + { + if ($setting == ACL_YES) + { + $set_group = true; + break 2; + } + } + } + + if ($set_group) + { + mass_auth('group', $row['forum_id'], $g_id, 'f_list', ACL_YES); + } + } + } + } + } +} + +/** +* Set primary group. +* Really simple and only based on user_level (remaining groups will be assigned later) +*/ +function phpbb_set_primary_group($user_level) +{ + global $convert_row; + + if ($user_level == 1) + { + return get_group_id('administrators'); + } +/* else if ($user_level == 2) + { + return get_group_id('global_moderators'); + } + else if ($user_level == 0 && $convert_row['user_active'])*/ + else if ($convert_row['user_active']) + { + return get_group_id('registered'); + } + + return 0; +} + +/** +* Convert the group name, making sure to avoid conflicts with 3.0 special groups +*/ +function phpbb_convert_group_name($group_name) +{ + $default_groups = array( + 'GUESTS', + 'REGISTERED', + 'REGISTERED_COPPA', + 'GLOBAL_MODERATORS', + 'ADMINISTRATORS', + 'BOTS', + ); + + if (in_array(strtoupper($group_name), $default_groups)) + { + return 'phpBB2 - ' . $group_name; + } + + return phpbb_set_default_encoding($group_name); +} + +/** +* Convert the group type constants +*/ +function phpbb_convert_group_type($group_type) +{ + switch ($group_type) + { + case 0: + return GROUP_OPEN; + break; + + case 1: + return GROUP_CLOSED; + break; + + case 2: + return GROUP_HIDDEN; + break; + } + + // Never return GROUP_SPECIAL here, because only phpBB3's default groups are allowed to have this type set. + return GROUP_HIDDEN; +} + +/** +* Convert the topic type constants +*/ +function phpbb_convert_topic_type($topic_type) +{ + switch ($topic_type) + { + case 0: + return POST_NORMAL; + break; + + case 1: + return POST_STICKY; + break; + + case 2: + return POST_ANNOUNCE; + break; + + case 3: + return POST_GLOBAL; + break; + } + + return POST_NORMAL; +} + +function phpbb_replace_size($matches) +{ + return '[size=' . min(200, ceil(100.0 * (((double) $matches[1])/12.0))) . ':' . $matches[2] . ']'; +} + +/** +* Reparse the message stripping out the bbcode_uid values and adding new ones and setting the bitfield +* @todo What do we want to do about HTML in messages - currently it gets converted to the entities, but there may be some objections to this +*/ +function phpbb_prepare_message($message) +{ + global $phpbb_root_path, $phpEx, $db, $convert, $user, $config, $cache, $convert_row, $message_parser; + + if (!$message) + { + $convert->row['mp_bbcode_bitfield'] = $convert_row['mp_bbcode_bitfield'] = 0; + return ''; + } + + // Decode phpBB 2.0.x Message + if (isset($convert->row['old_bbcode_uid']) && $convert->row['old_bbcode_uid'] != '') + { + // Adjust size... + if (strpos($message, '[size=') !== false) + { + $message = preg_replace_callback('/\[size=(\d*):(' . $convert->row['old_bbcode_uid'] . ')\]/', 'phpbb_replace_size', $message); + } + + $message = preg_replace('/\:(([a-z0-9]:)?)' . $convert->row['old_bbcode_uid'] . '/s', '', $message); + } + + if (strpos($message, '[quote=') !== false) + { + $message = preg_replace('/\[quote="(.*?)"\]/s', '[quote="\1"]', $message); + $message = preg_replace('/\[quote=\\\"(.*?)\\\"\]/s', '[quote="\1"]', $message); + + // let's hope that this solves more problems than it causes. Deal with escaped quotes. + $message = str_replace('\"', '"', $message); + $message = str_replace('\"', '"', $message); + } + + // Already the new user id ;) + $user_id = $convert->row['poster_id']; + + $message = str_replace('
', "\n", $message); + $message = str_replace('<', '<', $message); + $message = str_replace('>', '>', $message); + + // make the post UTF-8 + $message = phpbb_set_encoding($message); + + $message_parser->warn_msg = array(); // Reset the errors from the previous message + $message_parser->bbcode_uid = make_uid($convert->row['post_time']); + $message_parser->message = $message; + unset($message); + + // Make sure options are set. +// $enable_html = (!isset($row['enable_html'])) ? false : $row['enable_html']; + $enable_bbcode = (!isset($convert->row['enable_bbcode'])) ? true : $convert->row['enable_bbcode']; + $enable_smilies = (!isset($convert->row['enable_smilies'])) ? true : $convert->row['enable_smilies']; + $enable_magic_url = (!isset($convert->row['enable_magic_url'])) ? true : $convert->row['enable_magic_url']; + + // parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post') + $message_parser->parse($enable_bbcode, $enable_magic_url, $enable_smilies); + + if (sizeof($message_parser->warn_msg)) + { + $msg_id = isset($convert->row['post_id']) ? $convert->row['post_id'] : $convert->row['privmsgs_id']; + $convert->p_master->error('' . $user->lang['POST_ID'] . ': ' . $msg_id . ' ' . $user->lang['CONV_ERROR_MESSAGE_PARSER'] . ':

' . implode('
', $message_parser->warn_msg), __LINE__, __FILE__, true); + } + + $convert->row['mp_bbcode_bitfield'] = $convert_row['mp_bbcode_bitfield'] = $message_parser->bbcode_bitfield; + + $message = $message_parser->message; + unset($message_parser->message); + + return $message; +} + +/** +* Return the bitfield calculated by the previous function +*/ +function get_bbcode_bitfield() +{ + global $convert_row; + + return $convert_row['mp_bbcode_bitfield']; +} + +/** +* Determine the last user to edit a post +* In practice we only tracked edits by the original poster in 2.0.x so this will only be set if they had edited their own post +*/ +function phpbb_post_edit_user() +{ + global $convert_row, $config; + + if (isset($convert_row['post_edit_count'])) + { + return phpbb_user_id($convert_row['poster_id']); + } + + return 0; +} + +/** +* Obtain the path to uploaded files on the 2.0.x forum +* This is only used if the Attachment MOD was installed +*/ +function phpbb_get_files_dir() +{ + if (!defined('MOD_ATTACHMENT')) + { + return; + } + + global $src_db, $same_db, $convert, $user, $config, $cache; + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'binary'"); + } + $sql = 'SELECT config_value AS upload_dir + FROM ' . $convert->src_table_prefix . "attachments_config + WHERE config_name = 'upload_dir'"; + $result = $src_db->sql_query($sql); + $upload_path = $src_db->sql_fetchfield('upload_dir'); + $src_db->sql_freeresult($result); + + $sql = 'SELECT config_value AS ftp_upload + FROM ' . $convert->src_table_prefix . "attachments_config + WHERE config_name = 'allow_ftp_upload'"; + $result = $src_db->sql_query($sql); + $ftp_upload = (int) $src_db->sql_fetchfield('ftp_upload'); + $src_db->sql_freeresult($result); + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'utf8'"); + } + + if ($ftp_upload) + { + $convert->p_master->error($user->lang['CONV_ERROR_ATTACH_FTP_DIR'], __LINE__, __FILE__); + } + + return $upload_path; +} + +/** +* Copy thumbnails of uploaded images from the 2.0.x forum +* This is only used if the Attachment MOD was installed +*/ +function phpbb_copy_thumbnails() +{ + global $db, $convert, $user, $config, $cache, $phpbb_root_path; + + $src_path = $convert->options['forum_path'] . '/' . phpbb_get_files_dir() . '/thumbs/'; + + if ($handle = @opendir($src_path)) + { + while ($entry = readdir($handle)) + { + if ($entry[0] == '.') + { + continue; + } + + if (is_dir($src_path . $entry)) + { + continue; + } + else + { + copy_file($src_path . $entry, $config['upload_path'] . '/' . preg_replace('/^t_/', 'thumb_', $entry)); + @unlink($phpbb_root_path . $config['upload_path'] . '/thumbs/' . $entry); + } + } + closedir($handle); + } +} + +/** +* Convert the attachment category constants +* This is only used if the Attachment MOD was installed +*/ +function phpbb_attachment_category($cat_id) +{ + switch ($cat_id) + { + case 1: + return ATTACHMENT_CATEGORY_IMAGE; + break; + + case 2: + return ATTACHMENT_CATEGORY_WM; + break; + + case 3: + return ATTACHMENT_CATEGORY_FLASH; + break; + } + + return ATTACHMENT_CATEGORY_NONE; +} + +/** +* Convert the attachment extension names +* This is only used if the Attachment MOD was installed +*/ +function phpbb_attachment_extension_group_name() +{ + global $db, $phpbb_root_path, $phpEx; + + // Update file extension group names to use language strings. + $sql = 'SELECT lang_dir + FROM ' . LANG_TABLE; + $result = $db->sql_query($sql); + + $extension_groups_updated = array(); + while ($lang_dir = $db->sql_fetchfield('lang_dir')) + { + $lang_dir = basename($lang_dir); + $lang_file = $phpbb_root_path . 'language/' . $lang_dir . '/acp/attachments.' . $phpEx; + + if (!file_exists($lang_file)) + { + continue; + } + + $lang = array(); + include($lang_file); + + foreach ($lang as $lang_key => $lang_val) + { + if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0) + { + continue; + } + + $sql_ary = array( + 'group_name' => substr($lang_key, 10), // Strip off 'EXT_GROUP_' + ); + + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " + WHERE group_name = '" . $db->sql_escape($lang_val) . "'"; + $db->sql_query($sql); + + $extension_groups_updated[$lang_key] = true; + } + } + $db->sql_freeresult($result); +} + +/** +* Obtain list of forums in which different attachment categories can be used +*/ +function phpbb_attachment_forum_perms($forum_permissions) +{ + if (empty($forum_permissions)) + { + return ''; + } + + // Decode forum permissions + $forum_ids = array(); + + $one_char_encoding = '#'; + $two_char_encoding = '.'; + + $auth_len = 1; + for ($pos = 0; $pos < strlen($forum_permissions); $pos += $auth_len) + { + $forum_auth = substr($forum_permissions, $pos, 1); + if ($forum_auth == $one_char_encoding) + { + $auth_len = 1; + continue; + } + else if ($forum_auth == $two_char_encoding) + { + $auth_len = 2; + $pos--; + continue; + } + + $forum_auth = substr($forum_permissions, $pos, $auth_len); + $forum_id = base64_unpack($forum_auth); + + $forum_ids[] = (int) $forum_id; + } + + if (sizeof($forum_ids)) + { + return attachment_forum_perms($forum_ids); + } + + return ''; +} + +/** +* Convert the avatar type constants +*/ +function phpbb_avatar_type($type) +{ + switch ($type) + { + case 1: + return AVATAR_UPLOAD; + break; + + case 2: + return AVATAR_REMOTE; + break; + + case 3: + return AVATAR_GALLERY; + break; + } + + return 0; +} + + +/** +* Just undos the replacing of '<' and '>' +*/ +function phpbb_smilie_html_decode($code) +{ + $code = str_replace('<', '<', $code); + return str_replace('>', '>', $code); +} + +/** +* Transfer avatars, copying the image if it was uploaded +*/ +function phpbb_import_avatar($user_avatar) +{ + global $convert_row; + + if (!$convert_row['user_avatar_type']) + { + return ''; + } + else if ($convert_row['user_avatar_type'] == 1) + { + // Uploaded avatar + return import_avatar($user_avatar, false, $convert_row['user_id']); + } + else if ($convert_row['user_avatar_type'] == 2) + { + // Remote avatar + return $user_avatar; + } + else if ($convert_row['user_avatar_type'] == 3) + { + // Gallery avatar + return $user_avatar; + } + + return ''; +} + + +/** +* Find out about the avatar's dimensions +*/ +function phpbb_get_avatar_height($user_avatar) +{ + global $convert_row; + + if (empty($convert_row['user_avatar_type'])) + { + return 0; + } + return get_avatar_height($user_avatar, 'phpbb_avatar_type', $convert_row['user_avatar_type']); +} + + +/** +* Find out about the avatar's dimensions +*/ +function phpbb_get_avatar_width($user_avatar) +{ + global $convert_row; + + if (empty($convert_row['user_avatar_type'])) + { + return 0; + } + + return get_avatar_width($user_avatar, 'phpbb_avatar_type', $convert_row['user_avatar_type']); +} + + +/** +* Calculate the correct to_address field for private messages +*/ +function phpbb_privmsgs_to_userid($to_userid) +{ + global $config; + + return 'u_' . phpbb_user_id($to_userid); +} + +/** +* Calculate whether a private message was unread using the bitfield +*/ +function phpbb_unread_pm($pm_type) +{ + return ($pm_type == 5) ? 1 : 0; +} + +/** +* Calculate whether a private message was new using the bitfield +*/ +function phpbb_new_pm($pm_type) +{ + return ($pm_type == 1) ? 1 : 0; +} + +/** +* Obtain the folder_id for the custom folder created to replace the savebox from 2.0.x (used to store saved private messages) +*/ +function phpbb_get_savebox_id($user_id) +{ + global $db; + + $user_id = phpbb_user_id($user_id); + + // Only one custom folder, check only one + $sql = 'SELECT folder_id + FROM ' . PRIVMSGS_FOLDER_TABLE . ' + WHERE user_id = ' . $user_id; + $result = $db->sql_query_limit($sql, 1); + $folder_id = (int) $db->sql_fetchfield('folder_id'); + $db->sql_freeresult($result); + + return $folder_id; +} + +/** +* Transfer attachment specific configuration options +* These were not stored in the main config table on 2.0.x +* This is only used if the Attachment MOD was installed +*/ +function phpbb_import_attach_config() +{ + global $db, $src_db, $same_db, $convert, $config; + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'binary'"); + } + + $sql = 'SELECT * + FROM ' . $convert->src_table_prefix . 'attachments_config'; + $result = $src_db->sql_query($sql); + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'utf8'"); + } + + $attach_config = array(); + while ($row = $src_db->sql_fetchrow($result)) + { + $attach_config[$row['config_name']] = $row['config_value']; + } + $src_db->sql_freeresult($result); + + $config->set('allow_attachments', 1); + + // old attachment mod? Must be very old if this entry do not exist... + if (!empty($attach_config['display_order'])) + { + $config->set('display_order', $attach_config['display_order']); + } + $config->set('max_filesize', $attach_config['max_filesize']); + $config->set('max_filesize_pm', $attach_config['max_filesize_pm']); + $config->set('attachment_quota', $attach_config['attachment_quota']); + $config->set('max_attachments', $attach_config['max_attachments']); + $config->set('max_attachments_pm', $attach_config['max_attachments_pm']); + $config->set('allow_pm_attach', $attach_config['allow_pm_attach']); + + $config->set('img_display_inlined', $attach_config['img_display_inlined']); + $config->set('img_max_width', $attach_config['img_max_width']); + $config->set('img_max_height', $attach_config['img_max_height']); + $config->set('img_link_width', $attach_config['img_link_width']); + $config->set('img_link_height', $attach_config['img_link_height']); + $config->set('img_create_thumbnail', $attach_config['img_create_thumbnail']); + $config->set('img_max_thumb_width', 400); + $config->set('img_min_thumb_filesize', $attach_config['img_min_thumb_filesize']); + $config->set('img_imagick', $attach_config['img_imagick']); +} + +/** +* Calculate the date a user became inactive +*/ +function phpbb_inactive_time() +{ + global $convert_row; + + if ($convert_row['user_active']) + { + return 0; + } + + if ($convert_row['user_lastvisit']) + { + return $convert_row['user_lastvisit']; + } + + return $convert_row['user_regdate']; +} + +/** +* Calculate the reason a user became inactive +* We can't actually tell the difference between a manual deactivation and one for profile changes +* from the data available to assume the latter +*/ +function phpbb_inactive_reason() +{ + global $convert_row; + + if ($convert_row['user_active']) + { + return 0; + } + + if ($convert_row['user_lastvisit']) + { + return INACTIVE_PROFILE; + } + + return INACTIVE_REGISTER; +} + +/** +* Adjust 2.0.x disallowed names to 3.0.x format +*/ +function phpbb_disallowed_username($username) +{ + // Replace * with % + $username = phpbb_set_default_encoding(str_replace('*', '%', $username)); + return utf8_htmlspecialchars($username); +} + +/** +* Checks whether there are any usernames on the old board that would map to the same +* username_clean on phpBB3. Prints out a list if any exist and exits. +*/ +function phpbb_create_userconv_table() +{ + global $db, $src_db, $convert, $table_prefix, $user, $lang; + + $map_dbms = ''; + switch ($db->get_sql_layer()) + { + case 'mysql': + $map_dbms = 'mysql_40'; + break; + + case 'mysql4': + if (version_compare($db->sql_server_info(true), '4.1.3', '>=')) + { + $map_dbms = 'mysql_41'; + } + else + { + $map_dbms = 'mysql_40'; + } + break; + + case 'mysqli': + $map_dbms = 'mysql_41'; + break; + + case 'mssql': + case 'mssql_odbc': + case 'mssqlnative': + $map_dbms = 'mssql'; + break; + + default: + $map_dbms = $db->get_sql_layer(); + break; + } + + // create a temporary table in which we store the clean usernames + $drop_sql = 'DROP TABLE ' . USERCONV_TABLE; + switch ($map_dbms) + { + case 'mssql': + $create_sql = 'CREATE TABLE [' . USERCONV_TABLE . '] ( + [user_id] [int] NOT NULL , + [username_clean] [varchar] (255) DEFAULT (\'\') NOT NULL + )'; + break; + + case 'mysql_40': + $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( + user_id mediumint(8) NOT NULL, + username_clean blob NOT NULL + )'; + break; + + case 'mysql_41': + $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( + user_id mediumint(8) NOT NULL, + username_clean varchar(255) DEFAULT \'\' NOT NULL + ) CHARACTER SET `utf8` COLLATE `utf8_bin`'; + break; + + case 'oracle': + $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( + user_id number(8) NOT NULL, + username_clean varchar2(255) DEFAULT \'\' + )'; + break; + + case 'postgres': + $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( + user_id INT4 DEFAULT \'0\', + username_clean varchar_ci DEFAULT \'\' NOT NULL + )'; + break; + + case 'sqlite': + case 'sqlite3': + $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( + user_id INTEGER NOT NULL DEFAULT \'0\', + username_clean varchar(255) NOT NULL DEFAULT \'\' + )'; + break; + } + + $db->sql_return_on_error(true); + $db->sql_query($drop_sql); + $db->sql_return_on_error(false); + $db->sql_query($create_sql); +} + +function phpbb_check_username_collisions() +{ + global $db, $src_db, $convert, $table_prefix, $user, $lang; + + // now find the clean version of the usernames that collide + $sql = 'SELECT username_clean + FROM ' . USERCONV_TABLE .' + GROUP BY username_clean + HAVING COUNT(user_id) > 1'; + $result = $db->sql_query($sql); + + $colliding_names = array(); + while ($row = $db->sql_fetchrow($result)) + { + $colliding_names[] = $row['username_clean']; + } + $db->sql_freeresult($result); + + // there was at least one collision, the admin will have to solve it before conversion can continue + if (sizeof($colliding_names)) + { + $sql = 'SELECT user_id, username_clean + FROM ' . USERCONV_TABLE . ' + WHERE ' . $db->sql_in_set('username_clean', $colliding_names); + $result = $db->sql_query($sql); + unset($colliding_names); + + $colliding_user_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $colliding_user_ids[(int) $row['user_id']] = $row['username_clean']; + } + $db->sql_freeresult($result); + + $sql = 'SELECT username, user_id, user_posts + FROM ' . $convert->src_table_prefix . 'users + WHERE ' . $src_db->sql_in_set('user_id', array_keys($colliding_user_ids)); + $result = $src_db->sql_query($sql); + + $colliding_users = array(); + while ($row = $src_db->sql_fetchrow($result)) + { + $row['user_id'] = (int) $row['user_id']; + if (isset($colliding_user_ids[$row['user_id']])) + { + $colliding_users[$colliding_user_ids[$row['user_id']]][] = $row; + } + } + $src_db->sql_freeresult($result); + unset($colliding_user_ids); + + $list = ''; + foreach ($colliding_users as $username_clean => $users) + { + $list .= sprintf($user->lang['COLLIDING_CLEAN_USERNAME'], $username_clean) . "
\n"; + foreach ($users as $i => $row) + { + $list .= sprintf($user->lang['COLLIDING_USER'], $row['user_id'], phpbb_set_default_encoding($row['username']), $row['user_posts']) . "
\n"; + } + } + + $lang['INST_ERR_FATAL'] = $user->lang['CONV_ERR_FATAL']; + $convert->p_master->error('' . $user->lang['COLLIDING_USERNAMES_FOUND'] . '

' . $list . '', __LINE__, __FILE__); + } + + $drop_sql = 'DROP TABLE ' . USERCONV_TABLE; + $db->sql_query($drop_sql); +} + +function phpbb_convert_timezone($timezone) +{ + global $config, $db, $phpbb_root_path, $phpEx, $table_prefix; + + $factory = new \phpbb\db\tools\factory(); + $timezone_migration = new \phpbb\db\migration\data\v310\timezone($config, $db, $factory->get($db), $phpbb_root_path, $phpEx, $table_prefix); + return $timezone_migration->convert_phpbb30_timezone($timezone, 0); +} + +function phpbb_add_notification_options($user_notify_pm) +{ + global $convert_row, $db; + + $user_id = phpbb_user_id($convert_row['user_id']); + if ($user_id == ANONYMOUS) + { + return; + } + + $rows = array(); + + $rows[] = array( + 'item_type' => 'post', + 'item_id' => 0, + 'user_id' => (int) $user_id, + 'notify' => 1, + 'method' => 'email', + ); + $rows[] = array( + 'item_type' => 'topic', + 'item_id' => 0, + 'user_id' => (int) $user_id, + 'notify' => 1, + 'method' => 'email', + ); + if ($user_notify_pm) + { + $rows[] = array( + 'item_type' => 'pm', + 'item_id' => 0, + 'user_id' => (int) $user_id, + 'notify' => 1, + 'method' => 'email', + ); + } + + $sql = $db->sql_multi_insert(USER_NOTIFICATIONS_TABLE, $rows); +} + +function phpbb_convert_password_hash($hash) +{ + global $phpbb_container; + + /* @var $manager \phpbb\passwords\manager */ + $manager = $phpbb_container->get('passwords.manager'); + $hash = $manager->hash($hash, '$H$'); + + return '$CP$' . $hash; +} diff --git a/phpBB/install/data/confusables.php b/phpBB/install/data/confusables.php new file mode 100644 index 0000000000..992207c1ef --- /dev/null +++ b/phpBB/install/data/confusables.php @@ -0,0 +1,645 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +* @ignore +*/ +if (!defined('IN_PHPBB')) +{ + exit; +} + +function utf8_new_case_fold($text, $option = 'full') +{ + static $uniarray = array(); + global $phpbb_root_path, $phpEx; + + // common is always set + if (!isset($uniarray['c'])) + { + $uniarray['c'] = include($phpbb_root_path . 'includes/utf/data/case_fold_c.' . $phpEx); + } + + // only set full if we need to + if ($option === 'full' && !isset($uniarray['f'])) + { + $uniarray['f'] = include($phpbb_root_path . 'includes/utf/data/case_fold_f.' . $phpEx); + } + + // only set simple if we need to + if ($option !== 'full' && !isset($uniarray['s'])) + { + $uniarray['s'] = include($phpbb_root_path . 'includes/utf/data/case_fold_s.' . $phpEx); + } + + // common is always replaced + $text = strtr($text, $uniarray['c']); + + if ($option === 'full') + { + // full replaces a character with multiple characters + $text = strtr($text, $uniarray['f']); + } + else + { + // simple replaces a character with another character + $text = strtr($text, $uniarray['s']); + } + + return $text; +} + +function utf8_new_case_fold_nfkc($text, $option = 'full') +{ + static $fc_nfkc_closure = array( + "\xCD\xBA" => "\x20\xCE\xB9", + "\xCF\x92" => "\xCF\x85", + "\xCF\x93" => "\xCF\x8D", + "\xCF\x94" => "\xCF\x8B", + "\xCF\xB2" => "\xCF\x83", + "\xCF\xB9" => "\xCF\x83", + "\xE1\xB4\xAC" => "\x61", + "\xE1\xB4\xAD" => "\xC3\xA6", + "\xE1\xB4\xAE" => "\x62", + "\xE1\xB4\xB0" => "\x64", + "\xE1\xB4\xB1" => "\x65", + "\xE1\xB4\xB2" => "\xC7\x9D", + "\xE1\xB4\xB3" => "\x67", + "\xE1\xB4\xB4" => "\x68", + "\xE1\xB4\xB5" => "\x69", + "\xE1\xB4\xB6" => "\x6A", + "\xE1\xB4\xB7" => "\x6B", + "\xE1\xB4\xB8" => "\x6C", + "\xE1\xB4\xB9" => "\x6D", + "\xE1\xB4\xBA" => "\x6E", + "\xE1\xB4\xBC" => "\x6F", + "\xE1\xB4\xBD" => "\xC8\xA3", + "\xE1\xB4\xBE" => "\x70", + "\xE1\xB4\xBF" => "\x72", + "\xE1\xB5\x80" => "\x74", + "\xE1\xB5\x81" => "\x75", + "\xE1\xB5\x82" => "\x77", + "\xE2\x82\xA8" => "\x72\x73", + "\xE2\x84\x82" => "\x63", + "\xE2\x84\x83" => "\xC2\xB0\x63", + "\xE2\x84\x87" => "\xC9\x9B", + "\xE2\x84\x89" => "\xC2\xB0\x66", + "\xE2\x84\x8B" => "\x68", + "\xE2\x84\x8C" => "\x68", + "\xE2\x84\x8D" => "\x68", + "\xE2\x84\x90" => "\x69", + "\xE2\x84\x91" => "\x69", + "\xE2\x84\x92" => "\x6C", + "\xE2\x84\x95" => "\x6E", + "\xE2\x84\x96" => "\x6E\x6F", + "\xE2\x84\x99" => "\x70", + "\xE2\x84\x9A" => "\x71", + "\xE2\x84\x9B" => "\x72", + "\xE2\x84\x9C" => "\x72", + "\xE2\x84\x9D" => "\x72", + "\xE2\x84\xA0" => "\x73\x6D", + "\xE2\x84\xA1" => "\x74\x65\x6C", + "\xE2\x84\xA2" => "\x74\x6D", + "\xE2\x84\xA4" => "\x7A", + "\xE2\x84\xA8" => "\x7A", + "\xE2\x84\xAC" => "\x62", + "\xE2\x84\xAD" => "\x63", + "\xE2\x84\xB0" => "\x65", + "\xE2\x84\xB1" => "\x66", + "\xE2\x84\xB3" => "\x6D", + "\xE2\x84\xBB" => "\x66\x61\x78", + "\xE2\x84\xBE" => "\xCE\xB3", + "\xE2\x84\xBF" => "\xCF\x80", + "\xE2\x85\x85" => "\x64", + "\xE3\x89\x90" => "\x70\x74\x65", + "\xE3\x8B\x8C" => "\x68\x67", + "\xE3\x8B\x8E" => "\x65\x76", + "\xE3\x8B\x8F" => "\x6C\x74\x64", + "\xE3\x8D\xB1" => "\x68\x70\x61", + "\xE3\x8D\xB3" => "\x61\x75", + "\xE3\x8D\xB5" => "\x6F\x76", + "\xE3\x8D\xBA" => "\x69\x75", + "\xE3\x8E\x80" => "\x70\x61", + "\xE3\x8E\x81" => "\x6E\x61", + "\xE3\x8E\x82" => "\xCE\xBC\x61", + "\xE3\x8E\x83" => "\x6D\x61", + "\xE3\x8E\x84" => "\x6B\x61", + "\xE3\x8E\x85" => "\x6B\x62", + "\xE3\x8E\x86" => "\x6D\x62", + "\xE3\x8E\x87" => "\x67\x62", + "\xE3\x8E\x8A" => "\x70\x66", + "\xE3\x8E\x8B" => "\x6E\x66", + "\xE3\x8E\x8C" => "\xCE\xBC\x66", + "\xE3\x8E\x90" => "\x68\x7A", + "\xE3\x8E\x91" => "\x6B\x68\x7A", + "\xE3\x8E\x92" => "\x6D\x68\x7A", + "\xE3\x8E\x93" => "\x67\x68\x7A", + "\xE3\x8E\x94" => "\x74\x68\x7A", + "\xE3\x8E\xA9" => "\x70\x61", + "\xE3\x8E\xAA" => "\x6B\x70\x61", + "\xE3\x8E\xAB" => "\x6D\x70\x61", + "\xE3\x8E\xAC" => "\x67\x70\x61", + "\xE3\x8E\xB4" => "\x70\x76", + "\xE3\x8E\xB5" => "\x6E\x76", + "\xE3\x8E\xB6" => "\xCE\xBC\x76", + "\xE3\x8E\xB7" => "\x6D\x76", + "\xE3\x8E\xB8" => "\x6B\x76", + "\xE3\x8E\xB9" => "\x6D\x76", + "\xE3\x8E\xBA" => "\x70\x77", + "\xE3\x8E\xBB" => "\x6E\x77", + "\xE3\x8E\xBC" => "\xCE\xBC\x77", + "\xE3\x8E\xBD" => "\x6D\x77", + "\xE3\x8E\xBE" => "\x6B\x77", + "\xE3\x8E\xBF" => "\x6D\x77", + "\xE3\x8F\x80" => "\x6B\xCF\x89", + "\xE3\x8F\x81" => "\x6D\xCF\x89", + "\xE3\x8F\x83" => "\x62\x71", + "\xE3\x8F\x86" => "\x63\xE2\x88\x95\x6B\x67", + "\xE3\x8F\x87" => "\x63\x6F\x2E", + "\xE3\x8F\x88" => "\x64\x62", + "\xE3\x8F\x89" => "\x67\x79", + "\xE3\x8F\x8B" => "\x68\x70", + "\xE3\x8F\x8D" => "\x6B\x6B", + "\xE3\x8F\x8E" => "\x6B\x6D", + "\xE3\x8F\x97" => "\x70\x68", + "\xE3\x8F\x99" => "\x70\x70\x6D", + "\xE3\x8F\x9A" => "\x70\x72", + "\xE3\x8F\x9C" => "\x73\x76", + "\xE3\x8F\x9D" => "\x77\x62", + "\xE3\x8F\x9E" => "\x76\xE2\x88\x95\x6D", + "\xE3\x8F\x9F" => "\x61\xE2\x88\x95\x6D", + "\xF0\x9D\x90\x80" => "\x61", + "\xF0\x9D\x90\x81" => "\x62", + "\xF0\x9D\x90\x82" => "\x63", + "\xF0\x9D\x90\x83" => "\x64", + "\xF0\x9D\x90\x84" => "\x65", + "\xF0\x9D\x90\x85" => "\x66", + "\xF0\x9D\x90\x86" => "\x67", + "\xF0\x9D\x90\x87" => "\x68", + "\xF0\x9D\x90\x88" => "\x69", + "\xF0\x9D\x90\x89" => "\x6A", + "\xF0\x9D\x90\x8A" => "\x6B", + "\xF0\x9D\x90\x8B" => "\x6C", + "\xF0\x9D\x90\x8C" => "\x6D", + "\xF0\x9D\x90\x8D" => "\x6E", + "\xF0\x9D\x90\x8E" => "\x6F", + "\xF0\x9D\x90\x8F" => "\x70", + "\xF0\x9D\x90\x90" => "\x71", + "\xF0\x9D\x90\x91" => "\x72", + "\xF0\x9D\x90\x92" => "\x73", + "\xF0\x9D\x90\x93" => "\x74", + "\xF0\x9D\x90\x94" => "\x75", + "\xF0\x9D\x90\x95" => "\x76", + "\xF0\x9D\x90\x96" => "\x77", + "\xF0\x9D\x90\x97" => "\x78", + "\xF0\x9D\x90\x98" => "\x79", + "\xF0\x9D\x90\x99" => "\x7A", + "\xF0\x9D\x90\xB4" => "\x61", + "\xF0\x9D\x90\xB5" => "\x62", + "\xF0\x9D\x90\xB6" => "\x63", + "\xF0\x9D\x90\xB7" => "\x64", + "\xF0\x9D\x90\xB8" => "\x65", + "\xF0\x9D\x90\xB9" => "\x66", + "\xF0\x9D\x90\xBA" => "\x67", + "\xF0\x9D\x90\xBB" => "\x68", + "\xF0\x9D\x90\xBC" => "\x69", + "\xF0\x9D\x90\xBD" => "\x6A", + "\xF0\x9D\x90\xBE" => "\x6B", + "\xF0\x9D\x90\xBF" => "\x6C", + "\xF0\x9D\x91\x80" => "\x6D", + "\xF0\x9D\x91\x81" => "\x6E", + "\xF0\x9D\x91\x82" => "\x6F", + "\xF0\x9D\x91\x83" => "\x70", + "\xF0\x9D\x91\x84" => "\x71", + "\xF0\x9D\x91\x85" => "\x72", + "\xF0\x9D\x91\x86" => "\x73", + "\xF0\x9D\x91\x87" => "\x74", + "\xF0\x9D\x91\x88" => "\x75", + "\xF0\x9D\x91\x89" => "\x76", + "\xF0\x9D\x91\x8A" => "\x77", + "\xF0\x9D\x91\x8B" => "\x78", + "\xF0\x9D\x91\x8C" => "\x79", + "\xF0\x9D\x91\x8D" => "\x7A", + "\xF0\x9D\x91\xA8" => "\x61", + "\xF0\x9D\x91\xA9" => "\x62", + "\xF0\x9D\x91\xAA" => "\x63", + "\xF0\x9D\x91\xAB" => "\x64", + "\xF0\x9D\x91\xAC" => "\x65", + "\xF0\x9D\x91\xAD" => "\x66", + "\xF0\x9D\x91\xAE" => "\x67", + "\xF0\x9D\x91\xAF" => "\x68", + "\xF0\x9D\x91\xB0" => "\x69", + "\xF0\x9D\x91\xB1" => "\x6A", + "\xF0\x9D\x91\xB2" => "\x6B", + "\xF0\x9D\x91\xB3" => "\x6C", + "\xF0\x9D\x91\xB4" => "\x6D", + "\xF0\x9D\x91\xB5" => "\x6E", + "\xF0\x9D\x91\xB6" => "\x6F", + "\xF0\x9D\x91\xB7" => "\x70", + "\xF0\x9D\x91\xB8" => "\x71", + "\xF0\x9D\x91\xB9" => "\x72", + "\xF0\x9D\x91\xBA" => "\x73", + "\xF0\x9D\x91\xBB" => "\x74", + "\xF0\x9D\x91\xBC" => "\x75", + "\xF0\x9D\x91\xBD" => "\x76", + "\xF0\x9D\x91\xBE" => "\x77", + "\xF0\x9D\x91\xBF" => "\x78", + "\xF0\x9D\x92\x80" => "\x79", + "\xF0\x9D\x92\x81" => "\x7A", + "\xF0\x9D\x92\x9C" => "\x61", + "\xF0\x9D\x92\x9E" => "\x63", + "\xF0\x9D\x92\x9F" => "\x64", + "\xF0\x9D\x92\xA2" => "\x67", + "\xF0\x9D\x92\xA5" => "\x6A", + "\xF0\x9D\x92\xA6" => "\x6B", + "\xF0\x9D\x92\xA9" => "\x6E", + "\xF0\x9D\x92\xAA" => "\x6F", + "\xF0\x9D\x92\xAB" => "\x70", + "\xF0\x9D\x92\xAC" => "\x71", + "\xF0\x9D\x92\xAE" => "\x73", + "\xF0\x9D\x92\xAF" => "\x74", + "\xF0\x9D\x92\xB0" => "\x75", + "\xF0\x9D\x92\xB1" => "\x76", + "\xF0\x9D\x92\xB2" => "\x77", + "\xF0\x9D\x92\xB3" => "\x78", + "\xF0\x9D\x92\xB4" => "\x79", + "\xF0\x9D\x92\xB5" => "\x7A", + "\xF0\x9D\x93\x90" => "\x61", + "\xF0\x9D\x93\x91" => "\x62", + "\xF0\x9D\x93\x92" => "\x63", + "\xF0\x9D\x93\x93" => "\x64", + "\xF0\x9D\x93\x94" => "\x65", + "\xF0\x9D\x93\x95" => "\x66", + "\xF0\x9D\x93\x96" => "\x67", + "\xF0\x9D\x93\x97" => "\x68", + "\xF0\x9D\x93\x98" => "\x69", + "\xF0\x9D\x93\x99" => "\x6A", + "\xF0\x9D\x93\x9A" => "\x6B", + "\xF0\x9D\x93\x9B" => "\x6C", + "\xF0\x9D\x93\x9C" => "\x6D", + "\xF0\x9D\x93\x9D" => "\x6E", + "\xF0\x9D\x93\x9E" => "\x6F", + "\xF0\x9D\x93\x9F" => "\x70", + "\xF0\x9D\x93\xA0" => "\x71", + "\xF0\x9D\x93\xA1" => "\x72", + "\xF0\x9D\x93\xA2" => "\x73", + "\xF0\x9D\x93\xA3" => "\x74", + "\xF0\x9D\x93\xA4" => "\x75", + "\xF0\x9D\x93\xA5" => "\x76", + "\xF0\x9D\x93\xA6" => "\x77", + "\xF0\x9D\x93\xA7" => "\x78", + "\xF0\x9D\x93\xA8" => "\x79", + "\xF0\x9D\x93\xA9" => "\x7A", + "\xF0\x9D\x94\x84" => "\x61", + "\xF0\x9D\x94\x85" => "\x62", + "\xF0\x9D\x94\x87" => "\x64", + "\xF0\x9D\x94\x88" => "\x65", + "\xF0\x9D\x94\x89" => "\x66", + "\xF0\x9D\x94\x8A" => "\x67", + "\xF0\x9D\x94\x8D" => "\x6A", + "\xF0\x9D\x94\x8E" => "\x6B", + "\xF0\x9D\x94\x8F" => "\x6C", + "\xF0\x9D\x94\x90" => "\x6D", + "\xF0\x9D\x94\x91" => "\x6E", + "\xF0\x9D\x94\x92" => "\x6F", + "\xF0\x9D\x94\x93" => "\x70", + "\xF0\x9D\x94\x94" => "\x71", + "\xF0\x9D\x94\x96" => "\x73", + "\xF0\x9D\x94\x97" => "\x74", + "\xF0\x9D\x94\x98" => "\x75", + "\xF0\x9D\x94\x99" => "\x76", + "\xF0\x9D\x94\x9A" => "\x77", + "\xF0\x9D\x94\x9B" => "\x78", + "\xF0\x9D\x94\x9C" => "\x79", + "\xF0\x9D\x94\xB8" => "\x61", + "\xF0\x9D\x94\xB9" => "\x62", + "\xF0\x9D\x94\xBB" => "\x64", + "\xF0\x9D\x94\xBC" => "\x65", + "\xF0\x9D\x94\xBD" => "\x66", + "\xF0\x9D\x94\xBE" => "\x67", + "\xF0\x9D\x95\x80" => "\x69", + "\xF0\x9D\x95\x81" => "\x6A", + "\xF0\x9D\x95\x82" => "\x6B", + "\xF0\x9D\x95\x83" => "\x6C", + "\xF0\x9D\x95\x84" => "\x6D", + "\xF0\x9D\x95\x86" => "\x6F", + "\xF0\x9D\x95\x8A" => "\x73", + "\xF0\x9D\x95\x8B" => "\x74", + "\xF0\x9D\x95\x8C" => "\x75", + "\xF0\x9D\x95\x8D" => "\x76", + "\xF0\x9D\x95\x8E" => "\x77", + "\xF0\x9D\x95\x8F" => "\x78", + "\xF0\x9D\x95\x90" => "\x79", + "\xF0\x9D\x95\xAC" => "\x61", + "\xF0\x9D\x95\xAD" => "\x62", + "\xF0\x9D\x95\xAE" => "\x63", + "\xF0\x9D\x95\xAF" => "\x64", + "\xF0\x9D\x95\xB0" => "\x65", + "\xF0\x9D\x95\xB1" => "\x66", + "\xF0\x9D\x95\xB2" => "\x67", + "\xF0\x9D\x95\xB3" => "\x68", + "\xF0\x9D\x95\xB4" => "\x69", + "\xF0\x9D\x95\xB5" => "\x6A", + "\xF0\x9D\x95\xB6" => "\x6B", + "\xF0\x9D\x95\xB7" => "\x6C", + "\xF0\x9D\x95\xB8" => "\x6D", + "\xF0\x9D\x95\xB9" => "\x6E", + "\xF0\x9D\x95\xBA" => "\x6F", + "\xF0\x9D\x95\xBB" => "\x70", + "\xF0\x9D\x95\xBC" => "\x71", + "\xF0\x9D\x95\xBD" => "\x72", + "\xF0\x9D\x95\xBE" => "\x73", + "\xF0\x9D\x95\xBF" => "\x74", + "\xF0\x9D\x96\x80" => "\x75", + "\xF0\x9D\x96\x81" => "\x76", + "\xF0\x9D\x96\x82" => "\x77", + "\xF0\x9D\x96\x83" => "\x78", + "\xF0\x9D\x96\x84" => "\x79", + "\xF0\x9D\x96\x85" => "\x7A", + "\xF0\x9D\x96\xA0" => "\x61", + "\xF0\x9D\x96\xA1" => "\x62", + "\xF0\x9D\x96\xA2" => "\x63", + "\xF0\x9D\x96\xA3" => "\x64", + "\xF0\x9D\x96\xA4" => "\x65", + "\xF0\x9D\x96\xA5" => "\x66", + "\xF0\x9D\x96\xA6" => "\x67", + "\xF0\x9D\x96\xA7" => "\x68", + "\xF0\x9D\x96\xA8" => "\x69", + "\xF0\x9D\x96\xA9" => "\x6A", + "\xF0\x9D\x96\xAA" => "\x6B", + "\xF0\x9D\x96\xAB" => "\x6C", + "\xF0\x9D\x96\xAC" => "\x6D", + "\xF0\x9D\x96\xAD" => "\x6E", + "\xF0\x9D\x96\xAE" => "\x6F", + "\xF0\x9D\x96\xAF" => "\x70", + "\xF0\x9D\x96\xB0" => "\x71", + "\xF0\x9D\x96\xB1" => "\x72", + "\xF0\x9D\x96\xB2" => "\x73", + "\xF0\x9D\x96\xB3" => "\x74", + "\xF0\x9D\x96\xB4" => "\x75", + "\xF0\x9D\x96\xB5" => "\x76", + "\xF0\x9D\x96\xB6" => "\x77", + "\xF0\x9D\x96\xB7" => "\x78", + "\xF0\x9D\x96\xB8" => "\x79", + "\xF0\x9D\x96\xB9" => "\x7A", + "\xF0\x9D\x97\x94" => "\x61", + "\xF0\x9D\x97\x95" => "\x62", + "\xF0\x9D\x97\x96" => "\x63", + "\xF0\x9D\x97\x97" => "\x64", + "\xF0\x9D\x97\x98" => "\x65", + "\xF0\x9D\x97\x99" => "\x66", + "\xF0\x9D\x97\x9A" => "\x67", + "\xF0\x9D\x97\x9B" => "\x68", + "\xF0\x9D\x97\x9C" => "\x69", + "\xF0\x9D\x97\x9D" => "\x6A", + "\xF0\x9D\x97\x9E" => "\x6B", + "\xF0\x9D\x97\x9F" => "\x6C", + "\xF0\x9D\x97\xA0" => "\x6D", + "\xF0\x9D\x97\xA1" => "\x6E", + "\xF0\x9D\x97\xA2" => "\x6F", + "\xF0\x9D\x97\xA3" => "\x70", + "\xF0\x9D\x97\xA4" => "\x71", + "\xF0\x9D\x97\xA5" => "\x72", + "\xF0\x9D\x97\xA6" => "\x73", + "\xF0\x9D\x97\xA7" => "\x74", + "\xF0\x9D\x97\xA8" => "\x75", + "\xF0\x9D\x97\xA9" => "\x76", + "\xF0\x9D\x97\xAA" => "\x77", + "\xF0\x9D\x97\xAB" => "\x78", + "\xF0\x9D\x97\xAC" => "\x79", + "\xF0\x9D\x97\xAD" => "\x7A", + "\xF0\x9D\x98\x88" => "\x61", + "\xF0\x9D\x98\x89" => "\x62", + "\xF0\x9D\x98\x8A" => "\x63", + "\xF0\x9D\x98\x8B" => "\x64", + "\xF0\x9D\x98\x8C" => "\x65", + "\xF0\x9D\x98\x8D" => "\x66", + "\xF0\x9D\x98\x8E" => "\x67", + "\xF0\x9D\x98\x8F" => "\x68", + "\xF0\x9D\x98\x90" => "\x69", + "\xF0\x9D\x98\x91" => "\x6A", + "\xF0\x9D\x98\x92" => "\x6B", + "\xF0\x9D\x98\x93" => "\x6C", + "\xF0\x9D\x98\x94" => "\x6D", + "\xF0\x9D\x98\x95" => "\x6E", + "\xF0\x9D\x98\x96" => "\x6F", + "\xF0\x9D\x98\x97" => "\x70", + "\xF0\x9D\x98\x98" => "\x71", + "\xF0\x9D\x98\x99" => "\x72", + "\xF0\x9D\x98\x9A" => "\x73", + "\xF0\x9D\x98\x9B" => "\x74", + "\xF0\x9D\x98\x9C" => "\x75", + "\xF0\x9D\x98\x9D" => "\x76", + "\xF0\x9D\x98\x9E" => "\x77", + "\xF0\x9D\x98\x9F" => "\x78", + "\xF0\x9D\x98\xA0" => "\x79", + "\xF0\x9D\x98\xA1" => "\x7A", + "\xF0\x9D\x98\xBC" => "\x61", + "\xF0\x9D\x98\xBD" => "\x62", + "\xF0\x9D\x98\xBE" => "\x63", + "\xF0\x9D\x98\xBF" => "\x64", + "\xF0\x9D\x99\x80" => "\x65", + "\xF0\x9D\x99\x81" => "\x66", + "\xF0\x9D\x99\x82" => "\x67", + "\xF0\x9D\x99\x83" => "\x68", + "\xF0\x9D\x99\x84" => "\x69", + "\xF0\x9D\x99\x85" => "\x6A", + "\xF0\x9D\x99\x86" => "\x6B", + "\xF0\x9D\x99\x87" => "\x6C", + "\xF0\x9D\x99\x88" => "\x6D", + "\xF0\x9D\x99\x89" => "\x6E", + "\xF0\x9D\x99\x8A" => "\x6F", + "\xF0\x9D\x99\x8B" => "\x70", + "\xF0\x9D\x99\x8C" => "\x71", + "\xF0\x9D\x99\x8D" => "\x72", + "\xF0\x9D\x99\x8E" => "\x73", + "\xF0\x9D\x99\x8F" => "\x74", + "\xF0\x9D\x99\x90" => "\x75", + "\xF0\x9D\x99\x91" => "\x76", + "\xF0\x9D\x99\x92" => "\x77", + "\xF0\x9D\x99\x93" => "\x78", + "\xF0\x9D\x99\x94" => "\x79", + "\xF0\x9D\x99\x95" => "\x7A", + "\xF0\x9D\x99\xB0" => "\x61", + "\xF0\x9D\x99\xB1" => "\x62", + "\xF0\x9D\x99\xB2" => "\x63", + "\xF0\x9D\x99\xB3" => "\x64", + "\xF0\x9D\x99\xB4" => "\x65", + "\xF0\x9D\x99\xB5" => "\x66", + "\xF0\x9D\x99\xB6" => "\x67", + "\xF0\x9D\x99\xB7" => "\x68", + "\xF0\x9D\x99\xB8" => "\x69", + "\xF0\x9D\x99\xB9" => "\x6A", + "\xF0\x9D\x99\xBA" => "\x6B", + "\xF0\x9D\x99\xBB" => "\x6C", + "\xF0\x9D\x99\xBC" => "\x6D", + "\xF0\x9D\x99\xBD" => "\x6E", + "\xF0\x9D\x99\xBE" => "\x6F", + "\xF0\x9D\x99\xBF" => "\x70", + "\xF0\x9D\x9A\x80" => "\x71", + "\xF0\x9D\x9A\x81" => "\x72", + "\xF0\x9D\x9A\x82" => "\x73", + "\xF0\x9D\x9A\x83" => "\x74", + "\xF0\x9D\x9A\x84" => "\x75", + "\xF0\x9D\x9A\x85" => "\x76", + "\xF0\x9D\x9A\x86" => "\x77", + "\xF0\x9D\x9A\x87" => "\x78", + "\xF0\x9D\x9A\x88" => "\x79", + "\xF0\x9D\x9A\x89" => "\x7A", + "\xF0\x9D\x9A\xA8" => "\xCE\xB1", + "\xF0\x9D\x9A\xA9" => "\xCE\xB2", + "\xF0\x9D\x9A\xAA" => "\xCE\xB3", + "\xF0\x9D\x9A\xAB" => "\xCE\xB4", + "\xF0\x9D\x9A\xAC" => "\xCE\xB5", + "\xF0\x9D\x9A\xAD" => "\xCE\xB6", + "\xF0\x9D\x9A\xAE" => "\xCE\xB7", + "\xF0\x9D\x9A\xAF" => "\xCE\xB8", + "\xF0\x9D\x9A\xB0" => "\xCE\xB9", + "\xF0\x9D\x9A\xB1" => "\xCE\xBA", + "\xF0\x9D\x9A\xB2" => "\xCE\xBB", + "\xF0\x9D\x9A\xB3" => "\xCE\xBC", + "\xF0\x9D\x9A\xB4" => "\xCE\xBD", + "\xF0\x9D\x9A\xB5" => "\xCE\xBE", + "\xF0\x9D\x9A\xB6" => "\xCE\xBF", + "\xF0\x9D\x9A\xB7" => "\xCF\x80", + "\xF0\x9D\x9A\xB8" => "\xCF\x81", + "\xF0\x9D\x9A\xB9" => "\xCE\xB8", + "\xF0\x9D\x9A\xBA" => "\xCF\x83", + "\xF0\x9D\x9A\xBB" => "\xCF\x84", + "\xF0\x9D\x9A\xBC" => "\xCF\x85", + "\xF0\x9D\x9A\xBD" => "\xCF\x86", + "\xF0\x9D\x9A\xBE" => "\xCF\x87", + "\xF0\x9D\x9A\xBF" => "\xCF\x88", + "\xF0\x9D\x9B\x80" => "\xCF\x89", + "\xF0\x9D\x9B\x93" => "\xCF\x83", + "\xF0\x9D\x9B\xA2" => "\xCE\xB1", + "\xF0\x9D\x9B\xA3" => "\xCE\xB2", + "\xF0\x9D\x9B\xA4" => "\xCE\xB3", + "\xF0\x9D\x9B\xA5" => "\xCE\xB4", + "\xF0\x9D\x9B\xA6" => "\xCE\xB5", + "\xF0\x9D\x9B\xA7" => "\xCE\xB6", + "\xF0\x9D\x9B\xA8" => "\xCE\xB7", + "\xF0\x9D\x9B\xA9" => "\xCE\xB8", + "\xF0\x9D\x9B\xAA" => "\xCE\xB9", + "\xF0\x9D\x9B\xAB" => "\xCE\xBA", + "\xF0\x9D\x9B\xAC" => "\xCE\xBB", + "\xF0\x9D\x9B\xAD" => "\xCE\xBC", + "\xF0\x9D\x9B\xAE" => "\xCE\xBD", + "\xF0\x9D\x9B\xAF" => "\xCE\xBE", + "\xF0\x9D\x9B\xB0" => "\xCE\xBF", + "\xF0\x9D\x9B\xB1" => "\xCF\x80", + "\xF0\x9D\x9B\xB2" => "\xCF\x81", + "\xF0\x9D\x9B\xB3" => "\xCE\xB8", + "\xF0\x9D\x9B\xB4" => "\xCF\x83", + "\xF0\x9D\x9B\xB5" => "\xCF\x84", + "\xF0\x9D\x9B\xB6" => "\xCF\x85", + "\xF0\x9D\x9B\xB7" => "\xCF\x86", + "\xF0\x9D\x9B\xB8" => "\xCF\x87", + "\xF0\x9D\x9B\xB9" => "\xCF\x88", + "\xF0\x9D\x9B\xBA" => "\xCF\x89", + "\xF0\x9D\x9C\x8D" => "\xCF\x83", + "\xF0\x9D\x9C\x9C" => "\xCE\xB1", + "\xF0\x9D\x9C\x9D" => "\xCE\xB2", + "\xF0\x9D\x9C\x9E" => "\xCE\xB3", + "\xF0\x9D\x9C\x9F" => "\xCE\xB4", + "\xF0\x9D\x9C\xA0" => "\xCE\xB5", + "\xF0\x9D\x9C\xA1" => "\xCE\xB6", + "\xF0\x9D\x9C\xA2" => "\xCE\xB7", + "\xF0\x9D\x9C\xA3" => "\xCE\xB8", + "\xF0\x9D\x9C\xA4" => "\xCE\xB9", + "\xF0\x9D\x9C\xA5" => "\xCE\xBA", + "\xF0\x9D\x9C\xA6" => "\xCE\xBB", + "\xF0\x9D\x9C\xA7" => "\xCE\xBC", + "\xF0\x9D\x9C\xA8" => "\xCE\xBD", + "\xF0\x9D\x9C\xA9" => "\xCE\xBE", + "\xF0\x9D\x9C\xAA" => "\xCE\xBF", + "\xF0\x9D\x9C\xAB" => "\xCF\x80", + "\xF0\x9D\x9C\xAC" => "\xCF\x81", + "\xF0\x9D\x9C\xAD" => "\xCE\xB8", + "\xF0\x9D\x9C\xAE" => "\xCF\x83", + "\xF0\x9D\x9C\xAF" => "\xCF\x84", + "\xF0\x9D\x9C\xB0" => "\xCF\x85", + "\xF0\x9D\x9C\xB1" => "\xCF\x86", + "\xF0\x9D\x9C\xB2" => "\xCF\x87", + "\xF0\x9D\x9C\xB3" => "\xCF\x88", + "\xF0\x9D\x9C\xB4" => "\xCF\x89", + "\xF0\x9D\x9D\x87" => "\xCF\x83", + "\xF0\x9D\x9D\x96" => "\xCE\xB1", + "\xF0\x9D\x9D\x97" => "\xCE\xB2", + "\xF0\x9D\x9D\x98" => "\xCE\xB3", + "\xF0\x9D\x9D\x99" => "\xCE\xB4", + "\xF0\x9D\x9D\x9A" => "\xCE\xB5", + "\xF0\x9D\x9D\x9B" => "\xCE\xB6", + "\xF0\x9D\x9D\x9C" => "\xCE\xB7", + "\xF0\x9D\x9D\x9D" => "\xCE\xB8", + "\xF0\x9D\x9D\x9E" => "\xCE\xB9", + "\xF0\x9D\x9D\x9F" => "\xCE\xBA", + "\xF0\x9D\x9D\xA0" => "\xCE\xBB", + "\xF0\x9D\x9D\xA1" => "\xCE\xBC", + "\xF0\x9D\x9D\xA2" => "\xCE\xBD", + "\xF0\x9D\x9D\xA3" => "\xCE\xBE", + "\xF0\x9D\x9D\xA4" => "\xCE\xBF", + "\xF0\x9D\x9D\xA5" => "\xCF\x80", + "\xF0\x9D\x9D\xA6" => "\xCF\x81", + "\xF0\x9D\x9D\xA7" => "\xCE\xB8", + "\xF0\x9D\x9D\xA8" => "\xCF\x83", + "\xF0\x9D\x9D\xA9" => "\xCF\x84", + "\xF0\x9D\x9D\xAA" => "\xCF\x85", + "\xF0\x9D\x9D\xAB" => "\xCF\x86", + "\xF0\x9D\x9D\xAC" => "\xCF\x87", + "\xF0\x9D\x9D\xAD" => "\xCF\x88", + "\xF0\x9D\x9D\xAE" => "\xCF\x89", + "\xF0\x9D\x9E\x81" => "\xCF\x83", + "\xF0\x9D\x9E\x90" => "\xCE\xB1", + "\xF0\x9D\x9E\x91" => "\xCE\xB2", + "\xF0\x9D\x9E\x92" => "\xCE\xB3", + "\xF0\x9D\x9E\x93" => "\xCE\xB4", + "\xF0\x9D\x9E\x94" => "\xCE\xB5", + "\xF0\x9D\x9E\x95" => "\xCE\xB6", + "\xF0\x9D\x9E\x96" => "\xCE\xB7", + "\xF0\x9D\x9E\x97" => "\xCE\xB8", + "\xF0\x9D\x9E\x98" => "\xCE\xB9", + "\xF0\x9D\x9E\x99" => "\xCE\xBA", + "\xF0\x9D\x9E\x9A" => "\xCE\xBB", + "\xF0\x9D\x9E\x9B" => "\xCE\xBC", + "\xF0\x9D\x9E\x9C" => "\xCE\xBD", + "\xF0\x9D\x9E\x9D" => "\xCE\xBE", + "\xF0\x9D\x9E\x9E" => "\xCE\xBF", + "\xF0\x9D\x9E\x9F" => "\xCF\x80", + "\xF0\x9D\x9E\xA0" => "\xCF\x81", + "\xF0\x9D\x9E\xA1" => "\xCE\xB8", + "\xF0\x9D\x9E\xA2" => "\xCF\x83", + "\xF0\x9D\x9E\xA3" => "\xCF\x84", + "\xF0\x9D\x9E\xA4" => "\xCF\x85", + "\xF0\x9D\x9E\xA5" => "\xCF\x86", + "\xF0\x9D\x9E\xA6" => "\xCF\x87", + "\xF0\x9D\x9E\xA7" => "\xCF\x88", + "\xF0\x9D\x9E\xA8" => "\xCF\x89", + "\xF0\x9D\x9E\xBB" => "\xCF\x83", + "\xF0\x9D\x9F\x8A" => "\xCF\x9D", + ); + global $phpbb_root_path, $phpEx; + + // do the case fold + $text = utf8_new_case_fold($text, $option); + + // convert to NFKC + $text = Normalizer::normalize($text, Normalizer::NFKC); + + // FC_NFKC_Closure, http://www.unicode.org/Public/5.0.0/ucd/DerivedNormalizationProps.txt + $text = strtr($text, $fc_nfkc_closure); + + return $text; +} + +return array('Ā”'=>'i','ǃ'=>'!','α'=>'a','įš€'=>' ','Ā­'=>'','Ū'=>'','܏'=>'','į †'=>'','į Ž'=>'','​'=>'','ā€Œ'=>'','ā€'=>'','
'=>'','
'=>'','⁠'=>'','⁔'=>'','⁢'=>'','⁣'=>'',''=>'',''=>'',''=>'',''=>'',''=>'',''=>'',''=>'','ļæ¹'=>'','ļæŗ'=>'','ļæ»'=>'','ļæ¼'=>'','š…³'=>'','š…“'=>'','š…µ'=>'','š…¶'=>'','š…·'=>'','š…ø'=>'','š…¹'=>'','š…ŗ'=>'','Ū¬'=>'۟','̓'=>'Ģ“','Ł'=>'Ģ“','֜'=>'́','́'=>'́','݇'=>'́','ą„”'=>'́','Ķ€'=>'Ģ€','ą„“'=>'Ģ€','̌'=>'̆','Ģ‘'=>'Ģ‚','ÖÆ'=>'̊','ஂ'=>'̊','ą¹'=>'̊','ą»'=>'̊','ံ'=>'̊','įŸ†'=>'̊','įŸ“'=>'̊','悚'=>'̊','゚'=>'̊','ͦ'=>'̊','Ķ‚'=>'̃','ׄ'=>'̇','Ö¹'=>'̇','ׂ'=>'̇','ׁ'=>'̇','݁'=>'̇','ं'=>'̇','ਂ'=>'̇','ąŖ‚'=>'̇','ąÆ'=>'̇','Ģ…'=>'Ģ„','怬'=>'̉','̱'=>'Ģ ','ą„’'=>'Ģ ','̧'=>'Ģ”','̦'=>'Ģ”','ĢØ'=>'Ģ¢','़'=>'Ģ£','়'=>'Ģ£','਼'=>'Ģ£','ąŖ¼'=>'Ģ£','଼'=>'Ģ£','͇'=>'̳','̶'=>'̵','ļ±ž'=>'ﹲّ','ﱟ'=>'﹓ّ','ļ³²'=>'ļ¹·Ł‘','ļ± '=>'ļ¹¶Ł‘','ļ³³'=>'ﹹّ','ļ±”'=>'ļ¹øŁ‘','ﳓ'=>'ﹻّ','ļ±¢'=>'ļ¹ŗŁ‘','ļ±£'=>'ﹼٰ','Ł“'=>'Ł”','Ż‚'=>'ܼ','౦'=>'o','೦'=>'o','ļ¾ž'=>'悙','怀'=>' ',' '=>' ',' '=>' ',' '=>' ','ā€ƒ'=>' ',' '=>' ',' '=>' ',' '=>' ','ā€ˆ'=>' ',' '=>' ','ā€Š'=>' ',' '=>' ','Ā '=>' ',' '=>' ',' '=>' ','`'=>'`','ļ½€'=>'`','῀'=>'˜','ļ¼¾'=>'^','ļøæ'=>'^','_'=>'_','ļ¹'=>'_','ļ¹Ž'=>'_','ļ¹'=>'_','āŒ‡'=>'ļø“','ļ¼'=>'-','‐'=>'-','‑'=>'-','‒'=>'-','–'=>'-','﹘'=>'-','∼'=>'⁓','d'=>'惻','•'=>'惻',','=>',','ā€š'=>',','٬'=>'،','、'=>'态',';'=>';','ļ¼›'=>';',':'=>':','։'=>':','ļø°'=>':','׃'=>':','ā©“'=>'::=','ļ¼Ž'=>'.','․'=>'.','܂'=>'.',' '=>'..','…'=>'...','ļ½”'=>'怂','·'=>'Ā·','‧'=>'Ā·','āˆ™'=>'Ā·','ā‹…'=>'Ā·','ᐧ'=>'Ā·','ᔯ'=>'Ā·4','ᐌ'=>'·ᐁ','įŽ'=>'·ᐃ','ᐐ'=>'·ᐄ','ᐒ'=>'·ᐅ','ᐔ'=>'·ᐆ','ᐗ'=>'·ᐊ','ᐙ'=>'·ᐋ','ᐷ'=>'·ᐳ','į‘€'=>'·ᐳ','į‘‚'=>'·ᐓ','į‘„'=>'·ᐸ','ᑆ'=>'·ᐹ','į‘—'=>'Ā·į‘Œ','į‘™'=>'Ā·į‘Ž','į‘›'=>'Ā·į‘','į‘”'=>'·ᑐ','į‘'=>'·ᑐ','į‘Ÿ'=>'Ā·į‘‘','į‘”'=>'Ā·į‘•','į‘£'=>'Ā·į‘–','į‘“'=>'Ā·į‘«','ᑸ'=>'Ā·į‘®','ᑼ'=>'Ā·į‘°','ᑾ'=>'·ᑲ','į’€'=>'·ᑳ','į’’'=>'Ā·į’‰','į’”'=>'Ā·į’‹','į’–'=>'Ā·į’Œ','į’š'=>'Ā·į’Ž','į’œ'=>'·ᒐ','į’ž'=>'Ā·į’‘','į’¬'=>'Ā·į’£','į’®'=>'Ā·į’„','į’°'=>'Ā·į’¦','į’²'=>'Ā·į’§','į’“'=>'Ā·į’Ø','į’¶'=>'Ā·L','į’ø'=>'Ā·į’«','ᓉ'=>'Ā·į“€','į“‹'=>'·ᓇ','į“'=>'Ā·į“ˆ','į“œ'=>'Ā·į““','į“ž'=>'Ā·į“•','į“ '=>'Ā·į“–','į“¢'=>'Ā·į“—','ᓤ'=>'Ā·į“˜','ᓦ'=>'Ā·į“š','ᓨ'=>'Ā·į“›','į“¶'=>'Ā·į“­','ᓸ'=>'·ᓯ','ᓺ'=>'Ā·į“°','ᓼ'=>'·ᓱ','ᓾ'=>'·ᓲ','ᔀ'=>'Ā·į““','ᔂ'=>'·ᓵ','į”—'=>'·ᔐ','į”™'=>'·ᔑ','į”›'=>'Ā·į”’','į”'=>'·ᔓ','į”Ÿ'=>'Ā·į””','į””'=>'·ᔕ','ᔣ'=>'Ā·į”–','į”±'=>'·ᔨ','ᔳ'=>'·ᔩ','ᔵ'=>'·ᔪ','į”·'=>'·ᔫ','ᔹ'=>'Ā·į”­','į”»'=>'Ā·į”®','į•Ž'=>'Ā·į•Œ','į•›'=>'Ā·į•š','ᕨ'=>'Ā·į•§','('=>'(','ā‘“'=>'(1)','ā’§'=>'(l)','⑽'=>'(10)','⑾'=>'(11)','⑿'=>'(12)','ā’€'=>'(13)','⒁'=>'(14)','ā’‚'=>'(15)','ā’ƒ'=>'(16)','ā’„'=>'(17)','ā’…'=>'(18)','ā’†'=>'(19)','⑵'=>'(2)','ā’‡'=>'(20)','ā‘¶'=>'(3)','ā‘·'=>'(4)','⑸'=>'(5)','⑹'=>'(6)','⑺'=>'(7)','ā‘»'=>'(8)','⑼'=>'(9)','ā’œ'=>'(a)','ā’'=>'(b)','ā’ž'=>'(c)','ā’Ÿ'=>'(d)','ā’ '=>'(e)','ā’”'=>'(f)','ā’¢'=>'(g)','ā’£'=>'(h)','ā’¤'=>'(i)','ā’„'=>'(j)','ā’¦'=>'(k)','ā’Ø'=>'(m)','ā’©'=>'(n)','ā’Ŗ'=>'(o)','ā’«'=>'(p)','ā’¬'=>'(q)','ā’­'=>'(r)','ā’®'=>'(s)','ā’Æ'=>'(t)','ā’°'=>'(u)','ā’±'=>'(v)','ā’²'=>'(w)','ā’³'=>'(x)','ā’“'=>'(y)','ā’µ'=>'(z)','戀'=>'(į„€)','戎'=>'(ź°€)','戁'=>'(į„‚)','戏'=>'(ė‚˜)','戂'=>'(į„ƒ)','成'=>'(다)','戃'=>'(į„…)','我'=>'(ė¼)','戄'=>'(ᄆ)','戒'=>'(마)','戅'=>'(ᄇ)','戓'=>'(ė°”)','戆'=>'(ᄉ)','戔'=>'(사)','戇'=>'(į„‹)','戕'=>'(ģ•„)','戝'=>'(ģ˜¤ģ „)','戞'=>'(ģ˜¤ķ›„)','戈'=>'(į„Œ)','或'=>'(ģž)','㈜'=>'(주)','戉'=>'(į„Ž)','戗'=>'(ģ°Ø)','㈊'=>'(į„)','战'=>'(칓)','戋'=>'(ᄐ)','戙'=>'(ķƒ€)','㈌'=>'(į„‘)','㈚'=>'(파)','戍'=>'(į„’)','戛'=>'(ķ•˜)','戠'=>'(äø€)','戦'=>'(七)','㈢'=>'(äø‰)','㈨'=>'(九)','戔'=>'(二)','戤'=>'(äŗ”)','㈹'=>'(代)','㈽'=>'(企)','扁'=>'(休)','戧'=>'(八)','戄'=>'(六)','㈸'=>'(劓)','戩'=>'(十)','㈿'=>'(協)','戓'=>'(名)','㈺'=>'(呼)','㈣'=>'(四)','㈯'=>'(土)','戻'=>'(å­¦)','戰'=>'(ę—„)','㈪'=>'(月)','㈲'=>'(꜉)','戭'=>'(木)','戱'=>'(ę Ŗ)','戬'=>'(ę°“)','戫'=>'(火)','戵'=>'(特)','㈼'=>'(監)','㈳'=>'(社)','户'=>'(ē„)','所'=>'(ē„­)','扂'=>'(自)','扃'=>'(至)','戶'=>'(č²”)','㈾'=>'(資)','戮'=>'(金)',')'=>')','ļ¼»'=>'[','怔'=>'[','ļ¼½'=>']','怕'=>']','ļ½›'=>'{','ļ½'=>'}','⦅'=>'⦅','ļ½ '=>'⦆','ļ½¢'=>'怌','ļ½£'=>'怍','ļ¼ '=>'@','*'=>'*','ļ¼'=>'/','⁄'=>'/','āˆ•'=>'/','ļ¼¼'=>'\\','&'=>'&','#'=>'#','ļ¼…'=>'%','‶'=>'‵‵','‷'=>'‵‵‵','༌'=>'་','Ā“'=>'ʹ','Ī„'=>'ʹ','įæ½'=>'ʹ','\''=>'ʹ','''=>'ʹ','′'=>'ʹ','׳'=>'ʹ','Ķ“'=>'ʹ','ˊ'=>'ʹ','"'=>'ʹʹ','"'=>'ʹʹ','″'=>'ʹʹ','怃'=>'ʹʹ','ד'=>'ʹʹ','Źŗ'=>'ʹʹ','–'=>'ʹʹʹ','⁗'=>'ʹʹʹʹ','ĀÆ'=>'ˉ',' ̄'=>'ˉ','‾'=>'ˉ','﹉'=>'ˉ','﹊'=>'ˉ','﹋'=>'ˉ','﹌'=>'ˉ','˚'=>'°','௵'=>'௳','ļæ©'=>'←','ļæ«'=>'→','ļæŖ'=>'↑','↓'=>'↓','↵'=>'↲','⨔'=>'↾','š››'=>'āˆ‚','šœ•'=>'āˆ‚','š'=>'āˆ‚','šž‰'=>'āˆ‚','šŸƒ'=>'āˆ‚','š›'=>'āˆ‡','š›»'=>'āˆ‡','šœµ'=>'āˆ‡','šÆ'=>'āˆ‡','šž©'=>'āˆ‡','+'=>'+','﬩'=>'+','‹'=>'<','<'=>'<','ļ¼'=>'=','⩵'=>'==','ā©¶'=>'===','›'=>'>','ļ¼ž'=>'>','¬'=>'¬','¦'=>'¦','怜'=>'~','ļ½ž'=>'~','﹨'=>'āˆ–','ā‹€'=>'∧','⋁'=>'∨','ā‹‚'=>'∩','ā‹ƒ'=>'∪','∯'=>'∮∮','∰'=>'∮∮∮','≣'=>'≔','♁'=>'āŠ•','ā˜‰'=>'āŠ™','āŸ‚'=>'⊄','ā–·'=>'⊲','āØ'=>'ā‹ˆ','⨽'=>'āŒ™','☸'=>'āŽˆ','āŽ®'=>'āŽ„','│'=>'│','▐'=>'ā–Œ','ļæ­'=>'ā– ','☐'=>'ā–”','ļæ®'=>'ā—‹','⦾'=>'ā—Ž','怛'=>'⟧','〈'=>'⟨','怈'=>'⟨','〉'=>'⟩','怉'=>'⟩','ā§™'=>'⦚','怶'=>'怒','ļ½°'=>'ー','ļæ '=>'Ā¢','$'=>'$','ļæ”'=>'Ā£','ļæ„'=>'Y̵','₩'=>'W̵','0'=>'0','šŸŽ'=>'0','šŸ˜'=>'0','šŸ¢'=>'0','šŸ¬'=>'0','šŸ¶'=>'0','০'=>'0','ą­¦'=>'0','௦'=>'0','᠐'=>'0','怇'=>'0','šŽ'=>'0','š‘‚'=>'0','š‘¶'=>'0','š’Ŗ'=>'0','š“ž'=>'0','š”’'=>'0','š•†'=>'0','š•ŗ'=>'0','š–®'=>'0','š—¢'=>'0','š˜–'=>'0','š™Š'=>'0','š™¾'=>'0','šš¶'=>'0','š›°'=>'0','šœŖ'=>'0','š¤'=>'0','šžž'=>'0','āµ”'=>'0','ą“ '=>'0','āŠ–'=>'0̵','ššÆ'=>'0̵','šš¹'=>'0̵','š›©'=>'0̵','š›³'=>'0̵','šœ£'=>'0̵','šœ­'=>'0̵','š'=>'0̵','š§'=>'0̵','šž—'=>'0̵','šž”'=>'0̵','⓱'=>'0̵','įŽ¾'=>'0̵','Ū°'=>'Ł ','᭜'=>'᭐','捘'=>'0点','1'=>'1','šŸ'=>'1','šŸ™'=>'1','šŸ£'=>'1','šŸ­'=>'1','šŸ·'=>'1','ℐ'=>'1','ā„‘'=>'1','šˆ'=>'1','š¼'=>'1','š‘°'=>'1','š“˜'=>'1','š•€'=>'1','š•“'=>'1','š–Ø'=>'1','š—œ'=>'1','š˜'=>'1','š™„'=>'1','š™ø'=>'1','l'=>'l','l'=>'l','ā…¼'=>'1','ā„“'=>'l','š„'=>'l','š‘™'=>'l','š’'=>'l','š“'=>'l','š“µ'=>'l','š”©'=>'l','š•'=>'l','š–‘'=>'l','š—…'=>'l','š—¹'=>'l','š˜­'=>'l','š™”'=>'l','šš•'=>'l','šš°'=>'l','š›Ŗ'=>'l','šœ¤'=>'l','šž'=>'l','šž˜'=>'l','ā‘ '=>'āž€','É­'=>'lĢ¢','É«'=>'lĢ“','ƚ'=>'l̵','ł'=>'lĢ·','Ū±'=>'Ł”','ā’ˆ'=>'1.','ŀ'=>'lĀ·','į’·'=>'1Ā·','ā‘©'=>'āž‰','ā’‘'=>'10.','ć©'=>'10ę—„','拉'=>'10月','ć¢'=>'10点','ā’’'=>'11.','ćŖ'=>'11ę—„','拊'=>'11月','ć£'=>'11点','ā’“'=>'12.','ć«'=>'12ę—„','拋'=>'12月','捤'=>'12点','ā’”'=>'13.','ć¬'=>'13ę—„','ć„'=>'13点','ā’•'=>'14.','揭'=>'14ę—„','ć¦'=>'14点','ā’–'=>'15.','ć®'=>'15ę—„','捧'=>'15点','ā’—'=>'16.','ćÆ'=>'16ę—„','ćØ'=>'16点','ā’˜'=>'17.','揰'=>'17ę—„','ć©'=>'17点','ā’™'=>'18.','ć±'=>'18ę—„','ćŖ'=>'18点','ā’š'=>'19.','ć²'=>'19ę—„','ć«'=>'19点','lj'=>'lj','揠'=>'1ę—„','拀'=>'1月','捙'=>'1点','ļ¼’'=>'2','šŸ'=>'2','šŸš'=>'2','šŸ¤'=>'2','šŸ®'=>'2','šŸø'=>'2','į’æ'=>'2','ā‘”'=>'āž','Ū²'=>'Ł¢','ā’‰'=>'2.','ā’›'=>'20.','ć³'=>'20ę—„','ć¬'=>'20点','ć“'=>'21ę—„','捭'=>'21点','ćµ'=>'22ę—„','ć®'=>'22点','ć¶'=>'23ę—„','ćÆ'=>'23点','ć·'=>'24ę—„','捰'=>'24点','ćø'=>'25ę—„','ć¹'=>'26ę—„','ćŗ'=>'27ę—„','ć»'=>'28ę—„','ć¼'=>'29ę—„','ć”'=>'2ę—„','拁'=>'2月','捚'=>'2点','3'=>'3','šŸ‘'=>'3','šŸ›'=>'3','šŸ„'=>'3','šŸÆ'=>'3','šŸ¹'=>'3','ā‘¢'=>'āž‚','Ū³'=>'Ł£','ā’Š'=>'3.','ć½'=>'30ę—„','ć¾'=>'31ę—„','ć¢'=>'3ę—„','拂'=>'3月','捛'=>'3点','ļ¼”'=>'4','šŸ’'=>'4','šŸœ'=>'4','šŸ¦'=>'4','šŸ°'=>'4','šŸŗ'=>'4','įŽ'=>'4','ā‘£'=>'āžƒ','ā’‹'=>'4.','į”°'=>'4Ā·','ć£'=>'4ę—„','拃'=>'4月','捜'=>'4点','5'=>'5','šŸ“'=>'5','šŸ'=>'5','šŸ§'=>'5','šŸ±'=>'5','šŸ»'=>'5','⑤'=>'āž„','ā’Œ'=>'5.','揤'=>'5ę—„','拄'=>'5月','捝'=>'5点','ļ¼–'=>'6','šŸ”'=>'6','šŸž'=>'6','šŸØ'=>'6','šŸ²'=>'6','šŸ¼'=>'6','б'=>'6','ā‘„'=>'āž…','ā’'=>'6.','ć„'=>'6ę—„','担'=>'6月','捞'=>'6点','ļ¼—'=>'7','šŸ•'=>'7','šŸŸ'=>'7','šŸ©'=>'7','šŸ³'=>'7','šŸ½'=>'7','⑦'=>'āž†','Ū·'=>'٧','ā’Ž'=>'7.','ć¦'=>'7ę—„','拆'=>'7月','损'=>'7点','ଃ'=>'8','ą§Ŗ'=>'8','੪'=>'8','8'=>'8','šŸ–'=>'8','šŸ '=>'8','šŸŖ'=>'8','šŸ“'=>'8','šŸ¾'=>'8','Č£'=>'8','ā‘§'=>'āž‡','Ūø'=>'ŁØ','ā’'=>'8.','揧'=>'8ę—„','拇'=>'8月','捠'=>'8点','ą©§'=>'9','ą­Ø'=>'9','ą§­'=>'9','ļ¼™'=>'9','šŸ—'=>'9','šŸ”'=>'9','šŸ«'=>'9','šŸµ'=>'9','šŸæ'=>'9','⑨'=>'āžˆ','Ū¹'=>'Ł©','⒐'=>'9.','ćØ'=>'9ę—„','拈'=>'9月','ć”'=>'9点','a'=>'a','šš'=>'a','š‘Ž'=>'a','š’‚'=>'a','š’¶'=>'a','š“Ŗ'=>'a','š”ž'=>'a','š•’'=>'a','š–†'=>'a','š–ŗ'=>'a','š—®'=>'a','š˜¢'=>'a','š™–'=>'a','ššŠ'=>'a','ā„€'=>'a/c','℁'=>'a/s','Ʀ'=>'ae','b'=>'b','š›'=>'b','š‘'=>'b','š’ƒ'=>'b','š’·'=>'b','š“«'=>'b','š”Ÿ'=>'b','š•“'=>'b','š–‡'=>'b','š–»'=>'b','š—Æ'=>'b','š˜£'=>'b','š™—'=>'b','šš‹'=>'b','ɓ'=>'bĢ”','ʃ'=>'bĢ„','ʀ'=>'b̵','c'=>'c','ā…½'=>'c','šœ'=>'c','š‘'=>'c','š’„'=>'c','š’ø'=>'c','š“¬'=>'c','š” '=>'c','š•”'=>'c','š–ˆ'=>'c','š–¼'=>'c','š—°'=>'c','š˜¤'=>'c','š™˜'=>'c','ššŒ'=>'c','š›“'=>'c','šœ'=>'c','š‡'=>'c','šž'=>'c','šž»'=>'c','ā„…'=>'c/o','℆'=>'c/u','d'=>'d','ā…¾'=>'d','ā…†'=>'d','š'=>'d','š‘‘'=>'d','š’…'=>'d','š’¹'=>'d','š“­'=>'d','š””'=>'d','š••'=>'d','š–‰'=>'d','š–½'=>'d','š—±'=>'d','š˜„'=>'d','š™™'=>'d','šš'=>'d','ɗ'=>'dĢ”','ƌ'=>'dĢ„','ɖ'=>'dĢ¢','đ'=>'d̵','dz'=>'dz','dž'=>'dž','ļ½…'=>'e','ℯ'=>'e','ā…‡'=>'e','šž'=>'e','š‘’'=>'e','š’†'=>'e','š“®'=>'e','š”¢'=>'e','š•–'=>'e','š–Š'=>'e','š–¾'=>'e','š—²'=>'e','š˜¦'=>'e','š™š'=>'e','ššŽ'=>'e','⓹'=>'E','ə'=>'Ē','ɚ'=>'ĒĖž','ā‹“'=>'ɛ','š›†'=>'ɛ','š›œ'=>'ɛ','šœ€'=>'ɛ','šœ–'=>'ɛ','šœŗ'=>'ɛ','š'=>'ɛ','š“'=>'ɛ','šžŠ'=>'ɛ','šž®'=>'ɛ','šŸ„'=>'ɛ','f'=>'f','šŸ'=>'f','š‘“'=>'f','š’‡'=>'f','š’»'=>'f','š“Æ'=>'f','š”£'=>'f','š•—'=>'f','š–‹'=>'f','š–æ'=>'f','š—³'=>'f','š˜§'=>'f','š™›'=>'f','šš'=>'f','ʒ'=>'fĢ”','g'=>'g','ā„Š'=>'g','š '=>'g','š‘”'=>'g','š’ˆ'=>'g','š“°'=>'g','š”¤'=>'g','š•˜'=>'g','š–Œ'=>'g','š—€'=>'g','š—“'=>'g','š˜Ø'=>'g','š™œ'=>'g','šš'=>'g','É”'=>'g','É '=>'gĢ”','Ē„'=>'g̵','h'=>'h','ā„Ž'=>'h','š”'=>'h','š’‰'=>'h','š’½'=>'h','š“±'=>'h','š”„'=>'h','š•™'=>'h','š–'=>'h','š—'=>'h','š—µ'=>'h','š˜©'=>'h','š™'=>'h','šš‘'=>'h','ɦ'=>'hĢ”','ħ'=>'h̵','ā„'=>'h̵','įæ¾'=>'Ź»','ā€˜'=>'Ź»','‛'=>'Ź»','ʽ'=>'Ź»','ā³'=>'i','i'=>'i','ā…°'=>'i','ℹ'=>'i','ā…ˆ'=>'i','š¢'=>'i','š‘–'=>'i','š’Š'=>'i','š’¾'=>'i','š“²'=>'i','š”¦'=>'i','š•š'=>'i','š–Ž'=>'i','š—‚'=>'i','š—¶'=>'i','š˜Ŗ'=>'i','š™ž'=>'i','šš’'=>'i','ı'=>'i','šš¤'=>'i','ÉŖ'=>'i','É©'=>'i','š›Š'=>'i','šœ„'=>'i','šœ¾'=>'i','šø'=>'i','šž²'=>'i','ÉØ'=>'i̵','ā…±'=>'ii','ā…²'=>'iii','ij'=>'ij','ā…³'=>'iv','ā…ø'=>'ix','j'=>'j','ā…‰'=>'j','š£'=>'j','š‘—'=>'j','š’‹'=>'j','š’æ'=>'j','š“³'=>'j','š”§'=>'j','š•›'=>'j','š–'=>'j','š—ƒ'=>'j','š—·'=>'j','š˜«'=>'j','š™Ÿ'=>'j','šš“'=>'j','ϳ'=>'j','šš„'=>'Č·','k'=>'k','š¤'=>'k','š‘˜'=>'k','š’Œ'=>'k','š“€'=>'k','š““'=>'k','š”Ø'=>'k','š•œ'=>'k','š–'=>'k','š—„'=>'k','š—ø'=>'k','š˜¬'=>'k','š™ '=>'k','šš”'=>'k','ʙ'=>'kĢ”','ļ½'=>'m','ā…æ'=>'m','š¦'=>'m','š‘š'=>'m','š’Ž'=>'m','š“‚'=>'m','š“¶'=>'m','š”Ŗ'=>'m','š•ž'=>'m','š–’'=>'m','š—†'=>'m','š—ŗ'=>'m','š˜®'=>'m','š™¢'=>'m','šš–'=>'m','ɱ'=>'mĢ”','ļ½Ž'=>'n','š§'=>'n','š‘›'=>'n','š’'=>'n','š“ƒ'=>'n','š“·'=>'n','š”«'=>'n','š•Ÿ'=>'n','š–“'=>'n','š—‡'=>'n','š—»'=>'n','š˜Æ'=>'n','š™£'=>'n','šš—'=>'n','š'=>'N','š‘'=>'N','š‘µ'=>'N','š’©'=>'N','š“'=>'N','š”‘'=>'N','š•¹'=>'N','š–­'=>'N','š—”'=>'N','š˜•'=>'N','š™‰'=>'N','š™½'=>'N','šš“'=>'N','š›®'=>'N','šœØ'=>'N','š¢'=>'N','šžœ'=>'N','ɲ'=>'ņ','ɳ'=>'nĢ¢','ʞ'=>'nĢ©','š›ˆ'=>'nĢ©','šœ‚'=>'nĢ©','šœ¼'=>'nĢ©','š¶'=>'nĢ©','šž°'=>'nĢ©','nj'=>'nj','ļ½'=>'o','ā„“'=>'o','šØ'=>'o','š‘œ'=>'o','š’'=>'o','š“ø'=>'o','š”¬'=>'o','š• '=>'o','š–”'=>'o','š—ˆ'=>'o','š—¼'=>'o','š˜°'=>'o','š™¤'=>'o','šš˜'=>'o','į“'=>'o','š›'=>'o','šœŠ'=>'o','š„'=>'o','š¾'=>'o','šžø'=>'o','ɵ'=>'o̵','Ēæ'=>'ó̵','Ćø'=>'oĢ·','œ'=>'oe','Ę”'=>'oʼ','ā“'=>'p','p'=>'p','š©'=>'p','š‘'=>'p','š’‘'=>'p','š“…'=>'p','š“¹'=>'p','š”­'=>'p','š•”'=>'p','š–•'=>'p','š—‰'=>'p','š—½'=>'p','š˜±'=>'p','š™„'=>'p','šš™'=>'p','š›’'=>'p','š› '=>'p','šœŒ'=>'p','šœš'=>'p','š†'=>'p','š”'=>'p','šž€'=>'p','šžŽ'=>'p','šžŗ'=>'p','šŸˆ'=>'p','Ę„'=>'pĢ”','q'=>'q','šŖ'=>'q','š‘ž'=>'q','š’’'=>'q','š“†'=>'q','š“ŗ'=>'q','š”®'=>'q','š•¢'=>'q','š––'=>'q','š—Š'=>'q','š—¾'=>'q','š˜²'=>'q','š™¦'=>'q','ššš'=>'q','š'=>'Q','š‘„'=>'Q','š‘ø'=>'Q','š’¬'=>'Q','š“ '=>'Q','š””'=>'Q','š•¼'=>'Q','š–°'=>'Q','š—¤'=>'Q','š˜˜'=>'Q','š™Œ'=>'Q','šš€'=>'Q','Ź '=>'qĢ”','š›‹'=>'Äø','š›ž'=>'Äø','šœ…'=>'Äø','šœ˜'=>'Äø','šœæ'=>'Äø','š’'=>'Äø','š¹'=>'Äø','šžŒ'=>'Äø','šž³'=>'Äø','šŸ†'=>'Äø','ļ½’'=>'r','š«'=>'r','š‘Ÿ'=>'r','š’“'=>'r','š“‡'=>'r','š“»'=>'r','š”Æ'=>'r','š•£'=>'r','š–—'=>'r','š—‹'=>'r','š—æ'=>'r','š˜³'=>'r','š™§'=>'r','šš›'=>'r','ɽ'=>'rĢ¢','ɼ'=>'rĢ©','s'=>'s','š¬'=>'s','š‘ '=>'s','š’”'=>'s','š“ˆ'=>'s','š“¼'=>'s','š”°'=>'s','š•¤'=>'s','š–˜'=>'s','š—Œ'=>'s','š˜€'=>'s','š˜“'=>'s','š™Ø'=>'s','ššœ'=>'s','ƽ'=>'s','Ź‚'=>'sĢ¢','∫'=>'ʃ','∬'=>'ʃʃ','∭'=>'ʃʃʃ','⨌'=>'ʃʃʃʃ','ļ½”'=>'t','š­'=>'t','š‘”'=>'t','š’•'=>'t','š“‰'=>'t','š“½'=>'t','š”±'=>'t','š•„'=>'t','š–™'=>'t','š—'=>'t','š˜'=>'t','š˜µ'=>'t','š™©'=>'t','šš'=>'t','š‘‡'=>'T','š‘»'=>'T','š’Æ'=>'T','š“£'=>'T','š”—'=>'T','š•‹'=>'T','š•æ'=>'T','š–³'=>'T','š—§'=>'T','š˜›'=>'T','š™'=>'T','ššƒ'=>'T','šš»'=>'T','š›µ'=>'T','šœÆ'=>'T','š©'=>'T','šž£'=>'T','Ę­'=>'tĢ”','ț'=>'Å£','Ę«'=>'Å£','ŧ'=>'t̵','u'=>'u','š®'=>'u','š‘¢'=>'u','š’–'=>'u','š“Š'=>'u','š“¾'=>'u','š”²'=>'u','š•¦'=>'u','š–š'=>'u','š—Ž'=>'u','š˜‚'=>'u','š˜¶'=>'u','š™Ŗ'=>'u','ššž'=>'u','ʊ'=>'u','Ź‹'=>'u','š›–'=>'u','šœ'=>'u','šŠ'=>'u','šž„'=>'u','šž¾'=>'u','š‘ˆ'=>'U','š‘¼'=>'U','š’°'=>'U','š“¤'=>'U','š”˜'=>'U','š•Œ'=>'U','š–€'=>'U','š–“'=>'U','š—Ø'=>'U','š˜œ'=>'U','š™'=>'U','šš„'=>'U','ļ½–'=>'v','ā…“'=>'v','šÆ'=>'v','š‘£'=>'v','š’—'=>'v','š“‹'=>'v','š“æ'=>'v','š”³'=>'v','š•§'=>'v','š–›'=>'v','š—'=>'v','š˜ƒ'=>'v','š˜·'=>'v','š™«'=>'v','ššŸ'=>'v','š›Ž'=>'v','šœˆ'=>'v','š‚'=>'v','š¼'=>'v','šž¶'=>'v','ā…µ'=>'vi','ā…¶'=>'vii','ā…·'=>'viii','ÉÆ'=>'w','ļ½—'=>'w','š°'=>'w','š‘¤'=>'w','š’˜'=>'w','š“Œ'=>'w','š”€'=>'w','š”“'=>'w','š•Ø'=>'w','š–œ'=>'w','š—'=>'w','š˜„'=>'w','š˜ø'=>'w','š™¬'=>'w','šš '=>'w','š‘Š'=>'W','š‘¾'=>'W','š’²'=>'W','š“¦'=>'W','š”š'=>'W','š•Ž'=>'W','š–‚'=>'W','š–¶'=>'W','š—Ŗ'=>'W','š˜ž'=>'W','š™’'=>'W','šš†'=>'W','Ɨ'=>'x','x'=>'x','ā…¹'=>'x','š±'=>'x','š‘„'=>'x','š’™'=>'x','š“'=>'x','š”'=>'x','š”µ'=>'x','š•©'=>'x','š–'=>'x','š—‘'=>'x','š˜…'=>'x','š˜¹'=>'x','š™­'=>'x','šš”'=>'x','į™­'=>'X','š‘‹'=>'X','š‘æ'=>'X','š’³'=>'X','š“§'=>'X','š”›'=>'X','š•'=>'X','š–ƒ'=>'X','š–·'=>'X','š—«'=>'X','š˜Ÿ'=>'X','š™“'=>'X','šš‡'=>'X','šš¾'=>'X','š›ø'=>'X','šœ²'=>'X','š¬'=>'X','šž¦'=>'X','ā…ŗ'=>'xi','ā…»'=>'xii','ļ½™'=>'y','š²'=>'y','š‘¦'=>'y','š’š'=>'y','š“Ž'=>'y','š”‚'=>'y','š”¶'=>'y','š•Ŗ'=>'y','š–ž'=>'y','š—’'=>'y','š˜†'=>'y','š˜ŗ'=>'y','š™®'=>'y','šš¢'=>'y','Ę“'=>'yĢ”','z'=>'z','š³'=>'z','š‘§'=>'z','š’›'=>'z','š“'=>'z','š”ƒ'=>'z','š”·'=>'z','š•«'=>'z','š–Ÿ'=>'z','š—“'=>'z','š˜‡'=>'z','š˜»'=>'z','š™Æ'=>'z','šš£'=>'z','Č„'=>'zĢ”','ʐ'=>'zĢ¢','ʶ'=>'z̵','ȝ'=>'Ź’','?'=>'Ź”','?'=>'Ź”','⁇'=>'ʔʔ','⁈'=>'Ź”Ēƒ','į¾½'=>'ʼ','᾿'=>'ʼ','’'=>'ʼ','ʾ'=>'ʼ','!'=>'ǃ','!'=>'ǃ','⁉'=>'ĒƒŹ”','‼'=>'ǃǃ','āŗ'=>'α','š›‚'=>'α','š›¼'=>'α','šœ¶'=>'α','š°'=>'α','šžŖ'=>'α','š›ƒ'=>'β','š›½'=>'β','šœ·'=>'β','š±'=>'β','šž«'=>'β','ℽ'=>'γ','š›„'=>'γ','š›¾'=>'γ','šœø'=>'γ','š²'=>'γ','šž¬'=>'γ','š›…'=>'Ī“','š›æ'=>'Ī“','šœ¹'=>'Ī“','š³'=>'Ī“','šž­'=>'Ī“','šŸ‹'=>'Ļ','š›‡'=>'ζ','šœ'=>'ζ','šœ»'=>'ζ','šµ'=>'ζ','šžÆ'=>'ζ','ā¬'=>'Īø','š›‰'=>'Īø','š›'=>'Īø','šœƒ'=>'Īø','šœ—'=>'Īø','šœ½'=>'Īø','š‘'=>'Īø','š·'=>'Īø','šž‹'=>'Īø','šž±'=>'Īø','šŸ…'=>'Īø','š›Œ'=>'Ī»','šœ†'=>'Ī»','š€'=>'Ī»','šŗ'=>'Ī»','šž“'=>'Ī»','š›¬'=>'Ī›','šœ¦'=>'Ī›','š '=>'Ī›','šžš'=>'Ī›','š›'=>'μ','šœ‡'=>'μ','š'=>'μ','š»'=>'μ','šžµ'=>'μ','š›'=>'ξ','šœ‰'=>'ξ','šƒ'=>'ξ','š½'=>'ξ','šž·'=>'ξ','š›Æ'=>'Īž','šœ©'=>'Īž','š£'=>'Īž','šž'=>'Īž','ℼ'=>'Ļ€','š›‘'=>'Ļ€','š›”'=>'Ļ€','šœ‹'=>'Ļ€','šœ›'=>'Ļ€','š…'=>'Ļ€','š•'=>'Ļ€','šæ'=>'Ļ€','šž'=>'Ļ€','šž¹'=>'Ļ€','šŸ‰'=>'Ļ€','ᓨ'=>'Ļ€','āˆ'=>'Ī ','šš·'=>'Ī ','š›±'=>'Ī ','šœ«'=>'Ī ','š„'=>'Ī ','šžŸ'=>'Ī ','š›”'=>'σ','šœŽ'=>'σ','šˆ'=>'σ','šž‚'=>'σ','šž¼'=>'σ','š›•'=>'Ļ„','šœ'=>'Ļ„','š‰'=>'Ļ„','šžƒ'=>'Ļ„','šž½'=>'Ļ„','š˜'=>'Y','š‘Œ'=>'Y','š’€'=>'Y','š’“'=>'Y','š“Ø'=>'Y','š”œ'=>'Y','š•'=>'Y','š–„'=>'Y','š–ø'=>'Y','š—¬'=>'Y','š˜ '=>'Y','š™”'=>'Y','ššˆ'=>'Y','šš¼'=>'Y','š›¶'=>'Y','šœ°'=>'Y','šŖ'=>'Y','šž¤'=>'Y','š›—'=>'φ','š›Ÿ'=>'φ','šœ‘'=>'φ','šœ™'=>'φ','š‹'=>'φ','š“'=>'φ','šž…'=>'φ','šž'=>'φ','šžæ'=>'φ','šŸ‡'=>'φ','š›·'=>'Φ','šœ±'=>'Φ','š«'=>'Φ','šž„'=>'Φ','š›˜'=>'χ','šœ’'=>'χ','šŒ'=>'χ','šž†'=>'χ','šŸ€'=>'χ','š›™'=>'ψ','šœ“'=>'ψ','š'=>'ψ','šž‡'=>'ψ','šŸ'=>'ψ','š›¹'=>'ĪØ','šœ³'=>'ĪØ','š­'=>'ĪØ','šž§'=>'ĪØ','āµ'=>'ω','š›š'=>'ω','šœ”'=>'ω','šŽ'=>'ω','šžˆ'=>'ω','šŸ‚'=>'ω','ӕ'=>'ae','Ņ“'=>'r̵','Ņ‘'=>'rį‘Š','Ņ—'=>'ж̩','Ņ™'=>'Š·Ģ”','ӏ'=>'i','Ņ‹'=>'й̔','Ņ›'=>'ÄøĢ©','ҟ'=>'ĸ̵','į“«'=>'Š»','ӆ'=>'л̔','ӎ'=>'м̔','ӊ'=>'н̔','ӈ'=>'н̔','Ņ£'=>'н̩','Ó©'=>'o̵','ѳ'=>'o̵','Ņ«'=>'cĢ”','Ņ­'=>'т̩','ŅÆ'=>'y','ұ'=>'y̵','ћ'=>'h̵','ѽ'=>'є҃','ӌ'=>'Ņ·','Ņæ'=>'ҽ̢','Ņ'=>'Ь̵','Õ¦'=>'q','Õ¼'=>'n','ℵ'=>'א','ﬔ'=>'א','אָ'=>'אַ','אּ'=>'אַ','ļ­'=>'אל','ā„¶'=>'ב','ā„·'=>'ג','ℸ'=>'ד','ﬢ'=>'ד','ﬣ'=>'ה','ﬤ'=>'כ','ffl'=>'ל','ﬦ'=>'ם','ﬠ'=>'×¢','ﬧ'=>'ר','ﬨ'=>'×Ŗ','ļŗ€'=>'Ų”','ļŗ‚'=>'Ų¢','ﺁ'=>'Ų¢','ļŗ„'=>'Ų£','ﺃ'=>'Ų£','ٵ'=>'Ų§Ł”','ļ­‘'=>'ٱ','ﭐ'=>'ٱ','ļŗ†'=>'Ų¤','ļŗ…'=>'Ų¤','ٶ'=>'ŁˆŁ”','ﺈ'=>'Ų„','ļŗ‡'=>'Ų„','ļŗ‹'=>'Ų¦','ﺌ'=>'Ų¦','ﺊ'=>'Ų¦','ļŗ‰'=>'Ų¦','ﯫ'=>'Ų¦Ų§','ﯪ'=>'Ų¦Ų§','ﯸ'=>'ئٻ','ﯷ'=>'ئٻ','ﯶ'=>'ئٻ','ļ²—'=>'Ų¦Ų¬','ļ°€'=>'Ų¦Ų¬','ﲘ'=>'Ų¦Ų­','ﰁ'=>'Ų¦Ų­','ļ²™'=>'Ų¦Ų®','ﱤ'=>'Ų¦Ų±','ﱄ'=>'Ų¦Ų²','ﲚ'=>'ئم','ﳟ'=>'ئم','ﱦ'=>'ئم','ļ°‚'=>'ئم','ļ±§'=>'ئن','ļ²›'=>'ئه','ļ³ '=>'ئه','ﯭ'=>'ئه','ﯬ'=>'ئه','ﯯ'=>'ئو','ﯮ'=>'ئو','ﯳ'=>'Ų¦Ū†','ﯲ'=>'Ų¦Ū†','ﯱ'=>'Ų¦Ū‡','ﯰ'=>'Ų¦Ū‡','ﯵ'=>'ئۈ','ﯓ'=>'ئۈ','ﯻ'=>'ئى','ﯺ'=>'ئى','ﱨ'=>'ئى','ﯹ'=>'ئى','ﰃ'=>'ئى','ﱩ'=>'ئى','ļ°„'=>'ئى','ļŗŽ'=>'Ų§','ļŗ'=>'Ų§',''=>'Ų§Ł‹',''=>'Ų§Ł‹','ļ·³'=>'اكبر','ļ·²'=>'الله','ļŗ‘'=>'ŲØ','ļŗ’'=>'ŲØ','ﺐ'=>'ŲØ','ļŗ'=>'ŲØ','ﲜ'=>'ŲØŲ¬','ļ°…'=>'ŲØŲ¬','ļ²'=>'ŲØŲ­','ļ°†'=>'ŲØŲ­','ļ·‚'=>'بحى','ļ²ž'=>'ŲØŲ®','ļ°‡'=>'ŲØŲ®','ļ¶ž'=>'بخى','ļ±Ŗ'=>'ŲØŲ±','ﱫ'=>'ŲØŲ²','ﲟ'=>'ŲØŁ…','ļ³”'=>'ŲØŁ…','ﱬ'=>'ŲØŁ…','ﰈ'=>'ŲØŁ…','ļ±­'=>'بن','ļ² '=>'به','ļ³¢'=>'به','ļ±®'=>'بى','ļ°‰'=>'بى','ﱯ'=>'بى','ﰊ'=>'بى','ļ­”'=>'Ł»','ļ­•'=>'Ł»','ļ­“'=>'Ł»','ļ­’'=>'Ł»','ې'=>'Ł»','ﯦ'=>'Ł»','ﯧ'=>'Ł»','﯄'=>'Ł»','ﯤ'=>'Ł»','ﭘ'=>'پ','ļ­™'=>'پ','ļ­—'=>'پ','ļ­–'=>'پ','ﭜ'=>'Ś€','ļ­'=>'Ś€','ļ­›'=>'Ś€','ﭚ'=>'Ś€','ļŗ”'=>'Ų©','ļŗ“'=>'Ų©','ļŗ—'=>'ŲŖ','ﺘ'=>'ŲŖ','ļŗ–'=>'ŲŖ','ļŗ•'=>'ŲŖ','ļ²”'=>'ŲŖŲ¬','ļ°‹'=>'ŲŖŲ¬','ﵐ'=>'تجم','ļ¶ '=>'تجى','ﶟ'=>'تجى','ļ²¢'=>'ŲŖŲ­','ﰌ'=>'ŲŖŲ­','ļµ’'=>'ŲŖŲ­Ų¬','ﵑ'=>'ŲŖŲ­Ų¬','ﵓ'=>'ŲŖŲ­Ł…','ļ²£'=>'ŲŖŲ®','ļ°'=>'ŲŖŲ®','ļµ”'=>'تخم','ļ¶¢'=>'تخى','ļ¶”'=>'تخى','ļ±°'=>'ŲŖŲ±','ļ±±'=>'ŲŖŲ²','ﲤ'=>'ŲŖŁ…','ļ³£'=>'ŲŖŁ…','ļ±²'=>'ŲŖŁ…','ļ°Ž'=>'ŲŖŁ…','ﵕ'=>'ŲŖŁ…Ų¬','ļµ–'=>'ŲŖŁ…Ų­','ļµ—'=>'ŲŖŁ…Ų®','ﶤ'=>'تمى','ļ¶£'=>'تمى','ļ±³'=>'تن','ﲄ'=>'ته','ﳤ'=>'ته','ﱓ'=>'تى','ļ°'=>'تى','ļ±µ'=>'تى','ﰐ'=>'تى','ļŗ›'=>'Ų«','ﺜ'=>'Ų«','ﺚ'=>'Ų«','ļŗ™'=>'Ų«','ļ°‘'=>'Ų«Ų¬','ļ±¶'=>'Ų«Ų±','ļ±·'=>'Ų«Ų²','ﲦ'=>'Ų«Ł…','ﳄ'=>'Ų«Ł…','ļ±ø'=>'Ų«Ł…','ļ°’'=>'Ų«Ł…','ļ±¹'=>'ثن','ﳦ'=>'ثه','ļ±ŗ'=>'ثى','ļ°“'=>'ثى','ļ±»'=>'ثى','ļ°”'=>'ثى','ļ­Ø'=>'ٹ','ļ­©'=>'ٹ','ļ­§'=>'ٹ','ļ­¦'=>'ٹ','Ś»'=>'ٹ','ﮢ'=>'ٹ','ﮣ'=>'ٹ','ļ®”'=>'ٹ','ļ® '=>'ٹ','ļ­ '=>'Łŗ','ļ­”'=>'Łŗ','ﭟ'=>'Łŗ','ļ­ž'=>'Łŗ','ļ­¤'=>'Łæ','ļ­„'=>'Łæ','ļ­£'=>'Łæ','ļ­¢'=>'Łæ','ﺟ'=>'Ų¬','ļŗ '=>'Ų¬','ļŗž'=>'Ų¬','ļŗ'=>'Ų¬','ļ²§'=>'Ų¬Ų­','ļ°•'=>'Ų¬Ų­','ﶦ'=>'جحى','ļ¶¾'=>'جحى','ļ·»'=>'جل جلاله','ﲨ'=>'جم','ļ°–'=>'جم','ļµ™'=>'جمح','ﵘ'=>'جمح','ļ¶§'=>'جمى','ļ¶„'=>'جمى','ļ“'=>'جى',''=>'جى','ļ“ž'=>'جى','ļ“‚'=>'جى','ļ­ø'=>'ڃ','ļ­¹'=>'ڃ','ļ­·'=>'ڃ','ļ­¶'=>'ڃ','ļ­“'=>'Ś„','ļ­µ'=>'Ś„','ļ­³'=>'Ś„','ļ­²'=>'Ś„','ļ­¼'=>'چ','ļ­½'=>'چ','ļ­»'=>'چ','ļ­ŗ'=>'چ','ﮀ'=>'ڇ','ﮁ'=>'ڇ','ļ­æ'=>'ڇ','ļ­¾'=>'ڇ','ļŗ£'=>'Ų­','ļŗ¤'=>'Ų­','ļŗ¢'=>'Ų­','ļŗ”'=>'Ų­','ﲩ'=>'Ų­Ų¬','ļ°—'=>'Ų­Ų¬','ļ¶æ'=>'حجى','ļ²Ŗ'=>'Ų­Ł…','ﰘ'=>'Ų­Ł…','ļµ›'=>'حمى','ﵚ'=>'حمى','ļ“›'=>'حى','ﳿ'=>'حى',''=>'حى','ļ“€'=>'حى','ļŗ§'=>'Ų®','ļŗØ'=>'Ų®','ļŗ¦'=>'Ų®','ļŗ„'=>'Ų®','ﲫ'=>'Ų®Ų¬','ļ°™'=>'Ų®Ų¬','ﰚ'=>'Ų®Ų­','ﲬ'=>'خم','ļ°›'=>'خم',''=>'خى',''=>'خى','ļ“ '=>'خى','ļ“„'=>'خى','ļŗŖ'=>'ŲÆ','ļŗ©'=>'ŲÆ','ļŗ¬'=>'Ų°','ļŗ«'=>'Ų°','ļ±›'=>'ذٰ','ﮉ'=>'ڈ','ﮈ'=>'ڈ','ļ®…'=>'ڌ','ﮄ'=>'ڌ','ﮃ'=>'Ś','ﮂ'=>'Ś','ﮇ'=>'ŚŽ','ﮆ'=>'ŚŽ','ļŗ®'=>'Ų±','ļŗ­'=>'Ų±','ﱜ'=>'رٰ','ļ·¶'=>'Ų±Ų³ŁˆŁ„','ļ·¼'=>'رىال','ļŗ°'=>'Ų²','ļŗÆ'=>'Ų²','ļ®'=>'Ś‘','ﮌ'=>'Ś‘','ﮋ'=>'ژ','ﮊ'=>'ژ','ļŗ³'=>'Ų³','ļŗ“'=>'Ų³','ļŗ²'=>'Ų³','ļŗ±'=>'Ų³','ļ²­'=>'Ų³Ų¬','ļ““'=>'Ų³Ų¬','ﰜ'=>'Ų³Ų¬','ļµ'=>'Ų³Ų¬Ų­','ļµž'=>'سجى','ļ²®'=>'Ų³Ų­',''=>'Ų³Ų­','ļ°'=>'Ų³Ų­','ﵜ'=>'Ų³Ų­Ų¬','ﲯ'=>'Ų³Ų®','ļ“¶'=>'Ų³Ų®','ļ°ž'=>'Ų³Ų®','ļ¶Ø'=>'سخى','ļ·†'=>'سخى',''=>'Ų³Ų±','ļ“Ž'=>'Ų³Ų±','ļ²°'=>'سم','ļ³§'=>'سم','ﰟ'=>'سم','ļµ”'=>'سمج','ļµ '=>'سمح','ﵟ'=>'سمح','ļµ£'=>'سمم','ļµ¢'=>'سمم',''=>'سه','ﳨ'=>'سه','ļ“—'=>'سى','ļ³»'=>'سى',''=>'سى','ļ³¼'=>'سى','ļŗ·'=>'Ų“','ļŗø'=>'Ų“','ļŗ¶'=>'Ų“','ļŗµ'=>'Ų“','ļ“­'=>'Ų“Ų¬','ļ“·'=>'Ų“Ų¬','ļ“„'=>'Ų“Ų¬',''=>'Ų“Ų¬','ﵩ'=>'ؓجى','ļ“®'=>'Ų“Ų­',''=>'Ų“Ų­',''=>'Ų“Ų­',''=>'Ų“Ų­','ﵨ'=>'Ų“Ų­Ł…','ļµ§'=>'Ų“Ų­Ł…','ļ¶Ŗ'=>'ؓحى',''=>'Ų“Ų®',''=>'Ų“Ų®','ļ“§'=>'Ų“Ų®','ļ“‹'=>'Ų“Ų®','ļ“©'=>'Ų“Ų±','ļ“'=>'Ų“Ų±','ļ“°'=>'Ų“Ł…','ﳩ'=>'Ų“Ł…',''=>'Ų“Ł…',''=>'Ų“Ł…','ﵫ'=>'Ų“Ł…Ų®','ļµŖ'=>'Ų“Ł…Ų®','ļµ­'=>'Ų“Ł…Ł…','ﵬ'=>'Ų“Ł…Ł…',''=>'ؓه','ļ³Ŗ'=>'ؓه','ļ“™'=>'ؓى','ļ³½'=>'ؓى',''=>'ؓى','ļ³¾'=>'ؓى','ļŗ»'=>'Ųµ','ļŗ¼'=>'Ųµ','ļŗŗ'=>'Ųµ','ļŗ¹'=>'Ųµ','ļ²±'=>'ŲµŲ­','ļ° '=>'ŲµŲ­','﵄'=>'ŲµŲ­Ų­','ﵤ'=>'ŲµŲ­Ų­','ļ¶©'=>'صحى','ļ²²'=>'ŲµŲ®','ļ“«'=>'ŲµŲ±','ļ“'=>'ŲµŲ±','ļ·µ'=>'صلعم','ļ·¹'=>'صلى','ļ·ŗ'=>'صلى الله علىه ŁˆŲ³Ł„Ł…','ļ·°'=>'صلے','ļ²³'=>'صم','ļ°”'=>'صم','ļ·…'=>'صمم','ﵦ'=>'صمم','ļ“”'=>'صى','ļ“…'=>'صى','ļ“¢'=>'صى',''=>'صى','ļŗæ'=>'Ų¶','ﻀ'=>'Ų¶','ļŗ¾'=>'Ų¶','ļŗ½'=>'Ų¶','ﲓ'=>'Ų¶Ų¬','ļ°¢'=>'Ų¶Ų¬','ļ²µ'=>'Ų¶Ų­','ļ°£'=>'Ų¶Ų­','ļµ®'=>'ضحى','ļ¶«'=>'ضحى','ļ²¶'=>'Ų¶Ų®','ļ°¤'=>'Ų¶Ų®','ļµ°'=>'ضخم','ﵯ'=>'ضخم',''=>'Ų¶Ų±',''=>'Ų¶Ų±','ļ²·'=>'Ų¶Ł…','ļ°„'=>'Ų¶Ł…','ļ“£'=>'ضى',''=>'ضى',''=>'ضى',''=>'ضى','ﻃ'=>'Ų·','ﻄ'=>'Ų·','ﻂ'=>'Ų·','ﻁ'=>'Ų·','ļ²ø'=>'Ų·Ų­','ļ°¦'=>'Ų·Ų­',''=>'Ų·Ł…',''=>'Ų·Ł…','ļ°§'=>'Ų·Ł…','ļµ²'=>'Ų·Ł…Ų­','ļµ±'=>'Ų·Ł…Ų­','ļµ³'=>'Ų·Ł…Ł…','ﵓ'=>'طمى','ļ“‘'=>'طى','ļ³µ'=>'طى','ļ“’'=>'طى','ļ³¶'=>'طى','ﻇ'=>'Ųø','ﻈ'=>'Ųø','ﻆ'=>'Ųø','ļ»…'=>'Ųø','ļ²¹'=>'ŲøŁ…','ļ“»'=>'ŲøŁ…','ļ°Ø'=>'ŲøŁ…','ﻋ'=>'Ų¹','ﻌ'=>'Ų¹','ﻊ'=>'Ų¹','ﻉ'=>'Ų¹','ļ²ŗ'=>'Ų¹Ų¬','ļ°©'=>'Ų¹Ų¬','ļ·„'=>'عجم','ļµµ'=>'عجم','ļ··'=>'علىه','ļ²»'=>'عم','ļ°Ŗ'=>'عم','ļµ·'=>'عمم','ļµ¶'=>'عمم','ļµø'=>'عمى','ļ¶¶'=>'عمى','ļ““'=>'عى','ļ³·'=>'عى','ļ“”'=>'عى','ļ³ø'=>'عى','ļ»'=>'Ųŗ','ﻐ'=>'Ųŗ','ļ»Ž'=>'Ųŗ','ļ»'=>'Ųŗ','ļ²¼'=>'ŲŗŲ¬','ļ°«'=>'ŲŗŲ¬','ļ²½'=>'ŲŗŁ…','ļ°¬'=>'ŲŗŁ…','ļµ¹'=>'ŲŗŁ…Ł…','ļµ»'=>'غمى','ļµŗ'=>'غمى','ļ“•'=>'غى','ļ³¹'=>'غى','ļ“–'=>'غى','ļ³ŗ'=>'غى','ﻓ'=>'ف','ļ»”'=>'ف','ļ»’'=>'ف','ﻑ'=>'ف','ļ²¾'=>'فج','ļ°­'=>'فج','ﲿ'=>'فح','ļ°®'=>'فح','ļ³€'=>'فخ','ļ°Æ'=>'فخ','ļµ½'=>'فخم','ļµ¼'=>'فخم','ﳁ'=>'فم','ļ°°'=>'فم','ﷁ'=>'فمى','ļ±¼'=>'فى','ļ°±'=>'فى','ļ±½'=>'فى','ļ°²'=>'فى','ļ­¬'=>'ڤ','ļ­­'=>'ڤ','ļ­«'=>'ڤ','ļ­Ŗ'=>'ڤ','ļ­°'=>'ڦ','ļ­±'=>'ڦ','ļ­Æ'=>'ڦ','ļ­®'=>'ڦ','ļ»—'=>'Ł‚','ﻘ'=>'Ł‚','ļ»–'=>'Ł‚','ﻕ'=>'Ł‚','ﳂ'=>'قح','ļ°³'=>'قح','ļ·±'=>'قلے','ﳃ'=>'قم','ļ°“'=>'قم','ļ¶“'=>'قمح','ļµ¾'=>'قمح','ﵿ'=>'قمم','ļ¶²'=>'قمى','ļ±¾'=>'قى','ļ°µ'=>'قى','ﱿ'=>'قى','ļ°¶'=>'قى','ļ»›'=>'ك','ﻜ'=>'ك','ﻚ'=>'ك','ļ»™'=>'ك','Ś©'=>'ك','ﮐ'=>'ك','ﮑ'=>'ك','ļ®'=>'ك','ļ®Ž'=>'ك','ļ²€'=>'كا','ļ°·'=>'كا','ﳄ'=>'كج','ļ°ø'=>'كج','ļ³…'=>'كح','ļ°¹'=>'كح','ﳆ'=>'كخ','ļ°ŗ'=>'كخ','ﳇ'=>'ŁƒŁ„','ﳫ'=>'ŁƒŁ„','ﲁ'=>'ŁƒŁ„','ļ°»'=>'ŁƒŁ„','ﳈ'=>'ŁƒŁ…','ﳬ'=>'ŁƒŁ…','ﲂ'=>'ŁƒŁ…','ļ°¼'=>'ŁƒŁ…','ﷃ'=>'ŁƒŁ…Ł…','ļ¶»'=>'ŁƒŁ…Ł…','ļ¶·'=>'ŁƒŁ…Ł‰','ﲃ'=>'ŁƒŁ‰','ļ°½'=>'ŁƒŁ‰','ﲄ'=>'ŁƒŁ‰','ļ°¾'=>'ŁƒŁ‰','ﯕ'=>'Ś­','ﯖ'=>'Ś­','ﯔ'=>'Ś­','ﯓ'=>'Ś­','ļ®”'=>'ŚÆ','ﮕ'=>'ŚÆ','ﮓ'=>'ŚÆ','ļ®’'=>'ŚÆ','ﮜ'=>'ڱ','ļ®'=>'ڱ','ļ®›'=>'ڱ','ﮚ'=>'ڱ','ﮘ'=>'ڳ','ļ®™'=>'ڳ','ļ®—'=>'ڳ','ļ®–'=>'ڳ','ﻟ'=>'Ł„','ļ» '=>'Ł„','ļ»ž'=>'Ł„','ļ»'=>'Ł„','ļ»¶'=>'لآ','ﻵ'=>'لآ','ﻸ'=>'لأ','ļ»·'=>'لأ','ﻺ'=>'ل؄','ﻹ'=>'ل؄','ﻼ'=>'لا','ļ»»'=>'لا','ﳉ'=>'لج','ļ°æ'=>'لج','ﶃ'=>'لجج','ļ¶„'=>'لجج','ļ¶ŗ'=>'لجم','ļ¶¼'=>'لجم','ﶬ'=>'لجى','ﳊ'=>'لح','ļ±€'=>'لح','ļ¶µ'=>'لحم','ļ¶€'=>'لحم','ļ¶‚'=>'لحى','ﶁ'=>'لحى','ﳋ'=>'لخ','ﱁ'=>'لخ','ﶆ'=>'لخم','ļ¶…'=>'لخم','ﳌ'=>'لم','ļ³­'=>'لم','ļ²…'=>'لم','ﱂ'=>'لم','ﶈ'=>'لمح','ﶇ'=>'لمح','ļ¶­'=>'لمى','ļ³'=>'له','ﲆ'=>'لى','ﱃ'=>'لى','ﲇ'=>'لى','ﱄ'=>'لى','ﻣ'=>'Ł…','ﻤ'=>'Ł…','ﻢ'=>'Ł…','ļ»”'=>'Ł…','ﲈ'=>'Ł…Ų§','ļ³Ž'=>'Ł…Ų¬','ļ±…'=>'Ł…Ų¬','ﶌ'=>'Ł…Ų¬Ų­','ļ¶’'=>'Ł…Ų¬Ų®','ļ¶'=>'مجم','ļ·€'=>'مجى','ļ³'=>'Ł…Ų­','ﱆ'=>'Ł…Ų­','ﶉ'=>'Ł…Ų­Ų¬','ﶊ'=>'Ł…Ų­Ł…','ļ·“'=>'Ł…Ų­Ł…ŲÆ','ļ¶‹'=>'محى','ﳐ'=>'Ł…Ų®','ﱇ'=>'Ł…Ų®','ļ¶Ž'=>'Ł…Ų®Ų¬','ļ¶'=>'مخم','ļ¶¹'=>'مخى','ﳑ'=>'Ł…Ł…','ﲉ'=>'Ł…Ł…','ﱈ'=>'Ł…Ł…','ļ¶±'=>'ممى','ﱉ'=>'مى','ﱊ'=>'مى','ļ»§'=>'ن','ﻨ'=>'ن','ﻦ'=>'ن','ﻄ'=>'ن','ļ³’'=>'نج','ﱋ'=>'نج','ļ¶ø'=>'نجح','ļ¶½'=>'نجح','ﶘ'=>'نجم','ļ¶—'=>'نجم','ļ¶™'=>'نجى','ļ·‡'=>'نجى','ﳓ'=>'نح','ﱌ'=>'نح','ļ¶•'=>'نحم','ļ¶–'=>'نحى','ļ¶³'=>'نحى','ļ³”'=>'نخ','ļ±'=>'نخ','ﲊ'=>'نر','ﲋ'=>'نز','ﳕ'=>'نم','ļ³®'=>'نم','ﲌ'=>'نم','ļ±Ž'=>'نم','ļ¶›'=>'نمى','ﶚ'=>'نمى','ļ²'=>'نن','ļ³–'=>'نه','ﳯ'=>'نه','ļ²Ž'=>'نى','ļ±'=>'نى','ļ²'=>'نى','ﱐ'=>'نى','ﮟ'=>'Śŗ','ļ®ž'=>'Śŗ','ﻫ'=>'ه','ﻬ'=>'ه','ﻪ'=>'ه','ﻩ'=>'ه','ھ'=>'ه','ﮬ'=>'ه','ļ®­'=>'ه','ﮫ'=>'ه','ﮪ'=>'ه','ہ'=>'ه','ﮨ'=>'ه','ﮩ'=>'ه','ļ®§'=>'ه','ﮦ'=>'ه','Ū•'=>'ه','ļ³™'=>'هٰ','ļ³—'=>'هج','ﱑ'=>'هج','ﳘ'=>'هم','ļ±’'=>'هم','ļ¶“'=>'همج','ļ¶”'=>'همم','ﱓ'=>'هى','ļ±”'=>'هى','ﮄ'=>'Ū€','ﮤ'=>'Ū€','ļ»®'=>'و','ļ»­'=>'و','ļ·ø'=>'ŁˆŲ³Ł„Ł…','ﯔ'=>'Ū…','ﯠ'=>'Ū…','ﯚ'=>'Ū†','ﯙ'=>'Ū†','ﯘ'=>'Ū‡','ﯗ'=>'Ū‡','Ł·'=>'ۇٔ','ļÆ'=>'ۇٔ','ﯜ'=>'ۈ','ﯛ'=>'ۈ','ﯣ'=>'Ū‰','ﯢ'=>'Ū‰','ﯟ'=>'Ū‹','ļÆž'=>'Ū‹','ﯨ'=>'ى','ﯩ'=>'ى','ļ»°'=>'ى','ﻯ'=>'ى','ي'=>'ى','ﻳ'=>'ى','ﻓ'=>'ى','ﻲ'=>'ى','ļ»±'=>'ى','ی'=>'ى','ﯾ'=>'ى','ﯿ'=>'ى','ﯽ'=>'ى','ﯼ'=>'ى','Łø'=>'ىٔ','ﲐ'=>'ىٰ','ļ±'=>'ىٰ','ﳚ'=>'ىج','ﱕ'=>'ىج','ļ¶Æ'=>'ىجى','ļ³›'=>'ىح','ļ±–'=>'ىح','ļ¶®'=>'ىحى','ﳜ'=>'ىخ','ļ±—'=>'ىخ','ﲑ'=>'ىر','ļ²’'=>'ىز','ļ³'=>'ىم','ļ³°'=>'ىم','ﲓ'=>'ىم','ﱘ'=>'ىم','ļ¶'=>'ىمم','ﶜ'=>'ىمم','ļ¶°'=>'ىمى','ļ²”'=>'ىن','ļ³ž'=>'ىه','ļ³±'=>'ىه','ﲕ'=>'ىى','ļ±™'=>'ىى','ļ²–'=>'ىى','ﱚ'=>'ىى','Ū§'=>'Ū¦','ﮯ'=>'Ū’','ļ®®'=>'Ū’','ļ®±'=>'Ū“','ļ®°'=>'Ū“','∃'=>'⓺','आ'=>'अा','ऒ'=>'ą¤…ą¤¾ą„†','ओ'=>'ą¤…ą¤¾ą„‡','औ'=>'ą¤…ą¤¾ą„ˆ','ऄ'=>'ą¤…ą„†','ऑ'=>'ą¤…ą„‰','ą¤'=>'ą¤ą„…','ą¤Ž'=>'ą¤ą„†','ऐ'=>'ą¤ą„‡','ई'=>'ą¤°ą„ą¤‡','আ'=>'অা','ą§ '=>'ą¦‹ą§ƒ','ą§”'=>'ঌৢ','ਉ'=>'ੳੁ','ਊ'=>'ੳੂ','ਆ'=>'ਅਾ','ਐ'=>'ąØ…ą©ˆ','ਔ'=>'ąØ…ą©Œ','ਇ'=>'ੲਿ','ਈ'=>'ੲੀ','ąØ'=>'ੲੇ','ąŖ†'=>'ąŖ…ąŖ¾','ąŖ‘'=>'અાૅ','ąŖ“'=>'અાે','ąŖ”'=>'ąŖ…ąŖ¾ą«ˆ','ąŖ'=>'ąŖ…ą«…','ąŖ'=>'અે','ઐ'=>'ąŖ…ą«ˆ','ଆ'=>'ଅା','௮'=>'ą®…','ą®°'=>'ஈ','ா'=>'ஈ','௫'=>'ஈு','௨'=>'உ','ஊ'=>'உள','௭'=>'ą®Ž','௷'=>'ą®Žą®µ','ஜ'=>'ஐ','௧'=>'க','௪'=>'ச','௬'=>'சு','௲'=>'ą®šąÆ‚','௺'=>'நீ','ை'=>'ன','௓'=>'மீ','௰'=>'ய','ௗ'=>'ள','௸'=>'ą®·','ொ'=>'ąÆ†ą®ˆ','ௌ'=>'ெள','ோ'=>'ąÆ‡ą®ˆ','ą± '=>'ą°‹ą°¾','ą±”'=>'ఌా','ą°”'=>'ą°’ą±Œ','ą°“'=>'ఒౕ','ą°¢'=>'ఔ̣','ą°­'=>'బ̣','ą°·'=>'వ̣','ą°¹'=>'వా','ą°®'=>'వు','ూ'=>'ుా','ౄ'=>'ృా','ą³”'=>'ಌಾ','ą²”'=>'ą°’ą±Œ','ą“ˆ'=>'ą“‡ąµ—','ą“Š'=>'உൗ','ą“'=>'ą“Žąµ†','ą““'=>'ą“’ą“¾','ą“”'=>'ą“’ąµ—','ąµ”'=>'ą“ž','൫'=>'ą“¦ąµą“°','ą“Œ'=>'ą“ØąÆ‚','ą“™'=>'ą“ØąÆ‚','൯'=>'ą“Øąµ','ą“±'=>'ą“°','ąµŖ'=>'ą“°ąµ','ąµ®'=>'ą“µąµ','ąµ€'=>'ி','ൂ'=>'ூ','ൃ'=>'ூ','ൈ'=>'െെ','ฃ'=>'ąø‚','ąø”'=>'ąø„','ąø•'=>'ąø„','ąø”'=>'ąø†','ąø‹'=>'ช','ąø'=>'ąøŽ','ąø—'=>'ąø‘','ą¹…'=>'ąø²','ąø³'=>'̊า','แ'=>'เเ','ໜ'=>'ąŗ«ąŗ™','ą»'=>'ąŗ«ąŗ”','ąŗ³'=>'̊າ','ą½·'=>'ྲཱྀ','ą½¹'=>'ླཱྀ','၀'=>'o','įž£'=>'įž¢','᧐'=>'į¦ž','į­’'=>'į¬','į­“'=>'ᬑ','᭘'=>'ᬨ','ᢖ'=>'ᔜ','ᔕ'=>'į µ','į’'=>'įŽ”','įŽ½'=>'y','š€'=>'A','š“'=>'A','š‘Ø'=>'A','š’œ'=>'A','š“'=>'A','š”„'=>'A','š”ø'=>'A','š•¬'=>'A','š– '=>'A','š—”'=>'A','š˜ˆ'=>'A','š˜¼'=>'A','š™°'=>'A','ššØ'=>'A','š›¢'=>'A','šœœ'=>'A','š–'=>'A','šž'=>'A','š‰'=>'J','š½'=>'J','š‘±'=>'J','š’„'=>'J','š“™'=>'J','š”'=>'J','š•'=>'J','š•µ'=>'J','š–©'=>'J','š—'=>'J','š˜‘'=>'J','š™…'=>'J','š™¹'=>'J','į§'=>'J','⋿'=>'E','ā„°'=>'E','š„'=>'E','šø'=>'E','š‘¬'=>'E','š“”'=>'E','š”ˆ'=>'E','š”¼'=>'E','š•°'=>'E','š–¤'=>'E','š—˜'=>'E','š˜Œ'=>'E','š™€'=>'E','š™“'=>'E','šš¬'=>'E','š›¦'=>'E','šœ '=>'E','šš'=>'E','šž”'=>'E','ℾ'=>'įŽ±','ššŖ'=>'įŽ±','š›¤'=>'įŽ±','šœž'=>'įŽ±','š˜'=>'įŽ±','šž’'=>'įŽ±','į”'=>'w','ℳ'=>'M','šŒ'=>'M','š‘€'=>'M','š‘“'=>'M','š“œ'=>'M','š”'=>'M','š•„'=>'M','š•ø'=>'M','š–¬'=>'M','š— '=>'M','š˜”'=>'M','š™ˆ'=>'M','š™¼'=>'M','šš³'=>'M','š›­'=>'M','šœ§'=>'M','š”'=>'M','šž›'=>'M','ā„‹'=>'H','ā„Œ'=>'H','ā„'=>'H','š‡'=>'H','š»'=>'H','š‘Æ'=>'H','š“—'=>'H','š•³'=>'H','š–§'=>'H','š—›'=>'H','š˜'=>'H','š™ƒ'=>'H','š™·'=>'H','šš®'=>'H','š›Ø'=>'H','šœ¢'=>'H','šœ'=>'H','šž–'=>'H','š†'=>'G','šŗ'=>'G','š‘®'=>'G','š’¢'=>'G','š“–'=>'G','š”Š'=>'G','š”¾'=>'G','š•²'=>'G','š–¦'=>'G','š—š'=>'G','š˜Ž'=>'G','š™‚'=>'G','š™¶'=>'G','į³'=>'G','ℤ'=>'Z','ℨ'=>'Z','š™'=>'Z','š‘'=>'Z','š’'=>'Z','š’µ'=>'Z','š“©'=>'Z','š–…'=>'Z','š–¹'=>'Z','š—­'=>'Z','š˜”'=>'Z','š™•'=>'Z','šš‰'=>'Z','šš­'=>'Z','š›§'=>'Z','šœ”'=>'Z','š›'=>'Z','šž•'=>'Z','š’'=>'S','š‘†'=>'S','š‘ŗ'=>'S','š’®'=>'S','š“¢'=>'S','š”–'=>'S','š•Š'=>'S','š•¾'=>'S','š–²'=>'S','š—¦'=>'S','š˜š'=>'S','š™Ž'=>'S','šš‚'=>'S','įš'=>'S','š•'=>'V','š‘‰'=>'V','š‘½'=>'V','š’±'=>'V','š“„'=>'V','š”™'=>'V','š•'=>'V','š–'=>'V','š–µ'=>'V','š—©'=>'V','š˜'=>'V','š™‘'=>'V','šš…'=>'V','ā„’'=>'L','š‹'=>'L','šæ'=>'L','š‘³'=>'L','š“›'=>'L','š”'=>'L','š•ƒ'=>'L','š•·'=>'L','š–«'=>'L','š—Ÿ'=>'L','š˜“'=>'L','š™‡'=>'L','š™»'=>'L','āˆ‘'=>'C','ā…€'=>'C','ā„‚'=>'C','ā„­'=>'C','š‚'=>'C','š¶'=>'C','š‘Ŗ'=>'C','š’ž'=>'C','š“’'=>'C','š•®'=>'C','š–¢'=>'C','š—–'=>'C','š˜Š'=>'C','š˜¾'=>'C','š™²'=>'C','ššŗ'=>'C','š›“'=>'C','šœ®'=>'C','šØ'=>'C','šž¢'=>'C','ā„™'=>'P','š'=>'P','š‘ƒ'=>'P','š‘·'=>'P','š’«'=>'P','š“Ÿ'=>'P','š”“'=>'P','š•»'=>'P','š–Æ'=>'P','š—£'=>'P','š˜—'=>'P','š™‹'=>'P','š™æ'=>'P','ššø'=>'P','š›²'=>'P','šœ¬'=>'P','š¦'=>'P','šž '=>'P','šŠ'=>'K','š¾'=>'K','š‘²'=>'K','š’¦'=>'K','š“š'=>'K','š”Ž'=>'K','š•‚'=>'K','š•¶'=>'K','š–Ŗ'=>'K','š—ž'=>'K','š˜’'=>'K','š™†'=>'K','š™ŗ'=>'K','šš±'=>'K','š›«'=>'K','šœ„'=>'K','šŸ'=>'K','šž™'=>'K','ℬ'=>'B','š'=>'B','šµ'=>'B','š‘©'=>'B','š“‘'=>'B','š”…'=>'B','š”¹'=>'B','š•­'=>'B','š–”'=>'B','š—•'=>'B','š˜‰'=>'B','š˜½'=>'B','š™±'=>'B','šš©'=>'B','š›£'=>'B','šœ'=>'B','š—'=>'B','šž‘'=>'B','į'=>'ᐁ·','āˆ†'=>'ᐃ','šš«'=>'ᐃ','š›„'=>'ᐃ','šœŸ'=>'ᐃ','š™'=>'ᐃ','šž“'=>'ᐃ','į'=>'ᐃ·','ᐑ'=>'ᐄ·','ᐓ'=>'ᐅ·','ᐕ'=>'ᐆ·','ᐘ'=>'ᐊ·','ᐚ'=>'ᐋ·','į“‘'=>'ᐔ','į‘¶'=>'Ā·P','ᑺ'=>'Ā·d','į’˜'=>'Ā·J','ᑁ'=>'ᐳ·','į‘ƒ'=>'ᐓ·','į‘…'=>'ᐸ·','ᑇ'=>'ᐹ·','ˈ'=>'į‘Š','į‘˜'=>'į‘ŒĀ·','į‘§'=>'į‘Œį‘Š','į‘š'=>'į‘ŽĀ·','ᑨ'=>'į‘Žį‘Š','į‘œ'=>'į‘Ā·','į‘ž'=>'ᑐ·','į‘©'=>'į‘į‘Š','į‘ '=>'į‘‘Ā·','į‘¢'=>'į‘•Ā·','ᑪ'=>'į‘•į‘Š','ᑤ'=>'į‘–Ā·','ᑵ'=>'į‘«Ā·','į’…'=>'į‘«į‘Š','į‘·'=>'PĀ·','į’†'=>'Pį‘Š','ᑹ'=>'ᑮ·','į‘»'=>'dĀ·','į’‡'=>'dį‘Š','ᑽ'=>'į‘°Ā·','ᑿ'=>'ᑲ·','į’ˆ'=>'į‘²į‘Š','ᒁ'=>'ᑳ·','ᘃ'=>'į’‰','į’“'=>'ᒉ·','į’•'=>'į’‹Ā·','į’—'=>'į’ŒĀ·','į’™'=>'JĀ·','į’›'=>'į’ŽĀ·','į˜‚'=>'ᒐ','į’'=>'ᒐ·','į’Ÿ'=>'į’‘Ā·','į’­'=>'ᒣ·','į’Æ'=>'į’„Ā·','į’±'=>'ᒦ·','į’³'=>'į’§Ā·','į’µ'=>'į’ØĀ·','į’¹'=>'į’«Ā·','į“Š'=>'ᓀ·','į“Œ'=>'ᓇ·','į“Ž'=>'į“ˆį’«','į˜„'=>'į““','į“'=>'į““Ā·','į“Ÿ'=>'į“•Ā·','į“”'=>'į“–Ā·','į“£'=>'į“—Ā·','į“„'=>'į“˜Ā·','į˜‡'=>'į“š','į“§'=>'į“šĀ·','į“©'=>'ᓛ·','į“·'=>'į“­Ā·','ᓹ'=>'ᓯ·','į“»'=>'į“°Ā·','ᓽ'=>'ᓱ·','ᓿ'=>'ᓲ·','ᔁ'=>'į““Ā·','į”ƒ'=>'ᓵ·','į”Œ'=>'ᔋᐸ','į”'=>'ᔋᑕ','į”Ž'=>'ᔋᑲ','į”'=>'ᔋᒐ','į”˜'=>'ᔐ·','į”š'=>'ᔑ·','į”œ'=>'į”’Ā·','į”ž'=>'ᔓ·','į” '=>'ᔔ·','ᔢ'=>'ᔕ·','ᔤ'=>'į”–Ā·','ᔲ'=>'ᔨ·','ᔓ'=>'ᔩ·','į”¶'=>'ᔪ·','ᔸ'=>'ᔫ·','ᔺ'=>'į”­Ā·','ᔼ'=>'ᔮ·','į™®'=>'x','ᕽ'=>'x','ᘢ'=>'į•ƒ','ᘣ'=>'ᕆ','ᘤ'=>'į•Š','į•'=>'į•ŒĀ·','ᙯ'=>'ᕐᑫ','ᕾ'=>'ᕐᑬ','ᕿ'=>'ᕐP','į–€'=>'ᕐᑮ','ᖁ'=>'ᕐd','į–‚'=>'ᕐᑰ','į–ƒ'=>'ᕐᑲ','į–„'=>'ᕐᑳ','į–…'=>'į•į’ƒ','į•œ'=>'į•šĀ·','į•©'=>'į•§Ā·','ā„›'=>'R','ā„œ'=>'R','ā„'=>'R','š‘'=>'R','š‘…'=>'R','š‘¹'=>'R','š“”'=>'R','š•½'=>'R','š–±'=>'R','š—„'=>'R','š˜™'=>'R','š™'=>'R','šš'=>'R','į™°'=>'į–•į’‰','į–Ž'=>'į–•į’Š','į–'=>'į–•į’‹','ᖐ'=>'į–•į’Œ','į–‘'=>'į–•J','į–’'=>'į–•į’Ž','į–“'=>'ᖕᒐ','į–”'=>'į–•į’‘','į™±'=>'į––į’‹','ᙲ'=>'į––į’Œ','ᙳ'=>'į––J','ᙓ'=>'į––į’Ž','ᙵ'=>'ᖖᒐ','į™¶'=>'į––į’‘','ℱ'=>'F','š…'=>'F','š¹'=>'F','š‘­'=>'F','š“•'=>'F','š”‰'=>'F','š”½'=>'F','š•±'=>'F','š–„'=>'F','š—™'=>'F','š˜'=>'F','š™'=>'F','š™µ'=>'F','šŸŠ'=>'F','ā……'=>'D','šƒ'=>'D','š·'=>'D','š‘«'=>'D','š’Ÿ'=>'D','š““'=>'D','š”‡'=>'D','š”»'=>'D','š•Æ'=>'D','š–£'=>'D','š——'=>'D','š˜‹'=>'D','š˜æ'=>'D','š™³'=>'D','į—Ŗ'=>'D','ā„§'=>'ᘮ','ᘓ'=>'ᘮ','š›€'=>'ᘯ','š›ŗ'=>'ᘯ','šœ“'=>'ᘯ','š®'=>'ᘯ','šžØ'=>'ᘯ','ᘵ'=>'ᘯ','愱'=>'į„€','ļ¾”'=>'į„€','ᆨ'=>'į„€','ㄲ'=>'ᄁ','ļ¾¢'=>'ᄁ','ᆩ'=>'ᄁ','ć„“'=>'į„‚','ᄂ'=>'į„‚','ᆫ'=>'į„‚','ć„·'=>'į„ƒ','ļ¾§'=>'į„ƒ','ᆮ'=>'į„ƒ','ㄸ'=>'į„„','ᄄ'=>'į„„','ㄹ'=>'į„…','ᄅ'=>'į„…','ᆯ'=>'į„…','慁'=>'ᄆ','ļ¾±'=>'ᄆ','ᆷ'=>'ᄆ','慂'=>'ᄇ','ļ¾²'=>'ᄇ','ᆸ'=>'ᄇ','慃'=>'į„ˆ','ļ¾³'=>'į„ˆ','慅'=>'ᄉ','ļ¾µ'=>'ᄉ','ᆺ'=>'ᄉ','慆'=>'į„Š','ļ¾¶'=>'į„Š','ᆻ'=>'į„Š','慇'=>'į„‹','ļ¾·'=>'į„‹','ᆼ'=>'į„‹','慈'=>'į„Œ','ļ¾ø'=>'į„Œ','ᆽ'=>'į„Œ','慉'=>'į„','ļ¾¹'=>'į„','慊'=>'į„Ž','ļ¾ŗ'=>'į„Ž','ᆾ'=>'į„Ž','態'=>'į„','ļ¾»'=>'į„','ᆿ'=>'į„','慌'=>'ᄐ','ļ¾¼'=>'ᄐ','ᇀ'=>'ᄐ','慍'=>'į„‘','ļ¾½'=>'į„‘','ᇁ'=>'į„‘','慎'=>'į„’','ļ¾¾'=>'į„’','ᇂ'=>'į„’','ᇅ'=>'į„“','ć…„'=>'į„”','ć…¦'=>'į„•','ᇆ'=>'į„•','į‡Š'=>'į„—','į‡'=>'į„˜','ᇐ'=>'į„™','慀'=>'į„š','ļ¾°'=>'į„š','į„»'=>'į„š','ᆶ'=>'į„š','ć…®'=>'į„œ','į‡œ'=>'į„œ','ć…±'=>'į„','ᇢ'=>'į„','ć…²'=>'į„ž','ć…³'=>'į„ ','慄'=>'į„”','モ'=>'į„”','ᆹ'=>'į„”','ć…“'=>'į„¢','ć…µ'=>'į„£','ć…¶'=>'į„§','ć…·'=>'į„©','ć…ø'=>'į„«','ᇦ'=>'į„«','ć…¹'=>'ᄬ','ć…ŗ'=>'į„­','ᇧ'=>'į„­','ć…»'=>'į„®','ć…¼'=>'ᄯ','ᇨ'=>'ᄯ','ᇩ'=>'į„°','ć…½'=>'ᄲ','ᇪ'=>'ᄲ','ć…¾'=>'į„¶','ć…æ'=>'į…€','ᇫ'=>'į…€','ᇬ'=>'ᅁ','ᇱ'=>'į……','憂'=>'į……','ᇲ'=>'į…†','憃'=>'į…†','憀'=>'į…‡','ᇮ'=>'į…‡','憁'=>'į…Œ','ᇰ'=>'į…Œ','ᇳ'=>'į…–','憄'=>'į…—','ᇓ'=>'į…—','憅'=>'į…˜','憆'=>'į…™','ᇹ'=>'į…™','慤'=>'į… ','ļ¾ '=>'į… ','慏'=>'į…”','ļæ‚'=>'į…”','慐'=>'į…¢','ᅢ'=>'į…¢','慑'=>'į…£','ļæ„'=>'į…£','慒'=>'į…¤','ļæ…'=>'į…¤','慓'=>'į…„','ᅥ'=>'į…„','慔'=>'į…¦','ᅦ'=>'į…¦','慕'=>'į…§','ᅧ'=>'į…§','慖'=>'į…Ø','ļæ‹'=>'į…Ø','慗'=>'į…©','ᅩ'=>'į…©','慘'=>'į…Ŗ','ļæ'=>'į…Ŗ','慙'=>'į…«','ļæŽ'=>'į…«','慚'=>'į…¬','ļæ'=>'į…¬','慛'=>'į…­','ļæ’'=>'į…­','慜'=>'į…®','ļæ“'=>'į…®','慝'=>'į…Æ','ļæ”'=>'į…Æ','慞'=>'į…°','ļæ•'=>'į…°','慟'=>'į…±','ļæ–'=>'į…±','慠'=>'į…²','ļæ—'=>'į…²','ć…”'=>'äø€','ᅳ'=>'äø€','ć…¢'=>'į…“','ļæ›'=>'į…“','ć…£'=>'äøØ','ᅵ'=>'äøØ','憇'=>'ᆄ','ᆆ'=>'ᆄ','憈'=>'ᆅ','憉'=>'į†ˆ','憊'=>'ᆑ','憋'=>'ᆒ','憌'=>'ᆔ','憍'=>'į†ž','憎'=>'ᆔ','ㄳ'=>'ᆪ','ļ¾£'=>'ᆪ','愵'=>'ᆬ','ト'=>'ᆬ','ć„¶'=>'ᆭ','ᆭ'=>'ᆭ','ㄺ'=>'ᆰ','ļ¾Ŗ'=>'ᆰ','ć„»'=>'ᆱ','ᆱ'=>'ᆱ','ㄼ'=>'ᆲ','ᆲ'=>'ᆲ','ㄽ'=>'ᆳ','ļ¾­'=>'ᆳ','ㄾ'=>'ᆓ','ļ¾®'=>'ᆓ','ㄿ'=>'ᆵ','ᆵ'=>'ᆵ','慧'=>'ᇇ','ć…Ø'=>'į‡ˆ','ć…©'=>'į‡Œ','ć…Ŗ'=>'į‡Ž','ć…«'=>'ᇓ','ć…¬'=>'ᇗ','慭'=>'ᇙ','ć…Æ'=>'į‡','慰'=>'į‡Ÿ','ļ½§'=>'ć‚”','ļ½±'=>'ć‚¢','ィ'=>'ć‚£','ļ½²'=>'悤','ゥ'=>'ć‚„','ļ½³'=>'悦','ļ½Ŗ'=>'悧','s'=>'エ','ォ'=>'ć‚©','ļ½µ'=>'オ','ļ½¶'=>'ć‚«','ļ½·'=>'悭','ļ½ø'=>'ク','ļ½¹'=>'悱','ļ½ŗ'=>'コ','ļ½»'=>'悵','ļ½¼'=>'ć‚·','ļ½½'=>'ス','ļ½¾'=>'ć‚»','ソ'=>'ソ','ļ¾€'=>'タ','チ'=>'惁','ッ'=>'惃','ツ'=>'惄','テ'=>'惆','ト'=>'惈','ļ¾…'=>'ナ','ニ'=>'惋','ヌ'=>'ヌ','ネ'=>'惍','ノ'=>'惎','ハ'=>'惏','ヒ'=>'惒','フ'=>'惕','ļ¾'=>'へ','ļ¾Ž'=>'惛','ļ¾'=>'惞','ā§„'=>'〼','ミ'=>'ミ','ム'=>'惠','ļ¾’'=>'惔','モ'=>'モ','ャ'=>'ャ','ļ¾”'=>'惤','ļ½­'=>'惄','ユ'=>'惦','ļ½®'=>'惧','ļ¾–'=>'ヨ','ļ¾—'=>'惩','リ'=>'リ','ļ¾™'=>'惫','レ'=>'惬','ļ¾›'=>'惭','ワ'=>'ワ','ヲ'=>'ヲ','ļ¾'=>'ン','ź’ž'=>'ꁊ','ź’¬'=>'ꁐ','ź’œ'=>'źƒ€','ź’æ'=>'ꉙ','ź’¾'=>'ꊱ','ź“€'=>'źŽ«','ź“‚'=>'źŽµ','ź’ŗ'=>'źŽæ','ź’°'=>'ź‚','𐒠'=>'𐒆','—'=>'äø€','―'=>'äø€','āˆ’'=>'äø€','─'=>'äø€','ā¼€'=>'äø€','ļ„§'=>'äø','ļ©°'=>'äø¦','|'=>'äøØ','|'=>'äøØ','∣'=>'äøØ','⼁'=>'äøØ','‖'=>'äøØäøØ','∄'=>'äøØäøØ','串'=>'äø²','⼂'=>'äø¶','丸'=>'äøø','ļ„ž'=>'äø¹','丽'=>'äø½','⼃'=>'äøæ','乁'=>'乁','⼄'=>'乙','亂'=>'äŗ‚','ā¼…'=>'äŗ…','了'=>'äŗ†','⼆'=>'二','⼇'=>'äŗ ','ļ„·'=>'äŗ®','⼈'=>'äŗŗ','ļ§½'=>'什','仌'=>'仌','令'=>'令','你'=>'ä½ ','倂'=>'ä½µ','倂'=>'ä½µ','侀'=>'侀','來'=>'來','例'=>'例','侮'=>'ä¾®','侮'=>'ä¾®','侻'=>'ä¾»','ļ„„'=>'便','值'=>'値','ļ§”'=>'倫','偺'=>'偺','備'=>'備','像'=>'像','僚'=>'僚','僧'=>'僧','僧'=>'僧','⼉'=>'儿','兀'=>'兀','ļ©“'=>'充','免'=>'免','šÆ Ž'=>'免','šÆ '=>'兔','兤'=>'兤','⼊'=>'å…„','內'=>'內','全'=>'å…Ø',''=>'兩','⼋'=>'八','ļ§‘'=>'六','具'=>'具','冀'=>'冀','⼌'=>'冂','再'=>'再','冒'=>'冒','冕'=>'冕','ā¼'=>'冖','冗'=>'冗','冤'=>'冤','ā¼Ž'=>'冫','冬'=>'冬','况'=>'况','况'=>'况','冷'=>'冷',''=>'凉','ļ„•'=>'凌','ļ„”'=>'凜','凞'=>'凞','ā¼'=>'几','šÆ '=>'凵','⼐'=>'凵','⼑'=>'刀','šÆ ž'=>'刃','切'=>'切','𯔐'=>'切','列'=>'列','ļ§'=>'利','ļ§æ'=>'刺','刻'=>'刻','內'=>'剆','割'=>'割','剷'=>'剷','劉'=>'劉','力'=>'力','ā¼’'=>'力','ļ¦'=>'劣','劳'=>'劳','ļ©¶'=>'勇','你'=>'勇','勉'=>'勉','勉'=>'勉','ļ„’'=>'勒','勞'=>'勞','﨓'=>'勤','勤'=>'勤',''=>'勵','⼓'=>'勹','ļ©·'=>'勺','勺'=>'勺','包'=>'包','匆'=>'匆','ā¼”'=>'匕','ļ„£'=>'北','北'=>'北','⼕'=>'匚','ā¼–'=>'匸','ļ§«'=>'匿','ā¼—'=>'十','〸'=>'十','〹'=>'卄','〺'=>'卅','卉'=>'卉','卑'=>'卑','卑'=>'卑','博'=>'博','⼘'=>'卜','ā¼™'=>'卩','即'=>'即','卵'=>'卵','卽'=>'卽','卿'=>'åæ','卿'=>'åæ','卿'=>'åæ','⼚'=>'厂','ā¼›'=>'厶','ļ„«'=>'參','⼜'=>'又','及'=>'及','叟'=>'叟','ā¼'=>'口','句'=>'叄','叫'=>'叫','叱'=>'叱','吆'=>'吆','ļ§ž'=>'吏','ļ§­'=>'吝','吸'=>'吸','呂'=>'呂','呈'=>'呈','周'=>'周','咞'=>'咞','𯔀'=>'咢','ļ¦ž'=>'咽','𯔁'=>'哶','𯔂'=>'唐','𯔃'=>'啓','啟'=>'啓','啕'=>'啕','𯔄'=>'啣','𯔅'=>'善','𯔆'=>'善','喇'=>'喇','喙'=>'喙','𯔇'=>'喙','喝'=>'喝','喝'=>'喝','𯔈'=>'喫','𯔉'=>'喳','ļØ'=>'嗀','𯔊'=>'嗂','ļ©»'=>'嗢','嘆'=>'嘆','𯔌'=>'嘆','šÆ”Ž'=>'噑','器'=>'器','šÆ”'=>'噓','ā¼ž'=>'囗','囹'=>'囹','𯔋'=>'圖','šÆ”'=>'圗','⼟'=>'土','𯔕'=>'型','𯔒'=>'城','𯔓'=>'埓','𯔔'=>'堍','𯔗'=>'å ±','𯔖'=>'å ²','塀'=>'唀','塚'=>'唚','塚'=>'唚',''=>'唞','唫'=>'å””','墨'=>'墨','壿'=>'墫','𯔘'=>'墬','墳'=>'墳',''=>'壘','ļ„‚'=>'壟','ā¼ '=>'士','𯔑'=>'壮','𯔚'=>'売','𯔛'=>'壷','ā¼”'=>'夂','𯔜'=>'夆','ā¼¢'=>'夊','ā¼£'=>'夕','šÆ”'=>'多','šÆ”ž'=>'夢','⼤'=>'大','奄'=>'å„„','奈'=>'儈','契'=>'å„‘','奔'=>'å„”','𯔟'=>'å„¢','女'=>'儳','⼄'=>'儳','𯔄'=>'姘','𯔢'=>'姬','𯔣'=>'娛','𯔤'=>'娧','ļŖ€'=>'å©¢','𯔦'=>'婦','嬀'=>'åŖÆ','媵'=>'åŖµ','𯔩'=>'嬈','嬨'=>'嬨','𯔪'=>'嬾','𯔫'=>'嬾','⼦'=>'子','ā¼§'=>'宀','宅'=>'宅','𯔭'=>'寃','𯔮'=>'寘',''=>'寧','寧'=>'寧','𯔯'=>'寧','寮'=>'寮','𯔰'=>'寳','⼨'=>'寸','𯔲'=>'寿','𯔳'=>'将','⼩'=>'小','𯔵'=>'å°¢','ā¼Ŗ'=>'å°¢','⼫'=>'å°ø','尿'=>'å°æ','𯔷'=>'å± ','ļ„‹'=>'å±¢','層'=>'層','履'=>'屄','屮'=>'å±®','𯔸'=>'å±®','⼬'=>'å±®','ā¼­'=>'å±±','𯔺'=>'岍','𯔹'=>'峀','ļ§•'=>'å“™','𯔼'=>'嵃','樂'=>'嵐','𯔿'=>'嵫','𯔾'=>'åµ®','嵼'=>'åµ¼','𧲨'=>'å¶²','嶺'=>'å¶ŗ','ā¼®'=>'巛','巡'=>'å·”','巢'=>'å·¢','⼯'=>'å·„','ā¼°'=>'å·±','巽'=>'å·½','ā¼±'=>'å·¾','åø²'=>'åø”','帨'=>'åøØ','帽'=>'åø½','幩'=>'幩','ā¼²'=>'å¹²','ļ¦Ž'=>'幓','ā¼³'=>'å¹ŗ','⼓'=>'广','度'=>'åŗ¦','庰'=>'åŗ°','庳'=>'åŗ³','šÆ¢'=>'åŗ¶','廉'=>'廉','廊'=>'廊','šÆ¢Ž'=>'廊','ļŖ‚'=>'廒','廓'=>'廓','廙'=>'廙','廬'=>'廬','ā¼µ'=>'廓','廾'=>'廾','ā¼¶'=>'廾',''=>'弄','ā¼·'=>'弋','ā¼ø'=>'弓','弢'=>'å¼¢','弢'=>'å¼¢','ā¼¹'=>'彐','𯔓'=>'当','ā¼ŗ'=>'å½”','形'=>'å½¢','ļŖ„'=>'彩','彫'=>'彫','ā¼»'=>'å½³','律'=>'律','徚'=>'徚',''=>'復','ļŖ…'=>'å¾­','ā¼¼'=>'心','šÆ¢'=>'åæ','šÆ¢ž'=>'åæ—','念'=>'åæµ','忹'=>'åæ¹','ļ„ '=>'ꀒ','怜'=>'ꀜ','悁'=>'ꂁ','悔'=>'ꂔ','悔'=>'ꂔ','巽'=>'ꃇ','ļŖ†'=>'ꃘ','惡'=>'ꃔ','愈'=>'ꄈ','ļ§™'=>'ꅄ','慈'=>'ꅈ','慌'=>'ꅌ','慌'=>'ꅌ','ļŖ‡'=>'ꅎ','慎'=>'ꅎ','慠'=>'ꅠ','慨'=>'ę…Ø','慺'=>'ę…ŗ','憎'=>'ꆎ','ļŖ‰'=>'ꆎ','憎'=>'ꆎ','ļ¦'=>'ꆐ','憤'=>'ꆤ','憯'=>'憯','憲'=>'憲','懞'=>'ꇞ','ļ©€'=>'懲','ļŖ‹'=>'懲','懲'=>'懲','ļ¤'=>'ꇶ','懶'=>'ꇶ','戀'=>'ꈀ','ā¼½'=>'ꈈ','成'=>'ꈐ','戛'=>'ꈛ','ļ§’'=>'ꈮ','戴'=>'ꈓ','ā¼¾'=>'ꈶ','⼿'=>'ꉋ','舁'=>'ꉝ','抱'=>'抱','滑'=>'ꋉ','ļ„›'=>'ꋏ','拓'=>'ꋓ','拔'=>'ꋔ','拼'=>'拼',''=>'拾','挽'=>'挽','捐'=>'ꍐ','捨'=>'ęØ','捻'=>'ę»','掃'=>'ꎃ',''=>'ꎠ','掩'=>'ꎩ','ļŖ'=>'ꏄ','揅'=>'ꏅ','揤'=>'ꏤ','橁'=>'ꐉ','ļŖŽ'=>'搜','搢'=>'搢','ļŖ'=>'ꑒ','摩'=>'ę‘©','摷'=>'ę‘·','摾'=>'摾','撚'=>'꒚','撝'=>'꒝','擄'=>'꓄','ā½€'=>'支','⽁'=>'ꔓ','敏'=>'ꕏ','敏'=>'ꕏ','敖'=>'ꕖ','敬'=>'ꕬ','ļ„©'=>'數','⽂'=>'ꖇ','⽃'=>'ꖗ','料'=>'ꖙ','⽄'=>'ꖤ','ā½…'=>'ę–¹','旅'=>'ꗅ','⽆'=>'ꗠ','ļ©‚'=>'ę—¢','旣'=>'ę—£','⽇'=>'ę—„','ļ§ '=>'ꘓ','šÆ£'=>'ꙉ','ꙩ'=>'Ꙛ','䀿'=>'晣','晴'=>'ꙓ','ļŖ‘'=>'ꙓ','ļ§…'=>'暈','暑'=>'ꚑ','šÆ£'=>'ꚑ','暜'=>'暜','暴'=>'暓','曆'=>'ꛆ','⽈'=>'꛰','更'=>'ꛓ','㫚'=>'ę›¶','書'=>'書','最'=>'꜀','⽉'=>'月','肦'=>'朌','胐'=>'꜏','胊'=>'朐','脁'=>'꜓','朗'=>'ꜗ','ļŖ’'=>'ꜗ','朗'=>'ꜗ','脧'=>'朘','ļŖ“'=>'ꜛ','望'=>'ꜛ','朡'=>'朔','膧'=>'朣','⽊'=>'木','ļ§”'=>'Ꝏ','杓'=>'ꝓ','ļŖ”'=>'Ꝗ','杞'=>'Ꝟ','柿'=>'ę®','杻'=>'ę»','枅'=>'ꞅ','ļ§“'=>'ꞗ','柳'=>'柳','柺'=>'柺','栗'=>'ꠗ','摾'=>'栟','最'=>'ę”’',''=>'梁','ļ©„'=>'梅','梅'=>'梅','梎'=>'ę¢Ž','ļ§¢'=>'梨','椔'=>'ꤔ','楂'=>'ę„‚','樧'=>'ę¦','榣'=>'榣','槪'=>'ę§Ŗ','樂'=>'樂',''=>'樂','樂'=>'樂',''=>'樓','檨'=>'ęŖØ','櫓'=>'ę«“','櫛'=>'ę«›','ļ¤'=>'ꬄ','⽋'=>'ꬠ','次'=>'ꬔ','歔'=>'ꭔ','⽌'=>'ę­¢','歲'=>'ę­²','歷'=>'ę­·','ļŖ•'=>'ę­¹','ā½'=>'ę­¹','冕'=>'殟','濾'=>'ę®®','ā½Ž'=>'殳','ļ„°'=>'殺','ļŖ–'=>'殺','殺'=>'殺','殻'=>'ę®»','ā½'=>'毋','⺟'=>'ęÆ','⽐'=>'比','⽑'=>'毛','ā½’'=>'갏','⽓'=>'갔','ā½”'=>'ę°“','汎'=>'걎','汧'=>'ę±§',''=>'沈','沿'=>'沿',''=>'泌','泍'=>'ę³','ļ§£'=>'泄','洖'=>'ę“–','洛'=>'ę“›','洞'=>'ꓞ','洴'=>'ę““','派'=>'擾','流'=>'굁','ļŖ—'=>'굁','流'=>'굁','浩'=>'굩','浪'=>'ęµŖ','ļ©…'=>'ęµ·','海'=>'ęµ·','浸'=>'ęµø','涅'=>'ę¶…','ļ§µ'=>'ę·‹','ļ„'=>'淚','ļ§–'=>'ę·Ŗ','šÆ¤Ž'=>'ę·¹','渚'=>'渚','港'=>'ęøÆ','湮'=>'ę¹®','ę½™'=>'溈','ļ§‹'=>'溜','溺'=>'ęŗŗ','滇'=>'껇','ļŖ™'=>'껋','滋'=>'껋','滑'=>'껑','滛'=>'ę»›','ļ„Ž'=>'ę¼','漢'=>'ę¼¢','漢'=>'ę¼¢','漣'=>'ę¼£','šÆ¤'=>'ę½®','濆'=>'濆','濫'=>'ęæ«','濾'=>'ęæ¾','瀛'=>'瀛','ļŖ›'=>'ē€ž','瀞'=>'ē€ž','瀹'=>'瀹','灊'=>'灊','⽕'=>'火','灰'=>'灰','灷'=>'灷','災'=>'災','ļ§»'=>'ē‚™','炭'=>'ē‚­','烈'=>'烈','烙'=>'ēƒ™','煅'=>'ē……','煉'=>'ē…‰','煮'=>'ē…®','煮'=>'ē…®','šÆ¤ž'=>'ē†œ','ļ§€'=>'ē‡Ž','ļ§®'=>'燐','爐'=>'爐','ļ¤ž'=>'ēˆ›','爨'=>'爨','ā½–'=>'爪','爫'=>'爫','āŗ¤'=>'爫','ļŖž'=>'爵','瀞'=>'爵','ā½—'=>'父','⽘'=>'爻','ā½™'=>'爿','⽚'=>'片','牐'=>'牐','ā½›'=>'牙','⽜'=>'牛',''=>'牢','犀'=>'ēŠ€','浸'=>'ēŠ•','ā½'=>'犬','犯'=>'犯','ļ§ŗ'=>'ē‹€','狼'=>'狼','猪'=>'猪','ļŖ '=>'猪','獵'=>'ēµ','獺'=>'ēŗ','ā½ž'=>'ēŽ„','ļ„”'=>'ēŽ‡','ļ§›'=>'ēŽ‡','⽟'=>'ēŽ‰','王'=>'ēŽ‹','玥'=>'ēŽ„','玲'=>'ēŽ²','珞'=>'ēž','理'=>'理','琉'=>'琉','琢'=>'琢','瑇'=>'瑇','瑜'=>'ē‘œ','瑩'=>'ē‘©','ļŖ”'=>'瑱','瑱'=>'瑱','璅'=>'ē’…','璉'=>'ē’‰','ļ§Æ'=>'ē’˜','瓊'=>'ē“Š','ā½ '=>'ē“œ','ā½”'=>'瓦','ļŖ¢'=>'甆','ā½¢'=>'ē”˜','ā½£'=>'ē”Ÿ','瀹'=>'甤','⽤'=>'用','⽄'=>'ē”°','ļŖ£'=>'ē”»','甾'=>'甾','ļ§'=>'ē•™','ļ„¶'=>'ē•„','ļ„¢'=>'ē•°','異'=>'ē•°','⽦'=>'ē–‹','ā½§'=>'ē–’','ļ§„'=>'ē—¢','瘐'=>'瘐','ļŖ¤'=>'ē˜','ļŖ„'=>'瘟','療'=>'療','ļ¤Ž'=>'癩','⽨'=>'ē™¶','⽩'=>'白','ā½Ŗ'=>'皮','⽫'=>'皿','益'=>'ē›Š','ļŖ¦'=>'ē›Š','ļŖ§'=>'ē››','盧'=>'ē›§','⽬'=>'ē›®','ļŖØ'=>'盓','𯄀'=>'盓','ļ„­'=>'省','𯄅'=>'ēœž','𯄆'=>'真','𯄇'=>'真','ļŖŖ'=>'ē€','ļŖ©'=>'ēŠ','𯄈'=>'ēŠ','𯄊'=>'ēž‹','ļŖ'=>'ēž§','ā½­'=>'ēŸ›','ā½®'=>'矢','⽯'=>'石','ē”'=>'ē ”','šÆ„Ž'=>'ē”Ž','ļ§Ž'=>'甫','碌'=>'碌','šÆ„'=>'碌','ļ©‹'=>'碑',''=>'磊','ļŖ«'=>'磌','𯄐'=>'磌',''=>'磻','礪'=>'礪','ā½°'=>'示','礼'=>'礼','社'=>'社','ļ©Ž'=>'焈','ļ©'=>'焉','ļ©'=>'焐','祖'=>'ē„–','𯄓'=>'ē„–','ļ©‘'=>'ē„','神'=>'ē„ž','祥'=>'ē„„','祿'=>'焿','ļ©’'=>'ē¦','ļ©“'=>'ē¦Ž','福'=>'ē¦','𯄖'=>'ē¦','禮'=>'禮','ā½±'=>'禸','ā½²'=>'禾','秊'=>'秊','𯄗'=>'ē§«','ļ„–'=>'稜','ļ©”'=>'ē©€','𯄙'=>'ē©€','𯄚'=>'穊','𯄛'=>'ē©','ā½³'=>'ē©“','ļ©•'=>'突','ļŖ¬'=>'ēŖ±','ļ§·'=>'ē«‹','⽓'=>'ē«‹','𯄟'=>'ē«®','ā½µ'=>'竹','ļ§ø'=>'笠','ļ©–'=>'節','ļŖ­'=>'節','𯄢'=>'篆','𯄣'=>'築','簾'=>'ē°¾','ļ„„'=>'ē± ','ā½¶'=>'ē±³','ļŖ®'=>'ē±»','ļ§¹'=>'ē²’','ļØ'=>'ē²¾','𯄦'=>'ē³’','糖'=>'ē³–','𯄩'=>'ē³£','ļ„»'=>'ē³§','𯄨'=>'糨','ā½·'=>'ē³ø','𯄪'=>'ē“€','ļ§'=>'瓐',''=>'ē“¢','ļ„'=>'瓯','ēµ¶'=>'絕','ļŖÆ'=>'ēµ›','𯄬'=>'ēµ£','綠'=>'ē¶ ','ļ„—'=>'ē¶¾','𯄮'=>'ē·‡','練'=>'ē·“','ļ©—'=>'ē·“','ļŖ°'=>'ē·“','𯄯'=>'ēø‚','縉'=>'ēø‰',''=>'ēø·','ļ©™'=>'繁','𯄰'=>'ē¹…','ā½ø'=>'ē¼¶','ļŖ±'=>'ē¼¾','ā½¹'=>'网','āŗ«'=>'ē½’','署'=>'ē½²','罹'=>'ē½¹','𯄶'=>'ē½ŗ','ļ¤'=>'ē¾…','ā½ŗ'=>'羊','𯄸'=>'羕','羚'=>'羚','ļØž'=>'ē¾½','ā½»'=>'ē¾½','𯄹'=>'ēæŗ','邏'=>'老','ā½¼'=>'老','ļ©›'=>'者','ļŖ²'=>'者','𯄺'=>'者','ā½½'=>'而','ā½¾'=>'耒','⽿'=>'耳','聆'=>'聆','𯄽'=>'聠','聯'=>'聯','𯄿'=>'聰','ļ„…'=>'聾','ā¾€'=>'聿','⾁'=>'肉','ļ„“'=>'肋','肭'=>'肭','育'=>'育','欵'=>'胶','腁'=>'胼','脃'=>'脃','脾'=>'脾','臘'=>'臘','⾂'=>'臣','ļ§¶'=>'臨','⾃'=>'自','臭'=>'臭','⾄'=>'至','ā¾…'=>'臼','舁'=>'舁','舁'=>'舁','舄'=>'舄','⾆'=>'舌','⾇'=>'舛','⾈'=>'舟','⾉'=>'艮',''=>'良','⾊'=>'色','⾋'=>'艸','ļ©'=>'艹','ļ©ž'=>'艹','芋'=>'芋','šÆ¦'=>'芑','芝'=>'芝','花'=>'花','芳'=>'芳','芽'=>'芽','ļ„“'=>'č‹„','若'=>'č‹„','苦'=>'苦','茝'=>'茝','茣'=>'茣','ļ§¾'=>'茶','ļŖ³'=>'荒','荓'=>'荓','荣'=>'č£','莭'=>'莭','šÆ¦'=>'čŽ½','菉'=>'菉','芳'=>'菊','菌'=>'菌','菜'=>'菜','šÆ¦ž'=>'菧','ļŖ“'=>'čÆ',''=>'č±','落'=>'落','ļ„®'=>'葉','著'=>'著','著'=>'著','蔿'=>'蒍','蓮'=>'č“®','蓱'=>'蓱','蓳'=>'蓳','ļ§‚'=>'蓼','蔖'=>'蔖','蕤'=>'蕤','藍'=>'藍','ļ§°'=>'č—ŗ','蘆'=>'蘆','蘒'=>'蘒','蘭'=>'蘭','虁'=>'蘷','蘿'=>'蘿','⾌'=>'虍','虐'=>'虐','虜'=>'虜','花'=>'虜','虧'=>'虧','虩'=>'虩','ā¾'=>'虫','蚈'=>'蚈','蚩'=>'蚩','蛢'=>'蛢','蜎'=>'蜎','蜨'=>'蜨','蝫'=>'č«','ļŖµ'=>'č¹','蝹'=>'č¹','螆'=>'螆','螺'=>'čžŗ','蟡'=>'蟔','蠁'=>'蠁','蠟'=>'蠟','ā¾Ž'=>'蔀','行'=>'蔌','ā¾'=>'蔌','衠'=>'č” ','衣'=>'蔣','⾐'=>'蔣','裂'=>'裂','ļ§§'=>'č£','裗'=>'裗','裞'=>'č£ž','ļ§Ø'=>'裔','裸'=>'裸','裺'=>'裺','ļ© '=>'褐','ļŖ¶'=>'脁','襤'=>'脤','⾑'=>'脾','ļŖ·'=>'覆','見'=>'見','ā¾’'=>'見','ļ©”'=>'視','ļŖø'=>'視','⾓'=>'角','ā¾”'=>'言','䚶'=>'čØž','詽'=>'訮','šÆ§'=>'čŖ ',''=>'čŖŖ','璉'=>'čŖŖ','ļŖ¹'=>'čŖæ','ļŖ»'=>'č«‹',''=>'č«’',''=>'č«–','ļŖ¾'=>'č«­','諭'=>'č«­','諸'=>'諸','ļŖŗ'=>'諸','ļ„'=>'諾','ļŖ½'=>'諾','ļ©¢'=>'謁','ļŖ¼'=>'謁','ļ©£'=>'謹','ļŖæ'=>'謹','ļ§¼'=>'識',''=>'讀','č®'=>'讆','ļ«€'=>'變','變'=>'變','⾕'=>'č°·','ā¾–'=>'豆','豈'=>'豈','豕'=>'豕','ā¾—'=>'豕','⾘'=>'č±ø','ā¾™'=>'č²','貫'=>'貫','賁'=>'賁',''=>'賂','賈'=>'賈','賓'=>'賓','ļ©„'=>'蓈','贈'=>'蓈','贛'=>'č“›','⾚'=>'赤','ā¾›'=>'čµ°','起'=>'čµ·','趆'=>'赿','⾜'=>'č¶³','趼'=>'č¶¼','跋'=>'č·‹','č·ŗ'=>'č·„','路'=>'č·Æ','跰'=>'č·°','čŗ›'=>'čŗ—','ā¾'=>'čŗ«','車'=>'車','ā¾ž'=>'車','šÆ§ž'=>'č»”','č¼§'=>'軿','輦'=>'輦','ļ§—'=>'č¼Ŗ','ļ«‚'=>'č¼ø','輸'=>'č¼ø','輻'=>'č¼»','ļ¦'=>'č½¢','⾟'=>'č¾›','šÆ¦'=>'č¾ž',''=>'č¾°','ā¾ '=>'č¾°','ā¾”'=>'č¾µ','辶'=>'č¾¶','⻌'=>'č¾¶','連'=>'連','宅'=>'逸','ļ©§'=>'逸','遲'=>'遲','遼'=>'遼','邏'=>'邏','ā¾¢'=>'邑','邔'=>'邔','郎'=>'郎','郱'=>'郱','都'=>'都','鄑'=>'鄑','鄛'=>'鄛','ā¾£'=>'酉','酪'=>'é…Ŗ','ļ«„'=>'醙','醴'=>'醓','⾤'=>'釆','ļ§©'=>'里','⾄'=>'里',''=>'量','金'=>'金','⾦'=>'金','鈴'=>'鈓','鈸'=>'鈸','ļ«…'=>'鉶','鉼'=>'鉼','鋗'=>'鋗','鋘'=>'鋘','錄'=>'錄','鍊'=>'鍊','鎮'=>'鎭','鏹'=>'鏹','鐕'=>'鐕','ā¾§'=>'長','⾨'=>'門','開'=>'開','閭'=>'閭','閷'=>'閷','⾩'=>'阜','阮'=>'阮','ļ„‘'=>'陋','降'=>'降','ļ„™'=>'陵','ļ§“'=>'陸','陼'=>'陼','隆'=>'隆','ļ§±'=>'隣','ā¾Ŗ'=>'隶','隸'=>'隸','⾫'=>'隹','雃'=>'雃','ļ§Ŗ'=>'離','難'=>'難','難'=>'難','⾬'=>'雨','零'=>'零',''=>'雷','霣'=>'霣','露'=>'露','靈'=>'靈','ā¾­'=>'靑','靖'=>'靖','靖'=>'靖','ā¾®'=>'非','⾯'=>'面','ā¾°'=>'革','ā¾±'=>'韋','韛'=>'韛','韠'=>'韠','ā¾²'=>'韭','ā¾³'=>'音','ļ©©'=>'響','響'=>'響','⾓'=>'頁','ļ«‹'=>'頋','頋'=>'頋','頋'=>'頋','煉'=>'領','頩'=>'é ©','頻'=>'é »','頻'=>'é »','類'=>'锞','ā¾µ'=>'風','ā¾¶'=>'飛','ā»'=>'食','ā¾·'=>'食','飢'=>'飢','飯'=>'飯','飼'=>'飼','館'=>'館','餩'=>'餩','ā¾ø'=>'首','ā¾¹'=>'香','馧'=>'馧','ā¾ŗ'=>'馬','駂'=>'駂','駱'=>'é§±','駾'=>'é§¾','驪'=>'驪','ā¾»'=>'éŖØ','ā¾¼'=>'高','ā¾½'=>'髟','ļ«'=>'鬒','鬒'=>'鬒','ā¾¾'=>'鬄','⾿'=>'鬯','⿀'=>'鬲','⿁'=>'鬼','āæ‚'=>'魚','魯'=>'é­Æ','鱀'=>'鱀','ļ§²'=>'鱗','⿃'=>'鳄','鳽'=>'é³½','šÆØ'=>'éµ§','鶴'=>'é¶“','鷺'=>'é·ŗ','鸞'=>'éøž','鹃'=>'鹂','āæ„'=>'é¹µ','ļ„€'=>'鹿','āæ…'=>'鹿','麗'=>'éŗ—','ļ§³'=>'麟','⿆'=>'éŗ„','麻'=>'éŗ»','⿇'=>'éŗ»','⿈'=>'黃','⿉'=>'黍','黎'=>'黎','⿊'=>'黑','黹'=>'黹','āæ‹'=>'黹','⿌'=>'黽','黾'=>'黾','鼅'=>'鼅','āæ'=>'鼎','鼏'=>'鼏','āæŽ'=>'鼓','鼖'=>'鼖','āæ'=>'é¼ ','鼻'=>'é¼»','⿐'=>'é¼»','齃'=>'齃','āæ‘'=>'齊','āæ’'=>'齒','ļ§„'=>'龍','āæ“'=>'龍','ļ«™'=>'龎','龜'=>'龜','龜'=>'龜','ļ«Ž'=>'龜','āæ”'=>'龜','⻳'=>'龟','āæ•'=>'é¾ ','㒞'=>'撞','㒹'=>'ć’¹','㒻'=>'ć’»','㓟'=>'擟','㔕'=>'攕','䎛'=>'斈','𯔧'=>'ć›®','𯔨'=>'㛼','𯔶'=>'极','㠯'=>'ć Æ','㡢'=>'㔢','㡼'=>'㔼','㣇'=>'㣇','㣣'=>'㣣','㤜'=>'㤜','弢'=>'㤺','㨮'=>'㨮','㩬'=>'橬','㫤'=>'櫤','㬈'=>'欈','šÆ£Ž'=>'欙','䐠'=>'欻','šÆ£ž'=>'歉','ļ«’'=>'ć®','㮝'=>'ć®','㰘'=>'氘','㱎'=>'汎','㴳'=>'㓳','㶖'=>'ć¶–','㺬'=>'ćŗ¬','㺸'=>'ćŗø','㺸'=>'ćŗø','㼛'=>'ć¼›','㿼'=>'ćæ¼','䀈'=>'䀈','ļ«“'=>'䀘','ļ«”'=>'䀹','𯄉'=>'䀹','𯄋'=>'䁆','𯄌'=>'䂖','𯄑'=>'䃣','𯄘'=>'䄯','𯄠'=>'䈂','𯄤'=>'䈧','𯄧'=>'䊠','𯄭'=>'䌁','𯄱'=>'䌓','𯄓'=>'䍙','䏕'=>'䏕','䏙'=>'䏙','䐋'=>'䐋','šÆ¦Ž'=>'䑫','䔫'=>'䔫','䕝'=>'䕝','䕡'=>'ä•”','䕫'=>'䕫','䗗'=>'䗗','䗹'=>'䗹','䘵'=>'䘵','šÆ§'=>'䚾','šÆ§Ž'=>'䛇','䦕'=>'䦕','䧦'=>'䧦','䩮'=>'ä©®','䩶'=>'ä©¶','䪲'=>'äŖ²','䬳'=>'䬳','䯎'=>'äÆŽ','šÆØ'=>'䳎','šÆØŽ'=>'ä³­','䳸'=>'ä³ø','䵖'=>'䵖','𠄢'=>'š „¢','𠔜'=>'š ”œ','𠔥'=>'š ”„','𠕋'=>'š •‹','šÆ '=>'𠘺','𠠄'=>'š  „','šÆ§'=>'š £ž','㒹'=>'𠨬','𠭣'=>'š ­£','𯔙'=>'𔓤','𯔠'=>'𔚨','𯔔'=>'š”›Ŗ','𯔬'=>'𔧈','𯔱'=>'𔬘','𡴋'=>'𔓋','𯔻'=>'š”·¤','𯔽'=>'š”·¦','𢆃'=>'š¢†ƒ','𢆟'=>'š¢†Ÿ','𢌱'=>'𢌱','𢌱'=>'𢌱','𢛔'=>'𢛔','𢡄'=>'𢔄','ļ«'=>'𢔊','𢬌'=>'𢬌','𢯱'=>'𢯱','𣀊'=>'š£€Š','𣊸'=>'𣊸','𣍟'=>'š£Ÿ','𣎓'=>'š£Ž“','𣎜'=>'š£Žœ','šÆ£'=>'š£ƒ','ļ«‘'=>'š£•','𣑭'=>'𣑭','𣚣'=>'𣚣','𣢧'=>'𣢧','𣪍'=>'š£Ŗ','𣫺'=>'𣫺','𣲼'=>'𣲼','𣴞'=>'š£“ž','šÆ¤'=>'𣻑','𣽞'=>'š£½ž','𣾎'=>'š£¾Ž','šÆ¤'=>'𤉣','𤎫'=>'š¤Ž«','𤘈'=>'𤘈','𤜵'=>'𤜵','𤠔'=>'𤠔','𤰶'=>'𤰶','𤲒'=>'𤲒','𤾡'=>'𤾔','𤾸'=>'𤾸','𥁄'=>'š„„','𯄂'=>'š„ƒ²','𯄁'=>'š„ƒ³','𯄃'=>'š„„™','𯄄'=>'š„„³','ļ«•'=>'š„‰‰','šÆ„'=>'š„','𯄒'=>'š„˜¦','𯄔'=>'š„šš','𯄕'=>'š„›…','𯄜'=>'š„„¼','šÆ„'=>'š„Ŗ§','šÆ„ž'=>'š„Ŗ§','𯄔'=>'š„®«','𯄄'=>'š„²€','ļ«–'=>'š„³','𯄫'=>'š„¾†','𦇚'=>'š¦‡š','𯄲'=>'𦈨','𯄳'=>'𦉇','𯄵'=>'𦋙','𯄷'=>'𦌾','𯄻'=>'š¦“š','𯄼'=>'𦔣','𯄾'=>'𦖨','𦞧'=>'š¦ž§','𦞵'=>'š¦žµ','𦬼'=>'𦬼','𦰶'=>'𦰶','𦳕'=>'𦳕','䐋'=>'𦵫','𦼬'=>'𦼬','𦾱'=>'𦾱','𧃒'=>'š§ƒ’','𧏊'=>'š§Š','𧙧'=>'š§™§','𧢮'=>'š§¢®','𧥦'=>'𧄦','𧲨'=>'𧲨','ļ«—'=>'𧻓','𧼯'=>'𧼯','𨗒'=>'𨗒','貫'=>'𨗭','衣'=>'𨜮','𨯺'=>'𨯺','𨵷'=>'𨵷','𩅅'=>'š©……','𩇟'=>'š©‡Ÿ','𩈚'=>'𩈚','𩐊'=>'𩐊','𩒖'=>'š©’–','𩖶'=>'š©–¶','𩬰'=>'𩬰','𪃎'=>'šŖƒŽ','𪄅'=>'šŖ„…','𪈎'=>'šŖˆŽ','𪊑'=>'šŖŠ‘','šÆ¢'=>'šŖŽ’','šÆØ'=>'šŖ˜€','ā„ƒ'=>'°C','℉'=>'°F','ℇ'=>'ʐ','ā„»'=>'FAX','ā„•'=>'N','ā„–'=>'No','ā„š'=>'Q','₨'=>'Rs','š“'=>'T','ā„”'=>'TEL','š”'=>'U','š–'=>'W','ā‚©'=>'W̵','š—'=>'X','Ā„'=>'Y̵','šš²'=>'Ī›','ššµ'=>'Īž','ℿ'=>'Ī ','ϲ'=>'c','Ļ’'=>'Y','šš½'=>'Φ','ššæ'=>'ĪØ','Ń£'=>'Ь̵','ਃ'=>'ঃ','ಃ'=>'ః','່'=>'่','įŸ‹'=>'่','້'=>'้','໊'=>'๊','໋'=>'๋','įŸ•'=>'๚','៚'=>'ą¹›','ъ'=>'ˉb','įŸ™'=>'ą¹','ą³§'=>'ą±§','૨'=>'ą„Ø','೨'=>'౨','ą«©'=>'ą„©','૪'=>'ą„Ŗ','ą«®'=>'ą„®','೯'=>'౯','а'=>'a','į'=>'b','į–Æ'=>'b','с'=>'c','ԁ'=>'d','ᑯ'=>'d','е'=>'e','ә'=>'Ē','ε'=>'ɛ','є'=>'ɛ','ք'=>'f','ց'=>'g','Ņ»'=>'h','Õ°'=>'h','į‚'=>'h','į²'=>'hĢ”','ι'=>'i','і'=>'i','įŽ„'=>'i','ј'=>'j','Õµ'=>'j','į—°'=>'m','Õø'=>'n','Ī·'=>'nĢ©','ą°‚'=>'o','ಂ'=>'o','ą“‚'=>'o','ą„¦'=>'o','੦'=>'o','૦'=>'o','๐'=>'o','໐'=>'o','Īæ'=>'o','о'=>'o','օ'=>'o','į€'=>'o','ρ'=>'p','р'=>'p','į“©'=>'ᓘ','Õ£'=>'q','Īŗ'=>'Äø','Šŗ'=>'Äø','ᓦ'=>'r','г'=>'r','ѕ'=>'s','Ļ…'=>'u','Õ½'=>'u','ν'=>'v','ѵ'=>'v','įŽ³'=>'w','į—Æ'=>'w','х'=>'x','ᕁ'=>'x','у'=>'y','įŽ©'=>'y','Ó”'=>'Ź’','ჳ'=>'Ź’','Ļ©'=>'ĘØ','ь'=>'ʅ','ы'=>'ʅi','ɑ'=>'α','Õ®'=>'Ī“','į•·'=>'Ī“','Šæ'=>'Ļ€','Éø'=>'φ','ф'=>'φ','Ź™'=>'в','ɜ'=>'Š·','į“'=>'м','ʜ'=>'н','É¢'=>'Ō','į“›'=>'т','į“™'=>'я','ąŖ½'=>'ऽ','ુ'=>'ą„','ą«‚'=>'ą„‚','ą©‹'=>'ą„†','ą©'=>'ą„','ą«'=>'ą„','ą“‰'=>'உ','ą“œ'=>'ஐ','ą“£'=>'ண','ą““'=>'ஓ','ą“æ'=>'ி','ു'=>'ூ','ą²…'=>'ą°…','ಆ'=>'ą°†','ಇ'=>'ą°‡','ą²’'=>'ą°’','ಓ'=>'ఒౕ','ಜ'=>'జ','ą²ž'=>'ą°ž','ą²£'=>'ą°£','ą°„'=>'ą°§Ö¼','ಯ'=>'ą°Æ','ą° '=>'ą°°Ö¼','ą²±'=>'ą°±','ą²²'=>'ą°²','ඌ'=>'ą“Øąµą“Ø','ą®¶'=>'ą“¶','ຈ'=>'จ','ບ'=>'บ','ąŗ›'=>'ąø›','ąŗ'=>'ąø','ąŗž'=>'ąøž','ຟ'=>'ฟ','ąŗ'=>'ąø¢','įŸ”'=>'ąøÆ','įž·'=>'ąø“','įžø'=>'ąøµ','įž¹'=>'ąø¶','įžŗ'=>'ąø·','ąŗø'=>'ąøø','ąŗ¹'=>'ąø¹','į—…'=>'A','į’'=>'J','ᕼ'=>'H','ᐯ'=>'V','į‘­'=>'P','į—·'=>'B','惘'=>'へ','š‘'=>'šŽ‚','š“'=>'šŽ“','š’€ø'=>'šŽš','į…³'=>'äø€','Ē€'=>'äøØ','į…µ'=>'äøØ','įŽŖ'=>'A','į“'=>'B','įŸ'=>'C','į—ž'=>'D','įŽ¬'=>'E','į–“'=>'F','į€'=>'G','įŽ»'=>'H','įŽ«'=>'J','į¦'=>'K','įž'=>'L','įŽ·'=>'M','į¢'=>'P','į–‡'=>'R','į•'=>'S','į™'=>'V','įƒ'=>'Z'); diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php new file mode 100644 index 0000000000..7ba11c37c4 --- /dev/null +++ b/phpBB/install/database_update.php @@ -0,0 +1,267 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +$update_start_time = time(); + +/** +* @ignore +*/ +define('IN_PHPBB', true); +define('IN_INSTALL', true); +$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); + +function phpbb_end_update($cache, $config) +{ + $cache->purge(); + + $config->increment('assets_version', 1); + +?> +

+ + + + + + + + + + + + +register(); + +$phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx); +extract($phpbb_config_php_file->get_all()); + +if (!defined('PHPBB_INSTALLED') || empty($dbms) || empty($acm_type)) +{ + die("Please read: INSTALL.html before attempting to update."); +} + +// In case $phpbb_adm_relative_path is not set (in case of an update), use the default. +$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/'; +$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path; + +// Include files +require($phpbb_root_path . 'includes/functions.' . $phpEx); +require($phpbb_root_path . 'includes/functions_content.' . $phpEx); + +require($phpbb_root_path . 'includes/constants.' . $phpEx); +require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); + +// Set PHP error handler to ours +set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); + +// Set up container (must be done here because extensions table may not exist) +$phpbb_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); +$phpbb_container = $phpbb_container_builder + ->with_config($phpbb_config_php_file) + ->without_extensions() + ->without_cache() + ->get_container() +; + +// set up caching +/* @var $cache \phpbb\cache\service */ +$cache = $phpbb_container->get('cache'); + +// Instantiate some basic classes +/* @var $phpbb_dispatcher \phpbb\event\dispatcher */ +$phpbb_dispatcher = $phpbb_container->get('dispatcher'); + +/* @var $request \phpbb\request\request_interface */ +$request = $phpbb_container->get('request'); + +/* @var $user \phpbb\user */ +$user = $phpbb_container->get('user'); + +/* @var $auth \phpbb\auth\auth */ +$auth = $phpbb_container->get('auth'); + +/* @var $db \phpbb\db\driver\driver_interface */ +$db = $phpbb_container->get('dbal.conn'); + +/* @var $phpbb_log \phpbb\log\log_interface */ +$phpbb_log = $phpbb_container->get('log'); + +// Grab global variables, re-cache if necessary +/* @var $config \phpbb\config\config */ +$config = $phpbb_container->get('config'); + +if (!isset($config['version_update_from'])) +{ + $config->set('version_update_from', $config['version']); +} + +$orig_version = $config['version_update_from']; + +$user->add_lang(array('common', 'acp/common', 'old_install', 'migrator')); + +// Add own hook handler, if present. :o +if (file_exists($phpbb_root_path . 'includes/hooks/index.' . $phpEx)) +{ + require($phpbb_root_path . 'includes/hooks/index.' . $phpEx); + $phpbb_hook = new phpbb_hook(array('exit_handler', 'phpbb_user_session_handler', 'append_sid', array('template', 'display'))); + + /* @var $phpbb_hook_finder \phpbb\hook\finder */ + $phpbb_hook_finder = $phpbb_container->get('hook_finder'); + foreach ($phpbb_hook_finder->find() as $hook) + { + @include($phpbb_root_path . 'includes/hooks/' . $hook . '.' . $phpEx); + } +} +else +{ + $phpbb_hook = false; +} + +header('Content-type: text/html; charset=UTF-8'); +?> + + + + + +<?php echo $user->lang['UPDATING_TO_LATEST_STABLE']; ?> + + + + + + +
+ + +
+
+
+ +
+
+ +

lang['UPDATING_TO_LATEST_STABLE']; ?>

+ +
+ +

lang['DATABASE_TYPE']; ?> :: get_sql_layer(); ?>
+ lang['PREVIOUS_VERSION']; ?> ::
+ +get('migrator'); + +/** @var \phpbb\filesystem\filesystem_interface $phpbb_filesystem */ +$phpbb_filesystem = $phpbb_container->get('filesystem'); +$migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($user, new \phpbb\db\html_migrator_output_handler($user), $phpbb_root_path . 'store/migrations_' . time() . '.log', $phpbb_filesystem)); + +$migrator->create_migrations_table(); + +/* @var $phpbb_extension_manager \phpbb\extension\manager */ +$phpbb_extension_manager = $phpbb_container->get('ext.manager'); + +$migrations = $phpbb_extension_manager + ->get_finder() + ->core_path('phpbb/db/migration/data/') + ->extension_directory('/migrations') + ->get_classes(); + +$migrator->set_migrations($migrations); + +// What is a safe limit of execution time? Half the max execution time should be safe. +// No more than 15 seconds so the user isn't sitting and waiting for a very long time +$phpbb_ini = new \phpbb\php\ini(); +$safe_time_limit = min(15, ($phpbb_ini->get_int('max_execution_time') / 2)); + +// While we're going to try limit this to half the max execution time, +// we want to try and take additional measures to prevent hitting the +// max execution time (if, say, one migration step takes much longer +// than the max execution time) +@set_time_limit(0); + +while (!$migrator->finished()) +{ + try + { + $migrator->update(); + } + catch (\phpbb\db\migration\exception $e) + { + echo $e->getLocalisedMessage($user); + + phpbb_end_update($cache, $config); + } + + $state = array_merge(array( + 'migration_schema_done' => false, + 'migration_data_done' => false, + ), + $migrator->last_run_migration['state'] + ); + + // Are we approaching the time limit? If so we want to pause the update and continue after refreshing + if ((time() - $update_start_time) >= $safe_time_limit) + { + echo '
' . $user->lang['DATABASE_UPDATE_NOT_COMPLETED'] . '

'; + echo '' . $user->lang['DATABASE_UPDATE_CONTINUE'] . ''; + + phpbb_end_update($cache, $config); + } +} + +if ($orig_version != $config['version']) +{ + $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_UPDATE_DATABASE', false, array($orig_version, $config['version'])); +} + +echo $user->lang['DATABASE_UPDATE_COMPLETE'] . '
'; + +if ($request->variable('type', 0)) +{ + echo $user->lang['INLINE_UPDATE_SUCCESSFUL'] . '

'; + echo '' . $user->lang['CONTINUE_UPDATE_NOW'] . ''; +} +else +{ + echo '

' . $user->lang['UPDATE_FILES_NOTICE'] . '
'; + echo $user->lang['COMPLETE_LOGIN_TO_BOARD']; +} + +$config->delete('version_update_from'); + +phpbb_end_update($cache, $config); diff --git a/phpBB/install/index.php b/phpBB/install/index.php new file mode 100644 index 0000000000..a1a8fc02b6 --- /dev/null +++ b/phpBB/install/index.php @@ -0,0 +1,867 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/**#@+ +* @ignore +*/ +define('IN_PHPBB', true); +define('IN_INSTALL', true); +define('PHPBB_ENVIRONMENT', 'production'); +/**#@-*/ + +$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); + +if (version_compare(PHP_VERSION, '5.3.9') < 0) +{ + die('You are running an unsupported PHP version. Please upgrade to PHP 5.3.9 or higher before trying to install phpBB 3.1'); +} + +function phpbb_require_updated($path, $optional = false) +{ + global $phpbb_root_path, $table_prefix; + + $new_path = $phpbb_root_path . 'install/update/new/' . $path; + $old_path = $phpbb_root_path . $path; + + if (file_exists($new_path)) + { + require($new_path); + } + else if (!$optional || file_exists($old_path)) + { + require($old_path); + } +} + +function phpbb_include_updated($path, $optional = false) +{ + global $phpbb_root_path; + + $new_path = $phpbb_root_path . 'install/update/new/' . $path; + $old_path = $phpbb_root_path . $path; + + if (file_exists($new_path)) + { + include($new_path); + } + else if (!$optional || file_exists($old_path)) + { + include($old_path); + } +} + +phpbb_require_updated('includes/startup.' . $phpEx); + +// Try to override some limits - maybe it helps some... +@set_time_limit(0); +$mem_limit = @ini_get('memory_limit'); +if (!empty($mem_limit)) +{ + $unit = strtolower(substr($mem_limit, -1, 1)); + $mem_limit = (int) $mem_limit; + + if ($unit == 'k') + { + $mem_limit = floor($mem_limit / 1024); + } + else if ($unit == 'g') + { + $mem_limit *= 1024; + } + else if (is_numeric($unit)) + { + $mem_limit = floor((int) ($mem_limit . $unit) / 1048576); + } + $mem_limit = max(128, $mem_limit) . 'M'; +} +else +{ + $mem_limit = '128M'; +} +@ini_set('memory_limit', $mem_limit); + +// In case $phpbb_adm_relative_path is not set (in case of an update), use the default. +$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/'; +$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path; + +// Include essential scripts +phpbb_require_updated('phpbb/class_loader.' . $phpEx); + +phpbb_require_updated('includes/functions.' . $phpEx); + +phpbb_require_updated('includes/functions_content.' . $phpEx, true); + +phpbb_include_updated('includes/functions_admin.' . $phpEx); +phpbb_include_updated('includes/utf/utf_tools.' . $phpEx); +phpbb_require_updated('includes/functions_install.' . $phpEx); + +// Setup class loader first +$phpbb_class_loader_new = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}install/update/new/phpbb/", $phpEx); +$phpbb_class_loader_new->register(); +$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); +$phpbb_class_loader->register(); +$phpbb_class_loader_ext = new \phpbb\class_loader('\\', "{$phpbb_root_path}ext/", $phpEx); +$phpbb_class_loader_ext->register(); + +// Set up container +$phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx); +$phpbb_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); +$phpbb_container_builder + ->without_extensions() + ->without_cache() + ->without_compiled_container() +; + +$other_config_path = $phpbb_root_path . 'install/update/new/config/'; +$config_path = file_exists($other_config_path . 'services.yml') ? $other_config_path : $phpbb_root_path . 'config/'; +$phpbb_container_builder->with_config_path($config_path); + +$phpbb_container_builder->with_custom_parameters(array( + 'core.root_path' => $phpbb_root_path, + 'core.adm_relative_path' => $phpbb_adm_relative_path, + 'core.php_ext' => $phpEx, + 'core.table_prefix' => '', + 'cache.driver.class' => 'phpbb\cache\driver\file', +)); + +$phpbb_container = $phpbb_container_builder->get_container(); +$phpbb_container->register('dbal.conn.driver')->setSynthetic(true); +$phpbb_container->register('template.twig.environment')->setSynthetic(true); +$phpbb_container->register('language.loader')->setSynthetic(true); +$phpbb_container->compile(); + +$phpbb_class_loader->set_cache($phpbb_container->get('cache.driver')); +$phpbb_class_loader_ext->set_cache($phpbb_container->get('cache.driver')); + +/* @var $phpbb_dispatcher \phpbb\event\dispatcher */ +$phpbb_dispatcher = $phpbb_container->get('dispatcher'); + +/* @var $request \phpbb\request\request_interface */ +$request = $phpbb_container->get('request'); + +// Try and load an appropriate language if required +$language = basename($request->variable('language', '')); + +if ($request->header('Accept-Language') && !$language) +{ + $accept_lang_ary = explode(',', strtolower($request->header('Accept-Language'))); + foreach ($accept_lang_ary as $accept_lang) + { + // Set correct format ... guess full xx_yy form + $accept_lang = substr($accept_lang, 0, 2) . '_' . substr($accept_lang, 3, 2); + + if (file_exists($phpbb_root_path . 'language/' . $accept_lang) && is_dir($phpbb_root_path . 'language/' . $accept_lang)) + { + $language = $accept_lang; + break; + } + else + { + // No match on xx_yy so try xx + $accept_lang = substr($accept_lang, 0, 2); + if (file_exists($phpbb_root_path . 'language/' . $accept_lang) && is_dir($phpbb_root_path . 'language/' . $accept_lang)) + { + $language = $accept_lang; + break; + } + } + } +} + +// No appropriate language found ... so let's use the first one in the language +// dir, this may or may not be English +if (!$language) +{ + $dir = @opendir($phpbb_root_path . 'language'); + + if (!$dir) + { + die('Unable to access the language directory'); + exit; + } + + while (($file = readdir($dir)) !== false) + { + $path = $phpbb_root_path . 'language/' . $file; + + if (!is_file($path) && !is_link($path) && file_exists($path . '/iso.txt')) + { + $language = $file; + break; + } + } + closedir($dir); +} + +if (!file_exists($phpbb_root_path . 'language/' . $language) || !is_dir($phpbb_root_path . 'language/' . $language)) +{ + die('No language found!'); +} + +// And finally, load the relevant language files +$load_lang_files = array('common', 'acp/common', 'acp/board', 'old_install', 'posting'); +$new_path = $phpbb_root_path . 'install/update/new/language/' . $language . '/'; +$old_path = $phpbb_root_path . 'language/' . $language . '/'; + +// NOTE: we can not use "phpbb_include_updated" as the files uses vars which would be required +// to be global while loading. +foreach ($load_lang_files as $lang_file) +{ + if (file_exists($new_path . $lang_file . '.' . $phpEx)) + { + include($new_path . $lang_file . '.' . $phpEx); + } + else + { + include($old_path . $lang_file . '.' . $phpEx); + } +} + +// usually we would need every single constant here - and it would be consistent. For 3.0.x, use a dirty hack... :( + +// Define needed constants +define('CHMOD_ALL', 7); +define('CHMOD_READ', 4); +define('CHMOD_WRITE', 2); +define('CHMOD_EXECUTE', 1); + +$mode = $request->variable('mode', 'overview'); +$sub = $request->variable('sub', ''); + +// Set PHP error handler to ours +set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); + +$lang_service = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); +$user = new \phpbb\user($lang_service, '\phpbb\datetime'); +$auth = new \phpbb\auth\auth(); + +// Add own hook handler, if present. :o +if (file_exists($phpbb_root_path . 'includes/hooks/index.' . $phpEx)) +{ + require($phpbb_root_path . 'includes/hooks/index.' . $phpEx); + $phpbb_hook = new phpbb_hook(array('exit_handler', 'phpbb_user_session_handler', 'append_sid', array('template', 'display'))); + + /* @var $phpbb_hook_finder \phpbb\hook\finder */ + $phpbb_hook_finder = $phpbb_container->get('hook_finder'); + foreach ($phpbb_hook_finder->find() as $hook) + { + @include($phpbb_root_path . 'includes/hooks/' . $hook . '.' . $phpEx); + } +} +else +{ + $phpbb_hook = false; +} + +// Set some standard variables we want to force +$config = new \phpbb\config\config(array( + 'load_tplcompile' => '1' +)); + +/* @var $symfony_request \phpbb\symfony_request */ +$symfony_request = $phpbb_container->get('symfony_request'); + +/* @var $phpbb_filesystem \phpbb\filesystem\filesystem_interface */ +$phpbb_filesystem = $phpbb_container->get('filesystem'); + +/* @var $phpbb_path_helper \phpbb\path_helper */ +$phpbb_path_helper = $phpbb_container->get('path_helper'); +$cache_path = $phpbb_root_path . 'cache/'; + +$twig_environment = new \phpbb\template\twig\environment( + $config, + $phpbb_filesystem, + $phpbb_path_helper, + $phpbb_container, + $cache_path, + null, + $phpbb_container->get('template.twig.loader') +); + +$language_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); +$phpbb_container->set('template.twig.environment', $twig_environment); +$phpbb_container->set('language.loader', $language_loader); +$twig_context = new \phpbb\template\context(); +$template = new \phpbb\template\twig\twig( + $phpbb_path_helper, + $config, + $twig_context, + $twig_environment, + $cache_path, + $user, + array($phpbb_container->get('template.twig.extensions.phpbb')) +); + +$paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style'); +$paths = array_filter($paths, 'is_dir'); +$template->set_custom_style(array( + array( + 'name' => 'adm', + 'ext_path' => 'adm/style/', + ), +), $paths); + +$path = array_shift($paths); + +$template->assign_var('T_ASSETS_PATH', $path . '/../../assets'); +$template->assign_var('T_TEMPLATE_PATH', $path); + +$install = new module(); + +$install->create('install', "index.$phpEx", $mode, $sub); +$install->load(); + +// Generate the page +$install->page_header(); +$install->generate_navigation(); + +$template->set_filenames(array( + 'body' => $install->get_tpl_name()) +); + +$install->page_footer(); + +class module +{ + var $id = 0; + var $type = 'install'; + var $module_ary = array(); + var $filename; + var $module_url = ''; + var $tpl_name = ''; + var $mode; + var $sub; + + /** + * Private methods, should not be overwritten + */ + function create($module_type, $module_url, $selected_mod = false, $selected_submod = false) + { + global $db, $config, $phpEx, $phpbb_root_path; + + $module = array(); + + // Grab module information using Bart's "neat-o-module" system (tm) + $dir = @opendir('.'); + + if (!$dir) + { + $this->error('Unable to access the installation directory', __LINE__, __FILE__); + } + + $setmodules = 1; + while (($file = readdir($dir)) !== false) + { + if (preg_match('#^install_(.*?)\.' . $phpEx . '$#', $file)) + { + include($file); + } + } + closedir($dir); + + unset($setmodules); + + if (!sizeof($module)) + { + $this->error('No installation modules found', __LINE__, __FILE__); + } + + // Order to use and count further if modules get assigned to the same position or not having an order + $max_module_order = 1000; + + foreach ($module as $row) + { + // Module order not specified or module already assigned at this position? + if (!isset($row['module_order']) || isset($this->module_ary[$row['module_order']])) + { + $row['module_order'] = $max_module_order; + $max_module_order++; + } + + $this->module_ary[$row['module_order']]['name'] = $row['module_title']; + $this->module_ary[$row['module_order']]['filename'] = $row['module_filename']; + $this->module_ary[$row['module_order']]['subs'] = $row['module_subs']; + $this->module_ary[$row['module_order']]['stages'] = $row['module_stages']; + + if (strtolower($selected_mod) == strtolower($row['module_title'])) + { + $this->id = (int) $row['module_order']; + $this->filename = (string) $row['module_filename']; + $this->module_url = (string) $module_url; + $this->mode = (string) $selected_mod; + // Check that the sub-mode specified is valid or set a default if not + if (is_array($row['module_subs'])) + { + $this->sub = strtolower((in_array(strtoupper($selected_submod), $row['module_subs'])) ? $selected_submod : $row['module_subs'][0]); + } + else if (is_array($row['module_stages'])) + { + $this->sub = strtolower((in_array(strtoupper($selected_submod), $row['module_stages'])) ? $selected_submod : $row['module_stages'][0]); + } + else + { + $this->sub = ''; + } + } + } // END foreach + } // END create + + /** + * Load and run the relevant module if applicable + */ + function load($mode = false, $run = true) + { + global $phpbb_root_path, $phpEx; + + if ($run) + { + if (!empty($mode)) + { + $this->mode = $mode; + } + + $module = $this->filename; + if (!class_exists($module)) + { + $this->error('Module "' . htmlspecialchars($module) . '" not accessible.', __LINE__, __FILE__); + } + $this->module = new $module($this); + + if (method_exists($this->module, 'main')) + { + $this->module->main($this->mode, $this->sub); + } + } + } + + /** + * Output the standard page header + */ + function page_header() + { + if (defined('HEADER_INC')) + { + return; + } + + define('HEADER_INC', true); + global $template, $lang, $stage, $phpbb_admin_path, $path; + + $template->assign_vars(array( + 'L_CHANGE' => $lang['CHANGE'], + 'L_COLON' => $lang['COLON'], + 'L_INSTALL_PANEL' => $lang['INSTALL_PANEL'], + 'L_SELECT_LANG' => $lang['SELECT_LANG'], + 'L_SKIP' => $lang['SKIP'], + 'PAGE_TITLE' => $this->get_page_title(), + 'T_IMAGE_PATH' => htmlspecialchars($phpbb_admin_path) . 'images/', + 'T_JQUERY_LINK' => $path . '/../../assets/javascript/jquery.min.js', + + 'S_CONTENT_DIRECTION' => $lang['DIRECTION'], + 'S_CONTENT_FLOW_BEGIN' => ($lang['DIRECTION'] == 'ltr') ? 'left' : 'right', + 'S_CONTENT_FLOW_END' => ($lang['DIRECTION'] == 'ltr') ? 'right' : 'left', + 'S_CONTENT_ENCODING' => 'UTF-8', + + 'S_USER_LANG' => $lang['USER_LANG'], + ) + ); + + header('Content-type: text/html; charset=UTF-8'); + header('Cache-Control: private, no-cache="set-cookie"'); + header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT'); + + return; + } + + /** + * Output the standard page footer + */ + function page_footer() + { + global $db, $template; + + $template->display('body'); + + // Close our DB connection. + if (!empty($db) && is_object($db)) + { + $db->sql_close(); + } + + if (function_exists('exit_handler')) + { + exit_handler(); + } + } + + /** + * Returns desired template name + */ + function get_tpl_name() + { + return $this->module->tpl_name . '.html'; + } + + /** + * Returns the desired page title + */ + function get_page_title() + { + global $lang; + + if (!isset($this->module->page_title)) + { + return ''; + } + + return (isset($lang[$this->module->page_title])) ? $lang[$this->module->page_title] : $this->module->page_title; + } + + /** + * Generate an HTTP/1.1 header to redirect the user to another page + * This is used during the installation when we do not have a database available to call the normal redirect function + * @param string $page The page to redirect to relative to the installer root path + */ + function redirect($page) + { + global $request; + + // HTTP_HOST is having the correct browser url in most cases... + $server_name = strtolower(htmlspecialchars_decode($request->header('Host', $request->server('SERVER_NAME')))); + $server_port = $request->server('SERVER_PORT', 0); + $secure = $request->is_secure() ? 1 : 0; + + $script_name = htmlspecialchars_decode($request->server('PHP_SELF')); + if (!$script_name) + { + $script_name = htmlspecialchars_decode($request->server('REQUEST_URI')); + } + + // Replace backslashes and doubled slashes (could happen on some proxy setups) + $script_name = str_replace(array('\\', '//'), '/', $script_name); + $script_path = trim(dirname($script_name)); + + $url = (($secure) ? 'https://' : 'http://') . $server_name; + + if ($server_port && (($secure && $server_port <> 443) || (!$secure && $server_port <> 80))) + { + // HTTP HOST can carry a port number... + if (strpos($server_name, ':') === false) + { + $url .= ':' . $server_port; + } + } + + $url .= $script_path . '/' . $page; + header('Location: ' . $url); + exit; + } + + /** + * Generate the navigation tabs + */ + function generate_navigation() + { + global $lang, $template, $phpEx, $language; + + if (is_array($this->module_ary)) + { + @ksort($this->module_ary); + foreach ($this->module_ary as $cat_ary) + { + $cat = $cat_ary['name']; + $l_cat = (!empty($lang['CAT_' . $cat])) ? $lang['CAT_' . $cat] : preg_replace('#_#', ' ', $cat); + $cat = strtolower($cat); + $url = $this->module_url . "?mode=$cat&language=$language"; + + if ($this->mode == $cat) + { + $template->assign_block_vars('t_block1', array( + 'L_TITLE' => $l_cat, + 'S_SELECTED' => true, + 'U_TITLE' => $url, + )); + + if (is_array($this->module_ary[$this->id]['subs'])) + { + $subs = $this->module_ary[$this->id]['subs']; + foreach ($subs as $option) + { + $l_option = (!empty($lang['SUB_' . $option])) ? $lang['SUB_' . $option] : preg_replace('#_#', ' ', $option); + $option = strtolower($option); + $url = $this->module_url . '?mode=' . $this->mode . "&sub=$option&language=$language"; + + $template->assign_block_vars('l_block1', array( + 'L_TITLE' => $l_option, + 'S_SELECTED' => ($this->sub == $option), + 'U_TITLE' => $url, + )); + } + } + + if (is_array($this->module_ary[$this->id]['stages'])) + { + $subs = $this->module_ary[$this->id]['stages']; + $matched = false; + foreach ($subs as $option) + { + $l_option = (!empty($lang['STAGE_' . $option])) ? $lang['STAGE_' . $option] : preg_replace('#_#', ' ', $option); + $option = strtolower($option); + $matched = ($this->sub == $option) ? true : $matched; + + $template->assign_block_vars('l_block2', array( + 'L_TITLE' => $l_option, + 'S_SELECTED' => ($this->sub == $option), + 'S_COMPLETE' => !$matched, + )); + } + } + } + else + { + $template->assign_block_vars('t_block1', array( + 'L_TITLE' => $l_cat, + 'S_SELECTED' => false, + 'U_TITLE' => $url, + )); + } + } + } + } + + /** + * Output an error message + * If skip is true, return and continue execution, else exit + */ + function error($error, $line, $file, $skip = false) + { + global $lang, $db, $template, $phpbb_admin_path; + + if ($skip) + { + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['INST_ERR'], + )); + + $template->assign_block_vars('checks', array( + 'TITLE' => basename($file) . ' [ ' . $line . ' ]', + 'RESULT' => '' . $error . '', + )); + + return; + } + + echo ''; + echo ''; + echo ''; + echo ''; + echo '' . $lang['INST_ERR_FATAL'] . ''; + echo ''; + echo ''; + echo ''; + echo '
'; + echo ' '; + echo '
'; + echo '
'; + echo '
'; + echo ' '; + echo '
'; + echo '

' . $lang['INST_ERR_FATAL'] . '

'; + echo '

' . $lang['INST_ERR_FATAL'] . "

\n"; + echo '

' . basename($file) . ' [ ' . $line . " ]

\n"; + echo '

' . $error . "

\n"; + echo '
'; + echo ' '; + echo '
'; + echo '
'; + echo '
'; + echo ' '; + echo '
'; + echo ''; + echo ''; + + if (!empty($db) && is_object($db)) + { + $db->sql_close(); + } + + exit_handler(); + } + + /** + * Output an error message for a database related problem + * If skip is true, return and continue execution, else exit + */ + function db_error($error, $sql, $line, $file, $skip = false) + { + global $lang, $db, $template; + + if ($skip) + { + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['INST_ERR_FATAL'], + )); + + $template->assign_block_vars('checks', array( + 'TITLE' => basename($file) . ' [ ' . $line . ' ]', + 'RESULT' => '' . $error . '
» SQL:' . $sql, + )); + + return; + } + + $template->set_filenames(array( + 'body' => 'install_error.html') + ); + $this->page_header(); + $this->generate_navigation(); + + $template->assign_vars(array( + 'MESSAGE_TITLE' => $lang['INST_ERR_FATAL_DB'], + 'MESSAGE_TEXT' => '

' . basename($file) . ' [ ' . $line . ' ]

SQL : ' . $sql . '

' . $error . '

', + )); + + // Rollback if in transaction + if ($db->get_transaction()) + { + $db->sql_transaction('rollback'); + } + + $this->page_footer(); + } + + /** + * Generate the relevant HTML for an input field and the associated label and explanatory text + */ + function input_field($name, $type, $value = '', $options = '') + { + global $lang; + $tpl_type = explode(':', $type); + $tpl = ''; + + switch ($tpl_type[0]) + { + case 'text': + case 'password': + // HTML5 text-like input types + case 'color': + case 'date': + case 'time': + case 'datetime': + case 'datetime-local': + case 'email': + case 'month': + case 'number': + case 'range': + case 'search': + case 'tel': + case 'url': + case 'week': + + $size = (int) $tpl_type[1]; + $maxlength = (int) $tpl_type[2]; + $autocomplete = (isset($options['autocomplete']) && $options['autocomplete'] == 'off') ? ' autocomplete="off"' : ''; + + $tpl = ''; + break; + + case 'textarea': + $rows = (int) $tpl_type[1]; + $cols = (int) $tpl_type[2]; + + $tpl = ''; + break; + + case 'radio': + $key_yes = ($value) ? ' checked="checked" id="' . $name . '"' : ''; + $key_no = (!$value) ? ' checked="checked" id="' . $name . '"' : ''; + + $tpl_type_cond = explode('_', $tpl_type[1]); + $type_no = ($tpl_type_cond[0] == 'disabled' || $tpl_type_cond[0] == 'enabled') ? false : true; + + $tpl_no = ''; + $tpl_yes = ''; + + $tpl = ($tpl_type_cond[0] == 'yes' || $tpl_type_cond[0] == 'enabled') ? $tpl_yes . '  ' . $tpl_no : $tpl_no . '  ' . $tpl_yes; + break; + + case 'select': + // @codingStandardsIgnoreStart + eval('$s_options = ' . str_replace('{VALUE}', $value, $options) . ';'); + // @codingStandardsIgnoreEnd + $tpl = ''; + break; + + case 'custom': + // @codingStandardsIgnoreStart + eval('$tpl = ' . str_replace('{VALUE}', $value, $options) . ';'); + // @codingStandardsIgnoreEnd + break; + + default: + break; + } + + return $tpl; + } + + /** + * Generate the drop down of available language packs + */ + function inst_language_select($default = '') + { + global $phpbb_root_path, $phpEx; + + $dir = @opendir($phpbb_root_path . 'language'); + + if (!$dir) + { + $this->error('Unable to access the language directory', __LINE__, __FILE__); + } + + while ($file = readdir($dir)) + { + $path = $phpbb_root_path . 'language/' . $file; + + if ($file == '.' || $file == '..' || is_link($path) || is_file($path) || $file == 'CVS') + { + continue; + } + + if (file_exists($path . '/iso.txt')) + { + list($displayname, $localname) = @file($path . '/iso.txt'); + $lang[$localname] = $file; + } + } + closedir($dir); + + @asort($lang); + @reset($lang); + + $user_select = ''; + foreach ($lang as $displayname => $filename) + { + $selected = (strtolower($default) == strtolower($filename)) ? ' selected="selected"' : ''; + $user_select .= ''; + } + + return $user_select; + } +} diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php new file mode 100644 index 0000000000..d72ee1a633 --- /dev/null +++ b/phpBB/install/install_convert.php @@ -0,0 +1,2153 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +*/ + +if (!defined('IN_INSTALL')) +{ + // Someone has tried to access the file direct. This is not a good idea, so exit + exit; +} + +if (!empty($setmodules)) +{ + $module[] = array( + 'module_type' => 'install', + 'module_title' => 'CONVERT', + 'module_filename' => substr(basename(__FILE__), 0, -strlen($phpEx)-1), + 'module_order' => 20, + 'module_subs' => '', + 'module_stages' => array('INTRO', 'SETTINGS', 'IN_PROGRESS', 'FINAL'), + 'module_reqs' => '' + ); +} + +/** +* Class holding all convertor-specific details. +*/ +class convert +{ + var $options = array(); + + var $convertor_tag = ''; + var $src_dbms = ''; + var $src_dbhost = ''; + var $src_dbport = ''; + var $src_dbuser = ''; + var $src_dbpasswd = ''; + var $src_dbname = ''; + var $src_table_prefix = ''; + + var $convertor_data = array(); + var $tables = array(); + var $config_schema = array(); + var $convertor = array(); + var $src_truncate_statement = 'DELETE FROM '; + var $truncate_statement = 'DELETE FROM '; + + var $fulltext_search; + + // Batch size, can be adjusted by the conversion file + // For big boards a value of 6000 seems to be optimal + var $batch_size = 2000; + // Number of rows to be inserted at once (extended insert) if supported + // For installations having enough memory a value of 60 may be good. + var $num_wait_rows = 20; + + // Mysqls internal recoding engine messing up with our (better) functions? We at least support more encodings than mysql so should use it in favor. + var $mysql_convert = false; + + var $p_master; + + function convert(&$p_master) + { + $this->p_master = &$p_master; + } +} + +/** +* Convert class for conversions +*/ +class install_convert extends module +{ + /** @var array */ + protected $lang; + + /** @var string */ + protected $language; + + /** @var \phpbb\template\template */ + protected $template; + + /** @var string */ + protected $phpbb_root_path; + + /** @var string */ + protected $php_ext; + + /** @var \phpbb\filesystem\filesystem_interface */ + protected $filesystem; + + /** + * Variables used while converting, they are accessible from the global variable $convert + */ + function install_convert(&$p_master) + { + $this->p_master = &$p_master; + } + + function main($mode, $sub) + { + global $lang, $template, $phpbb_root_path, $phpEx, $cache, $config, $language, $table_prefix; + global $convert, $request, $phpbb_container, $phpbb_config_php_file; + + $this->tpl_name = 'install_convert'; + $this->mode = $mode; + $this->lang = $lang; + $this->language = $language; + $this->template = $template; + $this->phpbb_root_path = $phpbb_root_path; + $this->php_ext = $phpEx; + $this->filesystem = new \phpbb\filesystem\filesystem(); + + if (!$this->check_phpbb_installed()) + { + return; + } + + $convert = new convert($this->p_master); + + // Enable super globals to prevent issues with the new \phpbb\request\request object + $request->enable_super_globals(); + // Create a normal container now + $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); + $phpbb_container = $phpbb_container_builder->with_config($phpbb_config_php_file)->get_container(); + + // Create cache + /* @var $cache \phpbb\cache\service */ + $cache = $phpbb_container->get('cache'); + + switch ($sub) + { + case 'intro': + 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); + + // Detect if there is already a conversion in progress at this point and offer to resume + // It's quite possible that the user will get disconnected during a large conversion so they need to be able to resume it + $new_conversion = $request->variable('new_conv', 0); + + if ($new_conversion) + { + $config['convert_progress'] = ''; + $config['convert_db_server'] = ''; + $config['convert_db_user'] = ''; + $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " + WHERE config_name = 'convert_progress' + OR config_name = 'convert_db_server' + OR config_name = 'convert_db_user'" + ); + } + + // Let's see if there is a conversion in the works... + $options = array(); + if (!empty($config['convert_progress']) && !empty($config['convert_db_server']) && !empty($config['convert_db_user']) && !empty($config['convert_options'])) + { + $options = unserialize($config['convert_progress']); + $options = array_merge($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($options) && !empty($options['tag']) && + isset($options['dbms']) && + isset($options['dbhost']) && + isset($options['dbport']) && + isset($options['dbuser']) && + isset($options['dbpasswd']) && + isset($options['dbname']) && + isset($options['table_prefix'])) + { + $this->page_title = $lang['CONTINUE_CONVERT']; + + $template->assign_vars(array( + 'TITLE' => $lang['CONTINUE_CONVERT'], + 'BODY' => $lang['CONTINUE_CONVERT_BODY'], + 'L_NEW' => $lang['CONVERT_NEW_CONVERSION'], + 'L_CONTINUE' => $lang['CONTINUE_OLD_CONVERSION'], + 'S_CONTINUE' => true, + + 'U_NEW_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=intro&new_conv=1&language=$language", + 'U_CONTINUE_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$options['tag']}{$options['step']}&language=$language", + )); + + return; + } + + $this->list_convertors($sub); + + break; + + case 'settings': + $this->get_convert_settings($sub); + break; + + case 'in_progress': + $this->convert_data($sub); + break; + + case 'final': + $this->page_title = $lang['CONVERT_COMPLETE']; + + $template->assign_vars(array( + 'TITLE' => $lang['CONVERT_COMPLETE'], + 'BODY' => $lang['CONVERT_COMPLETE_EXPLAIN'], + )); + + // If we reached this step (conversion completed) we want to purge the cache and log the user out. + // This is for making sure the session get not screwed due to the 3.0.x users table being completely new. + $cache->purge(); + + 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); + + $sql = 'SELECT config_value + FROM ' . CONFIG_TABLE . ' + WHERE config_name = \'search_type\''; + $result = $db->sql_query($sql); + + if ($db->sql_fetchfield('config_value') != 'fulltext_mysql') + { + $template->assign_vars(array( + 'S_ERROR_BOX' => true, + 'ERROR_TITLE' => $lang['SEARCH_INDEX_UNCONVERTED'], + 'ERROR_MSG' => $lang['SEARCH_INDEX_UNCONVERTED_EXPLAIN'], + )); + } + + switch ($db->get_sql_layer()) + { + case 'sqlite': + case 'sqlite3': + $db->sql_query('DELETE FROM ' . SESSIONS_KEYS_TABLE); + $db->sql_query('DELETE FROM ' . SESSIONS_TABLE); + break; + + default: + $db->sql_query('TRUNCATE TABLE ' . SESSIONS_KEYS_TABLE); + $db->sql_query('TRUNCATE TABLE ' . SESSIONS_TABLE); + break; + } + + break; + } + } + + /** + * Check whether phpBB is installed. + * Assigns error template vars if not installed. + * + * @return bool Returns true if phpBB is installed. + */ + public function check_phpbb_installed() + { + if (phpbb_check_installation_exists($this->phpbb_root_path, $this->php_ext)) + { + return true; + } + + $this->page_title = 'BOARD_NOT_INSTALLED'; + $install_url = append_sid($this->phpbb_root_path . 'install/index.' . $this->php_ext, 'mode=install&language=' . $this->language); + + $this->template->assign_vars(array( + 'S_NOT_INSTALLED' => true, + 'BODY' => sprintf($this->lang['BOARD_NOT_INSTALLED_EXPLAIN'], $install_url), + )); + + return false; + } + + /** + * Generate a list of all available conversion modules + */ + function list_convertors($sub) + { + global $lang, $language, $template, $phpbb_root_path, $phpEx; + + $this->page_title = $lang['SUB_INTRO']; + + $template->assign_vars(array( + 'TITLE' => $lang['CONVERT_INTRO'], + 'BODY' => $lang['CONVERT_INTRO_BODY'], + + 'L_AUTHOR' => $lang['AUTHOR'], + 'L_AVAILABLE_CONVERTORS' => $lang['AVAILABLE_CONVERTORS'], + 'L_CONVERT' => $lang['CONVERT'], + 'L_NO_CONVERTORS' => $lang['NO_CONVERTORS'], + 'L_OPTIONS' => $lang['CONVERT_OPTIONS'], + 'L_SOFTWARE' => $lang['SOFTWARE'], + 'L_VERSION' => $lang['VERSION'], + + 'S_LIST' => true, + )); + + $convertors = $sort = array(); + $get_info = true; + + $handle = @opendir('./convertors/'); + + if (!$handle) + { + $this->error('Unable to access the convertors directory', __LINE__, __FILE__); + } + + while ($entry = readdir($handle)) + { + if (preg_match('/^convert_([a-z0-9_]+).' . $phpEx . '$/i', $entry, $m)) + { + include('./convertors/' . $entry); + if (isset($convertor_data)) + { + $sort[strtolower($convertor_data['forum_name'])] = sizeof($convertors); + + $convertors[] = array( + 'tag' => $m[1], + 'forum_name' => $convertor_data['forum_name'], + 'version' => $convertor_data['version'], + 'dbms' => $convertor_data['dbms'], + 'dbhost' => $convertor_data['dbhost'], + 'dbport' => $convertor_data['dbport'], + 'dbuser' => $convertor_data['dbuser'], + 'dbpasswd' => $convertor_data['dbpasswd'], + 'dbname' => $convertor_data['dbname'], + 'table_prefix' => $convertor_data['table_prefix'], + 'author' => $convertor_data['author'] + ); + } + unset($convertor_data); + } + } + closedir($handle); + + @ksort($sort); + + foreach ($sort as $void => $index) + { + $template->assign_block_vars('convertors', array( + 'AUTHOR' => $convertors[$index]['author'], + 'SOFTWARE' => $convertors[$index]['forum_name'], + 'VERSION' => $convertors[$index]['version'], + + 'U_CONVERT' => $this->p_master->module_url . "?mode={$this->mode}&language=$language&sub=settings&tag=" . $convertors[$index]['tag'], + )); + } + } + + /** + */ + function get_convert_settings($sub) + { + global $lang, $language, $template, $db, $phpbb_root_path, $phpEx, $config, $cache, $phpbb_config_php_file; + + 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); + + $this->page_title = $lang['STAGE_SETTINGS']; + + // 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); + + $convertor_tag = $request->variable('tag', ''); + + if (empty($convertor_tag)) + { + $this->p_master->error($lang['NO_CONVERT_SPECIFIED'], __LINE__, __FILE__); + } + $get_info = true; + + // check security implications of direct inclusion + $convertor_tag = basename($convertor_tag); + if (!file_exists('./convertors/convert_' . $convertor_tag . '.' . $phpEx)) + { + $this->p_master->error($lang['CONVERT_NOT_EXIST'], __LINE__, __FILE__); + } + + include('./convertors/convert_' . $convertor_tag . '.' . $phpEx); + + // The test_file is a file that should be present in the location of the old board. + if (!isset($test_file)) + { + $this->p_master->error($lang['DEV_NO_TEST_FILE'], __LINE__, __FILE__); + } + + $submit = (isset($_POST['submit'])) ? true : false; + + $src_dbms = $request->variable('src_dbms', $convertor_data['dbms']); + $src_dbhost = $request->variable('src_dbhost', $convertor_data['dbhost']); + $src_dbport = $request->variable('src_dbport', $convertor_data['dbport']); + $src_dbuser = $request->variable('src_dbuser', $convertor_data['dbuser']); + $src_dbpasswd = $request->variable('src_dbpasswd', $convertor_data['dbpasswd']); + $src_dbname = $request->variable('src_dbname', $convertor_data['dbname']); + $src_table_prefix = $request->variable('src_table_prefix', $convertor_data['table_prefix']); + $forum_path = $request->variable('forum_path', $convertor_data['forum_path']); + $refresh = $request->variable('refresh', 1); + + // Default URL of the old board + // @todo Are we going to use this for attempting to convert URL references in posts, or should we remove it? + // -> We should convert old urls to the new relative urls format + // $src_url = $request->variable('src_url', 'Not in use at the moment'); + + // strip trailing slash from old forum path + $forum_path = (strlen($forum_path) && $forum_path[strlen($forum_path) - 1] == '/') ? substr($forum_path, 0, -1) : $forum_path; + + $error = array(); + if ($submit) + { + if (!@file_exists('./../' . $forum_path . '/' . $test_file)) + { + $error[] = sprintf($lang['COULD_NOT_FIND_PATH'], $forum_path); + } + + $connect_test = false; + $available_dbms = get_available_dbms(false, true, true); + + if (!isset($available_dbms[$src_dbms]) || !$available_dbms[$src_dbms]['AVAILABLE']) + { + $error[] = $lang['INST_ERR_NO_DB']; + $connect_test = false; + } + else + { + $connect_test = connect_check_db(true, $error, $available_dbms[$src_dbms], $src_table_prefix, $src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd), $src_dbname, $src_dbport, true, ($src_dbms == $dbms) ? false : true, false); + } + + // The forum prefix of the old and the new forum can only be the same if two different databases are used. + if ($src_table_prefix == $table_prefix && $src_dbms == $dbms && $src_dbhost == $dbhost && $src_dbport == $dbport && $src_dbname == $dbname) + { + $error[] = sprintf($lang['TABLE_PREFIX_SAME'], $src_table_prefix); + } + + $src_dbms = $phpbb_config_php_file->convert_30_dbms_to_31($src_dbms); + + // Check table prefix + if (!sizeof($error)) + { + // initiate database connection to old db if old and new db differ + global $src_db, $same_db; + $src_db = $same_db = false; + + if ($src_dbms != $dbms || $src_dbhost != $dbhost || $src_dbport != $dbport || $src_dbname != $dbname || $src_dbuser != $dbuser) + { + $src_db = new $src_dbms(); + $src_db->sql_connect($src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd), $src_dbname, $src_dbport, false, true); + $same_db = false; + } + else + { + $src_db = $db; + $same_db = true; + } + + $src_db->sql_return_on_error(true); + $db->sql_return_on_error(true); + + // Try to select one row from the first table to see if the prefix is OK + $result = $src_db->sql_query_limit('SELECT * FROM ' . $src_table_prefix . $tables[0], 1); + + if (!$result) + { + $prefixes = array(); + + $db_tools_factory = new \phpbb\db\tools\factory(); + $db_tools = $db_tools_factory->get($src_db); + $tables_existing = $db_tools->sql_list_tables(); + $tables_existing = array_map('strtolower', $tables_existing); + foreach ($tables_existing as $table_name) + { + compare_table($tables, $table_name, $prefixes); + } + unset($tables_existing); + + foreach ($prefixes as $prefix => $count) + { + if ($count >= sizeof($tables)) + { + $possible_prefix = $prefix; + break; + } + } + + $msg = ''; + if (!empty($convertor_data['table_prefix'])) + { + $msg .= sprintf($lang['DEFAULT_PREFIX_IS'], $convertor_data['forum_name'], $convertor_data['table_prefix']); + } + + if (!empty($possible_prefix)) + { + $msg .= '
'; + $msg .= ($possible_prefix == '*') ? $lang['BLANK_PREFIX_FOUND'] : sprintf($lang['PREFIX_FOUND'], $possible_prefix); + $src_table_prefix = ($possible_prefix == '*') ? '' : $possible_prefix; + } + + $error[] = $msg; + } + $src_db->sql_freeresult($result); + $src_db->sql_return_on_error(false); + } + + if (!sizeof($error)) + { + // Save convertor Status + $config->set('convert_progress', serialize(array( + 'step' => '', + 'table_prefix' => $src_table_prefix, + 'tag' => $convertor_tag, + )), false); + $config->set('convert_db_server', serialize(array( + 'dbms' => $src_dbms, + 'dbhost' => $src_dbhost, + 'dbport' => $src_dbport, + 'dbname' => $src_dbname, + )), false); + $config->set('convert_db_user', serialize(array( + 'dbuser' => $src_dbuser, + 'dbpasswd' => $src_dbpasswd, + )), false); + + // Save options + $config->set('convert_options', serialize(array( + 'forum_path' => './../' . $forum_path, + 'refresh' => $refresh + )), false); + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['VERIFY_OPTIONS'], + 'RESULT' => $lang['CONVERT_SETTINGS_VERIFIED'], + )); + + $template->assign_vars(array( + 'L_SUBMIT' => $lang['BEGIN_CONVERT'], +// 'S_HIDDEN' => $s_hidden_fields, + 'U_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag=$convertor_tag&language=$language", + )); + + return; + } + else + { + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['VERIFY_OPTIONS'], + 'RESULT' => '' . implode('
', $error) . '
', + )); + } + } // end submit + + foreach ($this->convert_options as $config_key => $vars) + { + if (!is_array($vars) && strpos($config_key, 'legend') === false) + { + continue; + } + + if (strpos($config_key, 'legend') !== false) + { + $template->assign_block_vars('options', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang[$vars]) + ); + + continue; + } + + $options = isset($vars['options']) ? $vars['options'] : ''; + + $template->assign_block_vars('options', array( + 'KEY' => $config_key, + 'TITLE' => $lang[$vars['lang']], + 'S_EXPLAIN' => $vars['explain'], + 'S_LEGEND' => false, + 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '', + 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], ${$config_key}, $options), + ) + ); + } + + $template->assign_vars(array( + 'TITLE' => $lang['STAGE_SETTINGS'], + 'BODY' => $lang['CONV_OPTIONS_BODY'], + 'L_SUBMIT' => $lang['BEGIN_CONVERT'], + 'U_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=settings&tag=$convertor_tag&language=$language", + )); + } + + /** + * 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... + 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('
', $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}&sub=in_progress&tag={$convert->convertor_tag}&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]; + } + } + } + } + // 'left_join' => 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1' + 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)) . '

' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__); + } + + $url = $this->save_convert_progress('&confirm=1'); + $msg = $user->lang['PRE_CONVERT_COMPLETE']; + + if ($convert->convertor_data['author_notes']) + { + $msg .= '

' . 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) . '

' . 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) . '

' . 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) . '

' . 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/* && !defined('DEBUG')*/) + { + $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('&current_table=' . $current_table . '&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('&jump=1'); + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['FINAL_STEP'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + + /** + * Sync function being executed at the middle, some functions need to be executed after a successful sync. + */ + function sync_forums($sync_batch) + { + global $template, $user, $db, $phpbb_root_path, $phpEx, $config, $cache; + global $convert; + + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $user->lang['SYNC_TOPICS'], + )); + + $batch_size = $convert->batch_size; + + $sql = 'SELECT MIN(topic_id) as min_value, MAX(topic_id) AS max_value + FROM ' . TOPICS_TABLE; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + // Set values of minimum/maximum primary value for this table. + $primary_min = $row['min_value']; + $primary_max = $row['max_value']; + + if ($sync_batch == 0) + { + $sync_batch = (int) $primary_min; + } + + if ($sync_batch == 0) + { + $sync_batch = 1; + } + + // Fetch a batch of rows, process and insert them. + while ($sync_batch <= $primary_max && still_on_time()) + { + $end = ($sync_batch + $batch_size - 1); + + // Sync all topics in batch mode... + sync('topic', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, true); + + $template->assign_block_vars('checks', array( + 'TITLE' => sprintf($user->lang['SYNC_TOPIC_ID'], $sync_batch, ($sync_batch + $batch_size)) . ((defined('DEBUG') && function_exists('memory_get_usage')) ? ' [' . ceil(memory_get_usage()/1024) . ' ' . $user->lang['KIB'] . ']' : ''), + 'RESULT' => $user->lang['DONE'], + )); + + $sync_batch += $batch_size; + } + + if ($sync_batch >= $primary_max) + { + $url = $this->save_convert_progress('&final_jump=1'); + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + else + { + $sync_batch--; + } + + $url = $this->save_convert_progress('&sync_batch=' . $sync_batch); + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + + /** + * Save the convertor status + */ + function save_convert_progress($step) + { + global $config, $convert, $language; + + // Save convertor Status + $config->set('convert_progress', serialize(array( + 'step' => $step, + 'table_prefix' => $convert->src_table_prefix, + 'tag' => $convert->convertor_tag, + )), false); + + $config->set('convert_db_server', serialize(array( + 'dbms' => $convert->src_dbms, + 'dbhost' => $convert->src_dbhost, + 'dbport' => $convert->src_dbport, + 'dbname' => $convert->src_dbname, + )), false); + + $config->set('convert_db_user', serialize(array( + 'dbuser' => $convert->src_dbuser, + 'dbpasswd' => $convert->src_dbpasswd, + )), false); + + return $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}$step&language=$language"; + } + + /** + * Finish conversion, the last function to be called. + */ + function finish_conversion() + { + global $db, $phpbb_root_path, $phpEx, $convert, $config, $language, $user, $template; + global $cache, $auth, $phpbb_container, $phpbb_log; + + $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " + WHERE config_name = 'convert_progress' + OR config_name = 'convert_options' + OR config_name = 'convert_db_server' + OR config_name = 'convert_db_user'"); + $db->sql_query('DELETE FROM ' . SESSIONS_TABLE); + + @unlink($phpbb_root_path . 'cache/data_global.' . $phpEx); + phpbb_cache_moderators($db, $cache, $auth); + + // And finally, add a note to the log + $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_INSTALL_CONVERTED', false, array($convert->convertor_data['forum_name'], $config['version'])); + + $url = $this->p_master->module_url . "?mode={$this->mode}&sub=final&language=$language"; + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['FINAL_STEP'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + + /** + * This function marks the steps after syncing + */ + function final_jump($final_jump) + { + global $template, $user, $src_db, $same_db, $db, $phpbb_root_path, $phpEx, $config, $cache; + global $convert; + + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $user->lang['PROCESS_LAST'], + )); + + if ($final_jump == 1) + { + $db->sql_return_on_error(true); + + update_topics_posted(); + + $template->assign_block_vars('checks', array( + 'TITLE' => $user->lang['UPDATE_TOPICS_POSTED'], + 'RESULT' => $user->lang['DONE'], + )); + + if ($db->get_sql_error_triggered()) + { + $template->assign_vars(array( + 'S_ERROR_BOX' => true, + 'ERROR_TITLE' => $user->lang['UPDATE_TOPICS_POSTED'], + 'ERROR_MSG' => $user->lang['UPDATE_TOPICS_POSTED_ERR'], + )); + } + $db->sql_return_on_error(false); + + $this->finish_conversion(); + return; + } + } + + /** + * This function marks the steps before syncing (jump=1) + */ + function jump($jump, $last_statement) + { + global $template, $user, $src_db, $same_db, $db, $phpbb_root_path, $phpEx, $config, $cache; + global $convert; + + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $user->lang['PROCESS_LAST'], + )); + + if ($jump == 1) + { + // Execute 'last' statements/queries + if (!empty($convert->convertor['execute_last'])) + { + if (!is_array($convert->convertor['execute_last'])) + { + // @codingStandardsIgnoreStart + eval($convert->convertor['execute_last']); + // @codingStandardsIgnoreEnd + } + else + { + while ($last_statement < sizeof($convert->convertor['execute_last'])) + { + // @codingStandardsIgnoreStart + eval($convert->convertor['execute_last'][$last_statement]); + // @codingStandardsIgnoreEnd + + $template->assign_block_vars('checks', array( + 'TITLE' => $convert->convertor['execute_last'][$last_statement], + 'RESULT' => $user->lang['DONE'], + )); + + $last_statement++; + $url = $this->save_convert_progress('&jump=1&last=' . $last_statement); + + $percentage = ($last_statement == 0) ? 0 : floor(100 / (sizeof($convert->convertor['execute_last']) / $last_statement)); + $msg = sprintf($user->lang['STEP_PERCENT_COMPLETED'], $last_statement, sizeof($convert->convertor['execute_last']), $percentage); + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['CONTINUE_LAST'], + 'L_MESSAGE' => $msg, + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + } + } + + if (!empty($convert->convertor['query_last'])) + { + if (!is_array($convert->convertor['query_last'])) + { + $convert->convertor['query_last'] = array('target', array($convert->convertor['query_last'])); + } + else if (!is_array($convert->convertor['query_last'][0])) + { + $convert->convertor['query_last'] = array(array($convert->convertor['query_last'][0], $convert->convertor['query_last'][1])); + } + + foreach ($convert->convertor['query_last'] as $query_last) + { + if ($query_last[0] == 'src') + { + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'binary'"); + } + + $src_db->sql_query($query_last[1]); + + if ($convert->mysql_convert && $same_db) + { + $src_db->sql_query("SET NAMES 'utf8'"); + } + } + else + { + $db->sql_query($query_last[1]); + } + } + } + + // Sanity check + $db->sql_return_on_error(false); + $src_db->sql_return_on_error(false); + + fix_empty_primary_groups(); + + $sql = 'SELECT MIN(user_regdate) AS board_startdate + FROM ' . USERS_TABLE; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!isset($config['board_startdate']) || ($row['board_startdate'] < $config['board_startdate'] && $row['board_startdate'] > 0)) + { + $config->set('board_startdate', $row['board_startdate']); + $db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_regdate = ' . $row['board_startdate'] . ' WHERE user_id = ' . ANONYMOUS); + } + + update_dynamic_config(); + + $template->assign_block_vars('checks', array( + 'TITLE' => $user->lang['CLEAN_VERIFY'], + 'RESULT' => $user->lang['DONE'], + )); + + $url = $this->save_convert_progress('&jump=2'); + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + + if ($jump == 2) + { + $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_permissions = ''"); + + // TODO: sync() is likely going to bomb out on forums with a considerable amount of topics. + // TODO: the sync function is able to handle FROM-TO values, we should use them here (batch processing) + sync('forum', '', '', false, true); + $cache->destroy('sql', FORUMS_TABLE); + + $template->assign_block_vars('checks', array( + 'TITLE' => $user->lang['SYNC_FORUMS'], + 'RESULT' => $user->lang['DONE'], + )); + + // Continue with synchronizing the forums... + $url = $this->save_convert_progress('&sync_batch=0'); + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + } + + function build_insert_query(&$schema, &$sql_data, $current_table) + { + global $db, $user; + global $convert; + + // Can we use IGNORE with this DBMS? + $sql_ignore = (strpos($db->get_sql_layer(), 'mysql') === 0 && !defined('DEBUG')) ? 'IGNORE ' : ''; + $insert_query = 'INSERT ' . $sql_ignore . 'INTO ' . $schema['target'] . ' ('; + + $aliases = array(); + + $sql_data = array( + 'source_fields' => array(), + 'target_fields' => array(), + 'source_tables' => array(), + 'select_fields' => array(), + ); + + foreach ($schema as $key => $val) + { + // Example: array('group_name', 'extension_groups.group_name', 'htmlspecialchars'), + if (is_int($key)) + { + if (!empty($val[0])) + { + // Target fields + $sql_data['target_fields'][$val[0]] = $key; + $insert_query .= $val[0] . ', '; + } + + if (!is_array($val[1])) + { + $val[1] = array($val[1]); + } + + foreach ($val[1] as $valkey => $value_1) + { + // This should cover about any case: + // + // table.field => SELECT table.field FROM table + // table.field AS alias => SELECT table.field AS alias FROM table + // table.field AS table2.alias => SELECT table2.field AS alias FROM table table2 + // table.field AS table2.field => SELECT table2.field FROM table table2 + // + if (preg_match('/^([a-z0-9_]+)\.([a-z0-9_]+)( +AS +(([a-z0-9_]+?)\.)?([a-z0-9_]+))?$/i', $value_1, $m)) + { + // There is 'AS ...' in the field names + if (!empty($m[3])) + { + $value_1 = ($m[2] == $m[6]) ? $m[1] . '.' . $m[2] : $m[1] . '.' . $m[2] . ' AS ' . $m[6]; + + // Table alias: store it then replace the source table with it + if (!empty($m[5]) && $m[5] != $m[1]) + { + $aliases[$m[5]] = $m[1]; + $value_1 = str_replace($m[1] . '.' . $m[2], $m[5] . '.' . $m[2], $value_1); + } + } + else + { + // No table alias + $sql_data['source_tables'][$m[1]] = (empty($convert->src_table_prefix)) ? $m[1] : $convert->src_table_prefix . $m[1] . ' ' . $m[1]; + } + + $sql_data['select_fields'][$value_1] = $value_1; + $sql_data['source_fields'][$key][$valkey] = (!empty($m[6])) ? $m[6] : $m[2]; + } + } + } + else if ($key == 'where' || $key == 'group_by' || $key == 'order_by' || $key == 'having') + { + if (@preg_match_all('/([a-z0-9_]+)\.([a-z0-9_]+)/i', $val, $m)) + { + foreach ($m[1] as $value) + { + $sql_data['source_tables'][$value] = (empty($convert->src_table_prefix)) ? $value : $convert->src_table_prefix . $value . ' ' . $value; + } + } + } + } + + // Add the aliases to the list of tables + foreach ($aliases as $alias => $table) + { + $sql_data['source_tables'][$alias] = $convert->src_table_prefix . $table . ' ' . $alias; + } + + // 'left_join' => 'forums LEFT JOIN forum_prune ON forums.forum_id = forum_prune.forum_id', + if (!empty($schema['left_join'])) + { + if (!is_array($schema['left_join'])) + { + $schema['left_join'] = array($schema['left_join']); + } + + foreach ($schema['left_join'] as $left_join) + { + // This won't handle concatened LEFT JOINs + if (!preg_match('/([a-z0-9_]+) LEFT JOIN ([a-z0-9_]+) A?S? ?([a-z0-9_]*?) ?(ON|USING)(.*)/i', $left_join, $m)) + { + $this->p_master->error(sprintf($user->lang['NOT_UNDERSTAND'], 'LEFT JOIN', $left_join, $current_table, $schema['target']), __LINE__, __FILE__); + } + + if (!empty($aliases[$m[2]])) + { + if (!empty($m[3])) + { + $this->p_master->error(sprintf($user->lang['NAMING_CONFLICT'], $m[2], $m[3], $schema['left_join']), __LINE__, __FILE__); + } + + $m[2] = $aliases[$m[2]]; + $m[3] = $m[2]; + } + + $right_table = $convert->src_table_prefix . $m[2]; + if (!empty($m[3])) + { + unset($sql_data['source_tables'][$m[3]]); + } + else if ($m[2] != $m[1]) + { + unset($sql_data['source_tables'][$m[2]]); + } + + if (strpos($sql_data['source_tables'][$m[1]], "\nLEFT JOIN") !== false) + { + $sql_data['source_tables'][$m[1]] = '(' . $sql_data['source_tables'][$m[1]] . ")\nLEFT JOIN $right_table"; + } + else + { + $sql_data['source_tables'][$m[1]] .= "\nLEFT JOIN $right_table"; + } + + if (!empty($m[3])) + { + unset($sql_data['source_tables'][$m[3]]); + $sql_data['source_tables'][$m[1]] .= ' AS ' . $m[3]; + } + else if (!empty($convert->src_table_prefix)) + { + $sql_data['source_tables'][$m[1]] .= ' AS ' . $m[2]; + } + $sql_data['source_tables'][$m[1]] .= ' ' . $m[4] . $m[5]; + } + } + + // Remove ", " from the end of the insert query + $insert_query = substr($insert_query, 0, -2) . ') VALUES '; + + return $insert_query; + } + + /** + * Function for processing the currently handled row + */ + function process_row(&$schema, &$sql_data, &$insert_values) + { + global $template, $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache; + global $convert, $convert_row; + + $sql_flag = false; + + foreach ($schema as $key => $fields) + { + // We are only interested in the lines with: + // array('comment', 'attachments_desc.comment', 'htmlspecialchars'), + if (is_int($key)) + { + if (!is_array($fields[1])) + { + $fields[1] = array($fields[1]); + } + + $firstkey_set = false; + $firstkey = 0; + + foreach ($fields[1] as $inner_key => $inner_value) + { + if (!$firstkey_set) + { + $firstkey = $inner_key; + $firstkey_set = true; + } + + $src_field = isset($sql_data['source_fields'][$key][$inner_key]) ? $sql_data['source_fields'][$key][$inner_key] : ''; + + if (!empty($src_field)) + { + $fields[1][$inner_key] = $convert->row[$src_field]; + } + } + + if (!empty($fields[0])) + { + // We have a target field, if we haven't set $sql_flag yet it will be set to TRUE. + // If a function has already set it to FALSE it won't change it. + if ($sql_flag === false) + { + $sql_flag = true; + } + + // No function assigned? + if (empty($fields[2])) + { + $value = $fields[1][$firstkey]; + } + else if (is_array($fields[2]) && !is_callable($fields[2])) + { + // Execute complex function/eval/typecast + $value = $fields[1]; + + foreach ($fields[2] as $type => $execution) + { + if (strpos($type, 'typecast') === 0) + { + if (!is_array($value)) + { + $value = array($value); + } + $value = $value[0]; + settype($value, $execution); + } + else if (strpos($type, 'function') === 0) + { + if (!is_array($value)) + { + $value = array($value); + } + + $value = call_user_func_array($execution, $value); + } + else if (strpos($type, 'execute') === 0) + { + if (!is_array($value)) + { + $value = array($value); + } + + $execution = str_replace('{RESULT}', '$value', $execution); + $execution = str_replace('{VALUE}', '$value', $execution); + // @codingStandardsIgnoreStart + eval($execution); + // @codingStandardsIgnoreEnd + } + } + } + else + { + $value = call_user_func_array($fields[2], $fields[1]); + } + + if (is_null($value)) + { + $value = ''; + } + + $insert_values[] = $db->_sql_validate_value($value); + } + else if (!empty($fields[2])) + { + if (is_array($fields[2])) + { + // Execute complex function/eval/typecast + $value = ''; + + foreach ($fields[2] as $type => $execution) + { + if (strpos($type, 'typecast') === 0) + { + $value = settype($value, $execution); + } + else if (strpos($type, 'function') === 0) + { + if (!is_array($value)) + { + $value = array($value); + } + + $value = call_user_func_array($execution, $value); + } + else if (strpos($type, 'execute') === 0) + { + if (!is_array($value)) + { + $value = array($value); + } + + $execution = str_replace('{RESULT}', '$value', $execution); + $execution = str_replace('{VALUE}', '$value', $execution); + // @codingStandardsIgnoreStart + eval($execution); + // @codingStandardsIgnoreEnd + } + } + } + else + { + call_user_func_array($fields[2], $fields[1]); + } + } + } + } + + return $sql_flag; + } + + /** + * Own meta refresh function to be able to change the global time used + */ + function meta_refresh($url) + { + global $convert, $template; + + if ($convert->options['refresh']) + { + // Because we should not rely on correct settings, we simply use the relative path here directly. + $template->assign_vars(array( + 'S_REFRESH' => true, + 'META' => '') + ); + } + } + + /** + * The information below will be used to build the input fields presented to the user + */ + var $convert_options = array( + 'legend1' => 'SPECIFY_OPTIONS', + 'src_dbms' => array('lang' => 'DBMS', 'type' => 'select', 'options' => 'dbms_select(\'{VALUE}\', true)', 'explain' => false), + 'src_dbhost' => array('lang' => 'DB_HOST', 'type' => 'text:25:100', 'explain' => true), + 'src_dbport' => array('lang' => 'DB_PORT', 'type' => 'text:25:100', 'explain' => true), + 'src_dbname' => array('lang' => 'DB_NAME', 'type' => 'text:25:100', 'explain' => false), + 'src_dbuser' => array('lang' => 'DB_USERNAME', 'type' => 'text:25:100', 'explain' => false), + 'src_dbpasswd' => array('lang' => 'DB_PASSWORD', 'type' => 'password:25:100', 'explain' => false), + 'src_table_prefix' => array('lang' => 'TABLE_PREFIX', 'type' => 'text:25:100', 'explain' => false), + //'src_url' => array('lang' => 'FORUM_ADDRESS', 'type' => 'text:50:100', 'explain' => true), + 'forum_path' => array('lang' => 'FORUM_PATH', 'type' => 'text:25:100', 'explain' => true), + 'refresh' => array('lang' => 'REFRESH_PAGE', 'type' => 'radio:yes_no', 'explain' => true), + ); +} diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php new file mode 100644 index 0000000000..0e223866b1 --- /dev/null +++ b/phpBB/install/install_install.php @@ -0,0 +1,2368 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +*/ +if (!defined('IN_INSTALL')) +{ + // Someone has tried to access the file direct. This is not a good idea, so exit + exit; +} + +if (!empty($setmodules)) +{ + // If phpBB is already installed we do not include this module + if (phpbb_check_installation_exists($phpbb_root_path, $phpEx) && !file_exists($phpbb_root_path . 'cache/install_lock')) + { + return; + } + + $module[] = array( + 'module_type' => 'install', + 'module_title' => 'INSTALL', + 'module_filename' => substr(basename(__FILE__), 0, -strlen($phpEx)-1), + 'module_order' => 10, + 'module_subs' => '', + 'module_stages' => array('INTRO', 'REQUIREMENTS', 'DATABASE', 'ADMINISTRATOR', 'CONFIG_FILE', 'ADVANCED', 'CREATE_TABLE', 'FINAL'), + 'module_reqs' => '' + ); +} + +/** +* Installation +*/ +class install_install extends module +{ + /** + * @var \phpbb\filesystem\filesystem_interface + */ + protected $filesystem; + + function install_install(&$p_master) + { + $this->p_master = &$p_master; + $this->filesystem = new \phpbb\filesystem\filesystem(); + } + + function main($mode, $sub) + { + global $lang, $template, $language, $phpbb_root_path, $phpEx; + global $phpbb_container, $cache, $phpbb_log, $request, $phpbb_config_php_file; + + switch ($sub) + { + case 'intro': + $phpbb_container->get('cache.driver')->purge(); + + $this->page_title = $lang['SUB_INTRO']; + + $template->assign_vars(array( + 'TITLE' => $lang['INSTALL_INTRO'], + 'BODY' => $lang['INSTALL_INTRO_BODY'], + 'L_SUBMIT' => $lang['NEXT_STEP'], + 'S_LANG_SELECT' => '', + 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&sub=requirements&language=$language", + )); + + break; + + case 'requirements': + $this->check_server_requirements($mode, $sub); + + break; + + case 'database': + $this->obtain_database_settings($mode, $sub); + + break; + + case 'administrator': + $this->obtain_admin_settings($mode, $sub); + + break; + + case 'config_file': + $this->create_config_file($mode, $sub); + + break; + + case 'advanced': + $this->obtain_advanced_settings($mode, $sub); + + break; + + case 'create_table': + $this->load_schema($mode, $sub); + break; + + case 'final': + // Enable super globals to prevent issues with the new \phpbb\request\request object + $request->enable_super_globals(); + + // Create a normal container now + $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); + $phpbb_container = $phpbb_container_builder->with_config($phpbb_config_php_file)->get_container(); + + // Sets the global variables + /* @var $cache \phpbb\cache\service */ + $cache = $phpbb_container->get('cache'); + + /* @var $phpbb_log \phpbb\log\log_interface */ + $phpbb_log = $phpbb_container->get('log'); + + $this->build_search_index($mode, $sub); + $this->add_modules($mode, $sub); + $this->add_language($mode, $sub); + $this->add_bots($mode, $sub); + $this->email_admin($mode, $sub); + $this->disable_avatars_if_unwritable(); + $this->populate_migrations($phpbb_container->get('ext.manager'), $phpbb_container->get('migrator')); + + // Remove the lock file + @unlink($phpbb_root_path . 'cache/install_lock'); + + break; + } + + $this->tpl_name = 'install_install'; + } + + /** + * Checks that the server we are installing on meets the requirements for running phpBB + */ + function check_server_requirements($mode, $sub) + { + global $lang, $template, $phpbb_root_path, $phpEx, $language; + + $this->page_title = $lang['STAGE_REQUIREMENTS']; + + $template->assign_vars(array( + 'TITLE' => $lang['REQUIREMENTS_TITLE'], + 'BODY' => $lang['REQUIREMENTS_EXPLAIN'], + )); + + $passed = array('php' => false, 'db' => false, 'files' => false, 'pcre' => false, 'imagesize' => false, 'json' => false,); + + // Test for basic PHP settings + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['PHP_SETTINGS'], + 'LEGEND_EXPLAIN' => $lang['PHP_SETTINGS_EXPLAIN'], + )); + + // Test the minimum PHP version + $php_version = PHP_VERSION; + + if (version_compare($php_version, '5.3.9') < 0) + { + $result = '' . $lang['NO'] . ''; + } + else + { + $passed['php'] = true; + + // We also give feedback on whether we're running in safe mode + $result = '' . $lang['YES']; + if (@ini_get('safe_mode') == '1' || strtolower(@ini_get('safe_mode')) == 'on') + { + $result .= ', ' . $lang['PHP_SAFE_MODE']; + } + $result .= ''; + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['PHP_VERSION_REQD'], + 'RESULT' => $result, + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + + // Don't check for register_globals on 5.4+ + if (version_compare($php_version, '5.4.0-dev') < 0) + { + // Check for register_globals being enabled + if (@ini_get('register_globals') == '1' || strtolower(@ini_get('register_globals')) == 'on') + { + $result = '' . $lang['NO'] . ''; + } + else + { + $result = '' . $lang['YES'] . ''; + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['PHP_REGISTER_GLOBALS'], + 'TITLE_EXPLAIN' => $lang['PHP_REGISTER_GLOBALS_EXPLAIN'], + 'RESULT' => $result, + + 'S_EXPLAIN' => true, + 'S_LEGEND' => false, + )); + } + + // Check for url_fopen + if (@ini_get('allow_url_fopen') == '1' || strtolower(@ini_get('allow_url_fopen')) == 'on') + { + $result = '' . $lang['YES'] . ''; + } + else + { + $result = '' . $lang['NO'] . ''; + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['PHP_URL_FOPEN_SUPPORT'], + 'TITLE_EXPLAIN' => $lang['PHP_URL_FOPEN_SUPPORT_EXPLAIN'], + 'RESULT' => $result, + + 'S_EXPLAIN' => true, + 'S_LEGEND' => false, + )); + + // Check for getimagesize + if (@function_exists('getimagesize')) + { + $passed['imagesize'] = true; + $result = '' . $lang['YES'] . ''; + } + else + { + $result = '' . $lang['NO'] . ''; + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['PHP_GETIMAGESIZE_SUPPORT'], + 'TITLE_EXPLAIN' => $lang['PHP_GETIMAGESIZE_SUPPORT_EXPLAIN'], + 'RESULT' => $result, + + 'S_EXPLAIN' => true, + 'S_LEGEND' => false, + )); + + // Check for PCRE UTF-8 support + if (@preg_match('//u', '')) + { + $passed['pcre'] = true; + $result = '' . $lang['YES'] . ''; + } + else + { + $result = '' . $lang['NO'] . ''; + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['PCRE_UTF_SUPPORT'], + 'TITLE_EXPLAIN' => $lang['PCRE_UTF_SUPPORT_EXPLAIN'], + 'RESULT' => $result, + + 'S_EXPLAIN' => true, + 'S_LEGEND' => false, + )); + + // Check for php json support + if (@extension_loaded('json')) + { + $passed['json'] = true; + $result = '' . $lang['YES'] . ''; + } + else + { + $result = '' . $lang['NO'] . ''; + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['PHP_JSON_SUPPORT'], + 'TITLE_EXPLAIN' => $lang['PHP_JSON_SUPPORT_EXPLAIN'], + 'RESULT' => $result, + + 'S_EXPLAIN' => true, + 'S_LEGEND' => false, + )); + + $passed['mbstring'] = true; + if (@extension_loaded('mbstring')) + { + // Test for available database modules + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['MBSTRING_CHECK'], + 'LEGEND_EXPLAIN' => $lang['MBSTRING_CHECK_EXPLAIN'], + )); + + $checks = array( + array('func_overload', '&', MB_OVERLOAD_MAIL|MB_OVERLOAD_STRING), + array('encoding_translation', '!=', 0), + array('http_input', '!=', array('pass', '')), + array('http_output', '!=', array('pass', '')) + ); + + foreach ($checks as $mb_checks) + { + $ini_val = @ini_get('mbstring.' . $mb_checks[0]); + switch ($mb_checks[1]) + { + case '&': + if (intval($ini_val) & $mb_checks[2]) + { + $result = '' . $lang['NO'] . ''; + $passed['mbstring'] = false; + } + else + { + $result = '' . $lang['YES'] . ''; + } + break; + + case '!=': + if (!is_array($mb_checks[2]) && $ini_val != $mb_checks[2] || + is_array($mb_checks[2]) && !in_array($ini_val, $mb_checks[2])) + { + $result = '' . $lang['NO'] . ''; + $passed['mbstring'] = false; + } + else + { + $result = '' . $lang['YES'] . ''; + } + break; + } + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['MBSTRING_' . strtoupper($mb_checks[0])], + 'TITLE_EXPLAIN' => $lang['MBSTRING_' . strtoupper($mb_checks[0]) . '_EXPLAIN'], + 'RESULT' => $result, + + 'S_EXPLAIN' => true, + 'S_LEGEND' => false, + )); + } + } + + // Test for available database modules + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['PHP_SUPPORTED_DB'], + 'LEGEND_EXPLAIN' => $lang['PHP_SUPPORTED_DB_EXPLAIN'], + )); + + $available_dbms = get_available_dbms(false, true); + $passed['db'] = $available_dbms['ANY_DB_SUPPORT']; + unset($available_dbms['ANY_DB_SUPPORT']); + + foreach ($available_dbms as $db_name => $db_ary) + { + if (!$db_ary['AVAILABLE']) + { + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['DLL_' . strtoupper($db_name)], + 'RESULT' => '' . $lang['UNAVAILABLE'] . '', + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + } + else + { + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['DLL_' . strtoupper($db_name)], + 'RESULT' => '' . $lang['AVAILABLE'] . '', + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + } + } + + // Test for other modules + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['PHP_OPTIONAL_MODULE'], + 'LEGEND_EXPLAIN' => $lang['PHP_OPTIONAL_MODULE_EXPLAIN'], + )); + + foreach ($this->php_dlls_other as $dll) + { + if (!@extension_loaded($dll)) + { + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['DLL_' . strtoupper($dll)], + 'RESULT' => '' . $lang['UNAVAILABLE'] . '', + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + continue; + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['DLL_' . strtoupper($dll)], + 'RESULT' => '' . $lang['AVAILABLE'] . '', + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + } + + // Can we find Imagemagick anywhere on the system? + $exe = (DIRECTORY_SEPARATOR == '\\') ? '.exe' : ''; + + $magic_home = getenv('MAGICK_HOME'); + $img_imagick = ''; + if (empty($magic_home)) + { + $locations = array('C:/WINDOWS/', 'C:/WINNT/', 'C:/WINDOWS/SYSTEM/', 'C:/WINNT/SYSTEM/', 'C:/WINDOWS/SYSTEM32/', 'C:/WINNT/SYSTEM32/', '/usr/bin/', '/usr/sbin/', '/usr/local/bin/', '/usr/local/sbin/', '/opt/', '/usr/imagemagick/', '/usr/bin/imagemagick/'); + $path_locations = str_replace('\\', '/', (explode(($exe) ? ';' : ':', getenv('PATH')))); + + $locations = array_merge($path_locations, $locations); + foreach ($locations as $location) + { + // The path might not end properly, fudge it + if (substr($location, -1, 1) !== '/') + { + $location .= '/'; + } + + if (@file_exists($location) && @is_readable($location . 'mogrify' . $exe) && @filesize($location . 'mogrify' . $exe) > 3000) + { + $img_imagick = str_replace('\\', '/', $location); + continue; + } + } + } + else + { + $img_imagick = str_replace('\\', '/', $magic_home); + } + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['APP_MAGICK'], + 'RESULT' => ($img_imagick) ? '' . $lang['AVAILABLE'] . ', ' . $img_imagick . '' : '' . $lang['NO_LOCATION'] . '', + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + + // Check permissions on files/directories we need access to + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['FILES_REQUIRED'], + 'LEGEND_EXPLAIN' => $lang['FILES_REQUIRED_EXPLAIN'], + )); + + $directories = array('cache/', 'files/', 'store/'); + + umask(0); + + $passed['files'] = true; + foreach ($directories as $dir) + { + $exists = $write = false; + + // Try to create the directory if it does not exist + if (!file_exists($phpbb_root_path . $dir)) + { + @mkdir($phpbb_root_path . $dir, 0777); + + try + { + $this->filesystem->phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE); + } + catch (\phpbb\filesystem\exception\filesystem_exception $e) + { + // Do nothing + } + } + + // Now really check + if (file_exists($phpbb_root_path . $dir) && is_dir($phpbb_root_path . $dir)) + { + try + { + $this->filesystem->phpbb_chmod($phpbb_root_path . $dir, CHMOD_READ | CHMOD_WRITE); + } + catch (\phpbb\filesystem\exception\filesystem_exception $e) + { + // Do nothing + } + + $exists = true; + } + + // Now check if it is writable by storing a simple file + $fp = @fopen($phpbb_root_path . $dir . 'test_lock', 'wb'); + if ($fp !== false) + { + $write = true; + } + @fclose($fp); + + @unlink($phpbb_root_path . $dir . 'test_lock'); + + $passed['files'] = ($exists && $write && $passed['files']) ? true : false; + + $exists = ($exists) ? '' . $lang['FOUND'] . '' : '' . $lang['NOT_FOUND'] . ''; + $write = ($write) ? ', ' . $lang['WRITABLE'] . '' : (($exists) ? ', ' . $lang['UNWRITABLE'] . '' : ''); + + $template->assign_block_vars('checks', array( + 'TITLE' => $dir, + 'RESULT' => $exists . $write, + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + } + + // Check permissions on files/directories it would be useful access to + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['FILES_OPTIONAL'], + 'LEGEND_EXPLAIN' => $lang['FILES_OPTIONAL_EXPLAIN'], + )); + + $directories = array('config.' . $phpEx, 'images/avatars/upload/'); + + foreach ($directories as $dir) + { + $write = $exists = true; + if (file_exists($phpbb_root_path . $dir)) + { + if (!$this->filesystem->is_writable($phpbb_root_path . $dir)) + { + $write = false; + } + } + else + { + $write = $exists = false; + } + + $exists_str = ($exists) ? '' . $lang['FOUND'] . '' : '' . $lang['NOT_FOUND'] . ''; + $write_str = ($write) ? ', ' . $lang['WRITABLE'] . '' : (($exists) ? ', ' . $lang['UNWRITABLE'] . '' : ''); + + $template->assign_block_vars('checks', array( + 'TITLE' => $dir, + 'RESULT' => $exists_str . $write_str, + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + } + + // And finally where do we want to go next (well today is taken isn't it :P) + $s_hidden_fields = ($img_imagick) ? '' : ''; + + $url = (!in_array(false, $passed)) ? $this->p_master->module_url . "?mode=$mode&sub=database&language=$language" : $this->p_master->module_url . "?mode=$mode&sub=requirements&language=$language "; + $submit = (!in_array(false, $passed)) ? $lang['INSTALL_START'] : $lang['INSTALL_TEST']; + + $template->assign_vars(array( + 'L_SUBMIT' => $submit, + 'S_HIDDEN' => $s_hidden_fields, + 'U_ACTION' => $url, + )); + } + + /** + * Obtain the information required to connect to the database + */ + function obtain_database_settings($mode, $sub) + { + global $lang, $template, $phpEx; + + $this->page_title = $lang['STAGE_DATABASE']; + + // Obtain any submitted data + $data = $this->get_submitted_data(); + + $connect_test = false; + $error = array(); + $available_dbms = get_available_dbms(false, true); + + // Has the user opted to test the connection? + if (isset($_POST['testdb'])) + { + if (!isset($available_dbms[$data['dbms']]) || !$available_dbms[$data['dbms']]['AVAILABLE']) + { + $error[] = $lang['INST_ERR_NO_DB']; + $connect_test = false; + } + else if (!preg_match(get_preg_expression('table_prefix'), $data['table_prefix'])) + { + $error[] = $lang['INST_ERR_DB_INVALID_PREFIX']; + $connect_test = false; + } + else + { + $connect_test = connect_check_db(true, $error, $available_dbms[$data['dbms']], $data['table_prefix'], $data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport']); + } + + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['DB_CONNECTION'], + 'LEGEND_EXPLAIN' => false, + )); + + if ($connect_test) + { + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['DB_TEST'], + 'RESULT' => '' . $lang['SUCCESSFUL_CONNECT'] . '', + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + } + else + { + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['DB_TEST'], + 'RESULT' => '' . implode('
', $error) . '
', + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + } + } + + if (!$connect_test) + { + // Update the list of available DBMS modules to only contain those which can be used + $available_dbms_temp = array(); + foreach ($available_dbms as $type => $dbms_ary) + { + if (!$dbms_ary['AVAILABLE']) + { + continue; + } + + $available_dbms_temp[$type] = $dbms_ary; + } + + $available_dbms = &$available_dbms_temp; + + // And now for the main part of this page + $data['table_prefix'] = (!empty($data['table_prefix']) ? $data['table_prefix'] : 'phpbb_'); + + foreach ($this->db_config_options as $config_key => $vars) + { + if (!is_array($vars) && strpos($config_key, 'legend') === false) + { + continue; + } + + if (strpos($config_key, 'legend') !== false) + { + $template->assign_block_vars('options', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang[$vars]) + ); + + continue; + } + + $options = isset($vars['options']) ? $vars['options'] : ''; + + $template->assign_block_vars('options', array( + 'KEY' => $config_key, + 'TITLE' => $lang[$vars['lang']], + 'S_EXPLAIN' => $vars['explain'], + 'S_LEGEND' => false, + 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '', + 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options), + ) + ); + } + } + + // And finally where do we want to go next (well today is taken isn't it :P) + $s_hidden_fields = ($data['img_imagick']) ? '' : ''; + $s_hidden_fields .= ''; + if ($connect_test) + { + foreach ($this->db_config_options as $config_key => $vars) + { + if (!is_array($vars)) + { + continue; + } + $s_hidden_fields .= ''; + } + } + + $url = ($connect_test) ? $this->p_master->module_url . "?mode=$mode&sub=administrator" : $this->p_master->module_url . "?mode=$mode&sub=database"; + $s_hidden_fields .= ($connect_test) ? '' : ''; + + $submit = $lang['NEXT_STEP']; + + $template->assign_vars(array( + 'L_SUBMIT' => $submit, + 'S_HIDDEN' => $s_hidden_fields, + 'U_ACTION' => $url, + )); + } + + /** + * Obtain the administrator's name, password and email address + */ + function obtain_admin_settings($mode, $sub) + { + global $lang, $template, $phpEx; + + $this->page_title = $lang['STAGE_ADMINISTRATOR']; + + // Obtain any submitted data + $data = $this->get_submitted_data(); + + if ($data['dbms'] == '') + { + // Someone's been silly and tried calling this page direct + // So we send them back to the start to do it again properly + $this->p_master->redirect("index.$phpEx?mode=install"); + } + + $s_hidden_fields = ($data['img_imagick']) ? '' : ''; + $passed = false; + + $data['default_lang'] = ($data['default_lang'] !== '') ? $data['default_lang'] : $data['language']; + + if (isset($_POST['check'])) + { + $error = array(); + + // Check the entered email address and password + if ($data['admin_name'] == '' || $data['admin_pass1'] == '' || $data['admin_pass2'] == '' || $data['board_email'] == '') + { + $error[] = $lang['INST_ERR_MISSING_DATA']; + } + + if ($data['admin_pass1'] != $data['admin_pass2'] && $data['admin_pass1'] != '') + { + $error[] = $lang['INST_ERR_PASSWORD_MISMATCH']; + } + + // Test against the default username rules + if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) < 3) + { + $error[] = $lang['INST_ERR_USER_TOO_SHORT']; + } + + if ($data['admin_name'] != '' && utf8_strlen($data['admin_name']) > 20) + { + $error[] = $lang['INST_ERR_USER_TOO_LONG']; + } + + // Test against the default password rules + if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) < 6) + { + $error[] = $lang['INST_ERR_PASSWORD_TOO_SHORT']; + } + + if ($data['admin_pass1'] != '' && utf8_strlen($data['admin_pass1']) > 30) + { + $error[] = $lang['INST_ERR_PASSWORD_TOO_LONG']; + } + + if ($data['board_email'] != '' && !preg_match('/^' . get_preg_expression('email') . '$/i', $data['board_email'])) + { + $error[] = $lang['INST_ERR_EMAIL_INVALID']; + } + + $template->assign_block_vars('checks', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang['STAGE_ADMINISTRATOR'], + 'LEGEND_EXPLAIN' => false, + )); + + if (!sizeof($error)) + { + $passed = true; + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['ADMIN_TEST'], + 'RESULT' => '' . $lang['TESTS_PASSED'] . '', + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + } + else + { + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['ADMIN_TEST'], + 'RESULT' => '' . implode('
', $error) . '
', + + 'S_EXPLAIN' => false, + 'S_LEGEND' => false, + )); + } + } + + if (!$passed) + { + foreach ($this->admin_config_options as $config_key => $vars) + { + if (!is_array($vars) && strpos($config_key, 'legend') === false) + { + continue; + } + + if (strpos($config_key, 'legend') !== false) + { + $template->assign_block_vars('options', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang[$vars]) + ); + + continue; + } + + $options = isset($vars['options']) ? $vars['options'] : ''; + + $template->assign_block_vars('options', array( + 'KEY' => $config_key, + 'TITLE' => $lang[$vars['lang']], + 'S_EXPLAIN' => $vars['explain'], + 'S_LEGEND' => false, + 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '', + 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options), + ) + ); + } + } + else + { + foreach ($this->admin_config_options as $config_key => $vars) + { + if (!is_array($vars)) + { + continue; + } + $s_hidden_fields .= ''; + } + } + + $s_hidden_fields .= ($data['img_imagick']) ? '' : ''; + $s_hidden_fields .= ''; + + foreach ($this->db_config_options as $config_key => $vars) + { + if (!is_array($vars)) + { + continue; + } + $s_hidden_fields .= ''; + } + + $submit = $lang['NEXT_STEP']; + + $url = ($passed) ? $this->p_master->module_url . "?mode=$mode&sub=config_file" : $this->p_master->module_url . "?mode=$mode&sub=administrator"; + $s_hidden_fields .= ($passed) ? '' : ''; + + $template->assign_vars(array( + 'L_SUBMIT' => $submit, + 'S_HIDDEN' => $s_hidden_fields, + 'U_ACTION' => $url, + )); + } + + /** + * Writes the config file to disk, or if unable to do so offers alternative methods + */ + function create_config_file($mode, $sub) + { + global $lang, $template, $phpbb_root_path, $phpEx; + + $this->page_title = $lang['STAGE_CONFIG_FILE']; + + // Obtain any submitted data + $data = $this->get_submitted_data(); + + if ($data['dbms'] == '') + { + // Someone's been silly and tried calling this page direct + // So we send them back to the start to do it again properly + $this->p_master->redirect("index.$phpEx?mode=install"); + } + + $s_hidden_fields = ($data['img_imagick']) ? '' : ''; + $s_hidden_fields .= ''; + $written = false; + + // Create a list of any PHP modules we wish to have loaded + $available_dbms = get_available_dbms($data['dbms']); + + // Create a lock file to indicate that there is an install in progress + $fp = @fopen($phpbb_root_path . 'cache/install_lock', 'wb'); + if ($fp === false) + { + // We were unable to create the lock file - abort + $this->p_master->error($lang['UNABLE_WRITE_LOCK'], __LINE__, __FILE__); + } + @fclose($fp); + + @chmod($phpbb_root_path . 'cache/install_lock', 0777); + + // Time to convert the data provided into a config file + $config_data = phpbb_create_config_file_data($data, $available_dbms[$data['dbms']]['DRIVER']); + + // Attempt to write out the config file directly. If it works, this is the easiest way to do it ... + if ((file_exists($phpbb_root_path . 'config.' . $phpEx) && $this->filesystem->is_writable($phpbb_root_path . 'config.' . $phpEx)) || $this->filesystem->is_writable($phpbb_root_path)) + { + // Assume it will work ... if nothing goes wrong below + $written = true; + + if (!($fp = @fopen($phpbb_root_path . 'config.' . $phpEx, 'w'))) + { + // Something went wrong ... so let's try another method + $written = false; + } + + if (!(@fwrite($fp, $config_data))) + { + // Something went wrong ... so let's try another method + $written = false; + } + + @fclose($fp); + + if ($written) + { + // We may revert back to chmod() if we see problems with users not able to change their config.php file directly + try + { + $this->filesystem->phpbb_chmod($phpbb_root_path . 'config.' . $phpEx, CHMOD_READ); + } + catch (\phpbb\filesystem\exception\filesystem_exception $e) + { + // Do nothing + } + } + } + + if (isset($_POST['dldone'])) + { + // Do a basic check to make sure that the file has been uploaded + // Note that all we check is that the file has _something_ in it + // We don't compare the contents exactly - if they can't upload + // a single file correctly, it's likely they will have other problems.... + if (filesize($phpbb_root_path . 'config.' . $phpEx) > 10) + { + $written = true; + } + } + + $config_options = array_merge($this->db_config_options, $this->admin_config_options); + + foreach ($config_options as $config_key => $vars) + { + if (!is_array($vars)) + { + continue; + } + $s_hidden_fields .= ''; + } + + if (!$written) + { + // OK, so it didn't work let's try the alternatives + + if (isset($_POST['dlconfig'])) + { + // They want a copy of the file to download, so send the relevant headers and dump out the data + header("Content-Type: text/x-delimtext; name=\"config.$phpEx\""); + header("Content-disposition: attachment; filename=config.$phpEx"); + echo $config_data; + exit; + } + + // The option to download the config file is always available, so output it here + $template->assign_vars(array( + 'BODY' => $lang['CONFIG_FILE_UNABLE_WRITE'], + 'L_DL_CONFIG' => $lang['DL_CONFIG'], + 'L_DL_CONFIG_EXPLAIN' => $lang['DL_CONFIG_EXPLAIN'], + 'L_DL_DONE' => $lang['DONE'], + 'L_DL_DOWNLOAD' => $lang['DL_DOWNLOAD'], + 'S_HIDDEN' => $s_hidden_fields, + 'S_SHOW_DOWNLOAD' => true, + 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&sub=config_file", + )); + return; + } + else + { + $template->assign_vars(array( + 'BODY' => $lang['CONFIG_FILE_WRITTEN'], + 'L_SUBMIT' => $lang['NEXT_STEP'], + 'S_HIDDEN' => $s_hidden_fields, + 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&sub=advanced", + )); + return; + } + } + + /** + * Provide an opportunity to customise some advanced settings during the install + * in case it is necessary for them to be set to access later + */ + function obtain_advanced_settings($mode, $sub) + { + global $lang, $template, $phpEx, $request; + + $this->page_title = $lang['STAGE_ADVANCED']; + + // Obtain any submitted data + $data = $this->get_submitted_data(); + + if ($data['dbms'] == '') + { + // Someone's been silly and tried calling this page direct + // So we send them back to the start to do it again properly + $this->p_master->redirect("index.$phpEx?mode=install"); + } + + $s_hidden_fields = ($data['img_imagick']) ? '' : ''; + $s_hidden_fields .= ''; + + // HTTP_HOST is having the correct browser url in most cases... + $server_name = strtolower(htmlspecialchars_decode($request->header('Host', $request->server('SERVER_NAME')))); + + // HTTP HOST can carry a port number... + if (strpos($server_name, ':') !== false) + { + $server_name = substr($server_name, 0, strpos($server_name, ':')); + } + + $data['email_enable'] = ($data['email_enable'] !== '') ? $data['email_enable'] : true; + $data['server_name'] = ($data['server_name'] !== '') ? $data['server_name'] : $server_name; + $data['server_port'] = ($data['server_port'] !== '') ? $data['server_port'] : $request->server('SERVER_PORT', 0); + $data['server_protocol'] = ($data['server_protocol'] !== '') ? $data['server_protocol'] : ($request->is_secure() ? 'https://' : 'http://'); + $data['cookie_secure'] = ($data['cookie_secure'] !== '') ? $data['cookie_secure'] : $request->is_secure(); + + if ($data['script_path'] === '') + { + $name = htmlspecialchars_decode($request->server('PHP_SELF')); + if (!$name) + { + $name = htmlspecialchars_decode($request->server('REQUEST_URI')); + } + + // Replace backslashes and doubled slashes (could happen on some proxy setups) + $name = str_replace(array('\\', '//'), '/', $name); + $data['script_path'] = trim(dirname(dirname($name))); + } + + foreach ($this->advanced_config_options as $config_key => $vars) + { + if (!is_array($vars) && strpos($config_key, 'legend') === false) + { + continue; + } + + if (strpos($config_key, 'legend') !== false) + { + $template->assign_block_vars('options', array( + 'S_LEGEND' => true, + 'LEGEND' => $lang[$vars]) + ); + + continue; + } + + $options = isset($vars['options']) ? $vars['options'] : ''; + + $template->assign_block_vars('options', array( + 'KEY' => $config_key, + 'TITLE' => $lang[$vars['lang']], + 'S_EXPLAIN' => $vars['explain'], + 'S_LEGEND' => false, + 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '', + 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], $data[$config_key], $options), + ) + ); + } + + $config_options = array_merge($this->db_config_options, $this->admin_config_options); + foreach ($config_options as $config_key => $vars) + { + if (!is_array($vars)) + { + continue; + } + $s_hidden_fields .= ''; + } + + $submit = $lang['NEXT_STEP']; + + $url = $this->p_master->module_url . "?mode=$mode&sub=create_table"; + + $template->assign_vars(array( + 'BODY' => $lang['STAGE_ADVANCED_EXPLAIN'], + 'L_SUBMIT' => $submit, + 'S_HIDDEN' => $s_hidden_fields, + 'U_ACTION' => $url, + )); + } + + /** + * Load the contents of the schema into the database and then alter it based on what has been input during the installation + */ + function load_schema($mode, $sub) + { + global $db, $lang, $template, $phpbb_root_path, $phpEx, $request; + + $this->page_title = $lang['STAGE_CREATE_TABLE']; + $s_hidden_fields = ''; + + // Obtain any submitted data + $data = $this->get_submitted_data(); + + if ($data['dbms'] == '') + { + // Someone's been silly and tried calling this page direct + // So we send them back to the start to do it again properly + $this->p_master->redirect("index.$phpEx?mode=install"); + } + + // HTTP_HOST is having the correct browser url in most cases... + $server_name = strtolower(htmlspecialchars_decode($request->header('Host', $request->server('SERVER_NAME')))); + $referer = strtolower($request->header('Referer')); + + // HTTP HOST can carry a port number... + if (strpos($server_name, ':') !== false) + { + $server_name = substr($server_name, 0, strpos($server_name, ':')); + } + + $cookie_domain = ($data['server_name'] != '') ? $data['server_name'] : $server_name; + + // Try to come up with the best solution for cookie domain... + if (strpos($cookie_domain, 'www.') === 0) + { + $cookie_domain = str_replace('www.', '.', $cookie_domain); + } + + // If we get here and the extension isn't loaded it should be safe to just go ahead and load it + $available_dbms = get_available_dbms($data['dbms']); + + if (!isset($available_dbms[$data['dbms']])) + { + // Someone's been silly and tried providing a non-existant dbms + $this->p_master->redirect("index.$phpEx?mode=install"); + } + + $dbms = $available_dbms[$data['dbms']]['DRIVER']; + + // Instantiate the database + $db = new $dbms(); + $db->sql_connect($data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false); + + // NOTE: trigger_error does not work here. + $db->sql_return_on_error(true); + + // If mysql is chosen, we need to adjust the schema filename slightly to reflect the correct version. ;) + if ($data['dbms'] == 'mysql') + { + if (version_compare($db->sql_server_info(true), '4.1.3', '>=')) + { + $available_dbms[$data['dbms']]['SCHEMA'] .= '_41'; + } + else + { + $available_dbms[$data['dbms']]['SCHEMA'] .= '_40'; + } + } + + // Ok we have the db info go ahead and read in the relevant schema + // and work on building the table + $dbms_schema = 'schemas/' . $available_dbms[$data['dbms']]['SCHEMA'] . '_schema.sql'; + + // How should we treat this schema? + $delimiter = $available_dbms[$data['dbms']]['DELIM']; + + if (file_exists($dbms_schema)) + { + $sql_query = @file_get_contents($dbms_schema); + $sql_query = preg_replace('#phpbb_#i', $data['table_prefix'], $sql_query); + $sql_query = phpbb_remove_comments($sql_query); + $sql_query = split_sql_file($sql_query, $delimiter); + + foreach ($sql_query as $sql) + { + // Ignore errors when the functions or types already exist + // to allow installing phpBB twice in the same database with + // a different prefix + $db->sql_query($sql); + } + unset($sql_query); + } + + // Ok we have the db info go ahead and work on building the table + if (file_exists('schemas/schema.json')) + { + $db_table_schema = @file_get_contents('schemas/schema.json'); + $db_table_schema = json_decode($db_table_schema, true); + } + else + { + global $phpbb_root_path, $phpEx, $table_prefix; + $table_prefix = 'phpbb_'; + + 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($phpbb_root_path . 'includes/constants.' . $phpEx); + } + + $finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path, null, $phpEx); + $classes = $finder->core_path('phpbb/db/migration/data/') + ->get_classes(); + + $sqlite_db = new \phpbb\db\driver\sqlite(); + $factory = new \phpbb\db\tools\factory(); + $db_tools = $factory->get($sqlite_db, true); + $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $sqlite_db, $db_tools, $phpbb_root_path, $phpEx, $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', $data['table_prefix'] . 'config'); + } + + $factory = new \phpbb\db\tools\factory(); + $db_tools = $factory->get($db); + foreach ($db_table_schema as $table_name => $table_data) + { + $db_tools->sql_create_table( + $data['table_prefix'] . substr($table_name, 6), + $table_data + ); + } + + // Ok tables have been built, let's fill in the basic information + $sql_query = file_get_contents('schemas/schema_data.sql'); + + // Deal with any special comments and characters + switch ($data['dbms']) + { + case 'mssql': + case 'mssql_odbc': + case 'mssqlnative': + $sql_query = preg_replace('#\# MSSQL IDENTITY (phpbb_[a-z_]+) (ON|OFF) \##s', 'SET IDENTITY_INSERT \1 \2;', $sql_query); + break; + + case 'postgres': + $sql_query = preg_replace('#\# POSTGRES (BEGIN|COMMIT) \##s', '\1; ', $sql_query); + break; + + case 'mysql': + case 'mysqli': + $sql_query = str_replace('\\', '\\\\', $sql_query); + break; + } + + // Change prefix + $sql_query = preg_replace('# phpbb_([^\s]*) #i', ' ' . $data['table_prefix'] . '\1 ', $sql_query); + + // Change language strings... + $sql_query = preg_replace_callback('#\{L_([A-Z0-9\-_]*)\}#s', 'adjust_language_keys_callback', $sql_query); + + $sql_query = phpbb_remove_comments($sql_query); + $sql_query = split_sql_file($sql_query, ';'); + + foreach ($sql_query as $sql) + { + //$sql = trim(str_replace('|', ';', $sql)); + if (!$db->sql_query($sql)) + { + $error = $db->sql_error(); + $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__); + } + } + unset($sql_query); + + $current_time = time(); + + $user_ip = $request->server('REMOTE_ADDR') ? phpbb_ip_normalise($request->server('REMOTE_ADDR')) : ''; + + if ($data['script_path'] !== '/') + { + // Adjust destination path (no trailing slash) + if (substr($data['script_path'], -1) == '/') + { + $data['script_path'] = substr($data['script_path'], 0, -1); + } + + $data['script_path'] = str_replace(array('../', './'), '', $data['script_path']); + + if ($data['script_path'][0] != '/') + { + $data['script_path'] = '/' . $data['script_path']; + } + } + + // Set default config and post data, this applies to all DB's + $sql_ary = array( + 'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value) + VALUES ('board_startdate', '$current_time')", + + 'INSERT INTO ' . $data['table_prefix'] . "config (config_name, config_value) + VALUES ('default_lang', '" . $db->sql_escape($data['default_lang']) . "')", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['img_imagick']) . "' + WHERE config_name = 'img_imagick'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['server_name']) . "' + WHERE config_name = 'server_name'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['server_port']) . "' + WHERE config_name = 'server_port'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['board_email']) . "' + WHERE config_name = 'board_email'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['board_email']) . "' + WHERE config_name = 'board_contact'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($cookie_domain) . "' + WHERE config_name = 'cookie_domain'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($lang['default_dateformat']) . "' + WHERE config_name = 'default_dateformat'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['email_enable']) . "' + WHERE config_name = 'email_enable'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['smtp_delivery']) . "' + WHERE config_name = 'smtp_delivery'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['smtp_host']) . "' + WHERE config_name = 'smtp_host'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['smtp_auth']) . "' + WHERE config_name = 'smtp_auth_method'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['smtp_user']) . "' + WHERE config_name = 'smtp_username'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['smtp_pass']) . "' + WHERE config_name = 'smtp_password'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['cookie_secure']) . "' + WHERE config_name = 'cookie_secure'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['force_server_vars']) . "' + WHERE config_name = 'force_server_vars'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['script_path']) . "' + WHERE config_name = 'script_path'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['server_protocol']) . "' + WHERE config_name = 'server_protocol'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($data['admin_name']) . "' + WHERE config_name = 'newest_username'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . md5(mt_rand()) . "' + WHERE config_name = 'avatar_salt'", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . md5(mt_rand()) . "' + WHERE config_name = 'plupload_salt'", + + 'UPDATE ' . $data['table_prefix'] . "users + SET username = '" . $db->sql_escape($data['admin_name']) . "', user_password='" . $db->sql_escape(md5($data['admin_pass1'])) . "', user_ip = '" . $db->sql_escape($user_ip) . "', user_lang = '" . $db->sql_escape($data['default_lang']) . "', user_email='" . $db->sql_escape($data['board_email']) . "', user_dateformat='" . $db->sql_escape($lang['default_dateformat']) . "', user_email_hash = " . $db->sql_escape(phpbb_email_hash($data['board_email'])) . ", username_clean = '" . $db->sql_escape(utf8_clean_string($data['admin_name'])) . "' + WHERE username = 'Admin'", + + 'UPDATE ' . $data['table_prefix'] . "moderator_cache + SET username = '" . $db->sql_escape($data['admin_name']) . "' + WHERE username = 'Admin'", + + 'UPDATE ' . $data['table_prefix'] . "forums + SET forum_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "' + WHERE forum_last_poster_name = 'Admin'", + + 'UPDATE ' . $data['table_prefix'] . "topics + SET topic_first_poster_name = '" . $db->sql_escape($data['admin_name']) . "', topic_last_poster_name = '" . $db->sql_escape($data['admin_name']) . "' + WHERE topic_first_poster_name = 'Admin' + OR topic_last_poster_name = 'Admin'", + + 'UPDATE ' . $data['table_prefix'] . "users + SET user_regdate = $current_time", + + 'UPDATE ' . $data['table_prefix'] . "posts + SET post_time = $current_time, poster_ip = '" . $db->sql_escape($user_ip) . "'", + + 'UPDATE ' . $data['table_prefix'] . "topics + SET topic_time = $current_time, topic_last_post_time = $current_time", + + 'UPDATE ' . $data['table_prefix'] . "forums + SET forum_last_post_time = $current_time", + + 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($db->sql_server_info(true)) . "' + WHERE config_name = 'dbms_version'", + ); + + if (@extension_loaded('gd')) + { + $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = 'core.captcha.plugins.gd' + WHERE config_name = 'captcha_plugin'"; + + $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '1' + WHERE config_name = 'captcha_gd'"; + } + + $ref = substr($referer, strpos($referer, '://') + 3); + + if (!(stripos($ref, $server_name) === 0)) + { + $sql_ary[] = 'UPDATE ' . $data['table_prefix'] . "config + SET config_value = '0' + WHERE 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 ' . $data['table_prefix'] . "config + SET config_value = '" . $db->sql_escape($cookie_name) . "' + WHERE config_name = 'cookie_name'"; + + foreach ($sql_ary as $sql) + { + //$sql = trim(str_replace('|', ';', $sql)); + + if (!$db->sql_query($sql)) + { + $error = $db->sql_error(); + $this->p_master->db_error($error['message'], $sql, __LINE__, __FILE__); + } + } + + $submit = $lang['NEXT_STEP']; + + $url = $this->p_master->module_url . "?mode=$mode&sub=final"; + + $template->assign_vars(array( + 'BODY' => $lang['STAGE_CREATE_TABLE_EXPLAIN'], + 'L_SUBMIT' => $submit, + 'S_HIDDEN' => build_hidden_fields($data), + 'U_ACTION' => $url, + )); + } + + /** + * Build the search index... + */ + function build_search_index($mode, $sub) + { + global $db, $lang, $phpbb_root_path, $phpbb_dispatcher, $phpEx, $config, $auth, $user; + + // Obtain any submitted data + $data = $this->get_submitted_data(); + $table_prefix = $data['table_prefix']; + + // If we get here and the extension isn't loaded it should be safe to just go ahead and load it + $available_dbms = get_available_dbms($data['dbms']); + + if (!isset($available_dbms[$data['dbms']])) + { + // Someone's been silly and tried providing a non-existant dbms + $this->p_master->redirect("index.$phpEx?mode=install"); + } + + $dbms = $available_dbms[$data['dbms']]['DRIVER']; + + // Instantiate the database + $db = new $dbms(); + $db->sql_connect($data['dbhost'], $data['dbuser'], htmlspecialchars_decode($data['dbpasswd']), $data['dbname'], $data['dbport'], false, false); + + // NOTE: trigger_error does not work here. + $db->sql_return_on_error(true); + + include_once($phpbb_root_path . 'includes/constants.' . $phpEx); + include_once($phpbb_root_path . 'phpbb/search/fulltext_native.' . $phpEx); + + // 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); + + $error = false; + $search = new \phpbb\search\fulltext_native($error, $phpbb_root_path, $phpEx, $auth, $config, $db, $user, $phpbb_dispatcher); + + $sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id + FROM ' . POSTS_TABLE; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']); + } + $db->sql_freeresult($result); + } + + /** + * Populate the module tables + */ + function add_modules($mode, $sub) + { + global $db, $lang, $phpbb_root_path, $phpEx, $phpbb_extension_manager, $config, $phpbb_container; + + // modules require an extension manager + if (empty($phpbb_extension_manager)) + { + /* @var $phpbb_extension_manager \phpbb\extension\manager */ + $phpbb_extension_manager = $phpbb_container->get('ext.manager'); + } + + $_module = new \phpbb\module\module_manager( + new \phpbb\cache\driver\dummy(), + $db, + $phpbb_extension_manager, + MODULES_TABLE, + $phpbb_root_path, + $phpEx + ); + $module_classes = array('acp', 'mcp', 'ucp'); + + // Add categories + foreach ($module_classes as $module_class) + { + $categories = array(); + + // Set the module class + $_module->module_class = $module_class; + + foreach ($this->module_categories[$module_class] as $cat_name => $subs) + { + $basename = ''; + // Check if this sub-category has a basename. If it has, use it. + if (isset($this->module_categories_basenames[$cat_name])) + { + $basename = $this->module_categories_basenames[$cat_name]; + } + $module_data = array( + 'module_basename' => $basename, + 'module_enabled' => 1, + 'module_display' => 1, + 'parent_id' => 0, + 'module_class' => $module_class, + 'module_langname' => $cat_name, + 'module_mode' => '', + 'module_auth' => '', + ); + + // Add category + $_module->update_module_data($module_data); + + // Check for last sql error happened + if ($db->get_sql_error_triggered()) + { + $error = $db->sql_error($db->get_sql_error_sql()); + $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__); + } + + $categories[$cat_name]['id'] = (int) $module_data['module_id']; + $categories[$cat_name]['parent_id'] = 0; + + // Create sub-categories... + if (is_array($subs)) + { + foreach ($subs as $level2_name) + { + $basename = ''; + // Check if this sub-category has a basename. If it has, use it. + if (isset($this->module_categories_basenames[$level2_name])) + { + $basename = $this->module_categories_basenames[$level2_name]; + } + $module_data = array( + 'module_basename' => $basename, + 'module_enabled' => 1, + 'module_display' => 1, + 'parent_id' => (int) $categories[$cat_name]['id'], + 'module_class' => $module_class, + 'module_langname' => $level2_name, + 'module_mode' => '', + 'module_auth' => '', + ); + + $_module->update_module_data($module_data); + + // Check for last sql error happened + if ($db->get_sql_error_triggered()) + { + $error = $db->sql_error($db->get_sql_error_sql()); + $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__); + } + + $categories[$level2_name]['id'] = (int) $module_data['module_id']; + $categories[$level2_name]['parent_id'] = (int) $categories[$cat_name]['id']; + } + } + } + + // Get the modules we want to add... returned sorted by name + $module_info = $_module->get_module_infos($module_class); + + foreach ($module_info as $module_basename => $fileinfo) + { + foreach ($fileinfo['modes'] as $module_mode => $row) + { + foreach ($row['cat'] as $cat_name) + { + if (!isset($categories[$cat_name])) + { + continue; + } + + $module_data = array( + 'module_basename' => $module_basename, + 'module_enabled' => 1, + 'module_display' => (isset($row['display'])) ? (int) $row['display'] : 1, + 'parent_id' => (int) $categories[$cat_name]['id'], + 'module_class' => $module_class, + 'module_langname' => $row['title'], + 'module_mode' => $module_mode, + 'module_auth' => $row['auth'], + ); + + $_module->update_module_data($module_data); + + // Check for last sql error happened + if ($db->get_sql_error_triggered()) + { + $error = $db->sql_error($db->get_sql_error_sql()); + $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__); + } + } + } + } + + // Move some of the modules around since the code above will put them in the wrong place + if ($module_class == 'acp') + { + // Move main module 4 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_main' + AND module_class = 'acp' + AND module_mode = 'main'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'acp', 'move_up', 4); + + // Move permissions intro screen module 4 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_permissions' + AND module_class = 'acp' + AND module_mode = 'intro'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'acp', 'move_up', 4); + + // Move manage users screen module 5 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'acp_users' + AND module_class = 'acp' + AND module_mode = 'overview'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'acp', 'move_up', 5); + + // Move extension management module 1 up... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_langname = 'ACP_EXTENSION_MANAGEMENT' + AND module_class = 'acp' + AND module_mode = '' + AND module_basename = ''"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'acp', 'move_up', 1); + } + + if ($module_class == 'mcp') + { + // Move pm report details module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_report_details'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'mcp', 'move_down', 3); + + // Move closed pm reports module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_reports_closed'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'mcp', 'move_down', 3); + + // Move open pm reports module 3 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'mcp_pm_reports' + AND module_class = 'mcp' + AND module_mode = 'pm_reports'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'mcp', 'move_down', 3); + } + + if ($module_class == 'ucp') + { + // Move attachment module 4 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_attachments' + AND module_class = 'ucp' + AND module_mode = 'attachments'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'ucp', 'move_down', 4); + + // Move notification options module 4 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_notifications' + AND module_class = 'ucp' + AND module_mode = 'notification_options'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'ucp', 'move_down', 4); + + // Move OAuth module 5 down... + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_basename = 'ucp_auth_link' + AND module_class = 'ucp' + AND module_mode = 'auth_link'"; + $result = $db->sql_query($sql); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $_module->move_module_by($row, 'ucp', 'move_down', 5); + } + + // And now for the special ones + // (these are modules which appear in multiple categories and thus get added manually to some for more control) + if (isset($this->module_extras[$module_class])) + { + foreach ($this->module_extras[$module_class] as $cat_name => $mods) + { + $sql = 'SELECT module_id, left_id, right_id + FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $db->sql_escape($cat_name) . "' + AND module_class = '" . $db->sql_escape($module_class) . "'"; + $result = $db->sql_query_limit($sql, 1); + $row2 = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + foreach ($mods as $mod_name) + { + $sql = 'SELECT * + FROM ' . MODULES_TABLE . " + WHERE module_langname = '" . $db->sql_escape($mod_name) . "' + AND module_class = '" . $db->sql_escape($module_class) . "' + AND module_basename <> ''"; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $module_data = array( + 'module_basename' => $row['module_basename'], + 'module_enabled' => (int) $row['module_enabled'], + 'module_display' => (int) $row['module_display'], + 'parent_id' => (int) $row2['module_id'], + 'module_class' => $row['module_class'], + 'module_langname' => $row['module_langname'], + 'module_mode' => $row['module_mode'], + 'module_auth' => $row['module_auth'], + ); + + $_module->update_module_data($module_data); + + // Check for last sql error happened + if ($db->get_sql_error_triggered()) + { + $error = $db->sql_error($db->get_sql_error_sql()); + $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__); + } + } + } + } + + $_module->remove_cache_file($module_class); + } + } + + /** + * Populate the language tables + */ + function add_language($mode, $sub) + { + global $db, $lang, $phpbb_root_path, $phpEx; + + $dir = @opendir($phpbb_root_path . 'language'); + + if (!$dir) + { + $this->error('Unable to access the language directory', __LINE__, __FILE__); + } + + $installed_languages = array(); + while (($file = readdir($dir)) !== false) + { + $path = $phpbb_root_path . 'language/' . $file; + + if ($file == '.' || $file == '..' || is_link($path) || is_file($path) || $file == 'CVS') + { + continue; + } + + if (is_dir($path) && file_exists($path . '/iso.txt')) + { + $lang_file = file("$path/iso.txt"); + + $lang_pack = array( + 'lang_iso' => basename($path), + 'lang_dir' => basename($path), + 'lang_english_name' => trim(htmlspecialchars($lang_file[0])), + 'lang_local_name' => trim(htmlspecialchars($lang_file[1], ENT_COMPAT, 'UTF-8')), + 'lang_author' => trim(htmlspecialchars($lang_file[2], ENT_COMPAT, 'UTF-8')), + ); + + $db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $db->sql_build_array('INSERT', $lang_pack)); + + $installed_languages[] = (int) $db->sql_nextid(); + if ($db->get_sql_error_triggered()) + { + $error = $db->sql_error($db->get_sql_error_sql()); + $this->p_master->db_error($error['message'], $db->get_sql_error_sql(), __LINE__, __FILE__); + } + } + } + closedir($dir); + + $sql = 'SELECT * + FROM ' . PROFILE_FIELDS_TABLE; + $result = $db->sql_query($sql); + + $profile_fields = array(); + $insert_buffer = new \phpbb\db\sql_insert_buffer($db, PROFILE_LANG_TABLE); + while ($row = $db->sql_fetchrow($result)) + { + foreach ($installed_languages as $lang_id) + { + $insert_buffer->insert(array( + 'field_id' => $row['field_id'], + 'lang_id' => $lang_id, + 'lang_name' => strtoupper(substr($row['field_name'], 6)),// Remove phpbb_ from field name + 'lang_explain' => '', + 'lang_default_value' => '', + )); + } + } + $db->sql_freeresult($result); + + $insert_buffer->flush(); + } + + /** + * Add search robots to the database + */ + function add_bots($mode, $sub) + { + global $db, $lang, $phpbb_root_path, $phpEx, $config; + + // Obtain any submitted data + $data = $this->get_submitted_data(); + + // 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); + + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = 'BOTS'"; + $result = $db->sql_query($sql); + $group_id = (int) $db->sql_fetchfield('group_id'); + $db->sql_freeresult($result); + + if (!$group_id) + { + // If we reach this point then something has gone very wrong + $this->p_master->error($lang['NO_GROUP'], __LINE__, __FILE__); + } + + if (!function_exists('user_add')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } + + foreach ($this->bot_list as $bot_name => $bot_ary) + { + $user_row = array( + 'user_type' => USER_IGNORE, + 'group_id' => $group_id, + 'username' => $bot_name, + 'user_regdate' => time(), + 'user_password' => '', + 'user_colour' => '9E8DA7', + 'user_email' => '', + 'user_lang' => $data['default_lang'], + 'user_style' => 1, + 'user_timezone' => 'UTC', + 'user_dateformat' => $lang['default_dateformat'], + 'user_allow_massemail' => 0, + 'user_allow_pm' => 0, + ); + + $user_id = user_add($user_row); + + if (!$user_id) + { + // If we can't insert this user then continue to the next one to avoid inconsistent data + $this->p_master->db_error('Unable to insert bot into users table', $db->get_sql_error_sql(), __LINE__, __FILE__, true); + continue; + } + + $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( + 'bot_active' => 1, + 'bot_name' => (string) $bot_name, + 'user_id' => (int) $user_id, + 'bot_agent' => (string) $bot_ary[0], + 'bot_ip' => (string) $bot_ary[1], + )); + + $db->sql_query($sql); + } + } + + /** + * Sends an email to the board administrator with their password and some useful links + */ + function email_admin($mode, $sub) + { + global $auth, $config, $db, $lang, $template, $user, $phpbb_root_path, $phpbb_admin_path, $phpEx, $phpbb_log; + + $this->page_title = $lang['STAGE_FINAL']; + + // Obtain any submitted data + $data = $this->get_submitted_data(); + + // 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); + + $user->session_begin(); + $auth->login($data['admin_name'], $data['admin_pass1'], false, true, true); + + // OK, Now that we've reached this point we can be confident that everything + // is installed and working......I hope :) + // So it's time to send an email to the administrator confirming the details + // they entered + + if ($config['email_enable']) + { + include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx); + + $messenger = new messenger(false); + + $messenger->template('installed', $data['language']); + + $messenger->to($data['board_email'], $data['admin_name']); + + $messenger->anti_abuse_headers($config, $user); + + $messenger->assign_vars(array( + 'USERNAME' => htmlspecialchars_decode($data['admin_name']), + 'PASSWORD' => htmlspecialchars_decode($data['admin_pass1'])) + ); + + $messenger->send(NOTIFY_EMAIL); + } + + // And finally, add a note to the log + $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_INSTALL_INSTALLED', false, array($config['version'])); + + $template->assign_vars(array( + 'TITLE' => $lang['INSTALL_CONGRATS'], + 'BODY' => sprintf($lang['INSTALL_CONGRATS_EXPLAIN'], $config['version'], append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=convert&language=' . $data['language']), '../docs/README.html'), + 'L_SUBMIT' => $lang['INSTALL_LOGIN'], + 'U_ACTION' => append_sid($phpbb_admin_path . 'index.' . $phpEx, 'i=send_statistics&mode=send_statistics'), + )); + } + + /** + * 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); + } + } + + /** + * Populate migrations for the installation + * + * This "installs" all migrations from (root path)/phpbb/db/migrations/data. + * "installs" means it adds all migrations to the migrations table, but does not + * perform any of the actions in the migrations. + * + * @param \phpbb\extension\manager $extension_manager + * @param \phpbb\db\migrator $migrator + */ + function populate_migrations($extension_manager, $migrator) + { + $finder = $extension_manager->get_finder(); + + $migrations = $finder + ->core_path('phpbb/db/migration/data/') + ->get_classes(); + $migrator->populate_migrations($migrations); + } + + /** + * Generate a list of available mail server authentication methods + */ + function mail_auth_select($selected_method) + { + global $lang; + + $auth_methods = array('PLAIN', 'LOGIN', 'CRAM-MD5', 'DIGEST-MD5', 'POP-BEFORE-SMTP'); + $s_smtp_auth_options = ''; + + foreach ($auth_methods as $method) + { + $s_smtp_auth_options .= ''; + } + + return $s_smtp_auth_options; + } + + /** + * Get submitted data + */ + function get_submitted_data() + { + global $request; + + return array( + 'language' => basename($request->variable('language', '')), + 'dbms' => $request->variable('dbms', ''), + 'dbhost' => $request->variable('dbhost', ''), + 'dbport' => $request->variable('dbport', ''), + 'dbuser' => $request->variable('dbuser', ''), + 'dbpasswd' => $request->variable('dbpasswd', '', true), + 'dbname' => $request->variable('dbname', ''), + 'table_prefix' => $request->variable('table_prefix', ''), + 'default_lang' => basename($request->variable('default_lang', '')), + 'admin_name' => $request->variable('admin_name', '', true), + 'admin_pass1' => $request->variable('admin_pass1', '', true), + 'admin_pass2' => $request->variable('admin_pass2', '', true), + 'board_email' => strtolower($request->variable('board_email', '')), + 'img_imagick' => $request->variable('img_imagick', ''), + 'ftp_path' => $request->variable('ftp_path', ''), + 'ftp_user' => $request->variable('ftp_user', ''), + 'ftp_pass' => $request->variable('ftp_pass', ''), + 'email_enable' => $request->variable('email_enable', ''), + 'smtp_delivery' => $request->variable('smtp_delivery', ''), + 'smtp_host' => $request->variable('smtp_host', ''), + 'smtp_auth' => $request->variable('smtp_auth', ''), + 'smtp_user' => $request->variable('smtp_user', ''), + 'smtp_pass' => $request->variable('smtp_pass', ''), + 'cookie_secure' => $request->variable('cookie_secure', ''), + 'force_server_vars' => $request->variable('force_server_vars', ''), + 'server_protocol' => $request->variable('server_protocol', ''), + 'server_name' => $request->variable('server_name', ''), + 'server_port' => $request->variable('server_port', ''), + 'script_path' => $request->variable('script_path', ''), + ); + } + + /** + * The information below will be used to build the input fields presented to the user + */ + var $db_config_options = array( + 'legend1' => 'DB_CONFIG', + 'dbms' => array('lang' => 'DBMS', 'type' => 'select', 'options' => 'dbms_select(\'{VALUE}\')', 'explain' => false), + 'dbhost' => array('lang' => 'DB_HOST', 'type' => 'text:25:100', 'explain' => true), + 'dbport' => array('lang' => 'DB_PORT', 'type' => 'text:25:100', 'explain' => true), + 'dbname' => array('lang' => 'DB_NAME', 'type' => 'text:25:100', 'explain' => false), + 'dbuser' => array('lang' => 'DB_USERNAME', 'type' => 'text:25:100', 'explain' => false), + 'dbpasswd' => array('lang' => 'DB_PASSWORD', 'type' => 'password:25:100', 'explain' => false), + 'table_prefix' => array('lang' => 'TABLE_PREFIX', 'type' => 'text:25:100', 'explain' => true), + ); + var $admin_config_options = array( + 'legend1' => 'ADMIN_CONFIG', + 'default_lang' => array('lang' => 'DEFAULT_LANG', 'type' => 'select', 'options' => '$this->module->inst_language_select(\'{VALUE}\')', 'explain' => false), + 'admin_name' => array('lang' => 'ADMIN_USERNAME', 'type' => 'text:25:100', 'explain' => true), + 'admin_pass1' => array('lang' => 'ADMIN_PASSWORD', 'type' => 'password:25:100', 'explain' => true), + 'admin_pass2' => array('lang' => 'ADMIN_PASSWORD_CONFIRM', 'type' => 'password:25:100', 'explain' => false), + 'board_email' => array('lang' => 'CONTACT_EMAIL', 'type' => 'email:25:100', 'explain' => false), + ); + var $advanced_config_options = array( + 'legend1' => 'ACP_EMAIL_SETTINGS', + 'email_enable' => array('lang' => 'ENABLE_EMAIL', 'type' => 'radio:enabled_disabled', 'explain' => true), + 'smtp_delivery' => array('lang' => 'USE_SMTP', 'type' => 'radio:yes_no', 'explain' => true), + 'smtp_host' => array('lang' => 'SMTP_SERVER', 'type' => 'text:25:50', 'explain' => false), + 'smtp_auth' => array('lang' => 'SMTP_AUTH_METHOD', 'type' => 'select', 'options' => '$this->module->mail_auth_select(\'{VALUE}\')', 'explain' => true), + 'smtp_user' => array('lang' => 'SMTP_USERNAME', 'type' => 'text:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')), + 'smtp_pass' => array('lang' => 'SMTP_PASSWORD', 'type' => 'password:25:255', 'explain' => true, 'options' => array('autocomplete' => 'off')), + + 'legend2' => 'SERVER_URL_SETTINGS', + 'cookie_secure' => array('lang' => 'COOKIE_SECURE', 'type' => 'radio:enabled_disabled', 'explain' => true), + 'force_server_vars' => array('lang' => 'FORCE_SERVER_VARS', 'type' => 'radio:yes_no', 'explain' => true), + 'server_protocol' => array('lang' => 'SERVER_PROTOCOL', 'type' => 'text:10:10', 'explain' => true), + 'server_name' => array('lang' => 'SERVER_NAME', 'type' => 'text:40:255', 'explain' => true), + 'server_port' => array('lang' => 'SERVER_PORT', 'type' => 'text:5:5', 'explain' => true), + 'script_path' => array('lang' => 'SCRIPT_PATH', 'type' => 'text::255', 'explain' => true), + ); + + /** + * Specific PHP modules we may require for certain optional or extended features + */ + var $php_dlls_other = array('zlib', 'ftp', 'gd', 'xml'); + + /** + * A list of the web-crawlers/bots we recognise by default + * + * Candidates but not included: + * 'Accoona [Bot]' 'Accoona-AI-Agent/' + * 'ASPseek [Crawler]' 'ASPseek/' + * 'Boitho [Crawler]' 'boitho.com-dc/' + * 'Bunnybot [Bot]' 'powered by www.buncat.de' + * 'Cosmix [Bot]' 'cfetch/' + * 'Crawler Search [Crawler]' '.Crawler-Search.de' + * 'Findexa [Crawler]' 'Findexa Crawler (' + * 'GBSpider [Spider]' 'GBSpider v' + * 'genie [Bot]' 'genieBot (' + * 'Hogsearch [Bot]' 'oegp v. 1.3.0' + * 'Insuranco [Bot]' 'InsurancoBot' + * 'IRLbot [Bot]' 'http://irl.cs.tamu.edu/crawler' + * 'ISC Systems [Bot]' 'ISC Systems iRc Search' + * 'Jyxobot [Bot]' 'Jyxobot/' + * 'Kraehe [Metasuche]' '-DIE-KRAEHE- META-SEARCH-ENGINE/' + * 'LinkWalker' 'LinkWalker' + * 'MMSBot [Bot]' 'http://www.mmsweb.at/bot.html' + * 'Naver [Bot]' 'nhnbot@naver.com)' + * 'NetResearchServer' 'NetResearchServer/' + * 'Nimble [Crawler]' 'NimbleCrawler' + * 'Ocelli [Bot]' 'Ocelli/' + * 'Onsearch [Bot]' 'onCHECK-Robot' + * 'Orange [Spider]' 'OrangeSpider' + * 'Sproose [Bot]' 'http://www.sproose.com/bot' + * 'Susie [Sync]' '!Susie (http://www.sync2it.com/susie)' + * 'Tbot [Bot]' 'Tbot/' + * 'Thumbshots [Capture]' 'thumbshots-de-Bot' + * 'Vagabondo [Crawler]' 'http://webagent.wise-guys.nl/' + * 'Walhello [Bot]' 'appie 1.1 (www.walhello.com)' + * 'WissenOnline [Bot]' 'WissenOnline-Bot' + * 'WWWeasel [Bot]' 'WWWeasel Robot v' + * 'Xaldon [Spider]' 'Xaldon WebSpider' + */ + var $bot_list = array( + 'AdsBot [Google]' => array('AdsBot-Google', ''), + 'Alexa [Bot]' => array('ia_archiver', ''), + 'Alta Vista [Bot]' => array('Scooter/', ''), + 'Ask Jeeves [Bot]' => array('Ask Jeeves', ''), + 'Baidu [Spider]' => array('Baiduspider', ''), + 'Bing [Bot]' => array('bingbot/', ''), + 'Exabot [Bot]' => array('Exabot', ''), + 'FAST Enterprise [Crawler]' => array('FAST Enterprise Crawler', ''), + 'FAST WebCrawler [Crawler]' => array('FAST-WebCrawler/', ''), + 'Francis [Bot]' => array('http://www.neomo.de/', ''), + 'Gigabot [Bot]' => array('Gigabot/', ''), + 'Google Adsense [Bot]' => array('Mediapartners-Google', ''), + 'Google Desktop' => array('Google Desktop', ''), + 'Google Feedfetcher' => array('Feedfetcher-Google', ''), + 'Google [Bot]' => array('Googlebot', ''), + 'Heise IT-Markt [Crawler]' => array('heise-IT-Markt-Crawler', ''), + 'Heritrix [Crawler]' => array('heritrix/1.', ''), + 'IBM Research [Bot]' => array('ibm.com/cs/crawler', ''), + 'ICCrawler - ICjobs' => array('ICCrawler - ICjobs', ''), + 'ichiro [Crawler]' => array('ichiro/', ''), + 'Majestic-12 [Bot]' => array('MJ12bot/', ''), + 'Metager [Bot]' => array('MetagerBot/', ''), + 'MSN NewsBlogs' => array('msnbot-NewsBlogs/', ''), + 'MSN [Bot]' => array('msnbot/', ''), + 'MSNbot Media' => array('msnbot-media/', ''), + 'Nutch [Bot]' => array('http://lucene.apache.org/nutch/', ''), + 'Online link [Validator]' => array('online link validator', ''), + 'psbot [Picsearch]' => array('psbot/0', ''), + 'Sensis [Crawler]' => array('Sensis Web Crawler', ''), + 'SEO Crawler' => array('SEO search Crawler/', ''), + 'Seoma [Crawler]' => array('Seoma [SEO Crawler]', ''), + 'SEOSearch [Crawler]' => array('SEOsearch/', ''), + 'Snappy [Bot]' => array('Snappy/1.1 ( http://www.urltrends.com/ )', ''), + 'Steeler [Crawler]' => array('http://www.tkl.iis.u-tokyo.ac.jp/~crawler/', ''), + 'Telekom [Bot]' => array('crawleradmin.t-info@telekom.de', ''), + 'TurnitinBot [Bot]' => array('TurnitinBot/', ''), + 'Voyager [Bot]' => array('voyager/', ''), + 'W3 [Sitesearch]' => array('W3 SiteSearch Crawler', ''), + 'W3C [Linkcheck]' => array('W3C-checklink/', ''), + 'W3C [Validator]' => array('W3C_Validator', ''), + 'YaCy [Bot]' => array('yacybot', ''), + 'Yahoo MMCrawler [Bot]' => array('Yahoo-MMCrawler/', ''), + 'Yahoo Slurp [Bot]' => array('Yahoo! DE Slurp', ''), + 'Yahoo [Bot]' => array('Yahoo! Slurp', ''), + 'YahooSeeker [Bot]' => array('YahooSeeker/', ''), + ); + + /** + * Define the module structure so that we can populate the database without + * needing to hard-code module_id values + */ + var $module_categories = array( + 'acp' => array( + 'ACP_CAT_GENERAL' => array( + 'ACP_QUICK_ACCESS', + 'ACP_BOARD_CONFIGURATION', + 'ACP_CLIENT_COMMUNICATION', + 'ACP_SERVER_CONFIGURATION', + ), + 'ACP_CAT_FORUMS' => array( + 'ACP_MANAGE_FORUMS', + 'ACP_FORUM_BASED_PERMISSIONS', + ), + 'ACP_CAT_POSTING' => array( + 'ACP_MESSAGES', + 'ACP_ATTACHMENTS', + ), + 'ACP_CAT_USERGROUP' => array( + 'ACP_CAT_USERS', + 'ACP_GROUPS', + 'ACP_USER_SECURITY', + ), + 'ACP_CAT_PERMISSIONS' => array( + 'ACP_GLOBAL_PERMISSIONS', + 'ACP_FORUM_BASED_PERMISSIONS', + 'ACP_PERMISSION_ROLES', + 'ACP_PERMISSION_MASKS', + ), + 'ACP_CAT_CUSTOMISE' => array( + 'ACP_STYLE_MANAGEMENT', + 'ACP_EXTENSION_MANAGEMENT', + 'ACP_LANGUAGE', + ), + 'ACP_CAT_MAINTENANCE' => array( + 'ACP_FORUM_LOGS', + 'ACP_CAT_DATABASE', + ), + 'ACP_CAT_SYSTEM' => array( + 'ACP_AUTOMATION', + 'ACP_GENERAL_TASKS', + 'ACP_MODULE_MANAGEMENT', + ), + 'ACP_CAT_DOT_MODS' => null, + ), + 'mcp' => array( + 'MCP_MAIN' => null, + 'MCP_QUEUE' => null, + 'MCP_REPORTS' => null, + 'MCP_NOTES' => null, + 'MCP_WARN' => null, + 'MCP_LOGS' => null, + 'MCP_BAN' => null, + ), + 'ucp' => array( + 'UCP_MAIN' => null, + 'UCP_PROFILE' => null, + 'UCP_PREFS' => null, + 'UCP_PM' => null, + 'UCP_USERGROUPS' => null, + 'UCP_ZEBRA' => null, + ), + ); + var $module_categories_basenames = array( + 'UCP_PM' => 'ucp_pm', + ); + + var $module_extras = array( + 'acp' => array( + 'ACP_QUICK_ACCESS' => array( + 'ACP_MANAGE_USERS', + 'ACP_GROUPS_MANAGE', + 'ACP_MANAGE_FORUMS', + 'ACP_MOD_LOGS', + 'ACP_BOTS', + 'ACP_PHP_INFO', + ), + 'ACP_FORUM_BASED_PERMISSIONS' => array( + 'ACP_FORUM_PERMISSIONS', + 'ACP_FORUM_PERMISSIONS_COPY', + 'ACP_FORUM_MODERATORS', + 'ACP_USERS_FORUM_PERMISSIONS', + 'ACP_GROUPS_FORUM_PERMISSIONS', + ), + ), + ); +} diff --git a/phpBB/install/install_main.php b/phpBB/install/install_main.php new file mode 100644 index 0000000000..d5874dac83 --- /dev/null +++ b/phpBB/install/install_main.php @@ -0,0 +1,78 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +*/ + +if ( !defined('IN_INSTALL') ) +{ + // Someone has tried to access the file direct. This is not a good idea, so exit + exit; +} + +if (!empty($setmodules)) +{ + $module[] = array( + 'module_type' => 'install', + 'module_title' => 'OVERVIEW', + 'module_filename' => substr(basename(__FILE__), 0, -strlen($phpEx)-1), + 'module_order' => 0, + 'module_subs' => array('INTRO', 'LICENSE', 'SUPPORT'), + 'module_stages' => '', + 'module_reqs' => '' + ); +} + +/** +* Main Tab - Installation +*/ +class install_main extends module +{ + function install_main(&$p_master) + { + $this->p_master = &$p_master; + } + + function main($mode, $sub) + { + global $lang, $template, $language; + + switch ($sub) + { + case 'intro' : + $title = $lang['SUB_INTRO']; + $body = $lang['OVERVIEW_BODY']; + break; + + case 'license' : + $title = $lang['GPL']; + $body = implode("
\n", file(__DIR__ . '/../docs/LICENSE.txt')); + break; + + case 'support' : + $title = $lang['SUB_SUPPORT']; + $body = $lang['SUPPORT_BODY']; + break; + } + + $this->tpl_name = 'install_main'; + $this->page_title = $title; + + $template->assign_vars(array( + 'TITLE' => $title, + 'BODY' => $body, + + 'S_LANG_SELECT' => '', + )); + } +} diff --git a/phpBB/install/install_update.php b/phpBB/install/install_update.php new file mode 100644 index 0000000000..d9ba2e7fe9 --- /dev/null +++ b/phpBB/install/install_update.php @@ -0,0 +1,1790 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +/** +* @todo check for writable cache/store/files directory +*/ + +if (!defined('IN_INSTALL')) +{ + // Someone has tried to access the file directly. This is not a good idea, so exit + exit; +} + +if (!empty($setmodules)) +{ + // If phpBB is not installed we do not include this module + if (!phpbb_check_installation_exists($phpbb_root_path, $phpEx) || file_exists($phpbb_root_path . 'cache/install_lock')) + { + return; + } + + $module[] = array( + 'module_type' => 'update', + 'module_title' => 'UPDATE', + 'module_filename' => substr(basename(__FILE__), 0, -strlen($phpEx)-1), + 'module_order' => 30, + 'module_subs' => '', + 'module_stages' => array('INTRO', 'VERSION_CHECK', 'FILE_CHECK', 'UPDATE_FILES', 'UPDATE_DB'), + 'module_reqs' => '' + ); +} + +/** +* Update Installation +*/ +class install_update extends module +{ + var $p_master; + var $update_info; + + var $old_location; + var $new_location; + var $latest_version; + var $current_version; + + var $update_to_version; + + protected $filesystem; + + // Set to false + var $test_update = false; + + function install_update(&$p_master) + { + $this->p_master = &$p_master; + } + + function main($mode, $sub) + { + global $template, $phpEx, $phpbb_root_path, $user, $db, $config, $cache, $auth, $language; + global $request, $phpbb_admin_path, $phpbb_adm_relative_path, $phpbb_container, $phpbb_config_php_file; + + // We must enable super globals, otherwise creating a new instance of the request class, + // using the new container with a dbal connection will fail with the following PHP Notice: + // Object of class phpbb_request_deactivated_super_global could not be converted to int + $request->enable_super_globals(); + + // Create a normal container now + $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); + $phpbb_container = $phpbb_container_builder + ->with_config($phpbb_config_php_file) + ->without_cache() + ->without_extensions() + ; + + if (file_exists($phpbb_root_path . 'install/update/new/config')) + { + $phpbb_container_builder->with_config_path($phpbb_root_path . 'install/update/new/config'); + } + $phpbb_container = $phpbb_container_builder->get_container(); + + // Writes into global $cache + /* @var $cache \phpbb\cache\service */ + $cache = $phpbb_container->get('cache'); + + $this->filesystem = $phpbb_container->get('filesystem'); + + $this->tpl_name = 'install_update'; + $this->page_title = 'UPDATE_INSTALLATION'; + + $this->old_location = $phpbb_root_path . 'install/update/old/'; + $this->new_location = $phpbb_root_path . 'install/update/new/'; + + // Init DB + extract($phpbb_config_php_file->get_all()); + require($phpbb_root_path . 'includes/constants.' . $phpEx); + + // Special options for conflicts/modified files + define('MERGE_NO_MERGE_NEW', 1); + define('MERGE_NO_MERGE_MOD', 2); + define('MERGE_NEW_FILE', 3); + define('MERGE_MOD_FILE', 4); + + $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms); + + $db = new $dbms(); + + // Connect to DB + $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false); + + // We do not need this any longer, unset for safety purposes + 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); + + // Force template recompile + $config['load_tplcompile'] = 1; + + // First of all, init the user session + $user->session_begin(); + $auth->acl($user->data); + + // Overwrite user's language with the selected one. + // Config needs to be changed to ensure that guests also get the selected language. + $config_default_lang = $config['default_lang']; + $config['default_lang'] = $language; + $user->data['user_lang'] = $language; + + $user->add_lang(array('common', 'acp/common', 'acp/board', 'install', 'posting')); + + // Reset the default_lang + $config['default_lang'] = $config_default_lang; + unset($config_default_lang); + + // If we are within the intro page we need to make sure we get up-to-date version info + if ($sub == 'intro') + { + $cache->destroy('_version_info'); + } + + // Set custom template again. ;) + $paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style'); + $paths = array_filter($paths, 'is_dir'); + $template->set_custom_style(array( + array( + 'name' => 'adm', + 'ext_path' => 'adm/style/', + ), + ), $paths); + + $template->assign_vars(array( + 'S_USER_LANG' => $user->lang['USER_LANG'], + 'S_CONTENT_DIRECTION' => $user->lang['DIRECTION'], + 'S_CONTENT_ENCODING' => 'UTF-8', + 'S_CONTENT_FLOW_BEGIN' => ($user->lang['DIRECTION'] == 'ltr') ? 'left' : 'right', + 'S_CONTENT_FLOW_END' => ($user->lang['DIRECTION'] == 'ltr') ? 'right' : 'left', + )); + + // Get current and latest version + /* @var $version_helper \phpbb\version_helper */ + $version_helper = $phpbb_container->get('version_helper'); + try + { + $this->latest_version = $version_helper->get_latest_on_current_branch(true); + } + catch (\RuntimeException $e) + { + $this->latest_version = false; + + $update_info = array(); + include($phpbb_root_path . 'install/update/index.' . $phpEx); + $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info; + + if ($info !== false) + { + $this->latest_version = (!empty($info['version']['to'])) ? trim($info['version']['to']) : false; + } + } + + // For the current version we trick a bit. ;) + $this->current_version = (!empty($config['version_update_from'])) ? $config['version_update_from'] : $config['version']; + + $up_to_date = (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->latest_version)), '<')) ? false : true; + + // Check for a valid update directory, else point the user to the phpbb.com website + if (!file_exists($phpbb_root_path . 'install/update') || !file_exists($phpbb_root_path . 'install/update/index.' . $phpEx) || !file_exists($this->old_location) || !file_exists($this->new_location)) + { + $template->assign_vars(array( + 'S_ERROR' => true, + 'ERROR_MSG' => ($up_to_date) ? $user->lang['NO_UPDATE_FILES_UP_TO_DATE'] : sprintf($user->lang['NO_UPDATE_FILES_OUTDATED'], $config['version'], $this->current_version, $this->latest_version)) + ); + + return; + } + + $this->update_info = $this->get_file('update_info'); + + // Make sure the update directory holds the correct information + // Since admins are able to run the update/checks more than once we only check if the current version is lower or equal than the version to which we update to. + if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '>')) + { + $template->assign_vars(array( + 'S_ERROR' => true, + 'ERROR_MSG' => sprintf($user->lang['INCOMPATIBLE_UPDATE_FILES'], $config['version'], $this->update_info['version']['from'], $this->update_info['version']['to'])) + ); + + return; + } + + // Check if the update files are actually meant to update from the current version + if ($this->current_version != $this->update_info['version']['from']) + { + $template->assign_vars(array( + 'S_ERROR' => true, + 'ERROR_MSG' => sprintf($user->lang['INCOMPATIBLE_UPDATE_FILES'], $this->current_version, $this->update_info['version']['from'], $this->update_info['version']['to']), + )); + } + + // Check if the update files stored are for the latest version... + if (version_compare(strtolower($this->latest_version), strtolower($this->update_info['version']['to']), '>')) + { + $template->assign_vars(array( + 'S_WARNING' => true, + 'WARNING_MSG' => sprintf($user->lang['OLD_UPDATE_FILES'], $this->update_info['version']['from'], $this->update_info['version']['to'], $this->latest_version)) + ); + } + + // We store the "update to" version, because it is not always the latest. ;) + $this->update_to_version = $this->update_info['version']['to']; + + // Fill DB version + if (empty($config['dbms_version'])) + { + $config->set('dbms_version', $db->sql_server_info(true)); + } + + if ($this->test_update === false) + { + // What about the language file? Got it updated? + if (in_array('language/' . $language . '/install.' . $phpEx, $this->update_info['files'])) + { + $lang = array(); + include($this->new_location . 'language/' . $language . '/install.' . $phpEx); + // this is the user's language.. just merge it + $user->lang = array_merge($user->lang, $lang); + } + if ($language != 'en' && in_array('language/en/install.' . $phpEx, $this->update_info['files'])) + { + $lang = array(); + include($this->new_location . 'language/en/install.' . $phpEx); + // only add new keys to user's language in english + $new_keys = array_diff(array_keys($lang), array_keys($user->lang)); + foreach ($new_keys as $i => $new_key) + { + $user->lang[$new_key] = $lang[$new_key]; + } + } + } + + // Include renderer and engine + $this->include_file('includes/diff/diff.' . $phpEx); + $this->include_file('includes/diff/engine.' . $phpEx); + $this->include_file('includes/diff/renderer.' . $phpEx); + + // Make sure we stay at the file check if checking the files again + if ($request->variable('check_again', false, false, \phpbb\request\request_interface::POST)) + { + $sub = $this->p_master->sub = 'file_check'; + } + + switch ($sub) + { + case 'intro': + $this->page_title = 'UPDATE_INSTALLATION'; + + $template->assign_vars(array( + 'S_INTRO' => true, + 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=version_check"), + )); + + // Make sure the update list is destroyed. + $cache->destroy('_update_list'); + $cache->destroy('_diff_files'); + $cache->destroy('_expected_files'); + break; + + case 'version_check': + $this->page_title = 'STAGE_VERSION_CHECK'; + + $template->assign_vars(array( + 'S_VERSION_CHECK' => true, + + 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check"), + + 'S_UP_TO_DATE' => $up_to_date, + 'LATEST_VERSION' => $this->latest_version, + 'CURRENT_VERSION' => $this->current_version, + )); + + // Print out version the update package updates to + if ($this->latest_version != $this->update_info['version']['to']) + { + $template->assign_var('PACKAGE_VERSION', $this->update_info['version']['to']); + } + + // Since some people try to update to RC releases, but phpBB.com tells them the last version is the version they currently run + // we are faced with the updater thinking the database schema is up-to-date; which it is, but should be updated none-the-less + // We now try to cope with this by triggering the update process + if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '<')) + { + $template->assign_vars(array( + 'S_UP_TO_DATE' => false, + )); + } + + break; + + case 'update_db': + // Redirect the user to the database update script with some explanations... + $template->assign_vars(array( + 'S_DB_UPDATE' => true, + 'S_DB_UPDATE_FINISHED' => ($config['version'] == $this->update_info['version']['to']) ? true : false, + 'U_DB_UPDATE' => append_sid($phpbb_root_path . 'install/database_update.' . $phpEx, 'type=1&language=' . $user->data['user_lang']), + 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_db"), + 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check"), + 'L_EVERYTHING_UP_TO_DATE' => $user->lang('EVERYTHING_UP_TO_DATE', append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'), append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login&redirect=' . $phpbb_adm_relative_path . 'index.php%3Fi=send_statistics%26mode=send_statistics')), + )); + + // Do not display incompatible package note after successful update + if ($config['version'] == $this->update_info['version']['to']) + { + $template->assign_var('S_ERROR', false); + } + break; + + case 'file_check': + + // retrieve info on what changes should have already been made to the files. + $expected_files = $cache->get('_expected_files'); + if (!$expected_files) + { + $expected_files = array(); + } + + // Now make sure the previous file collection is no longer valid... + $cache->destroy('_diff_files'); + + $this->page_title = 'STAGE_FILE_CHECK'; + + // Now make sure our update list is correct if the admin refreshes + $action = $request->variable('action', ''); + + // We are directly within an update. To make sure our update list is correct we check its status. + $update_list = ($request->variable('check_again', false, false, \phpbb\request\request_interface::POST)) ? false : $cache->get('_update_list'); + $modified = ($update_list !== false) ? @filemtime($cache->get_driver()->cache_dir . 'data_update_list.' . $phpEx) : 0; + + // Make sure the list is up-to-date + if ($update_list !== false) + { + $get_new_list = false; + foreach ($this->update_info['files'] as $file) + { + if (file_exists($phpbb_root_path . $file) && filemtime($phpbb_root_path . $file) > $modified) + { + $get_new_list = true; + break; + } + } + } + else + { + $get_new_list = true; + } + + if (!$get_new_list && $update_list['status'] != -1) + { + $get_new_list = true; + } + + if ($get_new_list) + { + $this->get_update_structure($update_list, $expected_files); + $cache->put('_update_list', $update_list); + + // Refresh the page if we are still not finished... + if ($update_list['status'] != -1) + { + $refresh_url = append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check"); + meta_refresh(2, $refresh_url); + + $template->assign_vars(array( + 'S_IN_PROGRESS' => true, + 'S_COLLECTED' => (int) $update_list['status'], + 'S_TO_COLLECT' => sizeof($this->update_info['files']), + 'L_IN_PROGRESS' => $user->lang['COLLECTING_FILE_DIFFS'], + 'L_IN_PROGRESS_EXPLAIN' => sprintf($user->lang['NUMBER_OF_FILES_COLLECTED'], (int) $update_list['status'], sizeof($this->update_info['files']) + sizeof($this->update_info['deleted'])), + )); + + return; + } + } + + if ($action == 'diff') + { + $this->show_diff($update_list); + return; + } + + if (sizeof($update_list['no_update'])) + { + $template->assign_vars(array( + 'S_NO_UPDATE_FILES' => true, + 'NO_UPDATE_FILES' => implode(', ', array_map('htmlspecialchars', $update_list['no_update']))) + ); + } + + $new_expected_files = array(); + + // Now assign the list to the template + foreach ($update_list as $status => $filelist) + { + if ($status == 'no_update' || !sizeof($filelist) || $status == 'status' || $status == 'status_deleted') + { + continue; + } + +/* $template->assign_block_vars('files', array( + 'S_STATUS' => true, + 'STATUS' => $status, + 'L_STATUS' => $user->lang['STATUS_' . strtoupper($status)], + 'TITLE' => $user->lang['FILES_' . strtoupper($status)], + 'EXPLAIN' => $user->lang['FILES_' . strtoupper($status) . '_EXPLAIN'], + ) + );*/ + + foreach ($filelist as $file_struct) + { + $s_binary = (!empty($this->update_info['binary']) && in_array($file_struct['filename'], $this->update_info['binary'])) ? true : false; + + $filename = htmlspecialchars($file_struct['filename']); + if (strrpos($filename, '/') !== false) + { + $dir_part = substr($filename, 0, strrpos($filename, '/') + 1); + $file_part = substr($filename, strrpos($filename, '/') + 1); + } + else + { + $dir_part = ''; + $file_part = $filename; + } + + $diff_url = append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check&action=diff&status=$status&file=" . urlencode($file_struct['filename'])); + + if (isset($file_struct['as_expected']) && $file_struct['as_expected']) + { + $new_expected_files[$file_struct['filename']] = $expected_files[$file_struct['filename']]; + } + else + { + $template->assign_block_vars($status, array( + 'STATUS' => $status, + + 'FILENAME' => $filename, + 'DIR_PART' => $dir_part, + 'FILE_PART' => $file_part, + 'NUM_CONFLICTS' => (isset($file_struct['conflicts'])) ? $file_struct['conflicts'] : 0, + + 'S_CUSTOM' => ($file_struct['custom']) ? true : false, + 'S_BINARY' => $s_binary, + 'CUSTOM_ORIGINAL' => ($file_struct['custom']) ? $file_struct['original'] : '', + + 'U_SHOW_DIFF' => $diff_url, + 'L_SHOW_DIFF' => ($status != 'up_to_date') ? $user->lang['SHOW_DIFF_' . strtoupper($status)] : '', + + 'U_VIEW_MOD_FILE' => $diff_url . '&op=' . MERGE_MOD_FILE, + 'U_VIEW_NEW_FILE' => $diff_url . '&op=' . MERGE_NEW_FILE, + 'U_VIEW_NO_MERGE_MOD' => $diff_url . '&op=' . MERGE_NO_MERGE_MOD, + 'U_VIEW_NO_MERGE_NEW' => $diff_url . '&op=' . MERGE_NO_MERGE_NEW, + )); + } + } + } + + $cache->put('_expected_files', $new_expected_files); + + $all_up_to_date = true; + foreach ($update_list as $status => $filelist) + { + if ($status != 'up_to_date' && $status != 'custom' && $status != 'status' && $status != 'status_deleted' && sizeof($filelist)) + { + $all_up_to_date = false; + break; + } + } + + $template->assign_vars(array( + 'S_FILE_CHECK' => true, + 'S_ALL_UP_TO_DATE' => $all_up_to_date, + 'S_VERSION_UP_TO_DATE' => $up_to_date, + 'S_UP_TO_DATE' => $up_to_date, + 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check"), + 'U_UPDATE_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files"), + 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_db"), + )); + + // Since some people try to update to RC releases, but phpBB.com tells them the last version is the version they currently run + // we are faced with the updater thinking the database schema is up-to-date; which it is, but should be updated none-the-less + // We now try to cope with this by triggering the update process + if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '<')) + { + $template->assign_vars(array( + 'S_UP_TO_DATE' => false, + )); + } + + if ($all_up_to_date) + { + global $phpbb_container; + + /* @var $phpbb_log \phpbb\log\log_interface */ + $phpbb_log = $phpbb_container->get('log'); + + // Add database update to log + $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_UPDATE_PHPBB', time(), array($this->current_version, $this->update_to_version)); + + $db->sql_return_on_error(true); + $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'"); + $db->sql_return_on_error(false); + + $cache->purge(); + } + + break; + + case 'update_files': + + $this->page_title = 'STAGE_UPDATE_FILES'; + + $s_hidden_fields = ''; + $params = array(); + $conflicts = $request->variable('conflict', array('' => 0)); + $modified = $request->variable('modified', array('' => 0)); + + foreach ($conflicts as $filename => $merge_option) + { + $s_hidden_fields .= ''; + $params[] = 'conflict[' . urlencode($filename) . ']=' . urlencode($merge_option); + } + + foreach ($modified as $filename => $merge_option) + { + if (!$merge_option) + { + continue; + } + $s_hidden_fields .= ''; + $params[] = 'modified[' . urlencode($filename) . ']=' . urlencode($merge_option); + } + + $no_update = $request->variable('no_update', array(0 => '')); + + foreach ($no_update as $index => $filename) + { + $s_hidden_fields .= ''; + $params[] = 'no_update[]=' . urlencode($filename); + } + + // Before the user is choosing his preferred method, let's create the content list... + $update_list = $cache->get('_update_list'); + + if ($update_list === false) + { + trigger_error($user->lang['NO_UPDATE_INFO'], E_USER_ERROR); + } + + // Check if the conflicts data is valid + if (sizeof($conflicts)) + { + $conflict_filenames = array(); + foreach ($update_list['conflict'] as $files) + { + $conflict_filenames[] = $files['filename']; + } + + $new_conflicts = array(); + foreach ($conflicts as $filename => $diff_method) + { + if (in_array($filename, $conflict_filenames)) + { + $new_conflicts[$filename] = $diff_method; + } + } + + $conflicts = $new_conflicts; + } + + // Build list for modifications + if (sizeof($modified)) + { + $modified_filenames = array(); + foreach ($update_list['modified'] as $files) + { + $modified_filenames[] = $files['filename']; + } + + $new_modified = array(); + foreach ($modified as $filename => $diff_method) + { + if (in_array($filename, $modified_filenames)) + { + $new_modified[$filename] = $diff_method; + } + } + + $modified = $new_modified; + } + + // Check number of conflicting files, they need to be equal. For modified files the number can differ + if (sizeof($update_list['conflict']) != sizeof($conflicts)) + { + trigger_error($user->lang['MERGE_SELECT_ERROR'], E_USER_ERROR); + } + + // Before we do anything, let us diff the files and store the raw file information "somewhere" + $get_files = false; + $file_list = $cache->get('_diff_files'); + $expected_files = $cache->get('_expected_files'); + + if ($file_list === false || $file_list['status'] != -1) + { + $get_files = true; + } + + if ($get_files) + { + if ($file_list === false) + { + $file_list = array( + 'status' => 0, + ); + } + + if (!isset($expected_files) || $expected_files === false) + { + $expected_files = array(); + } + + $processed = 0; + foreach ($update_list as $status => $files) + { + if (!is_array($files)) + { + continue; + } + + foreach ($files as $file_struct) + { + // Skip this file if the user selected to not update it + if (in_array($file_struct['filename'], $no_update)) + { + $expected_files[$file_struct['filename']] = false; + continue; + } + + // Already handled... then skip of course... + if (isset($file_list[$file_struct['filename']])) + { + continue; + } + + // Refresh if we reach 5 diffs... + if ($processed >= 5) + { + $cache->put('_diff_files', $file_list); + + if ($request->variable('download', false)) + { + $params[] = 'download=1'; + } + + $redirect_url = append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files&" . implode('&', $params)); + meta_refresh(3, $redirect_url); + + $template->assign_vars(array( + 'S_IN_PROGRESS' => true, + 'L_IN_PROGRESS' => $user->lang['MERGING_FILES'], + 'L_IN_PROGRESS_EXPLAIN' => $user->lang['MERGING_FILES_EXPLAIN'], + )); + + return; + } + + if (file_exists($phpbb_root_path . $file_struct['filename'])) + { + $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); + if (isset($expected_files[$file_struct['filename']]) && md5($contents) == $expected_files[$file_struct['filename']]) + { + continue; + } + } + + $original_filename = ($file_struct['custom']) ? $file_struct['original'] : $file_struct['filename']; + + switch ($status) + { + case 'modified': + + $option = (isset($modified[$file_struct['filename']])) ? $modified[$file_struct['filename']] : 0; + + switch ($option) + { + case MERGE_NO_MERGE_NEW: + $contents = file_get_contents($this->new_location . $original_filename); + break; + + case MERGE_NO_MERGE_MOD: + $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); + break; + + default: + $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); + + $contents = implode("\n", $diff->merged_output()); + unset($diff); + break; + } + + $expected_files[$file_struct['filename']] = md5($contents); + $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']); + $cache->put($file_list[$file_struct['filename']], base64_encode($contents)); + + $file_list['status']++; + $processed++; + + break; + + case 'conflict': + + $option = $conflicts[$file_struct['filename']]; + $contents = ''; + + switch ($option) + { + case MERGE_NO_MERGE_NEW: + $contents = file_get_contents($this->new_location . $original_filename); + break; + + case MERGE_NO_MERGE_MOD: + $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); + break; + + default: + + $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); + + if ($option == MERGE_NEW_FILE) + { + $contents = implode("\n", $diff->merged_new_output()); + } + else if ($option == MERGE_MOD_FILE) + { + $contents = implode("\n", $diff->merged_orig_output()); + } + else + { + unset($diff); + break 2; + } + + unset($diff); + break; + } + + $expected_files[$file_struct['filename']] = md5($contents); + $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']); + $cache->put($file_list[$file_struct['filename']], base64_encode($contents)); + + $file_list['status']++; + $processed++; + + break; + } + } + } + $cache->put('_expected_files', $expected_files); + } + + $file_list['status'] = -1; + $cache->put('_diff_files', $file_list); + + if ($request->variable('download', false)) + { + $this->include_file('includes/functions_compress.' . $phpEx); + + $use_method = $request->variable('use_method', ''); + $methods = array('.tar'); + + $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); + foreach ($available_methods as $type => $module) + { + if (!@extension_loaded($module)) + { + continue; + } + + $methods[] = $type; + } + + // Let the user decide in which format he wants to have the pack + if (!$use_method) + { + $this->page_title = 'SELECT_DOWNLOAD_FORMAT'; + + $radio_buttons = ''; + foreach ($methods as $method) + { + $radio_buttons .= ''; + } + + $template->assign_vars(array( + 'S_DOWNLOAD_FILES' => true, + 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files"), + 'RADIO_BUTTONS' => $radio_buttons, + 'S_HIDDEN_FIELDS' => $s_hidden_fields) + ); + + // To ease the update process create a file location map + $update_list = $cache->get('_update_list'); + $script_path = ($config['force_server_vars']) ? (($config['script_path'] == '/') ? '/' : $config['script_path'] . '/') : $user->page['root_script_path']; + + foreach ($update_list as $status => $files) + { + if ($status == 'up_to_date' || $status == 'no_update' || $status == 'status' || $status == 'status_deleted') + { + continue; + } + + foreach ($files as $file_struct) + { + if (in_array($file_struct['filename'], $no_update)) + { + continue; + } + + $template->assign_block_vars('location', array( + 'SOURCE' => htmlspecialchars($file_struct['filename']), + 'DESTINATION' => $script_path . htmlspecialchars($file_struct['filename']), + )); + } + } + return; + } + + if (!in_array($use_method, $methods)) + { + $use_method = '.tar'; + } + + $update_mode = 'download'; + } + else + { + $this->include_file('includes/functions_transfer.' . $phpEx); + + // Choose FTP, if not available use fsock... + $method = basename($request->variable('method', '')); + $submit = (isset($_POST['submit'])) ? true : false; + $test_ftp_connection = $request->variable('test_connection', ''); + + if (!$method || !class_exists($method)) + { + $method = 'ftp'; + $methods = transfer::methods(); + + if (!in_array('ftp', $methods)) + { + $method = $methods[0]; + } + } + + $test_connection = false; + if ($test_ftp_connection || $submit) + { + $transfer = new $method( + $request->variable('host', ''), + $request->variable('username', ''), + htmlspecialchars_decode($request->untrimmed_variable('password', '')), + $request->variable('root_path', ''), + $request->variable('port', ''), + $request->variable('timeout', '') + ); + $test_connection = $transfer->open_session(); + + // Make sure that the directory is correct by checking for the existence of common.php + if ($test_connection === true) + { + // Check for common.php file + if (!$transfer->file_exists($phpbb_root_path, 'common.' . $phpEx)) + { + $test_connection = 'ERR_WRONG_PATH_TO_PHPBB'; + } + } + + $transfer->close_session(); + + // Make sure the login details are correct before continuing + if ($submit && $test_connection !== true) + { + $submit = false; + $test_ftp_connection = true; + } + } + + $s_hidden_fields .= build_hidden_fields(array('method' => $method)); + + if (!$submit) + { + $this->page_title = 'SELECT_FTP_SETTINGS'; + + if (!class_exists($method)) + { + trigger_error('Method does not exist.', E_USER_ERROR); + } + + $requested_data = call_user_func(array($method, 'data')); + foreach ($requested_data as $data => $default) + { + $template->assign_block_vars('data', array( + 'DATA' => $data, + 'NAME' => $user->lang[strtoupper($method . '_' . $data)], + 'EXPLAIN' => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'], + 'DEFAULT' => $request->variable($data, (string) $default), + )); + } + + $template->assign_vars(array( + 'S_CONNECTION_SUCCESS' => ($test_ftp_connection && $test_connection === true) ? true : false, + 'S_CONNECTION_FAILED' => ($test_ftp_connection && $test_connection !== true) ? true : false, + 'ERROR_MSG' => ($test_ftp_connection && $test_connection !== true) ? $user->lang[$test_connection] : '', + + 'S_FTP_UPLOAD' => true, + 'UPLOAD_METHOD' => $method, + 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files"), + 'U_DOWNLOAD_METHOD' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files&download=1"), + 'S_HIDDEN_FIELDS' => $s_hidden_fields, + )); + + return; + } + + $update_mode = 'upload'; + } + + // Now update the installation or download the archive... + $download_filename = 'update_' . $this->update_info['version']['from'] . '_to_' . $this->update_info['version']['to']; + $archive_filename = $download_filename . '_' . time() . '_' . unique_id(); + + // Now init the connection + if ($update_mode == 'download') + { + if ($this->filesystem->is_writable($phpbb_root_path . 'store/')) + { + trigger_error(sprintf('The directory ā€œ%sā€ is not writable.', $phpbb_root_path . 'store/'), E_USER_ERROR); + } + + if ($use_method == '.zip') + { + $compress = new compress_zip('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method); + } + else + { + $compress = new compress_tar('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method, $use_method); + } + } + else + { + $transfer = new $method( + $request->variable('host', ''), + $request->variable('username', ''), + htmlspecialchars_decode($request->untrimmed_variable('password', '')), + $request->variable('root_path', ''), + $request->variable('port', ''), + $request->variable('timeout', '') + ); + $transfer->open_session(); + } + + // Ok, go through the update list and do the operations based on their status + foreach ($update_list as $status => $files) + { + if (!is_array($files)) + { + continue; + } + + foreach ($files as $file_struct) + { + // Skip this file if the user selected to not update it + if (in_array($file_struct['filename'], $no_update)) + { + continue; + } + + $original_filename = ($file_struct['custom']) ? $file_struct['original'] : $file_struct['filename']; + + switch ($status) + { + case 'new': + case 'new_conflict': + case 'not_modified': + + if ($update_mode == 'download') + { + $compress->add_custom_file($this->new_location . $original_filename, $file_struct['filename']); + } + else + { + if ($status != 'new') + { + $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); + } + + // New directory too? + $dirname = dirname($file_struct['filename']); + + if ($dirname && !file_exists($phpbb_root_path . $dirname)) + { + $transfer->make_dir($dirname); + } + + $transfer->copy_file($this->new_location . $original_filename, $file_struct['filename']); + } + break; + + case 'modified': + + $contents = base64_decode($cache->get($file_list[$file_struct['filename']])); + + if ($update_mode == 'download') + { + $compress->add_data($contents, $file_struct['filename']); + } + else + { + // @todo add option to specify if a backup file should be created? + $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); + $transfer->write_file($file_struct['filename'], $contents); + } + break; + + case 'conflict': + + $contents = base64_decode($cache->get($file_list[$file_struct['filename']])); + + if ($update_mode == 'download') + { + $compress->add_data($contents, $file_struct['filename']); + } + else + { + $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); + $transfer->write_file($file_struct['filename'], $contents); + } + break; + + case 'deleted': + + if ($update_mode != 'download') + { + $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); + } + break; + } + } + } + + if ($update_mode == 'download') + { + $compress->close(); + + $compress->download($archive_filename, $download_filename); + @unlink($phpbb_root_path . 'store/' . $archive_filename . $use_method); + + exit; + } + else + { + $transfer->close_session(); + + $template->assign_vars(array( + 'S_UPLOAD_SUCCESS' => true, + 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check")) + ); + return; + } + + break; + + } + } + + /** + * Show file diff + */ + function show_diff(&$update_list) + { + global $phpbb_root_path, $template, $user, $request, $phpbb_adm_relative_path; + + $this->tpl_name = 'install_update_diff'; + + $this->page_title = 'VIEWING_FILE_DIFF'; + + $status = $request->variable('status', ''); + $file = $request->variable('file', ''); + $diff_mode = $request->variable('diff_mode', 'inline'); + + // First of all make sure the file is within our file update list with the correct status + $found_entry = array(); + foreach ($update_list[$status] as $index => $file_struct) + { + if ($file_struct['filename'] === $file) + { + $found_entry = $update_list[$status][$index]; + } + } + + if (empty($found_entry)) + { + trigger_error($user->lang['FILE_DIFF_NOT_ALLOWED'], E_USER_ERROR); + } + + // If the status is 'up_to_date' then we do not need to show a diff + if ($status == 'up_to_date') + { + trigger_error($user->lang['FILE_ALREADY_UP_TO_DATE'], E_USER_ERROR); + } + + $original_file = ($found_entry['custom']) ? $found_entry['original'] : $file; + + // Get the correct diff + switch ($status) + { + case 'conflict': + $option = $request->variable('op', 0); + + switch ($option) + { + case MERGE_NO_MERGE_NEW: + case MERGE_NO_MERGE_MOD: + + $diff = $this->return_diff(array(), ($option == MERGE_NO_MERGE_NEW) ? $this->new_location . $original_file : $phpbb_root_path . $file); + + $template->assign_var('S_DIFF_NEW_FILE', true); + $diff_mode = 'inline'; + $this->page_title = 'VIEWING_FILE_CONTENTS'; + + break; + + // Merge differences and use new phpBB code for conflicted blocks + case MERGE_NEW_FILE: + case MERGE_MOD_FILE: + + $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $file, $this->new_location . $original_file); + + $template->assign_vars(array( + 'S_DIFF_CONFLICT_FILE' => true, + 'NUM_CONFLICTS' => $diff->get_num_conflicts()) + ); + + $diff = $this->return_diff($phpbb_root_path . $file, ($option == MERGE_NEW_FILE) ? $diff->merged_new_output() : $diff->merged_orig_output()); + break; + + // Download conflict file + default: + + $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $file, $this->new_location . $original_file); + + header('Pragma: no-cache'); + header("Content-Type: application/octetstream; name=\"$file\""); + header("Content-disposition: attachment; filename=$file"); + + @set_time_limit(0); + + echo implode("\n", $diff->get_conflicts_content()); + + flush(); + exit; + + break; + } + + break; + + case 'modified': + $option = $request->variable('op', 0); + + switch ($option) + { + case MERGE_NO_MERGE_NEW: + case MERGE_NO_MERGE_MOD: + + $diff = $this->return_diff(array(), ($option == MERGE_NO_MERGE_NEW) ? $this->new_location . $original_file : $phpbb_root_path . $file); + + $template->assign_var('S_DIFF_NEW_FILE', true); + $diff_mode = 'inline'; + $this->page_title = 'VIEWING_FILE_CONTENTS'; + + break; + + default: + $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $original_file, $this->new_location . $file); + $diff = $this->return_diff($phpbb_root_path . $file, $diff->merged_output()); + break; + } + break; + + case 'not_modified': + case 'new_conflict': + $diff = $this->return_diff($phpbb_root_path . $file, $this->new_location . $original_file); + break; + + case 'new': + + $diff = $this->return_diff(array(), $this->new_location . $original_file); + + $template->assign_var('S_DIFF_NEW_FILE', true); + $diff_mode = 'inline'; + $this->page_title = 'VIEWING_FILE_CONTENTS'; + + break; + + case 'deleted': + + $diff = $this->return_diff(array(), $phpbb_root_path . $original_file); + + $template->assign_var('S_DIFF_NEW_FILE', true); + $diff_mode = 'inline'; + $this->page_title = 'VIEWING_FILE_CONTENTS'; + + break; + } + + $diff_mode_options = ''; + foreach (array('side_by_side', 'inline', 'unified', 'raw') as $option) + { + $diff_mode_options .= ''; + } + + // Now the correct renderer + $render_class = 'diff_renderer_' . $diff_mode; + + if (!class_exists($render_class)) + { + trigger_error('Chosen diff mode is not supported', E_USER_ERROR); + } + + $renderer = new $render_class(); + + $template->assign_vars(array( + 'DIFF_CONTENT' => $renderer->get_diff_content($diff), + 'DIFF_MODE' => $diff_mode, + 'S_DIFF_MODE_OPTIONS' => $diff_mode_options, + 'S_SHOW_DIFF' => true, + )); + + unset($diff, $renderer); + } + + /** + * Collect all file status infos we need for the update by diffing all files + */ + function get_update_structure(&$update_list, $expected_files) + { + global $phpbb_root_path, $phpEx, $user; + + if ($update_list === false) + { + $update_list = array( + 'up_to_date' => array(), + 'new' => array(), + 'not_modified' => array(), + 'modified' => array(), + 'new_conflict' => array(), + 'conflict' => array(), + 'no_update' => array(), + 'deleted' => array(), + 'status' => 0, + 'status_deleted'=> 0, + ); + } + + /* if (!empty($this->update_info['custom'])) + { + foreach ($this->update_info['custom'] as $original_file => $file_ary) + { + foreach ($file_ary as $index => $file) + { + $this->make_update_diff($update_list, $original_file, $file, true); + } + } + } */ + + // Get a list of those files which are completely new by checking with file_exists... + $num_bytes_processed = 0; + + foreach ($this->update_info['files'] as $index => $file) + { + if (is_int($update_list['status']) && $index < $update_list['status']) + { + continue; + } + + if ($num_bytes_processed >= 500 * 1024) + { + return; + } + + if (!file_exists($phpbb_root_path . $file)) + { + // Make sure the update files are consistent by checking if the file is in new_files... + if (!file_exists($this->new_location . $file)) + { + trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR); + } + + // If the file exists within the old directory the file got removed and we will write it back + // not a biggie, but we might want to state this circumstance separately later. + // if (file_exists($this->old_location . $file)) + // { + // $update_list['removed'][] = $file; + // } + + /* Only include a new file as new if the underlying path exist + // The path normally do not exist if the original style or language has been removed + if (file_exists($phpbb_root_path . dirname($file))) + { + $this->get_custom_info($update_list['new'], $file); + $update_list['new'][] = array('filename' => $file, 'custom' => false); + } + else + { + // Do not include style-related or language-related content + if (strpos($file, 'styles/') !== 0 && strpos($file, 'language/') !== 0) + { + $update_list['no_update'][] = $file; + } + }*/ + + if (!phpbb_ignore_new_file_on_update($phpbb_root_path, $file)) + { + $this->get_custom_info($update_list['new'], $file); + $update_list['new'][] = array('filename' => $file, 'custom' => false); + } + + // unset($this->update_info['files'][$index]); + } + else + { + // not modified? + $this->make_update_diff($update_list, $file, $file, $expected_files); + } + + $num_bytes_processed += (file_exists($this->new_location . $file)) ? filesize($this->new_location . $file) : 100 * 1024; + $update_list['status']++; + } + + foreach ($this->update_info['deleted'] as $index => $file) + { + if (is_int($update_list['status_deleted']) && $index < $update_list['status_deleted']) + { + continue; + } + + if ($num_bytes_processed >= 500 * 1024) + { + return; + } + + if (file_exists($phpbb_root_path . $file)) + { + $update_list['deleted'][] = array('filename' => $file, 'custom' => false, 'as_expected' => false); + $num_bytes_processed += filesize($phpbb_root_path . $file); + } + + $update_list['status_deleted']++; + $update_list['status']++; + } + + $update_list['status_deleted'] = -1; + $update_list['status'] = -1; + +/* if (!sizeof($this->update_info['files'])) + { + return $update_list; + } + + // Now diff the remaining files to get information about their status (not modified/modified/up-to-date) + + // not modified? + foreach ($this->update_info['files'] as $index => $file) + { + $this->make_update_diff($update_list, $file, $file); + } + + // Now to the styles... + if (empty($this->update_info['custom'])) + { + return $update_list; + } + + foreach ($this->update_info['custom'] as $original_file => $file_ary) + { + foreach ($file_ary as $index => $file) + { + $this->make_update_diff($update_list, $original_file, $file, true); + } + } + + return $update_list;*/ + } + + /** + * Compare files for storage in update_list + */ + function make_update_diff(&$update_list, $original_file, $file, $expected_files, $custom = false) + { + global $phpbb_root_path, $user; + + $update_ary = array('filename' => $file, 'custom' => $custom, 'as_expected' => false); + + if ($custom) + { + $update_ary['original'] = $original_file; + } + + if (file_exists($phpbb_root_path . $file)) + { + $content = file_get_contents($phpbb_root_path . $file); + + if (isset($expected_files[$file]) && // the user already selected what to do with this file + ($expected_files[$file] === false || // the user wanted this file to stay the same, so just assume it's alright + $expected_files[$file] === md5($content))) + { + // the file contains what it was supposed to contain after the merge + $update_ary['as_expected'] = true; + $update_ary['was_ignored'] = ($expected_files[$file] === false); + $update_list['up_to_date'][] = $update_ary; + + return; + } + } + + // we only want to know if the files are successfully merged and newlines could result in errors (duplicate addition of lines and such things) + // Therefore we check for empty diffs with two methods, preserving newlines and not preserving them (which mostly works best, therefore the first option) + + // On a successfull update the new location file exists but the old one does not exist. + // Check for this circumstance, the new file need to be up-to-date with the current file then... + if (!file_exists($this->old_location . $original_file) && file_exists($this->new_location . $original_file) && file_exists($phpbb_root_path . $file)) + { + $tmp = array( + 'file1' => file_get_contents($this->new_location . $original_file), + 'file2' => $content, + ); + + // We need to diff the contents here to make sure the file is really the one we expect + $diff = new diff($tmp['file1'], $tmp['file2'], false); + $empty = $diff->is_empty(); + + unset($tmp, $diff); + + // if there are no differences we have an up-to-date file... + if ($empty) + { + $update_list['up_to_date'][] = $update_ary; + return; + } + + // If no other status matches we have another file in the way... + $update_list['new_conflict'][] = $update_ary; + return; + } + + // Old file removed? + if (file_exists($this->old_location . $original_file) && !file_exists($this->new_location . $original_file)) + { + return; + } + + // Check for existance, else abort immediately + if (!file_exists($this->old_location . $original_file) || !file_exists($this->new_location . $original_file)) + { + trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR); + } + + $preserve_cr_ary = array(false, true); + + foreach ($preserve_cr_ary as $preserve_cr) + { + $tmp = array( + 'file1' => file_get_contents($this->old_location . $original_file), + 'file2' => $content, + ); + + // We need to diff the contents here to make sure the file is really the one we expect + $diff = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); + $empty_1 = $diff->is_empty(); + + unset($tmp, $diff); + + $tmp = array( + 'file1' => file_get_contents($this->new_location . $original_file), + 'file2' => $content, + ); + + $diff = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); + $empty_2 = $diff->is_empty(); + + unset($tmp, $diff); + + // If the file is not modified we are finished here... + if ($empty_1) + { + // Further check if it is already up to date - it could happen that non-modified files + // slip through + if ($empty_2) + { + $update_list['up_to_date'][] = $update_ary; + return; + } + + $update_list['not_modified'][] = $update_ary; + return; + } + + // If the file had been modified then we need to check if it is already up to date + + // if there are no differences we have an up-to-date file... + if ($empty_2) + { + $update_list['up_to_date'][] = $update_ary; + return; + } + } + + $conflicts = false; + + foreach ($preserve_cr_ary as $preserve_cr) + { + // if the file is modified we try to make sure a merge succeed + $tmp = array( + 'orig' => file_get_contents($this->old_location . $original_file), + 'final1' => file_get_contents($phpbb_root_path . $file), + 'final2' => file_get_contents($this->new_location . $original_file), + ); + + $diff = new diff3($tmp['orig'], $tmp['final1'], $tmp['final2'], $preserve_cr); + unset($tmp); + + if (!$diff->get_num_conflicts()) + { + $tmp = array( + 'file1' => file_get_contents($phpbb_root_path . $file), + 'file2' => implode("\n", $diff->merged_output()), + ); + + // now compare the merged output with the original file to see if the modified file is up to date + $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); + $empty = $diff2->is_empty(); + + unset($diff, $diff2); + + if ($empty) + { + $update_list['up_to_date'][] = $update_ary; + return; + } + + // If we preserve cr tag it as modified because the conflict would not show in this mode anyway + if ($preserve_cr) + { + $update_list['modified'][] = $update_ary; + return; + } + } + else + { + // There is one special case... users having merged with a conflicting file... we need to check this + $tmp = array( + 'file1' => file_get_contents($phpbb_root_path . $file), + 'file2' => implode("\n", $diff->merged_new_output()), + ); + + $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); + $empty = $diff2->is_empty(); + + if (!$empty) + { + unset($tmp, $diff2); + + // We check if the user merged with his output + $tmp = array( + 'file1' => file_get_contents($phpbb_root_path . $file), + 'file2' => implode("\n", $diff->merged_orig_output()), + ); + + $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); + $empty = $diff2->is_empty(); + } + + if (!$empty) + { + $conflicts = $diff->get_num_conflicts(); + } + + unset($diff, $diff2); + + if ($empty) + { + // A conflict got resolved... + $update_list['up_to_date'][] = $update_ary; + return; + } + } + } + + if ($conflicts !== false) + { + $update_ary['conflicts'] = $conflicts; + $update_list['conflict'][] = $update_ary; + return; + } + + // If no other status matches we have a modified file... + $update_list['modified'][] = $update_ary; + } + + /** + * Update update_list with custom new files + */ + function get_custom_info(&$update_list, $file) + { + if (empty($this->update_info['custom'])) + { + return; + } + + if (isset($this->update_info['custom'][$file])) + { + foreach ($this->update_info['custom'][$file] as $_file) + { + $update_list[] = array('filename' => $_file, 'custom' => true, 'original' => $file); + } + } + } + + /** + * Get remote file + */ + function get_file($mode) + { + global $user, $db; + + $errstr = ''; + $errno = 0; + + switch ($mode) + { + case 'update_info': + global $phpbb_root_path, $phpEx; + + $update_info = array(); + include($phpbb_root_path . 'install/update/index.' . $phpEx); + + $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info; + $errstr = ($info === false) ? $user->lang['WRONG_INFO_FILE_FORMAT'] : ''; + + if ($info !== false) + { + // We assume that all file extensions have been renamed to .$phpEx, + // if someone is using a non .php file extension for php files. + // However, in $update_info['files'] we use hardcoded .php. + // We therefore replace .php with .$phpEx. + $info['files'] = preg_replace('/\.php$/i', ".$phpEx", $info['files']); + + // Adjust the update info file to hold some specific style-related information + $info['custom'] = array(); +/* + // Get custom installed styles... + $sql = 'SELECT style_name, style_path + FROM ' . STYLES_TABLE . " + WHERE LOWER(style_name) NOT IN ('prosilver')"; + $result = $db->sql_query($sql); + + $templates = array(); + while ($row = $db->sql_fetchrow($result)) + { + $templates[] = $row; + } + $db->sql_freeresult($result); + + if (sizeof($templates)) + { + foreach ($info['files'] as $filename) + { + // Template update? + if (strpos(strtolower($filename), 'styles/prosilver/template/') === 0) + { + foreach ($templates as $row) + { + $info['custom'][$filename][] = str_replace('/prosilver/', '/' . $row['style_path'] . '/', $filename); + } + } + } + } +*/ + } + break; + + default: + trigger_error('Mode for getting remote file not specified', E_USER_ERROR); + break; + } + + if ($info === false) + { + trigger_error($errstr, E_USER_ERROR); + } + + return $info; + } + + /** + * Function for including files... + */ + function include_file($filename) + { + global $phpbb_root_path, $phpEx; + + if (!empty($this->update_info['files']) && in_array($filename, $this->update_info['files'])) + { + include_once($this->new_location . $filename); + } + else + { + include_once($phpbb_root_path . $filename); + } + } + + /** + * Wrapper for returning a diff object + */ + function return_diff() + { + $args = func_get_args(); + $three_way_diff = (func_num_args() > 2) ? true : false; + + $file1 = array_shift($args); + $file2 = array_shift($args); + + $tmp['file1'] = (!empty($file1) && is_string($file1)) ? file_get_contents($file1) : $file1; + $tmp['file2'] = (!empty($file2) && is_string($file2)) ? file_get_contents($file2) : $file2; + + if ($three_way_diff) + { + $file3 = array_shift($args); + $tmp['file3'] = (!empty($file3) && is_string($file3)) ? file_get_contents($file3) : $file3; + + $diff = new diff3($tmp['file1'], $tmp['file2'], $tmp['file3']); + } + else + { + $diff = new diff($tmp['file1'], $tmp['file2']); + } + + unset($tmp); + + return $diff; + } +} diff --git a/phpBB/install/phpbbcli.php b/phpBB/install/phpbbcli.php deleted file mode 100755 index 20a202f584..0000000000 --- a/phpBB/install/phpbbcli.php +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env php - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -use Symfony\Component\Console\Input\ArgvInput; - -if (php_sapi_name() !== 'cli') -{ - echo 'This program must be run from the command line.' . PHP_EOL; - exit(1); -} - -define('IN_PHPBB', true); -define('IN_INSTALL', true); -define('PHPBB_ENVIRONMENT', 'production'); -$phpbb_root_path = __DIR__ . '/../'; -$phpEx = substr(strrchr(__FILE__, '.'), 1); - -// -// Let's do the common.php logic -// -require($phpbb_root_path . 'includes/startup.' . $phpEx); -require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx); - -$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); -$phpbb_class_loader->register(); - -// In case $phpbb_adm_relative_path is not set (in case of an update), use the default. -$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/'; -$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path; - -// Include files -require($phpbb_root_path . 'includes/functions.' . $phpEx); -require($phpbb_root_path . 'includes/functions_content.' . $phpEx); -include($phpbb_root_path . 'includes/functions_compatibility.' . $phpEx); -require($phpbb_root_path . 'includes/functions_user.' . $phpEx); -require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); - -// Set PHP error handler to ours -set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); - -$phpbb_installer_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); -$phpbb_installer_container = $phpbb_installer_container_builder - ->with_environment('installer') - ->without_extensions() - ->without_cache() - ->get_container(); - -/** @var \phpbb\filesystem\filesystem $phpbb_filesystem */ -$phpbb_filesystem = $phpbb_installer_container->get('filesystem'); - -/** @var \phpbb\language\language $language */ -$language = $phpbb_installer_container->get('language'); -$language->add_lang(array('common', 'acp/common', 'acp/board', 'install', 'posting', 'cli')); - -$application = new \phpbb\console\application('phpBB Installer', PHPBB_VERSION, $language); -$application->register_container_commands($phpbb_installer_container->get('console.installer.command_collection')); -$application->run($input); diff --git a/phpBB/install/phpinfo.php b/phpBB/install/phpinfo.php new file mode 100644 index 0000000000..1512b00563 --- /dev/null +++ b/phpBB/install/phpinfo.php @@ -0,0 +1,14 @@ + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +phpinfo(); diff --git a/phpBB/install/schemas/index.htm b/phpBB/install/schemas/index.htm new file mode 100644 index 0000000000..ee1f723a7d --- /dev/null +++ b/phpBB/install/schemas/index.htm @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql new file mode 100644 index 0000000000..2473d31aab --- /dev/null +++ b/phpBB/install/schemas/oracle_schema.sql @@ -0,0 +1,37 @@ +/* + This first section is optional, however its probably the best method + of running phpBB on Oracle. If you already have a tablespace and user created + for phpBB you can leave this section commented out! + + The first set of statements create a phpBB tablespace and a phpBB user, + make sure you change the password of the phpBB user before you run this script!! +*/ + +/* +CREATE TABLESPACE "PHPBB" + LOGGING + DATAFILE 'E:\ORACLE\ORADATA\LOCAL\PHPBB.ora' + SIZE 10M + AUTOEXTEND ON NEXT 10M + MAXSIZE 100M; + +CREATE USER "PHPBB" + PROFILE "DEFAULT" + IDENTIFIED BY "phpbb_password" + DEFAULT TABLESPACE "PHPBB" + QUOTA UNLIMITED ON "PHPBB" + ACCOUNT UNLOCK; + +GRANT ANALYZE ANY TO "PHPBB"; +GRANT CREATE SEQUENCE TO "PHPBB"; +GRANT CREATE SESSION TO "PHPBB"; +GRANT CREATE TABLE TO "PHPBB"; +GRANT CREATE TRIGGER TO "PHPBB"; +GRANT CREATE VIEW TO "PHPBB"; +GRANT "CONNECT" TO "PHPBB"; + +COMMIT; +DISCONNECT; + +CONNECT phpbb/phpbb_password; +*/ diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql new file mode 100644 index 0000000000..65caba8d1c --- /dev/null +++ b/phpBB/install/schemas/postgres_schema.sql @@ -0,0 +1,80 @@ + +BEGIN; + +/* + Domain definition +*/ +CREATE DOMAIN varchar_ci AS varchar(255) NOT NULL DEFAULT ''::character varying; + +/* + Operation Functions +*/ +CREATE FUNCTION _varchar_ci_equal(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) = LOWER($2)' LANGUAGE SQL STRICT; +CREATE FUNCTION _varchar_ci_not_equal(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) != LOWER($2)' LANGUAGE SQL STRICT; +CREATE FUNCTION _varchar_ci_less_than(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) < LOWER($2)' LANGUAGE SQL STRICT; +CREATE FUNCTION _varchar_ci_less_equal(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) <= LOWER($2)' LANGUAGE SQL STRICT; +CREATE FUNCTION _varchar_ci_greater_than(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) > LOWER($2)' LANGUAGE SQL STRICT; +CREATE FUNCTION _varchar_ci_greater_equals(varchar_ci, varchar_ci) RETURNS boolean AS 'SELECT LOWER($1) >= LOWER($2)' LANGUAGE SQL STRICT; + +/* + Operators +*/ +CREATE OPERATOR <( + PROCEDURE = _varchar_ci_less_than, + LEFTARG = varchar_ci, + RIGHTARG = varchar_ci, + COMMUTATOR = >, + NEGATOR = >=, + RESTRICT = scalarltsel, + JOIN = scalarltjoinsel); + +CREATE OPERATOR <=( + PROCEDURE = _varchar_ci_less_equal, + LEFTARG = varchar_ci, + RIGHTARG = varchar_ci, + COMMUTATOR = >=, + NEGATOR = >, + RESTRICT = scalarltsel, + JOIN = scalarltjoinsel); + +CREATE OPERATOR >( + PROCEDURE = _varchar_ci_greater_than, + LEFTARG = varchar_ci, + RIGHTARG = varchar_ci, + COMMUTATOR = <, + NEGATOR = <=, + RESTRICT = scalargtsel, + JOIN = scalargtjoinsel); + +CREATE OPERATOR >=( + PROCEDURE = _varchar_ci_greater_equals, + LEFTARG = varchar_ci, + RIGHTARG = varchar_ci, + COMMUTATOR = <=, + NEGATOR = <, + RESTRICT = scalargtsel, + JOIN = scalargtjoinsel); + +CREATE OPERATOR <>( + PROCEDURE = _varchar_ci_not_equal, + LEFTARG = varchar_ci, + RIGHTARG = varchar_ci, + COMMUTATOR = <>, + NEGATOR = =, + RESTRICT = neqsel, + JOIN = neqjoinsel); + +CREATE OPERATOR =( + PROCEDURE = _varchar_ci_equal, + LEFTARG = varchar_ci, + RIGHTARG = varchar_ci, + COMMUTATOR = =, + NEGATOR = <>, + RESTRICT = eqsel, + JOIN = eqjoinsel, + HASHES, + MERGES, + SORT1= <); + +COMMIT; + diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql new file mode 100644 index 0000000000..1f856f016c --- /dev/null +++ b/phpBB/install/schemas/schema_data.sql @@ -0,0 +1,821 @@ +# +# $Id$ +# + +# POSTGRES BEGIN # + +# -- Config +INSERT INTO phpbb_config (config_name, config_value) VALUES ('active_sessions', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_attachments', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_autologin', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_gravatar', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_local', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_remote', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_upload', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_avatar_remote_upload', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bbcode', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_birthdays', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_bookmarks', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_cdn', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_emailreuse', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_password_reset', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_forum_notify', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_live_searches', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_mass_pm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_name_chars', 'USERNAME_CHARS_ANY'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_namechange', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_nocensors', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_pm_attach', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_pm_report', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_post_flash', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_post_links', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_privmsg', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_quick_reply', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_sig', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_sig_bbcode', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_sig_flash', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_sig_img', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_sig_links', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_sig_pm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_sig_smilies', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_smilies', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('allow_topic_notify', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('assets_version', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('attachment_quota', '52428800'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('auth_bbcode_pm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('auth_flash_pm', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('auth_img_pm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('auth_method', 'db'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('auth_smilies_pm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_filesize', '6144'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_gallery_path', 'images/avatars/gallery'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_max_height', '90'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_max_width', '90'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_min_height', '20'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_min_width', '20'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_path', 'images/avatars/upload'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_salt', 'phpbb_avatar'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact', 'contact@yourdomain.tld'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact_name', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_disable', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_disable_msg', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email', 'address@yourdomain.tld'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_form', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_sig', '{L_CONFIG_BOARD_EMAIL_SIG}'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_hide_emails', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_index_text', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_timezone', 'UTC'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('browser_check', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_interval', '10'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_type', 'd'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('cache_gc', '7200'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_plugin', 'core.captcha.plugins.nogd'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_foreground_noise', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_x_grid', '25'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_y_grid', '25'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_wave', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_3d_noise', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('captcha_gd_fonts', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('confirm_refresh', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('check_attachment_content', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('check_dnsbl', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('chg_passforce', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('contact_admin_form_enable', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('cookie_domain', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('cookie_name', 'phpbb3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('cookie_path', '/'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('cookie_secure', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('coppa_enable', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('coppa_fax', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('coppa_mail', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('database_gc', '604800'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('dbms_version', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('default_dateformat', 'D M d, Y g:i a'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('default_style', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('display_last_edited', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('display_last_subject', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('display_order', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('edit_time', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('extension_force_unstable', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('delete_time', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_check_mx', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_enable', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_function_name', 'mail'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_max_chunk_size', '50'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('email_package_size', '20'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_confirm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_mod_rewrite', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_pm_icons', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_post_confirm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_enable', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_http_auth', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_limit_post', '15'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_limit_topic', '10'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_overall_forums', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_overall', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_forum', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_topic', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_topics_new', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_topics_active', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('feed_item_statistics', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('flood_interval', '15'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('force_server_vars', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('form_token_lifetime', '7200'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('form_token_mintime', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('form_token_sid_guests', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('forward_pm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('forwarded_for_check', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('full_folder_action', '2'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_mysql_max_word_len', '254'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_mysql_min_word_len', '4'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_native_common_thres', '5'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_native_load_upd', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_native_max_chars', '14'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_native_min_chars', '3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_postgres_max_word_len', '254'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_postgres_min_word_len', '4'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_postgres_ts_name', 'simple'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_sphinx_indexer_mem_limit', '512'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('fulltext_sphinx_stopwords', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('gzip_compress', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('hot_threshold', '25'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('icons_path', 'images/icons'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_create_thumbnail', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_display_inlined', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_imagick', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_link_height', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_link_width', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_max_height', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_max_thumb_width', '400'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_max_width', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('img_min_thumb_filesize', '12000'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ip_check', '3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ip_login_limit_max', '50'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ip_login_limit_time', '21600'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ip_login_limit_use_forwarded', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_enable', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_host', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_password', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_package_size', '20'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_port', '5222'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_use_ssl', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_username', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ldap_base_dn', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ldap_email', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ldap_password', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ldap_port', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ldap_server', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ldap_uid', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ldap_user', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ldap_user_filter', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('legend_sort_groupname', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('limit_load', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('limit_search_load', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_anon_lastread', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_birthdays', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_memberlist', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_pm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_viewprofile', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_cpf_viewtopic', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_db_lastread', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_db_track', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jquery_url', '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_jumpbox', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_moderators', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_notifications', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_online', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_online_guests', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_online_time', '5'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_onlinetrack', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_search', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_tplcompile', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_unreads_search', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('load_user_activity', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_attachments', '3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_attachments_pm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_autologin_time', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_filesize', '262144'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_filesize_pm', '262144'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_login_attempts', '3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_name_chars', '20'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_num_search_keywords', '10'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_pass_chars', '100'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_poll_options', '10'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_post_chars', '60000'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_post_font_size', '200'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_post_img_height', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_post_img_width', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_post_smilies', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_post_urls', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_quote_depth', '3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_reg_attempts', '5'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_sig_chars', '255'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_sig_font_size', '200'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_sig_img_height', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_sig_img_width', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_sig_smilies', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('max_sig_urls', '5'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('min_name_chars', '3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('min_pass_chars', '6'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('min_post_chars', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('min_search_author_chars', '3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('mime_triggers', 'body|head|html|img|plaintext|a href|pre|script|table|title'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('new_member_post_limit', '3'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('new_member_group_default', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('override_user_style', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('pass_complex', 'PASS_TYPE_ANY'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('plupload_salt', 'phpbb_plupload'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_edit_time', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_max_boxes', '4'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_max_msgs', '50'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('pm_max_recipients', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('posts_per_page', '10'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('print_pm', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('queue_interval', '60'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('ranks_path', 'images/ranks'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('read_notification_expire_days', '30'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('read_notification_gc', '86400'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('require_activation', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('referer_validation', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('script_path', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_block_size', '250'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_gc', '7200'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_interval', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_anonymous_interval', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_type', '\phpbb\search\fulltext_native'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_store_results', '1800'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('secure_allow_deny', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('secure_allow_empty_referer', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('secure_downloads', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('server_name', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('server_port', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('server_protocol', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('session_gc', '3600'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('session_length', '3600'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('site_desc', '{L_CONFIG_SITE_DESC}'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('site_home_url', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('site_home_text', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('sitename', '{L_CONFIG_SITENAME}'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('smilies_path', 'images/smilies'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('smilies_per_page', '50'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_auth_method', 'PLAIN'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_delivery', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_host', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_password', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_port', '25'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('smtp_username', ''); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('teampage_memberships', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('teampage_forums', '1'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page', '25'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.2.0-a1-dev'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400'); + +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('cache_last_gc', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('cron_lock', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('database_last_gc', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('last_queue_run', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('newest_user_colour', 'AA0000', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('newest_user_id', '2', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('newest_username', '', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_files', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_posts', '1', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_topics', '1', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('num_users', '1', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('plupload_last_gc', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('rand_seed', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('rand_seed_last_update', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('read_notification_last_gc', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('record_online_date', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('record_online_users', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('search_indexing_state', '', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('search_last_gc', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('session_last_gc', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('upload_dir_size', '0', 1); +INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('warnings_last_gc', '0', 1); + +# Config text +INSERT INTO phpbb_config_text (config_name, config_value) VALUES ('contact_admin_info', ''); +INSERT INTO phpbb_config_text (config_name, config_value) VALUES ('contact_admin_info_uid', ''); +INSERT INTO phpbb_config_text (config_name, config_value) VALUES ('contact_admin_info_bitfield', ''); +INSERT INTO phpbb_config_text (config_name, config_value) VALUES ('contact_admin_info_flags', '7'); + +# -- Forum related auth options +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_announce', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_attach', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_bbcode', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_bump', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_delete', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_download', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_edit', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_email', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_flash', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_icons', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_ignoreflood', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_img', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_list', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_noapprove', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_poll', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_post', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_postcount', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_print', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_read', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_reply', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_report', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_search', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_sigs', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_smilies', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_sticky', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_subscribe', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_user_lock', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_vote', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_votechg', 1); +INSERT INTO phpbb_acl_options (auth_option, is_local) VALUES ('f_softdelete', 1); + +# -- Moderator related auth options +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_approve', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_chgposter', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_delete', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_edit', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_info', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_lock', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_merge', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_move', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_report', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_split', 1, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_softdelete', 1, 1); + +# -- Global moderator auth option (not a local option) +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_ban', 0, 1); +INSERT INTO phpbb_acl_options (auth_option, is_local, is_global) VALUES ('m_warn', 0, 1); + +# -- Admin related auth options +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_aauth', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_attach', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_authgroups', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_authusers', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_backup', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_ban', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_bbcode', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_board', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_bots', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_clearlogs', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_email', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_extensions', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_fauth', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_forum', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_forumadd', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_forumdel', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_group', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_groupadd', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_groupdel', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_icons', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_jabber', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_language', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_mauth', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_modules', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_names', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_phpinfo', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_profile', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_prune', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_ranks', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_reasons', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_roles', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_search', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_server', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_styles', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_switchperm', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_uauth', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_user', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_userdel', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_viewauth', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_viewlogs', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_words', 1); + +# -- User related auth options +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_attach', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_chgavatar', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_chgcensors', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_chgemail', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_chggrp', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_chgname', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_chgpasswd', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_chgprofileinfo', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_download', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_hideonline', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_ignoreflood', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_masspm', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_masspm_group', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_attach', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_bbcode', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_delete', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_download', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_edit', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_emailpm', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_flash', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_forward', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_img', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_printpm', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_pm_smilies', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_readpm', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_savedrafts', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_search', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_sendemail', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_sendim', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_sendpm', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_sig', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_viewonline', 1); +INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_viewprofile', 1); + + +# -- standard auth roles +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_ADMIN_STANDARD', 'ROLE_DESCRIPTION_ADMIN_STANDARD', 'a_', 1); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_ADMIN_FORUM', 'ROLE_DESCRIPTION_ADMIN_FORUM', 'a_', 3); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_ADMIN_USERGROUP', 'ROLE_DESCRIPTION_ADMIN_USERGROUP', 'a_', 4); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_ADMIN_FULL', 'ROLE_DESCRIPTION_ADMIN_FULL', 'a_', 2); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_FULL', 'ROLE_DESCRIPTION_USER_FULL', 'u_', 3); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_STANDARD', 'ROLE_DESCRIPTION_USER_STANDARD', 'u_', 1); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_LIMITED', 'ROLE_DESCRIPTION_USER_LIMITED', 'u_', 2); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NOPM', 'ROLE_DESCRIPTION_USER_NOPM', 'u_', 4); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NOAVATAR', 'ROLE_DESCRIPTION_USER_NOAVATAR', 'u_', 5); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_MOD_FULL', 'ROLE_DESCRIPTION_MOD_FULL', 'm_', 3); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_MOD_STANDARD', 'ROLE_DESCRIPTION_MOD_STANDARD', 'm_', 1); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_MOD_SIMPLE', 'ROLE_DESCRIPTION_MOD_SIMPLE', 'm_', 2); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_MOD_QUEUE', 'ROLE_DESCRIPTION_MOD_QUEUE', 'm_', 4); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_FULL', 'ROLE_DESCRIPTION_FORUM_FULL', 'f_', 7); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_STANDARD', 'ROLE_DESCRIPTION_FORUM_STANDARD', 'f_', 5); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NOACCESS', 'ROLE_DESCRIPTION_FORUM_NOACCESS', 'f_', 1); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_READONLY', 'ROLE_DESCRIPTION_FORUM_READONLY', 'f_', 2); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_LIMITED', 'ROLE_DESCRIPTION_FORUM_LIMITED', 'f_', 3); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_BOT', 'ROLE_DESCRIPTION_FORUM_BOT', 'f_', 9); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_ONQUEUE', 'ROLE_DESCRIPTION_FORUM_ONQUEUE', 'f_', 8); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_POLLS', 'ROLE_DESCRIPTION_FORUM_POLLS', 'f_', 6); +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_LIMITED_POLLS', 'ROLE_DESCRIPTION_FORUM_LIMITED_POLLS', 'f_', 4); + +# 23 +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NEW_MEMBER', 'ROLE_DESCRIPTION_USER_NEW_MEMBER', 'u_', 6); + +# 24 +INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NEW_MEMBER', 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER', 'f_', 10); + +# -- phpbb_styles +INSERT INTO phpbb_styles (style_name, style_copyright, style_active, style_path, bbcode_bitfield, style_parent_id, style_parent_tree) VALUES ('prosilver', '© phpBB Limited', 1, 'prosilver', 'kNg=', 0, ''); + +# -- Forums +INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents) VALUES ('{L_FORUMS_FIRST_CATEGORY}', '', 1, 4, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 'Admin', 'AA0000', 972086460, '', '', '', '', '', '', '', 0, 0, ''); + +INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts_approved, forum_posts_unapproved, forum_posts_softdeleted, forum_topics_approved, forum_topics_unapproved, forum_topics_softdeleted, forum_last_post_id, forum_last_poster_id, forum_last_poster_name, forum_last_poster_colour, forum_last_post_subject, forum_last_post_time, forum_link, forum_password, forum_image, forum_rules, forum_rules_link, forum_rules_uid, forum_desc_uid, prune_days, prune_viewed, forum_parents, forum_flags) VALUES ('{L_FORUMS_TEST_FORUM_TITLE}', '{L_FORUMS_TEST_FORUM_DESC}', 2, 3, 1, 1, 1, 0, 0, 1, 0, 0, 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, '', '', '', '', '', '', '', 0, 0, '', 48); + +# -- Users / Anonymous user +INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_jabber, user_actkey, user_newpasswd, user_allow_massemail) VALUES (2, 1, 'Anonymous', 'anonymous', 0, '', '', 'en', 1, 0, '', 0, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', 0); + +# -- username: Admin password: admin (change this or remove it once everything is working!) +INSERT INTO phpbb_users (user_type, group_id, username, username_clean, user_regdate, user_password, user_email, user_lang, user_style, user_rank, user_colour, user_posts, user_permissions, user_ip, user_birthday, user_lastpage, user_last_confirm_key, user_post_sortby_type, user_post_sortby_dir, user_topic_sortby_type, user_topic_sortby_dir, user_avatar, user_sig, user_sig_bbcode_uid, user_jabber, user_actkey, user_newpasswd) VALUES (3, 5, 'Admin', 'admin', 0, '21232f297a57a5a743894a0e4a801fc3', 'admin@yourdomain.com', 'en', 1, 1, 'AA0000', 1, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', ''); + +# -- Groups +INSERT INTO phpbb_groups (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('GUESTS', 3, 0, '', 0, '', '', '', 5); +INSERT INTO phpbb_groups (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('REGISTERED', 3, 0, '', 0, '', '', '', 5); +INSERT INTO phpbb_groups (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('REGISTERED_COPPA', 3, 0, '', 0, '', '', '', 5); +INSERT INTO phpbb_groups (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('GLOBAL_MODERATORS', 3, 0, '00AA00', 2, '', '', '', 0); +INSERT INTO phpbb_groups (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('ADMINISTRATORS', 3, 1, 'AA0000', 1, '', '', '', 0); +INSERT INTO phpbb_groups (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('BOTS', 3, 0, '9E8DA7', 0, '', '', '', 5); +INSERT INTO phpbb_groups (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('NEWLY_REGISTERED', 3, 0, '', 0, '', '', '', 5); + +# -- Teampage +INSERT INTO phpbb_teampage (group_id, teampage_name, teampage_position, teampage_parent) VALUES (5, '', 1, 0); +INSERT INTO phpbb_teampage (group_id, teampage_name, teampage_position, teampage_parent) VALUES (4, '', 2, 0); + +# -- User -> Group +INSERT INTO phpbb_user_group (group_id, user_id, user_pending, group_leader) VALUES (1, 1, 0, 0); +INSERT INTO phpbb_user_group (group_id, user_id, user_pending, group_leader) VALUES (2, 2, 0, 0); +INSERT INTO phpbb_user_group (group_id, user_id, user_pending, group_leader) VALUES (4, 2, 0, 0); +INSERT INTO phpbb_user_group (group_id, user_id, user_pending, group_leader) VALUES (5, 2, 0, 1); + +# -- Ranks +INSERT INTO phpbb_ranks (rank_title, rank_min, rank_special, rank_image) VALUES ('{L_RANKS_SITE_ADMIN_TITLE}', 0, 1, ''); + +# -- Roles data + +# Standard Admin (a_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 1, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'a_%' AND auth_option NOT IN ('a_switchperm', 'a_jabber', 'a_phpinfo', 'a_server', 'a_backup', 'a_styles', 'a_clearlogs', 'a_modules', 'a_language', 'a_email', 'a_bots', 'a_search', 'a_aauth', 'a_roles'); + +# Forum admin (a_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 2, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'a_%' AND auth_option IN ('a_', 'a_authgroups', 'a_authusers', 'a_fauth', 'a_forum', 'a_forumadd', 'a_forumdel', 'a_mauth', 'a_prune', 'a_uauth', 'a_viewauth', 'a_viewlogs'); + +# User and Groups Admin (a_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 3, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'a_%' AND auth_option IN ('a_', 'a_authgroups', 'a_authusers', 'a_ban', 'a_group', 'a_groupadd', 'a_groupdel', 'a_ranks', 'a_uauth', 'a_user', 'a_viewauth', 'a_viewlogs'); + +# Full Admin (a_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 4, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'a_%'; + +# All Features (u_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 5, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%'; + +# Standard Features (u_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 6, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option NOT IN ('u_viewonline', 'u_chggrp', 'u_chgname', 'u_ignoreflood', 'u_pm_flash', 'u_pm_forward'); + +# Limited Features (u_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 7, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option NOT IN ('u_attach', 'u_viewonline', 'u_chggrp', 'u_chgname', 'u_ignoreflood', 'u_pm_attach', 'u_pm_emailpm', 'u_pm_flash', 'u_savedrafts', 'u_search', 'u_sendemail', 'u_sendim', 'u_masspm', 'u_masspm_group'); + +# No Private Messages (u_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 8, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_', 'u_chgavatar', 'u_chgcensors', 'u_chgemail', 'u_chgpasswd', 'u_download', 'u_hideonline', 'u_sig', 'u_viewprofile'); +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 8, auth_option_id, 0 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_readpm', 'u_sendpm', 'u_masspm', 'u_masspm_group'); + +# No Avatar (u_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 9, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option NOT IN ('u_attach', 'u_chgavatar', 'u_viewonline', 'u_chggrp', 'u_chgname', 'u_ignoreflood', 'u_pm_attach', 'u_pm_emailpm', 'u_pm_flash', 'u_savedrafts', 'u_search', 'u_sendemail', 'u_sendim', 'u_masspm', 'u_masspm_group'); +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 9, auth_option_id, 0 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_chgavatar'); + +# Full Moderator (m_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 10, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%'; + +# Standard Moderator (m_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 11, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option NOT IN ('m_ban', 'm_chgposter'); + +# Simple Moderator (m_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 12, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option IN ('m_', 'm_delete', 'm_softdelete', 'm_edit', 'm_info', 'm_report'); + +# Queue Moderator (m_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 13, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'm_%' AND auth_option IN ('m_', 'm_approve', 'm_edit'); + +# Full Access (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 14, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%'; + +# Standard Access (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 15, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%' AND auth_option NOT IN ('f_announce', 'f_flash', 'f_ignoreflood', 'f_poll', 'f_sticky', 'f_user_lock'); + +# No Access (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 16, auth_option_id, 0 FROM phpbb_acl_options WHERE auth_option = 'f_'; + +# Read Only Access (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 17, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_', 'f_download', 'f_list', 'f_read', 'f_search', 'f_subscribe', 'f_print'); + +# Limited Access (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 18, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%' AND auth_option NOT IN ('f_announce', 'f_attach', 'f_bump', 'f_delete', 'f_flash', 'f_icons', 'f_ignoreflood', 'f_poll', 'f_sticky', 'f_user_lock', 'f_votechg'); + +# Bot Access (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 19, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_', 'f_download', 'f_list', 'f_read', 'f_print'); + +# On Moderation Queue (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 20, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%' AND auth_option NOT IN ('f_announce', 'f_bump', 'f_delete', 'f_flash', 'f_icons', 'f_ignoreflood', 'f_poll', 'f_sticky', 'f_user_lock', 'f_votechg', 'f_noapprove'); +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 20, auth_option_id, 0 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove'); + +# Standard Access + Polls (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 21, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%' AND auth_option NOT IN ('f_announce', 'f_flash', 'f_ignoreflood', 'f_sticky', 'f_user_lock'); + +# Limited Access + Polls (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 22, auth_option_id, 1 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%' AND auth_option NOT IN ('f_announce', 'f_attach', 'f_bump', 'f_delete', 'f_flash', 'f_icons', 'f_ignoreflood', 'f_sticky', 'f_user_lock', 'f_votechg'); + +# New Member (u_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 23, auth_option_id, 0 FROM phpbb_acl_options WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group', 'u_chgprofileinfo'); + +# New Member (f_) +INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 24, auth_option_id, 0 FROM phpbb_acl_options WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove'); + + +# Permissions + +# GUESTS - u_download and u_search ability +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) SELECT 1, 0, auth_option_id, 0, 1 FROM phpbb_acl_options WHERE auth_option IN ('u_', 'u_download', 'u_search'); + +# Admin user - full user features +INSERT INTO phpbb_acl_users (user_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (2, 0, 0, 5, 0); + +# ADMINISTRATOR Group - full user features +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (5, 0, 0, 5, 0); + +# ADMINISTRATOR Group - standard admin +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (5, 0, 0, 1, 0); + +# REGISTERED and REGISTERED_COPPA having standard user features +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (2, 0, 0, 6, 0); +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (3, 0, 0, 6, 0); + +# GLOBAL_MODERATORS having full user features +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (4, 0, 0, 5, 0); + +# GLOBAL_MODERATORS having full global moderator access +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (4, 0, 0, 10, 0); + +# Giving all groups read only access to the first category +# since administrators and moderators are already within the registered users group we do not need to set them here +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (1, 1, 0, 17, 0); +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (2, 1, 0, 17, 0); +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (3, 1, 0, 17, 0); +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (6, 1, 0, 17, 0); + +# Giving access to the first forum + +# guests having read only access +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (1, 2, 0, 17, 0); + +# registered and registered_coppa having standard access +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (2, 2, 0, 15, 0); +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (3, 2, 0, 15, 0); + +# global moderators having standard access + polls +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (4, 2, 0, 21, 0); + +# administrators having full forum and full moderator access +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (5, 2, 0, 14, 0); +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (5, 2, 0, 10, 0); + +# Bots having bot access +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (6, 2, 0, 19, 0); + +# NEW MEMBERS are not allowed to send private messages +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (7, 0, 0, 23, 0); + +# NEW MEMBERS on the queue +INSERT INTO phpbb_acl_groups (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (7, 2, 0, 24, 0); + + +# -- Demo Topic +INSERT INTO phpbb_topics (topic_title, topic_poster, topic_time, topic_views, topic_posts_approved, topic_posts_unapproved, topic_posts_softdeleted, forum_id, topic_status, topic_type, topic_first_post_id, topic_first_poster_name, topic_first_poster_colour, topic_last_post_id, topic_last_poster_id, topic_last_poster_name, topic_last_poster_colour, topic_last_post_subject, topic_last_post_time, topic_last_view_time, poll_title, topic_visibility) VALUES ('{L_TOPICS_TOPIC_TITLE}', 2, 972086460, 0, 1, 0, 0, 2, 0, 0, 1, 'Admin', 'AA0000', 1, 2, 'Admin', 'AA0000', '{L_TOPICS_TOPIC_TITLE}', 972086460, 972086460, '', 1); + +# -- Demo Post +INSERT INTO phpbb_posts (topic_id, forum_id, poster_id, icon_id, post_time, post_username, poster_ip, post_subject, post_text, post_checksum, bbcode_uid, post_visibility) VALUES (1, 2, 2, 0, 972086460, '', '127.0.0.1', '{L_TOPICS_TOPIC_TITLE}', '{L_DEFAULT_INSTALL_POST}', '5dd683b17f641daf84c040bfefc58ce9', '', 1); + +# -- Admin posted to the demo topic +INSERT INTO phpbb_topics_posted (user_id, topic_id, topic_posted) VALUES (2, 1, 1); + +# -- Smilies +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':D', 'icon_e_biggrin.gif', '{L_SMILIES_VERY_HAPPY}', 15, 17, 1); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':-D', 'icon_e_biggrin.gif', '{L_SMILIES_VERY_HAPPY}', 15, 17, 2); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':grin:', 'icon_e_biggrin.gif', '{L_SMILIES_VERY_HAPPY}', 15, 17, 3); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':)', 'icon_e_smile.gif', '{L_SMILIES_SMILE}', 15, 17, 4); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':-)', 'icon_e_smile.gif', '{L_SMILIES_SMILE}', 15, 17, 5); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':smile:', 'icon_e_smile.gif', '{L_SMILIES_SMILE}', 15, 17, 6); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (';)', 'icon_e_wink.gif', '{L_SMILIES_WINK}', 15, 17, 7); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (';-)', 'icon_e_wink.gif', '{L_SMILIES_WINK}', 15, 17, 8); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':wink:', 'icon_e_wink.gif', '{L_SMILIES_WINK}', 15, 17, 9); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':(', 'icon_e_sad.gif', '{L_SMILIES_SAD}', 15, 17, 10); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':-(', 'icon_e_sad.gif', '{L_SMILIES_SAD}', 15, 17, 11); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':sad:', 'icon_e_sad.gif', '{L_SMILIES_SAD}', 15, 17, 12); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':o', 'icon_e_surprised.gif', '{L_SMILIES_SURPRISED}', 15, 17, 13); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':-o', 'icon_e_surprised.gif', '{L_SMILIES_SURPRISED}', 15, 17, 14); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':eek:', 'icon_e_surprised.gif', '{L_SMILIES_SURPRISED}', 15, 17, 15); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':shock:', 'icon_eek.gif', '{L_SMILIES_SHOCKED}', 15, 17, 16); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':?', 'icon_e_confused.gif', '{L_SMILIES_CONFUSED}', 15, 17, 17); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':-?', 'icon_e_confused.gif', '{L_SMILIES_CONFUSED}', 15, 17, 18); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':???:', 'icon_e_confused.gif', '{L_SMILIES_CONFUSED}', 15, 17, 19); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES ('8-)', 'icon_cool.gif', '{L_SMILIES_COOL}', 15, 17, 20); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':cool:', 'icon_cool.gif', '{L_SMILIES_COOL}', 15, 17, 21); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':lol:', 'icon_lol.gif', '{L_SMILIES_LAUGHING}', 15, 17, 22); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':x', 'icon_mad.gif', '{L_SMILIES_MAD}', 15, 17, 23); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':-x', 'icon_mad.gif', '{L_SMILIES_MAD}', 15, 17, 24); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':mad:', 'icon_mad.gif', '{L_SMILIES_MAD}', 15, 17, 25); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':P', 'icon_razz.gif', '{L_SMILIES_RAZZ}', 15, 17, 26); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':-P', 'icon_razz.gif', '{L_SMILIES_RAZZ}', 15, 17, 27); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':razz:', 'icon_razz.gif', '{L_SMILIES_RAZZ}', 15, 17, 28); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':oops:', 'icon_redface.gif', '{L_SMILIES_EMARRASSED}', 15, 17, 29); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':cry:', 'icon_cry.gif', '{L_SMILIES_CRYING}', 15, 17, 30); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':evil:', 'icon_evil.gif', '{L_SMILIES_EVIL}', 15, 17, 31); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':twisted:', 'icon_twisted.gif', '{L_SMILIES_TWISTED_EVIL}', 15, 17, 32); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':roll:', 'icon_rolleyes.gif', '{L_SMILIES_ROLLING_EYES}', 15, 17, 33); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':!:', 'icon_exclaim.gif', '{L_SMILIES_EXCLAMATION}', 15, 17, 34); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':?:', 'icon_question.gif', '{L_SMILIES_QUESTION}', 15, 17, 35); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':idea:', 'icon_idea.gif', '{L_SMILIES_IDEA}', 15, 17, 36); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':arrow:', 'icon_arrow.gif', '{L_SMILIES_ARROW}', 15, 17, 37); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':|', 'icon_neutral.gif', '{L_SMILIES_NEUTRAL}', 15, 17, 38); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':-|', 'icon_neutral.gif', '{L_SMILIES_NEUTRAL}', 15, 17, 39); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':mrgreen:', 'icon_mrgreen.gif', '{L_SMILIES_MR_GREEN}', 15, 17, 40); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':geek:', 'icon_e_geek.gif', '{L_SMILIES_GEEK}', 17, 17, 41); +INSERT INTO phpbb_smilies (code, smiley_url, emotion, smiley_width, smiley_height, smiley_order) VALUES (':ugeek:', 'icon_e_ugeek.gif', '{L_SMILIES_UBER_GEEK}', 17, 18, 42); + +# -- icons +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('misc/fire.gif', 16, 16, 1, 1); +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('smile/redface.gif', 16, 16, 9, 1); +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('smile/mrgreen.gif', 16, 16, 10, 1); +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('misc/heart.gif', 16, 16, 4, 1); +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('misc/star.gif', 16, 16, 2, 1); +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('misc/radioactive.gif', 16, 16, 3, 1); +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('misc/thinking.gif', 16, 16, 5, 1); +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('smile/info.gif', 16, 16, 8, 1); +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('smile/question.gif', 16, 16, 6, 1); +INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, display_on_posting) VALUES ('smile/alert.gif', 16, 16, 7, 1); + +# -- reasons +INSERT INTO phpbb_reports_reasons (reason_title, reason_description, reason_order) VALUES ('warez', '{L_REPORT_WAREZ}', 1); +INSERT INTO phpbb_reports_reasons (reason_title, reason_description, reason_order) VALUES ('spam', '{L_REPORT_SPAM}', 2); +INSERT INTO phpbb_reports_reasons (reason_title, reason_description, reason_order) VALUES ('off_topic', '{L_REPORT_OFF_TOPIC}', 3); +INSERT INTO phpbb_reports_reasons (reason_title, reason_description, reason_order) VALUES ('other', '{L_REPORT_OTHER}', 4); + +# -- extension_groups +INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('IMAGES', 1, 1, 1, '', 0, ''); +INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('ARCHIVES', 0, 1, 1, '', 0, ''); +INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('PLAIN_TEXT', 0, 0, 1, '', 0, ''); +INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('DOCUMENTS', 0, 0, 1, '', 0, ''); +INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('REAL_MEDIA', 3, 0, 1, '', 0, ''); +INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('WINDOWS_MEDIA', 2, 0, 1, '', 0, ''); +INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('FLASH_FILES', 5, 0, 1, '', 0, ''); +INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('QUICKTIME_MEDIA', 6, 0, 1, '', 0, ''); +INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('DOWNLOADABLE_FILES', 0, 0, 1, '', 0, ''); + +# -- extensions +INSERT INTO phpbb_extensions (group_id, extension) VALUES (1, 'gif'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (1, 'png'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (1, 'jpeg'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (1, 'jpg'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (1, 'tif'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (1, 'tiff'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (1, 'tga'); + +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, 'gtar'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, 'gz'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, 'tar'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, 'zip'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, 'rar'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, 'ace'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, 'torrent'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, 'tgz'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, 'bz2'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (2, '7z'); + +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'txt'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'c'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'h'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'cpp'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'hpp'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'diz'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'csv'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'ini'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'log'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'js'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (3, 'xml'); + +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'xls'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'xlsx'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'xlsm'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'xlsb'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'doc'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'docx'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'docm'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'dot'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'dotx'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'dotm'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'pdf'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'ai'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'ps'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'ppt'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'pptx'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'pptm'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'odg'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'odp'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'ods'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'odt'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (4, 'rtf'); + +INSERT INTO phpbb_extensions (group_id, extension) VALUES (5, 'rm'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (5, 'ram'); + +INSERT INTO phpbb_extensions (group_id, extension) VALUES (6, 'wma'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (6, 'wmv'); + +INSERT INTO phpbb_extensions (group_id, extension) VALUES (7, 'swf'); + +INSERT INTO phpbb_extensions (group_id, extension) VALUES (8, 'mov'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (8, 'm4v'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (8, 'm4a'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (8, 'mp4'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (8, '3gp'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (8, '3g2'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (8, 'qt'); + +INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'mpeg'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'mpg'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'mp3'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'ogg'); +INSERT INTO phpbb_extensions (group_id, extension) VALUES (9, 'ogm'); + +# Add default profile fields +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_location', 'profilefields.type.string', 'phpbb_location', '20', '2', '100', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_website', 'profilefields.type.url', 'phpbb_website', '40', '12', '255', '', '', '', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 2, 1, 'VISIT_WEBSITE', '%s'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_interests', 'profilefields.type.text', 'phpbb_interests', '3|30', '2', '500', '', '', '.*', 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_occupation', 'profilefields.type.text', 'phpbb_occupation', '3|30', '2', '500', '', '', '.*', 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_aol', 'profilefields.type.string', 'phpbb_aol', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 5, 1, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_icq', 'profilefields.type.string', 'phpbb_icq', '20', '3', '15', '', '', '[0-9]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 6, 1, 'SEND_ICQ_MESSAGE', 'https://www.icq.com/people/%s/'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_wlm', 'profilefields.type.string', 'phpbb_wlm', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 7, 1, '', ''); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_yahoo', 'profilefields.type.string', 'phpbb_yahoo', '40', '5', '255', '', '', '.*', 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 8, 1, 'SEND_YIM_MESSAGE', 'ymsgr:sendim?%s'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_facebook', 'profilefields.type.string', 'phpbb_facebook', '20', '5', '50', '', '', '[\w.]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 9, 1, 'VIEW_FACEBOOK_PROFILE', 'http://facebook.com/%s/'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_twitter', 'profilefields.type.string', 'phpbb_twitter', '20', '1', '15', '', '', '[\w_]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 10, 1, 'VIEW_TWITTER_PROFILE', 'http://twitter.com/%s'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_skype', 'profilefields.type.string', 'phpbb_skype', '20', '6', '32', '', '', '[a-zA-Z][\w\.,\-_]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 11, 1, 'VIEW_SKYPE_PROFILE', 'skype:%s?userinfo'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_youtube', 'profilefields.type.string', 'phpbb_youtube', '20', '3', '60', '', '', '[a-zA-Z][\w\.,\-_]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 12, 1, 'VIEW_YOUTUBE_CHANNEL', 'http://youtube.com/user/%s'); +INSERT INTO phpbb_profile_fields (field_name, field_type, field_ident, field_length, field_minlen, field_maxlen, field_novalue, field_default_value, field_validation, field_required, field_show_novalue, field_show_on_reg, field_show_on_pm, field_show_on_vt, field_show_on_ml, field_show_profile, field_hide, field_no_view, field_active, field_order, field_is_contact, field_contact_desc, field_contact_url) VALUES ('phpbb_googleplus', 'profilefields.type.googleplus', 'phpbb_googleplus', '20', '3', '255', '', '', '[\w]+', 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 13, 1, 'VIEW_GOOGLEPLUS_PROFILE', 'http://plus.google.com/%s'); + +# User Notification Options (for first user) +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.post', 0, 2, ''); +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.post', 0, 2, 'notification.method.email'); +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.topic', 0, 2, ''); +INSERT INTO phpbb_user_notifications (item_type, item_id, user_id, method) VALUES('notification.type.topic', 0, 2, 'notification.method.email'); + +# POSTGRES COMMIT # diff --git a/phpBB/install_new/app.php b/phpBB/install_new/app.php new file mode 100644 index 0000000000..75b28fa092 --- /dev/null +++ b/phpBB/install_new/app.php @@ -0,0 +1,79 @@ + + * @license GNU General Public License, version 2 (GPL-2.0) + * + * For full copyright and license information, please see + * the docs/CREDITS.txt file. + * + */ + +/** + * @ignore + */ +define('IN_PHPBB', true); +define('IN_INSTALL', true); +define('PHPBB_ENVIRONMENT', 'production'); +$phpbb_root_path = '../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); + +// +// Let's do the common.php logic +// +require($phpbb_root_path . 'includes/startup.' . $phpEx); +require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx); + +$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); +$phpbb_class_loader->register(); + +// In case $phpbb_adm_relative_path is not set (in case of an update), use the default. +$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/'; +$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path; + +// Include files +require($phpbb_root_path . 'includes/functions.' . $phpEx); +require($phpbb_root_path . 'includes/functions_content.' . $phpEx); +include($phpbb_root_path . 'includes/functions_compatibility.' . $phpEx); +require($phpbb_root_path . 'includes/functions_user.' . $phpEx); +require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); + +// Set PHP error handler to ours +set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); + +$phpbb_installer_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); +$phpbb_installer_container = $phpbb_installer_container_builder + ->with_environment('installer') + ->without_extensions() + ->get_container(); + +// Path to templates +$paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style'); +$paths = array_filter($paths, 'is_dir'); + +/** @var \phpbb\filesystem\filesystem $phpbb_filesystem */ +$phpbb_filesystem = $phpbb_installer_container->get('filesystem'); + +/** @var \phpbb\template\template $template */ +$template = $phpbb_installer_container->get('template'); +$template->set_custom_style(array( + array( + 'name' => 'adm', + 'ext_path' => 'adm/style/', + ), +), $paths); + +/** @var \phpbb\language\language $language */ +$language = $phpbb_installer_container->get('language'); +$language->add_lang(array('common', 'acp/common', 'acp/board', 'install', 'posting')); + +/* @var $http_kernel \Symfony\Component\HttpKernel\HttpKernel */ +$http_kernel = $phpbb_installer_container->get('http_kernel'); + +/* @var $symfony_request \phpbb\symfony_request */ +$symfony_request = $phpbb_installer_container->get('symfony_request'); +$response = $http_kernel->handle($symfony_request); +$response->send(); +$http_kernel->terminate($symfony_request, $response); diff --git a/phpBB/install_new/phpbbcli.php b/phpBB/install_new/phpbbcli.php new file mode 100644 index 0000000000..20a202f584 --- /dev/null +++ b/phpBB/install_new/phpbbcli.php @@ -0,0 +1,68 @@ +#!/usr/bin/env php + +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +use Symfony\Component\Console\Input\ArgvInput; + +if (php_sapi_name() !== 'cli') +{ + echo 'This program must be run from the command line.' . PHP_EOL; + exit(1); +} + +define('IN_PHPBB', true); +define('IN_INSTALL', true); +define('PHPBB_ENVIRONMENT', 'production'); +$phpbb_root_path = __DIR__ . '/../'; +$phpEx = substr(strrchr(__FILE__, '.'), 1); + +// +// Let's do the common.php logic +// +require($phpbb_root_path . 'includes/startup.' . $phpEx); +require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx); + +$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); +$phpbb_class_loader->register(); + +// In case $phpbb_adm_relative_path is not set (in case of an update), use the default. +$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/'; +$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path; + +// Include files +require($phpbb_root_path . 'includes/functions.' . $phpEx); +require($phpbb_root_path . 'includes/functions_content.' . $phpEx); +include($phpbb_root_path . 'includes/functions_compatibility.' . $phpEx); +require($phpbb_root_path . 'includes/functions_user.' . $phpEx); +require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); + +// Set PHP error handler to ours +set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); + +$phpbb_installer_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); +$phpbb_installer_container = $phpbb_installer_container_builder + ->with_environment('installer') + ->without_extensions() + ->without_cache() + ->get_container(); + +/** @var \phpbb\filesystem\filesystem $phpbb_filesystem */ +$phpbb_filesystem = $phpbb_installer_container->get('filesystem'); + +/** @var \phpbb\language\language $language */ +$language = $phpbb_installer_container->get('language'); +$language->add_lang(array('common', 'acp/common', 'acp/board', 'install', 'posting', 'cli')); + +$application = new \phpbb\console\application('phpBB Installer', PHPBB_VERSION, $language); +$application->register_container_commands($phpbb_installer_container->get('console.installer.command_collection')); +$application->run($input); diff --git a/phpBB/install_old/convertors/convert_phpbb20.php b/phpBB/install_old/convertors/convert_phpbb20.php deleted file mode 100644 index a19bb2504b..0000000000 --- a/phpBB/install_old/convertors/convert_phpbb20.php +++ /dev/null @@ -1,975 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -/** -* NOTE to potential convertor authors. Please use this file to get -* familiar with the structure since we added some bare explanations here. -* -* Since this file gets included more than once on one page you are not able to add functions to it. -* Instead use a functions_ file. -* -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -$phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx); -extract($phpbb_config_php_file->get_all()); -unset($dbpasswd); - -$dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms); - -/** -* $convertor_data provides some basic information about this convertor which is -* used on the initial list of convertors and to populate the default settings -*/ -$convertor_data = array( - 'forum_name' => 'phpBB 2.0.x', - 'version' => '1.0.3', - 'phpbb_version' => '3.1.5', - 'author' => 'phpBB Limited', - 'dbms' => $dbms, - 'dbhost' => $dbhost, - 'dbport' => $dbport, - 'dbuser' => $dbuser, - 'dbpasswd' => '', - 'dbname' => $dbname, - 'table_prefix' => 'phpbb_', - 'forum_path' => '../forums', - 'author_notes' => '', -); - -/** -* $tables is a list of the tables (minus prefix) which we expect to find in the -* source forum. It is used to guess the prefix if the specified prefix is incorrect -*/ -$tables = array( - 'auth_access', - 'banlist', - 'categories', - 'disallow', - 'forum_prune', - 'forums', - 'groups', - 'posts', - 'posts_text', - 'privmsgs', - 'privmsgs_text', - 'ranks', - 'smilies', - 'topics', - 'topics_watch', - 'user_group', - 'users', - 'vote_desc', - 'vote_results', - 'vote_voters', - 'words' -); - -/** -* $config_schema details how the board configuration information is stored in the source forum. -* -* 'table_format' can take the value 'file' to indicate a config file. In this case array_name -* is set to indicate the name of the array the config values are stored in -* Example of using a file: -* $config_schema = array( -* 'table_format' => 'file', -* 'filename' => 'NAME OF FILE', // If the file is not in the root directory, the path needs to be added with no leading slash -* 'array_name' => 'NAME OF ARRAY', // Only used if the configuration file stores the setting in an array. -* 'settings' => array( -* 'board_email' => 'SUPPORT_EMAIL', // target config name => source target name -* ) -* ); -* 'table_format' can be an array if the values are stored in a table which is an assosciative array -* (as per phpBB 2.0.x) -* If left empty, values are assumed to be stored in a table where each config setting is -* a column (as per phpBB 1.x) -* -* In either of the latter cases 'table_name' indicates the name of the table in the database -* -* 'settings' is an array which maps the name of the config directive in the source forum -* to the config directive in phpBB3. It can either be a direct mapping or use a function. -* Please note that the contents of the old config value are passed to the function, therefore -* an in-built function requiring the variable passed by reference is not able to be used. Since -* empty() is such a function we created the function is_empty() to be used instead. -*/ -$config_schema = array( - 'table_name' => 'config', - 'table_format' => array('config_name' => 'config_value'), - 'settings' => array( - 'allow_bbcode' => 'allow_bbcode', - 'allow_smilies' => 'allow_smilies', - 'allow_sig' => 'allow_sig', - 'allow_namechange' => 'allow_namechange', - 'allow_avatar_local' => 'allow_avatar_local', - 'allow_avatar_remote' => 'allow_avatar_remote', - 'allow_avatar_upload' => 'allow_avatar_upload', - 'board_disable' => 'board_disable', - 'sitename' => 'phpbb_set_encoding(sitename)', - 'site_desc' => 'phpbb_set_encoding(site_desc)', - 'session_length' => 'session_length', - 'board_email_sig' => 'phpbb_set_encoding(board_email_sig)', - 'posts_per_page' => 'posts_per_page', - 'topics_per_page' => 'topics_per_page', - 'enable_confirm' => 'enable_confirm', - 'board_email_form' => 'board_email_form', - 'override_user_style' => 'override_user_style', - 'hot_threshold' => 'hot_threshold', - 'max_poll_options' => 'max_poll_options', - 'max_sig_chars' => 'max_sig_chars', - 'pm_max_msgs' => 'max_inbox_privmsgs', - 'smtp_delivery' => 'smtp_delivery', - 'smtp_host' => 'smtp_host', - 'smtp_username' => 'smtp_username', - 'smtp_password' => 'smtp_password', - 'require_activation' => 'require_activation', - 'flood_interval' => 'flood_interval', - 'avatar_filesize' => 'avatar_filesize', - 'avatar_max_width' => 'avatar_max_width', - 'avatar_max_height' => 'avatar_max_height', - 'default_dateformat' => 'phpbb_set_encoding(default_dateformat)', - 'board_timezone' => 'phpbb_convert_timezone(board_timezone)', - 'allow_privmsg' => 'not(privmsg_disable)', - 'gzip_compress' => 'gzip_compress', - 'coppa_enable' => '!is_empty(coppa_mail)', - 'coppa_fax' => 'coppa_fax', - 'coppa_mail' => 'coppa_mail', - 'record_online_users' => 'record_online_users', - 'record_online_date' => 'record_online_date', - 'board_startdate' => 'board_startdate', - ) -); - -/** -* $test_file is the name of a file which is present on the source -* forum which can be used to check that the path specified by the -* user was correct -*/ -$test_file = 'modcp.php'; - -/** -* If this is set then we are not generating the first page of information but getting the conversion information. -*/ -if (!$get_info) -{ - // Test to see if the birthday MOD is installed on the source forum - // Niels' birthday mod - if (get_config_value('birthday_required') !== false || get_config_value('bday_require') !== false) - { - define('MOD_BIRTHDAY', true); - } - - // TerraFrost's validated birthday mod - if (get_config_value('bday_require') !== false) - { - define('MOD_BIRTHDAY_TERRA', true); - } - - // Test to see if the attachment MOD is installed on the source forum - // If it is, we will convert this data as well - $src_db->sql_return_on_error(true); - - $sql = "SELECT config_value - FROM {$convert->src_table_prefix}attachments_config - WHERE config_name = 'upload_dir'"; - $result = $src_db->sql_query($sql); - - if ($result && $row = $src_db->sql_fetchrow($result)) - { - // Here the constant is defined - define('MOD_ATTACHMENT', true); - - // Here i add more tables to be checked in the old forum - $tables += array( - 'attachments', - 'attachments_desc', - 'extensions', - 'extension_groups' - ); - - $src_db->sql_freeresult($result); - } - else if ($result) - { - $src_db->sql_freeresult($result); - } - - - /** - * Tests for further MODs can be included here. - * Please use constants for this, prefixing them with MOD_ - */ - - $src_db->sql_return_on_error(false); - - // Now let us set a temporary config variable for user id incrementing - $sql = "SELECT user_id - FROM {$convert->src_table_prefix}users - WHERE user_id = 1"; - $result = $src_db->sql_query($sql); - $user_id = (int) $src_db->sql_fetchfield('user_id'); - $src_db->sql_freeresult($result); - - // If there is a user id 1, we need to increment user ids. :/ - if ($user_id === 1) - { - // Try to get the maximum user id possible... - $sql = "SELECT MAX(user_id) AS max_user_id - FROM {$convert->src_table_prefix}users"; - $result = $src_db->sql_query($sql); - $user_id = (int) $src_db->sql_fetchfield('max_user_id'); - $src_db->sql_freeresult($result); - - $config->set('increment_user_id', ($user_id + 1), false); - } - else - { - $config->set('increment_user_id', 0, false); - } - - // Overwrite maximum avatar width/height - @define('DEFAULT_AVATAR_X_CUSTOM', get_config_value('avatar_max_width')); - @define('DEFAULT_AVATAR_Y_CUSTOM', get_config_value('avatar_max_height')); - - // additional table used only during conversion - @define('USERCONV_TABLE', $table_prefix . 'userconv'); - -/** -* Description on how to use the convertor framework. -* -* 'schema' Syntax Description -* -> 'target' => Target Table. If not specified the next table will be handled -* -> 'primary' => Primary Key. If this is specified then this table is processed in batches -* -> 'query_first' => array('target' or 'src', Query to execute before beginning the process -* (if more than one then specified as array)) -* -> 'function_first' => Function to execute before beginning the process (if more than one then specified as array) -* (This is mostly useful if variables need to be given to the converting process) -* -> 'test_file' => This is not used at the moment but should be filled with a file from the old installation -* -* // DB Functions -* 'distinct' => Add DISTINCT to the select query -* 'where' => Add WHERE to the select query -* 'group_by' => Add GROUP BY to the select query -* 'left_join' => Add LEFT JOIN to the select query (if more than one joins specified as array) -* 'having' => Add HAVING to the select query -* -* // DB INSERT array -* This one consist of three parameters -* First Parameter: -* The key need to be filled within the target table -* If this is empty, the target table gets not assigned the source value -* Second Parameter: -* Source value. If the first parameter is specified, it will be assigned this value. -* If the first parameter is empty, this only gets added to the select query -* Third Parameter: -* Custom Function. Function to execute while storing source value into target table. -* The functions return value get stored. -* The function parameter consist of the value of the second parameter. -* -* types: -* - empty string == execute nothing -* - string == function to execute -* - array == complex execution instructions -* -* Complex execution instructions: -* @todo test complex execution instructions - in theory they will work fine -* -* By defining an array as the third parameter you are able to define some statements to be executed. The key -* is defining what to execute, numbers can be appended... -* -* 'function' => execute function -* 'execute' => run code, whereby all occurrences of {VALUE} get replaced by the last returned value. -* The result *must* be assigned/stored to {RESULT}. -* 'typecast' => typecast value -* -* The returned variables will be made always available to the next function to continue to work with. -* -* example (variable inputted is an integer of 1): -* -* array( -* 'function1' => 'increment_by_one', // returned variable is 2 -* 'typecast' => 'string', // typecast variable to be a string -* 'execute' => '{RESULT} = {VALUE} . ' is good';', // returned variable is '2 is good' -* 'function2' => 'replace_good_with_bad', // returned variable is '2 is bad' -* ), -* -*/ - - $convertor = array( - 'test_file' => 'viewtopic.php', - - 'avatar_path' => get_config_value('avatar_path') . '/', - 'avatar_gallery_path' => get_config_value('avatar_gallery_path') . '/', - 'smilies_path' => get_config_value('smilies_path') . '/', - 'upload_path' => (defined('MOD_ATTACHMENT')) ? phpbb_get_files_dir() . '/' : '', - 'thumbnails' => (defined('MOD_ATTACHMENT')) ? array('thumbs/', 't_') : '', - 'ranks_path' => false, // phpBB 2.0.x had no config value for a ranks path - - // We empty some tables to have clean data available - 'query_first' => array( - array('target', $convert->truncate_statement . SEARCH_RESULTS_TABLE), - array('target', $convert->truncate_statement . SEARCH_WORDLIST_TABLE), - array('target', $convert->truncate_statement . SEARCH_WORDMATCH_TABLE), - array('target', $convert->truncate_statement . LOG_TABLE), - ), - -// with this you are able to import all attachment files on the fly. For large boards this is not an option, therefore commented out by default. -// Instead every file gets copied while processing the corresponding attachment entry. -// if (defined("MOD_ATTACHMENT")) { import_attachment_files(); phpbb_copy_thumbnails(); } - - // phpBB2 allowed some similar usernames to coexist which would have the same - // username_clean in phpBB3 which is not possible, so we'll give the admin a list - // of user ids and usernames and let him deicde what he wants to do with them - 'execute_first' => ' - phpbb_create_userconv_table(); - import_avatar_gallery(); - if (defined("MOD_ATTACHMENT")) phpbb_import_attach_config(); - phpbb_insert_forums(); - ', - - 'execute_last' => array(' - add_bots(); - ', ' - update_folder_pm_count(); - ', ' - update_unread_count(); - ', (defined('MOD_ATTACHMENT')) ? ' - phpbb_attachment_extension_group_name(); - ' : ' - ', ' - phpbb_convert_authentication(\'start\'); - ', ' - phpbb_convert_authentication(\'first\'); - ', ' - phpbb_convert_authentication(\'second\'); - ', ' - phpbb_convert_authentication(\'third\'); - '), - - 'schema' => array( - array( - 'target' => USERCONV_TABLE, - 'query_first' => array('target', $convert->truncate_statement . USERCONV_TABLE), - - - array('user_id', 'users.user_id', ''), - array('username_clean', 'users.username', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_clean_string')), - ), - - array( - 'target' => (defined('MOD_ATTACHMENT')) ? ATTACHMENTS_TABLE : '', - 'primary' => 'attachments.attach_id', - 'query_first' => (defined('MOD_ATTACHMENT')) ? array('target', $convert->truncate_statement . ATTACHMENTS_TABLE) : '', - 'autoincrement' => 'attach_id', - - array('attach_id', 'attachments.attach_id', ''), - array('post_msg_id', 'attachments.post_id', ''), - array('topic_id', 'posts.topic_id', ''), - array('in_message', 0, ''), - array('is_orphan', 0, ''), - array('poster_id', 'attachments.user_id_1 AS poster_id', 'phpbb_user_id'), - array('physical_filename', 'attachments_desc.physical_filename', 'import_attachment'), - array('real_filename', 'attachments_desc.real_filename', 'phpbb_set_encoding'), - array('download_count', 'attachments_desc.download_count', ''), - array('attach_comment', 'attachments_desc.comment', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), - array('extension', 'attachments_desc.extension', ''), - array('mimetype', 'attachments_desc.mimetype', ''), - array('filesize', 'attachments_desc.filesize', ''), - array('filetime', 'attachments_desc.filetime', ''), - array('thumbnail', 'attachments_desc.thumbnail', ''), - - 'where' => 'attachments_desc.attach_id = attachments.attach_id AND attachments.privmsgs_id = 0 AND posts.post_id = attachments.post_id', - 'group_by' => 'attachments.attach_id' - ), - - array( - 'target' => (defined('MOD_ATTACHMENT')) ? ATTACHMENTS_TABLE : '', - 'primary' => 'attachments.attach_id', - 'autoincrement' => 'attach_id', - - array('attach_id', 'attachments.attach_id', ''), - array('post_msg_id', 'attachments.privmsgs_id', ''), - array('topic_id', 0, ''), - array('in_message', 1, ''), - array('is_orphan', 0, ''), - array('poster_id', 'attachments.user_id_1 AS poster_id', 'phpbb_user_id'), - array('physical_filename', 'attachments_desc.physical_filename', 'import_attachment'), - array('real_filename', 'attachments_desc.real_filename', 'phpbb_set_encoding'), - array('download_count', 'attachments_desc.download_count', ''), - array('attach_comment', 'attachments_desc.comment', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), - array('extension', 'attachments_desc.extension', ''), - array('mimetype', 'attachments_desc.mimetype', ''), - array('filesize', 'attachments_desc.filesize', ''), - array('filetime', 'attachments_desc.filetime', ''), - array('thumbnail', 'attachments_desc.thumbnail', ''), - - 'where' => 'attachments_desc.attach_id = attachments.attach_id AND attachments.post_id = 0', - 'group_by' => 'attachments.attach_id' - ), - - array( - 'target' => (defined('MOD_ATTACHMENT')) ? EXTENSIONS_TABLE : '', - 'query_first' => (defined('MOD_ATTACHMENT')) ? array('target', $convert->truncate_statement . EXTENSIONS_TABLE) : '', - 'autoincrement' => 'extension_id', - - array('extension_id', 'extensions.ext_id', ''), - array('group_id', 'extensions.group_id', ''), - array('extension', 'extensions.extension', ''), - ), - - array( - 'target' => (defined('MOD_ATTACHMENT')) ? EXTENSION_GROUPS_TABLE : '', - 'query_first' => (defined('MOD_ATTACHMENT')) ? array('target', $convert->truncate_statement . EXTENSION_GROUPS_TABLE) : '', - 'autoincrement' => 'group_id', - - array('group_id', 'extension_groups.group_id', ''), - array('group_name', 'extension_groups.group_name', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), - array('cat_id', 'extension_groups.cat_id', 'phpbb_attachment_category'), - array('allow_group', 'extension_groups.allow_group', ''), - array('download_mode', 1, ''), - array('upload_icon', '', ''), - array('max_filesize', 'extension_groups.max_filesize', ''), - array('allowed_forums', 'extension_groups.forum_permissions', 'phpbb_attachment_forum_perms'), - array('allow_in_pm', 1, ''), - ), - - array( - 'target' => BANLIST_TABLE, - 'execute_first' => 'phpbb_check_username_collisions();', - 'query_first' => array('target', $convert->truncate_statement . BANLIST_TABLE), - - array('ban_ip', 'banlist.ban_ip', 'decode_ban_ip'), - array('ban_userid', 'banlist.ban_userid', 'phpbb_user_id'), - array('ban_email', 'banlist.ban_email', ''), - array('ban_reason', '', ''), - array('ban_give_reason', '', ''), - - 'where' => "banlist.ban_ip NOT LIKE '%.%'", - ), - - array( - 'target' => BANLIST_TABLE, - - array('ban_ip', 'banlist.ban_ip', ''), - array('ban_userid', 0, ''), - array('ban_email', '', ''), - array('ban_reason', '', ''), - array('ban_give_reason', '', ''), - - 'where' => "banlist.ban_ip LIKE '%.%'", - ), - - array( - 'target' => DISALLOW_TABLE, - 'query_first' => array('target', $convert->truncate_statement . DISALLOW_TABLE), - - array('disallow_username', 'disallow.disallow_username', 'phpbb_disallowed_username'), - ), - - array( - 'target' => RANKS_TABLE, - 'query_first' => array('target', $convert->truncate_statement . RANKS_TABLE), - 'autoincrement' => 'rank_id', - - array('rank_id', 'ranks.rank_id', ''), - array('rank_title', 'ranks.rank_title', array('function1' => 'phpbb_set_default_encoding', 'function2' => 'utf8_htmlspecialchars')), - array('rank_min', 'ranks.rank_min', array('typecast' => 'int', 'execute' => '{RESULT} = ({VALUE}[0] < 0) ? 0 : {VALUE}[0];')), - array('rank_special', 'ranks.rank_special', ''), - array('rank_image', 'ranks.rank_image', 'import_rank'), - ), - - array( - 'target' => TOPICS_TABLE, - 'query_first' => array('target', $convert->truncate_statement . TOPICS_TABLE), - 'primary' => 'topics.topic_id', - 'autoincrement' => 'topic_id', - - array('topic_id', 'topics.topic_id', ''), - array('forum_id', 'topics.forum_id', ''), - array('icon_id', 0, ''), - array('topic_poster', 'topics.topic_poster AS poster_id', 'phpbb_user_id'), - array('topic_attachment', ((defined('MOD_ATTACHMENT')) ? 'topics.topic_attachment' : 0), ''), - array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'), - array('topic_time', 'topics.topic_time', ''), - array('topic_views', 'topics.topic_views', ''), - array('topic_posts_approved', 'topics.topic_replies', 'phpbb_topic_replies_to_posts'), - array('topic_posts_unapproved', 0, ''), - array('topic_posts_softdeleted',0, ''), - array('topic_last_post_id', 'topics.topic_last_post_id', ''), - array('topic_status', 'topics.topic_status', 'is_topic_locked'), - array('topic_moved_id', 0, ''), - array('topic_type', 'topics.topic_type', 'phpbb_convert_topic_type'), - array('topic_first_post_id', 'topics.topic_first_post_id', ''), - array('topic_last_view_time', 'posts.post_time', 'intval'), - array('topic_visibility', ITEM_APPROVED, ''), - - array('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => 'htmlspecialchars_decode', 'function4' => 'utf8_htmlspecialchars')), - array('poll_start', 'vote_desc.vote_start', 'null_to_zero'), - array('poll_length', 'vote_desc.vote_length', 'null_to_zero'), - array('poll_max_options', 1, ''), - array('poll_vote_change', 0, ''), - - 'left_join' => array ( 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1', - 'topics LEFT JOIN posts ON topics.topic_last_post_id = posts.post_id', - ), - 'where' => 'topics.topic_moved_id = 0', - ), - - array( - 'target' => TOPICS_TABLE, - 'primary' => 'topics.topic_id', - 'autoincrement' => 'topic_id', - - array('topic_id', 'topics.topic_id', ''), - array('forum_id', 'topics.forum_id', ''), - array('icon_id', 0, ''), - array('topic_poster', 'topics.topic_poster AS poster_id', 'phpbb_user_id'), - array('topic_attachment', ((defined('MOD_ATTACHMENT')) ? 'topics.topic_attachment' : 0), ''), - array('topic_title', 'topics.topic_title', 'phpbb_set_encoding'), - array('topic_time', 'topics.topic_time', ''), - array('topic_views', 'topics.topic_views', ''), - array('topic_posts_approved', 'topics.topic_replies', 'phpbb_topic_replies_to_posts'), - array('topic_posts_unapproved', 0, ''), - array('topic_posts_softdeleted',0, ''), - array('topic_last_post_id', 'topics.topic_last_post_id', ''), - array('topic_status', ITEM_MOVED, ''), - array('topic_moved_id', 'topics.topic_moved_id', ''), - array('topic_type', 'topics.topic_type', 'phpbb_convert_topic_type'), - array('topic_first_post_id', 'topics.topic_first_post_id', ''), - array('topic_visibility', ITEM_APPROVED, ''), - - array('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => 'htmlspecialchars_decode', 'function4' => 'utf8_htmlspecialchars')), - array('poll_start', 'vote_desc.vote_start', 'null_to_zero'), - array('poll_length', 'vote_desc.vote_length', 'null_to_zero'), - array('poll_max_options', 1, ''), - array('poll_vote_change', 0, ''), - - 'left_join' => 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1', - 'where' => 'topics.topic_moved_id <> 0', - ), - - array( - 'target' => TOPICS_WATCH_TABLE, - 'primary' => 'topics_watch.topic_id', - 'query_first' => array('target', $convert->truncate_statement . TOPICS_WATCH_TABLE), - - array('topic_id', 'topics_watch.topic_id', ''), - array('user_id', 'topics_watch.user_id', 'phpbb_user_id'), - array('notify_status', 'topics_watch.notify_status', ''), - ), - - array( - 'target' => SMILIES_TABLE, - 'query_first' => array('target', $convert->truncate_statement . SMILIES_TABLE), - 'autoincrement' => 'smiley_id', - - array('smiley_id', 'smilies.smilies_id', ''), - array('code', 'smilies.code', array('function1' => 'phpbb_smilie_html_decode', 'function2' => 'phpbb_set_encoding', 'function3' => 'utf8_htmlspecialchars')), - array('emotion', 'smilies.emoticon', 'phpbb_set_encoding'), - array('smiley_url', 'smilies.smile_url', 'import_smiley'), - array('smiley_width', 'smilies.smile_url', 'get_smiley_width'), - array('smiley_height', 'smilies.smile_url', 'get_smiley_height'), - array('smiley_order', 'smilies.smilies_id', ''), - array('display_on_posting', 'smilies.smilies_id', 'get_smiley_display'), - - 'order_by' => 'smilies.smilies_id ASC', - ), - - array( - 'target' => POLL_OPTIONS_TABLE, - 'primary' => 'vote_results.vote_option_id', - 'query_first' => array('target', $convert->truncate_statement . POLL_OPTIONS_TABLE), - - array('poll_option_id', 'vote_results.vote_option_id', ''), - array('topic_id', 'vote_desc.topic_id', ''), - array('', 'topics.topic_poster AS poster_id', 'phpbb_user_id'), - array('poll_option_text', 'vote_results.vote_option_text', array('function1' => 'phpbb_set_encoding', 'function2' => 'htmlspecialchars_decode', 'function3' => 'utf8_htmlspecialchars')), - array('poll_option_total', 'vote_results.vote_result', ''), - - 'where' => 'vote_results.vote_id = vote_desc.vote_id', - 'left_join' => 'vote_desc LEFT JOIN topics ON topics.topic_id = vote_desc.topic_id', - ), - - array( - 'target' => POLL_VOTES_TABLE, - 'primary' => 'vote_desc.topic_id', - 'query_first' => array('target', $convert->truncate_statement . POLL_VOTES_TABLE), - - array('poll_option_id', VOTE_CONVERTED, ''), - array('topic_id', 'vote_desc.topic_id', ''), - array('vote_user_id', 'vote_voters.vote_user_id', 'phpbb_user_id'), - array('vote_user_ip', 'vote_voters.vote_user_ip', 'decode_ip'), - - 'where' => 'vote_voters.vote_id = vote_desc.vote_id', - ), - - array( - 'target' => WORDS_TABLE, - 'primary' => 'words.word_id', - 'query_first' => array('target', $convert->truncate_statement . WORDS_TABLE), - 'autoincrement' => 'word_id', - - array('word_id', 'words.word_id', ''), - array('word', 'words.word', 'phpbb_set_encoding'), - array('replacement', 'words.replacement', 'phpbb_set_encoding'), - ), - - array( - 'target' => POSTS_TABLE, - 'primary' => 'posts.post_id', - 'autoincrement' => 'post_id', - 'query_first' => array('target', $convert->truncate_statement . POSTS_TABLE), - 'execute_first' => ' - $config["max_post_chars"] = 0; - $config["min_post_chars"] = 0; - $config["max_quote_depth"] = 0; - ', - - array('post_id', 'posts.post_id', ''), - array('topic_id', 'posts.topic_id', ''), - array('forum_id', 'posts.forum_id', ''), - array('poster_id', 'posts.poster_id', 'phpbb_user_id'), - array('icon_id', 0, ''), - array('poster_ip', 'posts.poster_ip', 'decode_ip'), - array('post_time', 'posts.post_time', ''), - array('enable_bbcode', 'posts.enable_bbcode', ''), - array('', 'posts.enable_html', ''), - array('enable_smilies', 'posts.enable_smilies', ''), - array('enable_sig', 'posts.enable_sig', ''), - array('enable_magic_url', 1, ''), - array('post_username', 'posts.post_username', 'phpbb_set_encoding'), - array('post_subject', 'posts_text.post_subject', 'phpbb_set_encoding'), - array('post_attachment', ((defined('MOD_ATTACHMENT')) ? 'posts.post_attachment' : 0), ''), - array('post_edit_time', 'posts.post_edit_time', array('typecast' => 'int')), - array('post_edit_count', 'posts.post_edit_count', ''), - array('post_edit_reason', '', ''), - array('post_edit_user', '', 'phpbb_post_edit_user'), - array('post_visibility', ITEM_APPROVED, ''), - - array('bbcode_uid', 'posts.post_time', 'make_uid'), - array('post_text', 'posts_text.post_text', 'phpbb_prepare_message'), - array('', 'posts_text.bbcode_uid AS old_bbcode_uid', ''), - array('bbcode_bitfield', '', 'get_bbcode_bitfield'), - array('post_checksum', '', ''), - - // Commented out inline search indexing, this takes up a LOT of time. :D - // @todo We either need to enable this or call the rebuild search functionality post convert -/* array('', '', 'search_indexing'), - array('', 'posts_text.post_text AS message', ''), - array('', 'posts_text.post_subject AS title', ''),*/ - - 'where' => 'posts.post_id = posts_text.post_id' - ), - - array( - 'target' => PRIVMSGS_TABLE, - 'primary' => 'privmsgs.privmsgs_id', - 'autoincrement' => 'msg_id', - 'query_first' => array( - array('target', $convert->truncate_statement . PRIVMSGS_TABLE), - array('target', $convert->truncate_statement . PRIVMSGS_RULES_TABLE), - ), - - 'execute_first' => ' - $config["max_post_chars"] = 0; - $config["min_post_chars"] = 0; - $config["max_quote_depth"] = 0; - ', - - array('msg_id', 'privmsgs.privmsgs_id', ''), - array('root_level', 0, ''), - array('author_id', 'privmsgs.privmsgs_from_userid AS poster_id', 'phpbb_user_id'), - array('icon_id', 0, ''), - array('author_ip', 'privmsgs.privmsgs_ip', 'decode_ip'), - array('message_time', 'privmsgs.privmsgs_date', ''), - array('enable_bbcode', 'privmsgs.privmsgs_enable_bbcode AS enable_bbcode', ''), - array('', 'privmsgs.privmsgs_enable_html AS enable_html', ''), - array('enable_smilies', 'privmsgs.privmsgs_enable_smilies AS enable_smilies', ''), - array('enable_magic_url', 1, ''), - array('enable_sig', 'privmsgs.privmsgs_attach_sig', ''), - array('message_subject', 'privmsgs.privmsgs_subject', 'phpbb_set_encoding'), // Already specialchared in 2.0.x - array('message_attachment', ((defined('MOD_ATTACHMENT')) ? 'privmsgs.privmsgs_attachment' : 0), ''), - array('message_edit_reason', '', ''), - array('message_edit_user', 0, ''), - array('message_edit_time', 0, ''), - array('message_edit_count', 0, ''), - - array('bbcode_uid', 'privmsgs.privmsgs_date AS post_time', 'make_uid'), - array('message_text', 'privmsgs_text.privmsgs_text', 'phpbb_prepare_message'), - array('', 'privmsgs_text.privmsgs_bbcode_uid AS old_bbcode_uid', ''), - array('bbcode_bitfield', '', 'get_bbcode_bitfield'), - array('to_address', 'privmsgs.privmsgs_to_userid', 'phpbb_privmsgs_to_userid'), - array('bcc_address', '', ''), - - 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id' - ), - - array( - 'target' => PRIVMSGS_FOLDER_TABLE, - 'primary' => 'users.user_id', - 'query_first' => array('target', $convert->truncate_statement . PRIVMSGS_FOLDER_TABLE), - - array('user_id', 'users.user_id', 'phpbb_user_id'), - array('folder_name', $user->lang['CONV_SAVED_MESSAGES'], ''), - array('pm_count', 0, ''), - - 'where' => 'users.user_id <> -1', - ), - - // Inbox - array( - 'target' => PRIVMSGS_TO_TABLE, - 'primary' => 'privmsgs.privmsgs_id', - 'query_first' => array('target', $convert->truncate_statement . PRIVMSGS_TO_TABLE), - - array('msg_id', 'privmsgs.privmsgs_id', ''), - array('user_id', 'privmsgs.privmsgs_to_userid', 'phpbb_user_id'), - array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), - array('pm_deleted', 0, ''), - array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'), - array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'), - array('pm_replied', 0, ''), - array('pm_marked', 0, ''), - array('pm_forwarded', 0, ''), - array('folder_id', PRIVMSGS_INBOX, ''), - - 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id - AND (privmsgs.privmsgs_type = 0 OR privmsgs.privmsgs_type = 1 OR privmsgs.privmsgs_type = 5)', - ), - - // Outbox - array( - 'target' => PRIVMSGS_TO_TABLE, - 'primary' => 'privmsgs.privmsgs_id', - - array('msg_id', 'privmsgs.privmsgs_id', ''), - array('user_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), - array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), - array('pm_deleted', 0, ''), - array('pm_new', 0, ''), - array('pm_unread', 0, ''), - array('pm_replied', 0, ''), - array('pm_marked', 0, ''), - array('pm_forwarded', 0, ''), - array('folder_id', PRIVMSGS_OUTBOX, ''), - - 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id - AND (privmsgs.privmsgs_type = 1 OR privmsgs.privmsgs_type = 5)', - ), - - // Sentbox - array( - 'target' => PRIVMSGS_TO_TABLE, - 'primary' => 'privmsgs.privmsgs_id', - - array('msg_id', 'privmsgs.privmsgs_id', ''), - array('user_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), - array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), - array('pm_deleted', 0, ''), - array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'), - array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'), - array('pm_replied', 0, ''), - array('pm_marked', 0, ''), - array('pm_forwarded', 0, ''), - array('folder_id', PRIVMSGS_SENTBOX, ''), - - 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id - AND privmsgs.privmsgs_type = 2', - ), - - // Savebox (SAVED IN) - array( - 'target' => PRIVMSGS_TO_TABLE, - 'primary' => 'privmsgs.privmsgs_id', - - array('msg_id', 'privmsgs.privmsgs_id', ''), - array('user_id', 'privmsgs.privmsgs_to_userid', 'phpbb_user_id'), - array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), - array('pm_deleted', 0, ''), - array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'), - array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'), - array('pm_replied', 0, ''), - array('pm_marked', 0, ''), - array('pm_forwarded', 0, ''), - array('folder_id', 'privmsgs.privmsgs_to_userid', 'phpbb_get_savebox_id'), - - 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id - AND privmsgs.privmsgs_type = 3', - ), - - // Savebox (SAVED OUT) - array( - 'target' => PRIVMSGS_TO_TABLE, - 'primary' => 'privmsgs.privmsgs_id', - - array('msg_id', 'privmsgs.privmsgs_id', ''), - array('user_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), - array('author_id', 'privmsgs.privmsgs_from_userid', 'phpbb_user_id'), - array('pm_deleted', 0, ''), - array('pm_new', 'privmsgs.privmsgs_type', 'phpbb_new_pm'), - array('pm_unread', 'privmsgs.privmsgs_type', 'phpbb_unread_pm'), - array('pm_replied', 0, ''), - array('pm_marked', 0, ''), - array('pm_forwarded', 0, ''), - array('folder_id', 'privmsgs.privmsgs_from_userid', 'phpbb_get_savebox_id'), - - 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id - AND privmsgs.privmsgs_type = 4', - ), - - array( - 'target' => GROUPS_TABLE, - 'autoincrement' => 'group_id', - 'query_first' => array( - array('target', $convert->truncate_statement . GROUPS_TABLE), - array('target', $convert->truncate_statement . TEAMPAGE_TABLE), - ), - - array('group_id', 'groups.group_id', ''), - array('group_type', 'groups.group_type', 'phpbb_convert_group_type'), - array('group_display', 0, ''), - array('group_legend', 0, ''), - array('group_name', 'groups.group_name', 'phpbb_convert_group_name'), // phpbb_set_encoding called in phpbb_convert_group_name - array('group_desc', 'groups.group_description', 'phpbb_set_encoding'), - - 'where' => 'groups.group_single_user = 0', - ), - - array( - 'target' => USER_GROUP_TABLE, - 'query_first' => array('target', $convert->truncate_statement . USER_GROUP_TABLE), - 'execute_first' => ' - add_default_groups(); - add_groups_to_teampage(); - ', - - array('group_id', 'groups.group_id', ''), - array('user_id', 'groups.group_moderator', 'phpbb_user_id'), - array('group_leader', 1, ''), - array('user_pending', 0, ''), - - 'where' => 'groups.group_single_user = 0 AND groups.group_moderator <> 0', - ), - - array( - 'target' => USER_GROUP_TABLE, - - array('group_id', 'user_group.group_id', ''), - array('user_id', 'user_group.user_id', 'phpbb_user_id'), - array('group_leader', 0, ''), - array('user_pending', 'user_group.user_pending', ''), - - 'where' => 'user_group.group_id = groups.group_id AND groups.group_single_user = 0 AND groups.group_moderator <> user_group.user_id', - ), - - array( - 'target' => USERS_TABLE, - 'primary' => 'users.user_id', - 'autoincrement' => 'user_id', - 'query_first' => array( - array('target', 'DELETE FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS), - array('target', $convert->truncate_statement . BOTS_TABLE), - array('target', $convert->truncate_statement . USER_NOTIFICATIONS_TABLE), - ), - - 'execute_last' => ' - remove_invalid_users(); - ', - - array('user_id', 'users.user_id', 'phpbb_user_id'), - array('', 'users.user_id AS poster_id', 'phpbb_user_id'), - array('user_type', 'users.user_active', 'set_user_type'), - array('group_id', 'users.user_level', 'phpbb_set_primary_group'), - array('user_regdate', 'users.user_regdate', ''), - array('username', 'users.username', 'phpbb_set_default_encoding'), // recode to utf8 with default lang - array('username_clean', 'users.username', array('function1' => 'phpbb_set_default_encoding', 'function2' => 'utf8_clean_string')), - array('user_password', 'users.user_password', 'phpbb_convert_password_hash'), - array('user_posts', 'users.user_posts', 'intval'), - array('user_email', 'users.user_email', 'strtolower'), - array('user_email_hash', 'users.user_email', 'gen_email_hash'), - array('user_birthday', ((defined('MOD_BIRTHDAY')) ? 'users.user_birthday' : ''), 'phpbb_get_birthday'), - array('user_lastvisit', 'users.user_lastvisit', 'intval'), - array('user_lastmark', 'users.user_lastvisit', 'intval'), - array('user_lang', $config['default_lang'], ''), - array('', 'users.user_lang', ''), - array('user_timezone', 'users.user_timezone', 'phpbb_convert_timezone'), - array('user_dateformat', 'users.user_dateformat', array('function1' => 'phpbb_set_encoding', 'function2' => 'fill_dateformat')), - array('user_inactive_reason', '', 'phpbb_inactive_reason'), - array('user_inactive_time', '', 'phpbb_inactive_time'), - - array('user_jabber', '', ''), - array('user_rank', 'users.user_rank', 'intval'), - array('user_permissions', '', ''), - - array('user_avatar', 'users.user_avatar', 'phpbb_import_avatar'), - array('user_avatar_type', 'users.user_avatar_type', 'phpbb_avatar_type'), - array('user_avatar_width', 'users.user_avatar', 'phpbb_get_avatar_width'), - array('user_avatar_height', 'users.user_avatar', 'phpbb_get_avatar_height'), - - array('user_new_privmsg', 'users.user_new_privmsg', ''), - array('user_unread_privmsg', 0, ''), //'users.user_unread_privmsg' - array('user_last_privmsg', 'users.user_last_privmsg', 'intval'), - array('user_emailtime', 'users.user_emailtime', 'null_to_zero'), - array('user_notify', 'users.user_notify', 'intval'), - array('user_notify_pm', 'users.user_notify_pm', 'intval'), - array('user_notify_type', NOTIFY_EMAIL, ''), - array('user_allow_pm', 'users.user_allow_pm', 'intval'), - array('user_allow_viewonline', 'users.user_allow_viewonline', 'intval'), - array('user_allow_viewemail', 'users.user_viewemail', 'intval'), - array('user_actkey', 'users.user_actkey', ''), - array('user_newpasswd', '', ''), // Users need to re-request their password... - array('user_style', $config['default_style'], ''), - - array('user_options', '', 'set_user_options'), - array('', 'users.user_popup_pm AS popuppm', ''), - array('', 'users.user_allowhtml AS html', ''), - array('', 'users.user_allowbbcode AS bbcode', ''), - array('', 'users.user_allowsmile AS smile', ''), - array('', 'users.user_attachsig AS attachsig',''), - - array('user_sig_bbcode_uid', 'users.user_regdate', 'make_uid'), - array('user_sig', 'users.user_sig', 'phpbb_prepare_message'), - array('', 'users.user_sig_bbcode_uid AS old_bbcode_uid', ''), - array('user_sig_bbcode_bitfield', '', 'get_bbcode_bitfield'), - array('', 'users.user_regdate AS post_time', ''), - - array('', 'users.user_notify_pm', 'phpbb_add_notification_options'), - - 'where' => 'users.user_id <> -1', - ), - - array( - 'target' => PROFILE_FIELDS_DATA_TABLE, - 'primary' => 'users.user_id', - 'query_first' => array( - array('target', $convert->truncate_statement . PROFILE_FIELDS_DATA_TABLE), - ), - - array('user_id', 'users.user_id', 'phpbb_user_id'), - array('pf_phpbb_occupation', 'users.user_occ', array('function1' => 'phpbb_set_encoding')), - array('pf_phpbb_interests', 'users.user_interests', array('function1' => 'phpbb_set_encoding')), - array('pf_phpbb_location', 'users.user_from', array('function1' => 'phpbb_set_encoding')), - array('pf_phpbb_icq', 'users.user_icq', array('function1' => 'phpbb_set_encoding')), - array('pf_phpbb_wlm', 'users.user_msnm', array('function1' => 'phpbb_set_encoding')), - array('pf_phpbb_yahoo', 'users.user_yim', array('function1' => 'phpbb_set_encoding')), - array('pf_phpbb_aol', 'users.user_aim', array('function1' => 'phpbb_set_encoding')), - array('pf_phpbb_website', 'users.user_website', 'validate_website'), - - 'where' => 'users.user_id <> -1', - ), - ), - ); -} diff --git a/phpBB/install_old/convertors/functions_phpbb20.php b/phpBB/install_old/convertors/functions_phpbb20.php deleted file mode 100644 index 48cff426b8..0000000000 --- a/phpBB/install_old/convertors/functions_phpbb20.php +++ /dev/null @@ -1,1984 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -if (!defined('IN_PHPBB')) -{ - exit; -} - -/** -* Helper functions for phpBB 2.0.x to phpBB 3.1.x conversion -*/ - -/** -* Set forum flags - only prune old polls by default -*/ -function phpbb_forum_flags() -{ - // Set forum flags - $forum_flags = 0; - - // FORUM_FLAG_LINK_TRACK - $forum_flags += 0; - - // FORUM_FLAG_PRUNE_POLL - $forum_flags += FORUM_FLAG_PRUNE_POLL; - - // FORUM_FLAG_PRUNE_ANNOUNCE - $forum_flags += 0; - - // FORUM_FLAG_PRUNE_STICKY - $forum_flags += 0; - - // FORUM_FLAG_ACTIVE_TOPICS - $forum_flags += 0; - - // FORUM_FLAG_POST_REVIEW - $forum_flags += FORUM_FLAG_POST_REVIEW; - - return $forum_flags; -} - -/** -* Insert/Convert forums -*/ -function phpbb_insert_forums() -{ - global $db, $src_db, $same_db, $convert, $user, $config; - - $db->sql_query($convert->truncate_statement . FORUMS_TABLE); - - // Determine the highest id used within the old forums table (we add the categories after the forum ids) - $sql = 'SELECT MAX(forum_id) AS max_forum_id - FROM ' . $convert->src_table_prefix . 'forums'; - $result = $src_db->sql_query($sql); - $max_forum_id = (int) $src_db->sql_fetchfield('max_forum_id'); - $src_db->sql_freeresult($result); - - $max_forum_id++; - - // pruning disabled globally? - $sql = "SELECT config_value - FROM {$convert->src_table_prefix}config - WHERE config_name = 'prune_enable'"; - $result = $src_db->sql_query($sql); - $prune_enabled = (int) $src_db->sql_fetchfield('config_value'); - $src_db->sql_freeresult($result); - - // Insert categories - $sql = 'SELECT cat_id, cat_title - FROM ' . $convert->src_table_prefix . 'categories - ORDER BY cat_order'; - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'binary'"); - } - - $result = $src_db->sql_query($sql); - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'utf8'"); - } - - switch ($db->get_sql_layer()) - { - case 'mssql': - case 'mssql_odbc': - case 'mssqlnative': - $db->sql_query('SET IDENTITY_INSERT ' . FORUMS_TABLE . ' ON'); - break; - } - - $cats_added = array(); - while ($row = $src_db->sql_fetchrow($result)) - { - $sql_ary = array( - 'forum_id' => (int) $max_forum_id, - 'forum_name' => ($row['cat_title']) ? htmlspecialchars(phpbb_set_default_encoding($row['cat_title']), ENT_COMPAT, 'UTF-8') : $user->lang['CATEGORY'], - 'parent_id' => 0, - 'forum_parents' => '', - 'forum_desc' => '', - 'forum_type' => FORUM_CAT, - 'forum_status' => ITEM_UNLOCKED, - 'forum_rules' => '', - ); - - $sql = 'SELECT MAX(right_id) AS right_id - FROM ' . FORUMS_TABLE; - $_result = $db->sql_query($sql); - $cat_row = $db->sql_fetchrow($_result); - $db->sql_freeresult($_result); - - $sql_ary['left_id'] = (int) ($cat_row['right_id'] + 1); - $sql_ary['right_id'] = (int) ($cat_row['right_id'] + 2); - - $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); - $db->sql_query($sql); - - $cats_added[$row['cat_id']] = $max_forum_id; - $max_forum_id++; - } - $src_db->sql_freeresult($result); - - // There may be installations having forums with non-existant category ids. - // We try to catch them and add them to an "unknown" category instead of leaving them out. - $sql = 'SELECT cat_id - FROM ' . $convert->src_table_prefix . 'forums - GROUP BY cat_id'; - $result = $src_db->sql_query($sql); - - $unknown_cat_id = false; - while ($row = $src_db->sql_fetchrow($result)) - { - // Catch those categories not been added before - if (!isset($cats_added[$row['cat_id']])) - { - $unknown_cat_id = true; - } - } - $src_db->sql_freeresult($result); - - // Is there at least one category not known? - if ($unknown_cat_id === true) - { - $unknown_cat_id = 'ghost'; - - $sql_ary = array( - 'forum_id' => (int) $max_forum_id, - 'forum_name' => (string) $user->lang['CATEGORY'], - 'parent_id' => 0, - 'forum_parents' => '', - 'forum_desc' => '', - 'forum_type' => FORUM_CAT, - 'forum_status' => ITEM_UNLOCKED, - 'forum_rules' => '', - ); - - $sql = 'SELECT MAX(right_id) AS right_id - FROM ' . FORUMS_TABLE; - $_result = $db->sql_query($sql); - $cat_row = $db->sql_fetchrow($_result); - $db->sql_freeresult($_result); - - $sql_ary['left_id'] = (int) ($cat_row['right_id'] + 1); - $sql_ary['right_id'] = (int) ($cat_row['right_id'] + 2); - - $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); - $db->sql_query($sql); - - $cats_added[$unknown_cat_id] = $max_forum_id; - $max_forum_id++; - } - - // Now insert the forums - $sql = 'SELECT f.forum_id, f.forum_name, f.cat_id, f.forum_desc, f.forum_status, f.prune_enable, f.prune_next, fp.prune_days, fp.prune_freq FROM ' . $convert->src_table_prefix . 'forums f - LEFT JOIN ' . $convert->src_table_prefix . 'forum_prune fp ON f.forum_id = fp.forum_id - GROUP BY f.forum_id, f.forum_name, f.cat_id, f.forum_desc, f.forum_status, f.prune_enable, f.prune_next, f.forum_order, fp.prune_days, fp.prune_freq - ORDER BY f.cat_id, f.forum_order'; - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'binary'"); - } - - $result = $src_db->sql_query($sql); - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'utf8'"); - } - - while ($row = $src_db->sql_fetchrow($result)) - { - // Some might have forums here with an id not being "possible"... - // To be somewhat friendly we "change" the category id for those to a previously created ghost category - if (!isset($cats_added[$row['cat_id']]) && $unknown_cat_id !== false) - { - $row['cat_id'] = $unknown_cat_id; - } - - if (!isset($cats_added[$row['cat_id']])) - { - continue; - } - - // Define the new forums sql ary - $sql_ary = array( - 'forum_id' => (int) $row['forum_id'], - 'forum_name' => htmlspecialchars(phpbb_set_default_encoding($row['forum_name']), ENT_COMPAT, 'UTF-8'), - 'parent_id' => (int) $cats_added[$row['cat_id']], - 'forum_parents' => '', - 'forum_desc' => htmlspecialchars(phpbb_set_default_encoding($row['forum_desc']), ENT_COMPAT, 'UTF-8'), - 'forum_type' => FORUM_POST, - 'forum_status' => is_item_locked($row['forum_status']), - 'enable_prune' => ($prune_enabled) ? (int) $row['prune_enable'] : 0, - 'prune_next' => (int) null_to_zero($row['prune_next']), - 'prune_days' => (int) null_to_zero($row['prune_days']), - 'prune_viewed' => 0, - 'prune_freq' => (int) null_to_zero($row['prune_freq']), - - 'forum_flags' => phpbb_forum_flags(), - 'forum_options' => 0, - - // Default values - 'forum_desc_bitfield' => '', - 'forum_desc_options' => 7, - 'forum_desc_uid' => '', - 'forum_link' => '', - 'forum_password' => '', - 'forum_style' => 0, - 'forum_image' => '', - 'forum_rules' => '', - 'forum_rules_link' => '', - 'forum_rules_bitfield' => '', - 'forum_rules_options' => 7, - 'forum_rules_uid' => '', - 'forum_topics_per_page' => 0, - 'forum_posts_approved' => 0, - 'forum_posts_unapproved' => 0, - 'forum_posts_softdeleted' => 0, - 'forum_topics_approved' => 0, - 'forum_topics_unapproved' => 0, - 'forum_topics_softdeleted' => 0, - 'forum_last_post_id' => 0, - 'forum_last_poster_id' => 0, - 'forum_last_post_subject' => '', - 'forum_last_post_time' => 0, - 'forum_last_poster_name' => '', - 'forum_last_poster_colour' => '', - 'display_on_index' => 1, - 'enable_indexing' => 1, - 'enable_icons' => 0, - ); - - // Now add the forums with proper left/right ids - $sql = 'SELECT left_id, right_id - FROM ' . FORUMS_TABLE . ' - WHERE forum_id = ' . $cats_added[$row['cat_id']]; - $_result = $db->sql_query($sql); - $cat_row = $db->sql_fetchrow($_result); - $db->sql_freeresult($_result); - - $sql = 'UPDATE ' . FORUMS_TABLE . ' - SET left_id = left_id + 2, right_id = right_id + 2 - WHERE left_id > ' . $cat_row['right_id']; - $db->sql_query($sql); - - $sql = 'UPDATE ' . FORUMS_TABLE . ' - SET right_id = right_id + 2 - WHERE ' . $cat_row['left_id'] . ' BETWEEN left_id AND right_id'; - $db->sql_query($sql); - - $sql_ary['left_id'] = (int) $cat_row['right_id']; - $sql_ary['right_id'] = (int) ($cat_row['right_id'] + 1); - - $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); - $db->sql_query($sql); - } - $src_db->sql_freeresult($result); - - switch ($db->get_sql_layer()) - { - case 'postgres': - $db->sql_query("SELECT SETVAL('" . FORUMS_TABLE . "_seq',(select case when max(forum_id)>0 then max(forum_id)+1 else 1 end from " . FORUMS_TABLE . '));'); - break; - - case 'mssql': - case 'mssql_odbc': - case 'mssqlnative': - $db->sql_query('SET IDENTITY_INSERT ' . FORUMS_TABLE . ' OFF'); - break; - - case 'oracle': - $result = $db->sql_query('SELECT MAX(forum_id) as max_id FROM ' . FORUMS_TABLE); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - $largest_id = (int) $row['max_id']; - - if ($largest_id) - { - $db->sql_query('DROP SEQUENCE ' . FORUMS_TABLE . '_seq'); - $db->sql_query('CREATE SEQUENCE ' . FORUMS_TABLE . '_seq START WITH ' . ($largest_id + 1)); - } - break; - } -} - -/** -* Function for recoding text with the default language -* -* @param string $text text to recode to utf8 -* @param bool $grab_user_lang if set to true the function tries to use $convert_row['user_lang'] (and falls back to $convert_row['poster_id']) instead of the boards default language -*/ -function phpbb_set_encoding($text, $grab_user_lang = true) -{ - global $lang_enc_array, $convert_row; - global $convert, $phpEx; - - /*static $lang_enc_array = array( - 'korean' => 'euc-kr', - 'serbian' => 'windows-1250', - 'polish' => 'iso-8859-2', - 'kurdish' => 'windows-1254', - 'slovak' => 'Windows-1250', - 'russian' => 'windows-1251', - 'estonian' => 'iso-8859-4', - 'chinese_simplified' => 'gb2312', - 'macedonian' => 'windows-1251', - 'azerbaijani' => 'UTF-8', - 'romanian' => 'iso-8859-2', - 'romanian_diacritice' => 'iso-8859-2', - 'lithuanian' => 'windows-1257', - 'turkish' => 'iso-8859-9', - 'ukrainian' => 'windows-1251', - 'japanese' => 'shift_jis', - 'hungarian' => 'ISO-8859-2', - 'romanian_no_diacritics' => 'iso-8859-2', - 'mongolian' => 'UTF-8', - 'slovenian' => 'windows-1250', - 'bosnian' => 'windows-1250', - 'czech' => 'Windows-1250', - 'farsi' => 'Windows-1256', - 'croatian' => 'windows-1250', - 'greek' => 'iso-8859-7', - 'russian_tu' => 'windows-1251', - 'sakha' => 'UTF-8', - 'serbian_cyrillic' => 'windows-1251', - 'bulgarian' => 'windows-1251', - 'chinese_traditional_taiwan' => 'big5', - 'chinese_traditional' => 'big5', - 'arabic' => 'windows-1256', - 'hebrew' => 'WINDOWS-1255', - 'thai' => 'windows-874', - //'chinese_traditional_taiwan' => 'utf-8' // custom modified, we may have to do an include :-( - );*/ - - if (empty($lang_enc_array)) - { - $lang_enc_array = array(); - } - - $get_lang = trim(get_config_value('default_lang')); - - // Do we need the users language encoding? - if ($grab_user_lang && !empty($convert_row)) - { - if (!empty($convert_row['user_lang'])) - { - $get_lang = trim($convert_row['user_lang']); - } - else if (!empty($convert_row['poster_id'])) - { - global $src_db, $same_db; - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'binary'"); - } - - $sql = 'SELECT user_lang - FROM ' . $convert->src_table_prefix . 'users - WHERE user_id = ' . (int) $convert_row['poster_id']; - $result = $src_db->sql_query($sql); - $get_lang = (string) $src_db->sql_fetchfield('user_lang'); - $src_db->sql_freeresult($result); - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'utf8'"); - } - - $get_lang = (!trim($get_lang)) ? trim(get_config_value('default_lang')) : trim($get_lang); - } - } - - if (!isset($lang_enc_array[$get_lang])) - { - $filename = $convert->options['forum_path'] . '/language/lang_' . $get_lang . '/lang_main.' . $phpEx; - - if (!file_exists($filename)) - { - $get_lang = trim(get_config_value('default_lang')); - } - - if (!isset($lang_enc_array[$get_lang])) - { - include($convert->options['forum_path'] . '/language/lang_' . $get_lang . '/lang_main.' . $phpEx); - $lang_enc_array[$get_lang] = $lang['ENCODING']; - unset($lang); - } - } - - $encoding = $lang_enc_array[$get_lang]; - - return utf8_recode($text, $lang_enc_array[$get_lang]); -} - -/** -* Same as phpbb_set_encoding, but forcing boards default language -*/ -function phpbb_set_default_encoding($text) -{ - return phpbb_set_encoding($text, false); -} - -/** -* Convert Birthday from Birthday MOD to phpBB Format -*/ -function phpbb_get_birthday($birthday = '') -{ - if (defined('MOD_BIRTHDAY_TERRA')) - { - $birthday = (string) $birthday; - - // stored as month, day, year - if (!$birthday) - { - return ' 0- 0- 0'; - } - - // We use the original mod code to retrieve the birthday (not ideal) - preg_match('/(..)(..)(....)/', sprintf('%08d', $birthday), $birthday_parts); - - $month = $birthday_parts[1]; - $day = $birthday_parts[2]; - $year = $birthday_parts[3]; - - return sprintf('%2d-%2d-%4d', $day, $month, $year); - } - else - { - $birthday = (int) $birthday; - - if (!$birthday || $birthday == 999999) - { - return ' 0- 0- 0'; - } - - // The birthday mod from niels is using this code to transform to day/month/year - return sprintf('%2d-%2d-%4d', gmdate('j', $birthday * 86400 + 1), gmdate('n', $birthday * 86400 + 1), gmdate('Y', $birthday * 86400 + 1)); - } -} - -/** -* Return correct user id value -* Everyone's id will be one higher to allow the guest/anonymous user to have a positive id as well -*/ -function phpbb_user_id($user_id) -{ - global $config; - - // Increment user id if the old forum is having a user with the id 1 - if (!isset($config['increment_user_id'])) - { - global $src_db, $same_db, $convert; - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'binary'"); - } - - // Now let us set a temporary config variable for user id incrementing - $sql = "SELECT user_id - FROM {$convert->src_table_prefix}users - WHERE user_id = 1"; - $result = $src_db->sql_query($sql); - $id = (int) $src_db->sql_fetchfield('user_id'); - $src_db->sql_freeresult($result); - - // Try to get the maximum user id possible... - $sql = "SELECT MAX(user_id) AS max_user_id - FROM {$convert->src_table_prefix}users"; - $result = $src_db->sql_query($sql); - $max_id = (int) $src_db->sql_fetchfield('max_user_id'); - $src_db->sql_freeresult($result); - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'utf8'"); - } - - // If there is a user id 1, we need to increment user ids. :/ - if ($id === 1) - { - $config->set('increment_user_id', ($max_id + 1), false); - $config['increment_user_id'] = $max_id + 1; - } - else - { - $config->set('increment_user_id', 0, false); - $config['increment_user_id'] = 0; - } - } - - // If the old user id is -1 in 2.0.x it is the anonymous user... - if ($user_id == -1) - { - return ANONYMOUS; - } - - if (!empty($config['increment_user_id']) && $user_id == 1) - { - return $config['increment_user_id']; - } - - // A user id of 0 can happen, for example within the ban table if no user is banned... - // Within the posts and topics table this can be "dangerous" but is the fault of the user - // having mods installed (a poster id of 0 is not possible in 2.0.x). - // Therefore, we return the user id "as is". - - return (int) $user_id; -} - -/** -* Return correct user id value -* Everyone's id will be one higher to allow the guest/anonymous user to have a positive id as well -*/ -function phpbb_topic_replies_to_posts($num_replies) -{ - return (int) $num_replies + 1; -} - -/* Copy additional table fields from old forum to new forum if user wants this (for Mod compatibility for example) -function phpbb_copy_table_fields() -{ -} -*/ - -/** -* Convert authentication -* user, group and forum table has to be filled in order to work -*/ -function phpbb_convert_authentication($mode) -{ - global $db, $src_db, $same_db, $convert, $user, $config, $cache; - - if ($mode == 'start') - { - $db->sql_query($convert->truncate_statement . ACL_USERS_TABLE); - $db->sql_query($convert->truncate_statement . ACL_GROUPS_TABLE); - - // What we will do is handling all 2.0.x admins as founder to replicate what is common in 2.0.x. - // After conversion the main admin need to make sure he is removing permissions and the founder status if wanted. - - // Grab user ids of users with user_level of ADMIN - $sql = "SELECT user_id - FROM {$convert->src_table_prefix}users - WHERE user_level = 1 - ORDER BY user_regdate ASC"; - $result = $src_db->sql_query($sql); - - while ($row = $src_db->sql_fetchrow($result)) - { - $user_id = (int) phpbb_user_id($row['user_id']); - // Set founder admin... - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_type = ' . USER_FOUNDER . " - WHERE user_id = $user_id"; - $db->sql_query($sql); - } - $src_db->sql_freeresult($result); - - $sql = 'SELECT group_id - FROM ' . GROUPS_TABLE . " - WHERE group_name = '" . $db->sql_escape('BOTS') . "'"; - $result = $db->sql_query($sql); - $bot_group_id = (int) $db->sql_fetchfield('group_id'); - $db->sql_freeresult($result); - } - - // Grab forum auth information - $sql = "SELECT * - FROM {$convert->src_table_prefix}forums"; - $result = $src_db->sql_query($sql); - - $forum_access = array(); - while ($row = $src_db->sql_fetchrow($result)) - { - $forum_access[$row['forum_id']] = $row; - } - $src_db->sql_freeresult($result); - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'binary'"); - } - // Grab user auth information from 2.0.x board - $sql = "SELECT ug.user_id, aa.* - FROM {$convert->src_table_prefix}auth_access aa, {$convert->src_table_prefix}user_group ug, {$convert->src_table_prefix}groups g, {$convert->src_table_prefix}forums f - WHERE g.group_id = aa.group_id - AND g.group_single_user = 1 - AND ug.group_id = g.group_id - AND f.forum_id = aa.forum_id"; - $result = $src_db->sql_query($sql); - - $user_access = array(); - while ($row = $src_db->sql_fetchrow($result)) - { - $user_access[$row['forum_id']][] = $row; - } - $src_db->sql_freeresult($result); - - // Grab group auth information - $sql = "SELECT g.group_id, aa.* - FROM {$convert->src_table_prefix}auth_access aa, {$convert->src_table_prefix}groups g - WHERE g.group_id = aa.group_id - AND g.group_single_user <> 1"; - $result = $src_db->sql_query($sql); - - $group_access = array(); - while ($row = $src_db->sql_fetchrow($result)) - { - $group_access[$row['forum_id']][] = $row; - } - $src_db->sql_freeresult($result); - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'utf8'"); - } - - // Add Forum Access List - $auth_map = array( - 'auth_view' => array('f_', 'f_list'), - 'auth_read' => array('f_read', 'f_search'), - 'auth_post' => array('f_post', 'f_bbcode', 'f_smilies', 'f_img', 'f_sigs', 'f_postcount', 'f_report', 'f_subscribe', 'f_print', 'f_email'), - 'auth_reply' => 'f_reply', - 'auth_edit' => 'f_edit', - 'auth_delete' => 'f_delete', - 'auth_pollcreate' => 'f_poll', - 'auth_vote' => 'f_vote', - 'auth_announce' => 'f_announce', - 'auth_sticky' => 'f_sticky', - 'auth_attachments' => array('f_attach', 'f_download'), - 'auth_download' => 'f_download', - ); - - // Define the ACL constants used in 2.0 to make the code slightly more readable - define('AUTH_ALL', 0); - define('AUTH_REG', 1); - define('AUTH_ACL', 2); - define('AUTH_MOD', 3); - define('AUTH_ADMIN', 5); - - // A mapping of the simple permissions used by 2.0 - $simple_auth_ary = array( - 'public' => array( - 'auth_view' => AUTH_ALL, - 'auth_read' => AUTH_ALL, - 'auth_post' => AUTH_ALL, - 'auth_reply' => AUTH_ALL, - 'auth_edit' => AUTH_REG, - 'auth_delete' => AUTH_REG, - 'auth_sticky' => AUTH_MOD, - 'auth_announce' => AUTH_MOD, - 'auth_vote' => AUTH_REG, - 'auth_pollcreate' => AUTH_REG, - ), - 'registered' => array( - 'auth_view' => AUTH_ALL, - 'auth_read' => AUTH_ALL, - 'auth_post' => AUTH_REG, - 'auth_reply' => AUTH_REG, - 'auth_edit' => AUTH_REG, - 'auth_delete' => AUTH_REG, - 'auth_sticky' => AUTH_MOD, - 'auth_announce' => AUTH_MOD, - 'auth_vote' => AUTH_REG, - 'auth_pollcreate' => AUTH_REG, - ), - 'registered_hidden' => array( - 'auth_view' => AUTH_REG, - 'auth_read' => AUTH_REG, - 'auth_post' => AUTH_REG, - 'auth_reply' => AUTH_REG, - 'auth_edit' => AUTH_REG, - 'auth_delete' => AUTH_REG, - 'auth_sticky' => AUTH_MOD, - 'auth_announce' => AUTH_MOD, - 'auth_vote' => AUTH_REG, - 'auth_pollcreate' => AUTH_REG, - ), - 'private' => array( - 'auth_view' => AUTH_ALL, - 'auth_read' => AUTH_ACL, - 'auth_post' => AUTH_ACL, - 'auth_reply' => AUTH_ACL, - 'auth_edit' => AUTH_ACL, - 'auth_delete' => AUTH_ACL, - 'auth_sticky' => AUTH_ACL, - 'auth_announce' => AUTH_MOD, - 'auth_vote' => AUTH_ACL, - 'auth_pollcreate' => AUTH_ACL, - ), - 'private_hidden' => array( - 'auth_view' => AUTH_ACL, - 'auth_read' => AUTH_ACL, - 'auth_post' => AUTH_ACL, - 'auth_reply' => AUTH_ACL, - 'auth_edit' => AUTH_ACL, - 'auth_delete' => AUTH_ACL, - 'auth_sticky' => AUTH_ACL, - 'auth_announce' => AUTH_MOD, - 'auth_vote' => AUTH_ACL, - 'auth_pollcreate' => AUTH_ACL, - ), - 'moderator' => array( - 'auth_view' => AUTH_ALL, - 'auth_read' => AUTH_MOD, - 'auth_post' => AUTH_MOD, - 'auth_reply' => AUTH_MOD, - 'auth_edit' => AUTH_MOD, - 'auth_delete' => AUTH_MOD, - 'auth_sticky' => AUTH_MOD, - 'auth_announce' => AUTH_MOD, - 'auth_vote' => AUTH_MOD, - 'auth_pollcreate' => AUTH_MOD, - ), - 'moderator_hidden' => array( - 'auth_view' => AUTH_MOD, - 'auth_read' => AUTH_MOD, - 'auth_post' => AUTH_MOD, - 'auth_reply' => AUTH_MOD, - 'auth_edit' => AUTH_MOD, - 'auth_delete' => AUTH_MOD, - 'auth_sticky' => AUTH_MOD, - 'auth_announce' => AUTH_MOD, - 'auth_vote' => AUTH_MOD, - 'auth_pollcreate' => AUTH_MOD, - ), - ); - - if ($mode == 'start') - { - user_group_auth('guests', 'SELECT user_id, {GUESTS} FROM ' . USERS_TABLE . ' WHERE user_id = ' . ANONYMOUS, false); - user_group_auth('registered', 'SELECT user_id, {REGISTERED} FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS . " AND group_id <> $bot_group_id", false); - - // Selecting from old table - if (!empty($config['increment_user_id'])) - { - $auth_sql = 'SELECT user_id, {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id <> 1'; - user_group_auth('administrators', $auth_sql, true); - - $auth_sql = 'SELECT ' . $config['increment_user_id'] . ' as user_id, {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id = 1'; - user_group_auth('administrators', $auth_sql, true); - } - else - { - $auth_sql = 'SELECT user_id, {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1'; - user_group_auth('administrators', $auth_sql, true); - } - - if (!empty($config['increment_user_id'])) - { - $auth_sql = 'SELECT user_id, {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id <> 1'; - user_group_auth('global_moderators', $auth_sql, true); - - $auth_sql = 'SELECT ' . $config['increment_user_id'] . ' as user_id, {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1 AND user_id = 1'; - user_group_auth('global_moderators', $auth_sql, true); - } - else - { - $auth_sql = 'SELECT user_id, {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1'; - user_group_auth('global_moderators', $auth_sql, true); - } - } - else if ($mode == 'first') - { - // Go through all 2.0.x forums - foreach ($forum_access as $forum) - { - $new_forum_id = (int) $forum['forum_id']; - - // Administrators have full access to all forums whatever happens - mass_auth('group_role', $new_forum_id, 'administrators', 'FORUM_FULL'); - - $matched_type = ''; - foreach ($simple_auth_ary as $key => $auth_levels) - { - $matched = 1; - foreach ($auth_levels as $k => $level) - { - if ($forum[$k] != $auth_levels[$k]) - { - $matched = 0; - } - } - - if ($matched) - { - $matched_type = $key; - break; - } - } - - switch ($matched_type) - { - case 'public': - mass_auth('group_role', $new_forum_id, 'guests', 'FORUM_LIMITED'); - mass_auth('group_role', $new_forum_id, 'registered', 'FORUM_LIMITED_POLLS'); - mass_auth('group_role', $new_forum_id, 'bots', 'FORUM_BOT'); - break; - - case 'registered': - mass_auth('group_role', $new_forum_id, 'guests', 'FORUM_READONLY'); - mass_auth('group_role', $new_forum_id, 'bots', 'FORUM_BOT'); - - // no break; - - case 'registered_hidden': - mass_auth('group_role', $new_forum_id, 'registered', 'FORUM_POLLS'); - break; - - case 'private': - case 'private_hidden': - case 'moderator': - case 'moderator_hidden': - default: - // The permissions don't match a simple set, so we're going to have to map them directly - - // No post approval for all, in 2.0.x this feature does not exist - mass_auth('group', $new_forum_id, 'guests', 'f_noapprove', ACL_YES); - mass_auth('group', $new_forum_id, 'registered', 'f_noapprove', ACL_YES); - - // Go through authentication map - foreach ($auth_map as $old_auth_key => $new_acl) - { - // If old authentication key does not exist we continue - // This is helpful for mods adding additional authentication fields, we need to add them to the auth_map array - if (!isset($forum[$old_auth_key])) - { - continue; - } - - // Now set the new ACL correctly - switch ($forum[$old_auth_key]) - { - // AUTH_ALL - case AUTH_ALL: - mass_auth('group', $new_forum_id, 'guests', $new_acl, ACL_YES); - mass_auth('group', $new_forum_id, 'bots', $new_acl, ACL_YES); - mass_auth('group', $new_forum_id, 'registered', $new_acl, ACL_YES); - break; - - // AUTH_REG - case AUTH_REG: - mass_auth('group', $new_forum_id, 'registered', $new_acl, ACL_YES); - break; - - // AUTH_ACL - case AUTH_ACL: - // Go through the old group access list for this forum - if (isset($group_access[$forum['forum_id']])) - { - foreach ($group_access[$forum['forum_id']] as $index => $access) - { - // We only check for ACL_YES equivalence entry - if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1) - { - mass_auth('group', $new_forum_id, (int) $access['group_id'], $new_acl, ACL_YES); - } - } - } - - if (isset($user_access[$forum['forum_id']])) - { - foreach ($user_access[$forum['forum_id']] as $index => $access) - { - // We only check for ACL_YES equivalence entry - if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1) - { - mass_auth('user', $new_forum_id, (int) phpbb_user_id($access['user_id']), $new_acl, ACL_YES); - } - } - } - break; - - // AUTH_MOD - case AUTH_MOD: - if (isset($group_access[$forum['forum_id']])) - { - foreach ($group_access[$forum['forum_id']] as $index => $access) - { - // We only check for ACL_YES equivalence entry - if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1) - { - mass_auth('group', $new_forum_id, (int) $access['group_id'], $new_acl, ACL_YES); - } - } - } - - if (isset($user_access[$forum['forum_id']])) - { - foreach ($user_access[$forum['forum_id']] as $index => $access) - { - // We only check for ACL_YES equivalence entry - if (isset($access[$old_auth_key]) && $access[$old_auth_key] == 1) - { - mass_auth('user', $new_forum_id, (int) phpbb_user_id($access['user_id']), $new_acl, ACL_YES); - } - } - } - break; - } - } - break; - } - } - } - else if ($mode == 'second') - { - // Assign permission roles and other default permissions - - // guests having u_download and u_search ability - $db->sql_query('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) SELECT ' . get_group_id('guests') . ', 0, auth_option_id, 0, 1 FROM ' . ACL_OPTIONS_TABLE . " WHERE auth_option IN ('u_', 'u_download', 'u_search')"); - - // administrators/global mods having full user features - mass_auth('group_role', 0, 'administrators', 'USER_FULL'); - mass_auth('group_role', 0, 'global_moderators', 'USER_FULL'); - - // By default all converted administrators are given full access - mass_auth('group_role', 0, 'administrators', 'ADMIN_FULL'); - - // All registered users are assigned the standard user role - mass_auth('group_role', 0, 'registered', 'USER_STANDARD'); - mass_auth('group_role', 0, 'registered_coppa', 'USER_STANDARD'); - - // Instead of administrators being global moderators we give the MOD_FULL role to global mods (admins already assigned to this group) - mass_auth('group_role', 0, 'global_moderators', 'MOD_FULL'); - - // And now those who have had their avatar rights removed get assigned a more restrictive role - $sql = 'SELECT user_id FROM ' . $convert->src_table_prefix . 'users - WHERE user_allowavatar = 0 - AND user_id > 0'; - $result = $src_db->sql_query($sql); - - while ($row = $src_db->sql_fetchrow($result)) - { - mass_auth('user_role', 0, (int) phpbb_user_id($row['user_id']), 'USER_NOAVATAR'); - } - $src_db->sql_freeresult($result); - - // And the same for those who have had their PM rights removed - $sql = 'SELECT user_id FROM ' . $convert->src_table_prefix . 'users - WHERE user_allow_pm = 0 - AND user_id > 0'; - $result = $src_db->sql_query($sql); - - while ($row = $src_db->sql_fetchrow($result)) - { - mass_auth('user_role', 0, (int) phpbb_user_id($row['user_id']), 'USER_NOPM'); - } - $src_db->sql_freeresult($result); - } - else if ($mode == 'third') - { - // And now the moderators - // We make sure that they have at least standard access to the forums they moderate in addition to the moderating permissions - - $mod_post_map = array( - 'auth_announce' => 'f_announce', - 'auth_sticky' => 'f_sticky' - ); - - foreach ($user_access as $forum_id => $access_map) - { - $forum_id = (int) $forum_id; - - foreach ($access_map as $access) - { - if (isset($access['auth_mod']) && $access['auth_mod'] == 1) - { - mass_auth('user_role', $forum_id, (int) phpbb_user_id($access['user_id']), 'MOD_STANDARD'); - mass_auth('user_role', $forum_id, (int) phpbb_user_id($access['user_id']), 'FORUM_STANDARD'); - foreach ($mod_post_map as $old => $new) - { - if (isset($forum_access[$forum_id]) && isset($forum_access[$forum_id][$old]) && $forum_access[$forum_id][$old] == AUTH_MOD) - { - mass_auth('user', $forum_id, (int) phpbb_user_id($access['user_id']), $new, ACL_YES); - } - } - } - } - } - - foreach ($group_access as $forum_id => $access_map) - { - $forum_id = (int) $forum_id; - - foreach ($access_map as $access) - { - if (isset($access['auth_mod']) && $access['auth_mod'] == 1) - { - mass_auth('group_role', $forum_id, (int) $access['group_id'], 'MOD_STANDARD'); - mass_auth('group_role', $forum_id, (int) $access['group_id'], 'FORUM_STANDARD'); - foreach ($mod_post_map as $old => $new) - { - if (isset($forum_access[$forum_id]) && isset($forum_access[$forum_id][$old]) && $forum_access[$forum_id][$old] == AUTH_MOD) - { - mass_auth('group', $forum_id, (int) $access['group_id'], $new, ACL_YES); - } - } - } - } - } - - // We grant everyone readonly access to the categories to ensure that the forums are visible - $sql = 'SELECT forum_id, forum_name, parent_id, left_id, right_id - FROM ' . FORUMS_TABLE . ' - ORDER BY left_id ASC'; - $result = $db->sql_query($sql); - - $parent_forums = $forums = array(); - while ($row = $db->sql_fetchrow($result)) - { - if ($row['parent_id'] == 0) - { - mass_auth('group_role', $row['forum_id'], 'administrators', 'FORUM_FULL'); - mass_auth('group_role', $row['forum_id'], 'global_moderators', 'FORUM_FULL'); - $parent_forums[] = $row; - } - else - { - $forums[] = $row; - } - } - $db->sql_freeresult($result); - - global $auth; - - // Let us see which groups have access to these forums... - foreach ($parent_forums as $row) - { - // Get the children - $branch = $forum_ids = array(); - - foreach ($forums as $key => $_row) - { - if ($_row['left_id'] > $row['left_id'] && $_row['left_id'] < $row['right_id']) - { - $branch[] = $_row; - $forum_ids[] = $_row['forum_id']; - continue; - } - } - - if (sizeof($forum_ids)) - { - // Now make sure the user is able to read these forums - $hold_ary = $auth->acl_group_raw_data(false, 'f_list', $forum_ids); - - if (empty($hold_ary)) - { - continue; - } - - foreach ($hold_ary as $g_id => $f_id_ary) - { - $set_group = false; - - foreach ($f_id_ary as $f_id => $auth_ary) - { - foreach ($auth_ary as $auth_option => $setting) - { - if ($setting == ACL_YES) - { - $set_group = true; - break 2; - } - } - } - - if ($set_group) - { - mass_auth('group', $row['forum_id'], $g_id, 'f_list', ACL_YES); - } - } - } - } - } -} - -/** -* Set primary group. -* Really simple and only based on user_level (remaining groups will be assigned later) -*/ -function phpbb_set_primary_group($user_level) -{ - global $convert_row; - - if ($user_level == 1) - { - return get_group_id('administrators'); - } -/* else if ($user_level == 2) - { - return get_group_id('global_moderators'); - } - else if ($user_level == 0 && $convert_row['user_active'])*/ - else if ($convert_row['user_active']) - { - return get_group_id('registered'); - } - - return 0; -} - -/** -* Convert the group name, making sure to avoid conflicts with 3.0 special groups -*/ -function phpbb_convert_group_name($group_name) -{ - $default_groups = array( - 'GUESTS', - 'REGISTERED', - 'REGISTERED_COPPA', - 'GLOBAL_MODERATORS', - 'ADMINISTRATORS', - 'BOTS', - ); - - if (in_array(strtoupper($group_name), $default_groups)) - { - return 'phpBB2 - ' . $group_name; - } - - return phpbb_set_default_encoding($group_name); -} - -/** -* Convert the group type constants -*/ -function phpbb_convert_group_type($group_type) -{ - switch ($group_type) - { - case 0: - return GROUP_OPEN; - break; - - case 1: - return GROUP_CLOSED; - break; - - case 2: - return GROUP_HIDDEN; - break; - } - - // Never return GROUP_SPECIAL here, because only phpBB3's default groups are allowed to have this type set. - return GROUP_HIDDEN; -} - -/** -* Convert the topic type constants -*/ -function phpbb_convert_topic_type($topic_type) -{ - switch ($topic_type) - { - case 0: - return POST_NORMAL; - break; - - case 1: - return POST_STICKY; - break; - - case 2: - return POST_ANNOUNCE; - break; - - case 3: - return POST_GLOBAL; - break; - } - - return POST_NORMAL; -} - -function phpbb_replace_size($matches) -{ - return '[size=' . min(200, ceil(100.0 * (((double) $matches[1])/12.0))) . ':' . $matches[2] . ']'; -} - -/** -* Reparse the message stripping out the bbcode_uid values and adding new ones and setting the bitfield -* @todo What do we want to do about HTML in messages - currently it gets converted to the entities, but there may be some objections to this -*/ -function phpbb_prepare_message($message) -{ - global $phpbb_root_path, $phpEx, $db, $convert, $user, $config, $cache, $convert_row, $message_parser; - - if (!$message) - { - $convert->row['mp_bbcode_bitfield'] = $convert_row['mp_bbcode_bitfield'] = 0; - return ''; - } - - // Decode phpBB 2.0.x Message - if (isset($convert->row['old_bbcode_uid']) && $convert->row['old_bbcode_uid'] != '') - { - // Adjust size... - if (strpos($message, '[size=') !== false) - { - $message = preg_replace_callback('/\[size=(\d*):(' . $convert->row['old_bbcode_uid'] . ')\]/', 'phpbb_replace_size', $message); - } - - $message = preg_replace('/\:(([a-z0-9]:)?)' . $convert->row['old_bbcode_uid'] . '/s', '', $message); - } - - if (strpos($message, '[quote=') !== false) - { - $message = preg_replace('/\[quote="(.*?)"\]/s', '[quote="\1"]', $message); - $message = preg_replace('/\[quote=\\\"(.*?)\\\"\]/s', '[quote="\1"]', $message); - - // let's hope that this solves more problems than it causes. Deal with escaped quotes. - $message = str_replace('\"', '"', $message); - $message = str_replace('\"', '"', $message); - } - - // Already the new user id ;) - $user_id = $convert->row['poster_id']; - - $message = str_replace('
', "\n", $message); - $message = str_replace('<', '<', $message); - $message = str_replace('>', '>', $message); - - // make the post UTF-8 - $message = phpbb_set_encoding($message); - - $message_parser->warn_msg = array(); // Reset the errors from the previous message - $message_parser->bbcode_uid = make_uid($convert->row['post_time']); - $message_parser->message = $message; - unset($message); - - // Make sure options are set. -// $enable_html = (!isset($row['enable_html'])) ? false : $row['enable_html']; - $enable_bbcode = (!isset($convert->row['enable_bbcode'])) ? true : $convert->row['enable_bbcode']; - $enable_smilies = (!isset($convert->row['enable_smilies'])) ? true : $convert->row['enable_smilies']; - $enable_magic_url = (!isset($convert->row['enable_magic_url'])) ? true : $convert->row['enable_magic_url']; - - // parse($allow_bbcode, $allow_magic_url, $allow_smilies, $allow_img_bbcode = true, $allow_flash_bbcode = true, $allow_quote_bbcode = true, $allow_url_bbcode = true, $update_this_message = true, $mode = 'post') - $message_parser->parse($enable_bbcode, $enable_magic_url, $enable_smilies); - - if (sizeof($message_parser->warn_msg)) - { - $msg_id = isset($convert->row['post_id']) ? $convert->row['post_id'] : $convert->row['privmsgs_id']; - $convert->p_master->error('' . $user->lang['POST_ID'] . ': ' . $msg_id . ' ' . $user->lang['CONV_ERROR_MESSAGE_PARSER'] . ':

' . implode('
', $message_parser->warn_msg), __LINE__, __FILE__, true); - } - - $convert->row['mp_bbcode_bitfield'] = $convert_row['mp_bbcode_bitfield'] = $message_parser->bbcode_bitfield; - - $message = $message_parser->message; - unset($message_parser->message); - - return $message; -} - -/** -* Return the bitfield calculated by the previous function -*/ -function get_bbcode_bitfield() -{ - global $convert_row; - - return $convert_row['mp_bbcode_bitfield']; -} - -/** -* Determine the last user to edit a post -* In practice we only tracked edits by the original poster in 2.0.x so this will only be set if they had edited their own post -*/ -function phpbb_post_edit_user() -{ - global $convert_row, $config; - - if (isset($convert_row['post_edit_count'])) - { - return phpbb_user_id($convert_row['poster_id']); - } - - return 0; -} - -/** -* Obtain the path to uploaded files on the 2.0.x forum -* This is only used if the Attachment MOD was installed -*/ -function phpbb_get_files_dir() -{ - if (!defined('MOD_ATTACHMENT')) - { - return; - } - - global $src_db, $same_db, $convert, $user, $config, $cache; - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'binary'"); - } - $sql = 'SELECT config_value AS upload_dir - FROM ' . $convert->src_table_prefix . "attachments_config - WHERE config_name = 'upload_dir'"; - $result = $src_db->sql_query($sql); - $upload_path = $src_db->sql_fetchfield('upload_dir'); - $src_db->sql_freeresult($result); - - $sql = 'SELECT config_value AS ftp_upload - FROM ' . $convert->src_table_prefix . "attachments_config - WHERE config_name = 'allow_ftp_upload'"; - $result = $src_db->sql_query($sql); - $ftp_upload = (int) $src_db->sql_fetchfield('ftp_upload'); - $src_db->sql_freeresult($result); - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'utf8'"); - } - - if ($ftp_upload) - { - $convert->p_master->error($user->lang['CONV_ERROR_ATTACH_FTP_DIR'], __LINE__, __FILE__); - } - - return $upload_path; -} - -/** -* Copy thumbnails of uploaded images from the 2.0.x forum -* This is only used if the Attachment MOD was installed -*/ -function phpbb_copy_thumbnails() -{ - global $db, $convert, $user, $config, $cache, $phpbb_root_path; - - $src_path = $convert->options['forum_path'] . '/' . phpbb_get_files_dir() . '/thumbs/'; - - if ($handle = @opendir($src_path)) - { - while ($entry = readdir($handle)) - { - if ($entry[0] == '.') - { - continue; - } - - if (is_dir($src_path . $entry)) - { - continue; - } - else - { - copy_file($src_path . $entry, $config['upload_path'] . '/' . preg_replace('/^t_/', 'thumb_', $entry)); - @unlink($phpbb_root_path . $config['upload_path'] . '/thumbs/' . $entry); - } - } - closedir($handle); - } -} - -/** -* Convert the attachment category constants -* This is only used if the Attachment MOD was installed -*/ -function phpbb_attachment_category($cat_id) -{ - switch ($cat_id) - { - case 1: - return ATTACHMENT_CATEGORY_IMAGE; - break; - - case 2: - return ATTACHMENT_CATEGORY_WM; - break; - - case 3: - return ATTACHMENT_CATEGORY_FLASH; - break; - } - - return ATTACHMENT_CATEGORY_NONE; -} - -/** -* Convert the attachment extension names -* This is only used if the Attachment MOD was installed -*/ -function phpbb_attachment_extension_group_name() -{ - global $db, $phpbb_root_path, $phpEx; - - // Update file extension group names to use language strings. - $sql = 'SELECT lang_dir - FROM ' . LANG_TABLE; - $result = $db->sql_query($sql); - - $extension_groups_updated = array(); - while ($lang_dir = $db->sql_fetchfield('lang_dir')) - { - $lang_dir = basename($lang_dir); - $lang_file = $phpbb_root_path . 'language/' . $lang_dir . '/acp/attachments.' . $phpEx; - - if (!file_exists($lang_file)) - { - continue; - } - - $lang = array(); - include($lang_file); - - foreach ($lang as $lang_key => $lang_val) - { - if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0) - { - continue; - } - - $sql_ary = array( - 'group_name' => substr($lang_key, 10), // Strip off 'EXT_GROUP_' - ); - - $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " - WHERE group_name = '" . $db->sql_escape($lang_val) . "'"; - $db->sql_query($sql); - - $extension_groups_updated[$lang_key] = true; - } - } - $db->sql_freeresult($result); -} - -/** -* Obtain list of forums in which different attachment categories can be used -*/ -function phpbb_attachment_forum_perms($forum_permissions) -{ - if (empty($forum_permissions)) - { - return ''; - } - - // Decode forum permissions - $forum_ids = array(); - - $one_char_encoding = '#'; - $two_char_encoding = '.'; - - $auth_len = 1; - for ($pos = 0; $pos < strlen($forum_permissions); $pos += $auth_len) - { - $forum_auth = substr($forum_permissions, $pos, 1); - if ($forum_auth == $one_char_encoding) - { - $auth_len = 1; - continue; - } - else if ($forum_auth == $two_char_encoding) - { - $auth_len = 2; - $pos--; - continue; - } - - $forum_auth = substr($forum_permissions, $pos, $auth_len); - $forum_id = base64_unpack($forum_auth); - - $forum_ids[] = (int) $forum_id; - } - - if (sizeof($forum_ids)) - { - return attachment_forum_perms($forum_ids); - } - - return ''; -} - -/** -* Convert the avatar type constants -*/ -function phpbb_avatar_type($type) -{ - switch ($type) - { - case 1: - return AVATAR_UPLOAD; - break; - - case 2: - return AVATAR_REMOTE; - break; - - case 3: - return AVATAR_GALLERY; - break; - } - - return 0; -} - - -/** -* Just undos the replacing of '<' and '>' -*/ -function phpbb_smilie_html_decode($code) -{ - $code = str_replace('<', '<', $code); - return str_replace('>', '>', $code); -} - -/** -* Transfer avatars, copying the image if it was uploaded -*/ -function phpbb_import_avatar($user_avatar) -{ - global $convert_row; - - if (!$convert_row['user_avatar_type']) - { - return ''; - } - else if ($convert_row['user_avatar_type'] == 1) - { - // Uploaded avatar - return import_avatar($user_avatar, false, $convert_row['user_id']); - } - else if ($convert_row['user_avatar_type'] == 2) - { - // Remote avatar - return $user_avatar; - } - else if ($convert_row['user_avatar_type'] == 3) - { - // Gallery avatar - return $user_avatar; - } - - return ''; -} - - -/** -* Find out about the avatar's dimensions -*/ -function phpbb_get_avatar_height($user_avatar) -{ - global $convert_row; - - if (empty($convert_row['user_avatar_type'])) - { - return 0; - } - return get_avatar_height($user_avatar, 'phpbb_avatar_type', $convert_row['user_avatar_type']); -} - - -/** -* Find out about the avatar's dimensions -*/ -function phpbb_get_avatar_width($user_avatar) -{ - global $convert_row; - - if (empty($convert_row['user_avatar_type'])) - { - return 0; - } - - return get_avatar_width($user_avatar, 'phpbb_avatar_type', $convert_row['user_avatar_type']); -} - - -/** -* Calculate the correct to_address field for private messages -*/ -function phpbb_privmsgs_to_userid($to_userid) -{ - global $config; - - return 'u_' . phpbb_user_id($to_userid); -} - -/** -* Calculate whether a private message was unread using the bitfield -*/ -function phpbb_unread_pm($pm_type) -{ - return ($pm_type == 5) ? 1 : 0; -} - -/** -* Calculate whether a private message was new using the bitfield -*/ -function phpbb_new_pm($pm_type) -{ - return ($pm_type == 1) ? 1 : 0; -} - -/** -* Obtain the folder_id for the custom folder created to replace the savebox from 2.0.x (used to store saved private messages) -*/ -function phpbb_get_savebox_id($user_id) -{ - global $db; - - $user_id = phpbb_user_id($user_id); - - // Only one custom folder, check only one - $sql = 'SELECT folder_id - FROM ' . PRIVMSGS_FOLDER_TABLE . ' - WHERE user_id = ' . $user_id; - $result = $db->sql_query_limit($sql, 1); - $folder_id = (int) $db->sql_fetchfield('folder_id'); - $db->sql_freeresult($result); - - return $folder_id; -} - -/** -* Transfer attachment specific configuration options -* These were not stored in the main config table on 2.0.x -* This is only used if the Attachment MOD was installed -*/ -function phpbb_import_attach_config() -{ - global $db, $src_db, $same_db, $convert, $config; - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'binary'"); - } - - $sql = 'SELECT * - FROM ' . $convert->src_table_prefix . 'attachments_config'; - $result = $src_db->sql_query($sql); - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'utf8'"); - } - - $attach_config = array(); - while ($row = $src_db->sql_fetchrow($result)) - { - $attach_config[$row['config_name']] = $row['config_value']; - } - $src_db->sql_freeresult($result); - - $config->set('allow_attachments', 1); - - // old attachment mod? Must be very old if this entry do not exist... - if (!empty($attach_config['display_order'])) - { - $config->set('display_order', $attach_config['display_order']); - } - $config->set('max_filesize', $attach_config['max_filesize']); - $config->set('max_filesize_pm', $attach_config['max_filesize_pm']); - $config->set('attachment_quota', $attach_config['attachment_quota']); - $config->set('max_attachments', $attach_config['max_attachments']); - $config->set('max_attachments_pm', $attach_config['max_attachments_pm']); - $config->set('allow_pm_attach', $attach_config['allow_pm_attach']); - - $config->set('img_display_inlined', $attach_config['img_display_inlined']); - $config->set('img_max_width', $attach_config['img_max_width']); - $config->set('img_max_height', $attach_config['img_max_height']); - $config->set('img_link_width', $attach_config['img_link_width']); - $config->set('img_link_height', $attach_config['img_link_height']); - $config->set('img_create_thumbnail', $attach_config['img_create_thumbnail']); - $config->set('img_max_thumb_width', 400); - $config->set('img_min_thumb_filesize', $attach_config['img_min_thumb_filesize']); - $config->set('img_imagick', $attach_config['img_imagick']); -} - -/** -* Calculate the date a user became inactive -*/ -function phpbb_inactive_time() -{ - global $convert_row; - - if ($convert_row['user_active']) - { - return 0; - } - - if ($convert_row['user_lastvisit']) - { - return $convert_row['user_lastvisit']; - } - - return $convert_row['user_regdate']; -} - -/** -* Calculate the reason a user became inactive -* We can't actually tell the difference between a manual deactivation and one for profile changes -* from the data available to assume the latter -*/ -function phpbb_inactive_reason() -{ - global $convert_row; - - if ($convert_row['user_active']) - { - return 0; - } - - if ($convert_row['user_lastvisit']) - { - return INACTIVE_PROFILE; - } - - return INACTIVE_REGISTER; -} - -/** -* Adjust 2.0.x disallowed names to 3.0.x format -*/ -function phpbb_disallowed_username($username) -{ - // Replace * with % - $username = phpbb_set_default_encoding(str_replace('*', '%', $username)); - return utf8_htmlspecialchars($username); -} - -/** -* Checks whether there are any usernames on the old board that would map to the same -* username_clean on phpBB3. Prints out a list if any exist and exits. -*/ -function phpbb_create_userconv_table() -{ - global $db, $src_db, $convert, $table_prefix, $user, $lang; - - $map_dbms = ''; - switch ($db->get_sql_layer()) - { - case 'mysql': - $map_dbms = 'mysql_40'; - break; - - case 'mysql4': - if (version_compare($db->sql_server_info(true), '4.1.3', '>=')) - { - $map_dbms = 'mysql_41'; - } - else - { - $map_dbms = 'mysql_40'; - } - break; - - case 'mysqli': - $map_dbms = 'mysql_41'; - break; - - case 'mssql': - case 'mssql_odbc': - case 'mssqlnative': - $map_dbms = 'mssql'; - break; - - default: - $map_dbms = $db->get_sql_layer(); - break; - } - - // create a temporary table in which we store the clean usernames - $drop_sql = 'DROP TABLE ' . USERCONV_TABLE; - switch ($map_dbms) - { - case 'mssql': - $create_sql = 'CREATE TABLE [' . USERCONV_TABLE . '] ( - [user_id] [int] NOT NULL , - [username_clean] [varchar] (255) DEFAULT (\'\') NOT NULL - )'; - break; - - case 'mysql_40': - $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( - user_id mediumint(8) NOT NULL, - username_clean blob NOT NULL - )'; - break; - - case 'mysql_41': - $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( - user_id mediumint(8) NOT NULL, - username_clean varchar(255) DEFAULT \'\' NOT NULL - ) CHARACTER SET `utf8` COLLATE `utf8_bin`'; - break; - - case 'oracle': - $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( - user_id number(8) NOT NULL, - username_clean varchar2(255) DEFAULT \'\' - )'; - break; - - case 'postgres': - $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( - user_id INT4 DEFAULT \'0\', - username_clean varchar_ci DEFAULT \'\' NOT NULL - )'; - break; - - case 'sqlite': - case 'sqlite3': - $create_sql = 'CREATE TABLE ' . USERCONV_TABLE . ' ( - user_id INTEGER NOT NULL DEFAULT \'0\', - username_clean varchar(255) NOT NULL DEFAULT \'\' - )'; - break; - } - - $db->sql_return_on_error(true); - $db->sql_query($drop_sql); - $db->sql_return_on_error(false); - $db->sql_query($create_sql); -} - -function phpbb_check_username_collisions() -{ - global $db, $src_db, $convert, $table_prefix, $user, $lang; - - // now find the clean version of the usernames that collide - $sql = 'SELECT username_clean - FROM ' . USERCONV_TABLE .' - GROUP BY username_clean - HAVING COUNT(user_id) > 1'; - $result = $db->sql_query($sql); - - $colliding_names = array(); - while ($row = $db->sql_fetchrow($result)) - { - $colliding_names[] = $row['username_clean']; - } - $db->sql_freeresult($result); - - // there was at least one collision, the admin will have to solve it before conversion can continue - if (sizeof($colliding_names)) - { - $sql = 'SELECT user_id, username_clean - FROM ' . USERCONV_TABLE . ' - WHERE ' . $db->sql_in_set('username_clean', $colliding_names); - $result = $db->sql_query($sql); - unset($colliding_names); - - $colliding_user_ids = array(); - while ($row = $db->sql_fetchrow($result)) - { - $colliding_user_ids[(int) $row['user_id']] = $row['username_clean']; - } - $db->sql_freeresult($result); - - $sql = 'SELECT username, user_id, user_posts - FROM ' . $convert->src_table_prefix . 'users - WHERE ' . $src_db->sql_in_set('user_id', array_keys($colliding_user_ids)); - $result = $src_db->sql_query($sql); - - $colliding_users = array(); - while ($row = $src_db->sql_fetchrow($result)) - { - $row['user_id'] = (int) $row['user_id']; - if (isset($colliding_user_ids[$row['user_id']])) - { - $colliding_users[$colliding_user_ids[$row['user_id']]][] = $row; - } - } - $src_db->sql_freeresult($result); - unset($colliding_user_ids); - - $list = ''; - foreach ($colliding_users as $username_clean => $users) - { - $list .= sprintf($user->lang['COLLIDING_CLEAN_USERNAME'], $username_clean) . "
\n"; - foreach ($users as $i => $row) - { - $list .= sprintf($user->lang['COLLIDING_USER'], $row['user_id'], phpbb_set_default_encoding($row['username']), $row['user_posts']) . "
\n"; - } - } - - $lang['INST_ERR_FATAL'] = $user->lang['CONV_ERR_FATAL']; - $convert->p_master->error('' . $user->lang['COLLIDING_USERNAMES_FOUND'] . '


' . $list . '', __LINE__, __FILE__); - } - - $drop_sql = 'DROP TABLE ' . USERCONV_TABLE; - $db->sql_query($drop_sql); -} - -function phpbb_convert_timezone($timezone) -{ - global $config, $db, $phpbb_root_path, $phpEx, $table_prefix; - - $factory = new \phpbb\db\tools\factory(); - $timezone_migration = new \phpbb\db\migration\data\v310\timezone($config, $db, $factory->get($db), $phpbb_root_path, $phpEx, $table_prefix); - return $timezone_migration->convert_phpbb30_timezone($timezone, 0); -} - -function phpbb_add_notification_options($user_notify_pm) -{ - global $convert_row, $db; - - $user_id = phpbb_user_id($convert_row['user_id']); - if ($user_id == ANONYMOUS) - { - return; - } - - $rows = array(); - - $rows[] = array( - 'item_type' => 'post', - 'item_id' => 0, - 'user_id' => (int) $user_id, - 'notify' => 1, - 'method' => 'email', - ); - $rows[] = array( - 'item_type' => 'topic', - 'item_id' => 0, - 'user_id' => (int) $user_id, - 'notify' => 1, - 'method' => 'email', - ); - if ($user_notify_pm) - { - $rows[] = array( - 'item_type' => 'pm', - 'item_id' => 0, - 'user_id' => (int) $user_id, - 'notify' => 1, - 'method' => 'email', - ); - } - - $sql = $db->sql_multi_insert(USER_NOTIFICATIONS_TABLE, $rows); -} - -function phpbb_convert_password_hash($hash) -{ - global $phpbb_container; - - /* @var $manager \phpbb\passwords\manager */ - $manager = $phpbb_container->get('passwords.manager'); - $hash = $manager->hash($hash, '$H$'); - - return '$CP$' . $hash; -} diff --git a/phpBB/install_old/data/confusables.php b/phpBB/install_old/data/confusables.php deleted file mode 100644 index 992207c1ef..0000000000 --- a/phpBB/install_old/data/confusables.php +++ /dev/null @@ -1,645 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -/** -* @ignore -*/ -if (!defined('IN_PHPBB')) -{ - exit; -} - -function utf8_new_case_fold($text, $option = 'full') -{ - static $uniarray = array(); - global $phpbb_root_path, $phpEx; - - // common is always set - if (!isset($uniarray['c'])) - { - $uniarray['c'] = include($phpbb_root_path . 'includes/utf/data/case_fold_c.' . $phpEx); - } - - // only set full if we need to - if ($option === 'full' && !isset($uniarray['f'])) - { - $uniarray['f'] = include($phpbb_root_path . 'includes/utf/data/case_fold_f.' . $phpEx); - } - - // only set simple if we need to - if ($option !== 'full' && !isset($uniarray['s'])) - { - $uniarray['s'] = include($phpbb_root_path . 'includes/utf/data/case_fold_s.' . $phpEx); - } - - // common is always replaced - $text = strtr($text, $uniarray['c']); - - if ($option === 'full') - { - // full replaces a character with multiple characters - $text = strtr($text, $uniarray['f']); - } - else - { - // simple replaces a character with another character - $text = strtr($text, $uniarray['s']); - } - - return $text; -} - -function utf8_new_case_fold_nfkc($text, $option = 'full') -{ - static $fc_nfkc_closure = array( - "\xCD\xBA" => "\x20\xCE\xB9", - "\xCF\x92" => "\xCF\x85", - "\xCF\x93" => "\xCF\x8D", - "\xCF\x94" => "\xCF\x8B", - "\xCF\xB2" => "\xCF\x83", - "\xCF\xB9" => "\xCF\x83", - "\xE1\xB4\xAC" => "\x61", - "\xE1\xB4\xAD" => "\xC3\xA6", - "\xE1\xB4\xAE" => "\x62", - "\xE1\xB4\xB0" => "\x64", - "\xE1\xB4\xB1" => "\x65", - "\xE1\xB4\xB2" => "\xC7\x9D", - "\xE1\xB4\xB3" => "\x67", - "\xE1\xB4\xB4" => "\x68", - "\xE1\xB4\xB5" => "\x69", - "\xE1\xB4\xB6" => "\x6A", - "\xE1\xB4\xB7" => "\x6B", - "\xE1\xB4\xB8" => "\x6C", - "\xE1\xB4\xB9" => "\x6D", - "\xE1\xB4\xBA" => "\x6E", - "\xE1\xB4\xBC" => "\x6F", - "\xE1\xB4\xBD" => "\xC8\xA3", - "\xE1\xB4\xBE" => "\x70", - "\xE1\xB4\xBF" => "\x72", - "\xE1\xB5\x80" => "\x74", - "\xE1\xB5\x81" => "\x75", - "\xE1\xB5\x82" => "\x77", - "\xE2\x82\xA8" => "\x72\x73", - "\xE2\x84\x82" => "\x63", - "\xE2\x84\x83" => "\xC2\xB0\x63", - "\xE2\x84\x87" => "\xC9\x9B", - "\xE2\x84\x89" => "\xC2\xB0\x66", - "\xE2\x84\x8B" => "\x68", - "\xE2\x84\x8C" => "\x68", - "\xE2\x84\x8D" => "\x68", - "\xE2\x84\x90" => "\x69", - "\xE2\x84\x91" => "\x69", - "\xE2\x84\x92" => "\x6C", - "\xE2\x84\x95" => "\x6E", - "\xE2\x84\x96" => "\x6E\x6F", - "\xE2\x84\x99" => "\x70", - "\xE2\x84\x9A" => "\x71", - "\xE2\x84\x9B" => "\x72", - "\xE2\x84\x9C" => "\x72", - "\xE2\x84\x9D" => "\x72", - "\xE2\x84\xA0" => "\x73\x6D", - "\xE2\x84\xA1" => "\x74\x65\x6C", - "\xE2\x84\xA2" => "\x74\x6D", - "\xE2\x84\xA4" => "\x7A", - "\xE2\x84\xA8" => "\x7A", - "\xE2\x84\xAC" => "\x62", - "\xE2\x84\xAD" => "\x63", - "\xE2\x84\xB0" => "\x65", - "\xE2\x84\xB1" => "\x66", - "\xE2\x84\xB3" => "\x6D", - "\xE2\x84\xBB" => "\x66\x61\x78", - "\xE2\x84\xBE" => "\xCE\xB3", - "\xE2\x84\xBF" => "\xCF\x80", - "\xE2\x85\x85" => "\x64", - "\xE3\x89\x90" => "\x70\x74\x65", - "\xE3\x8B\x8C" => "\x68\x67", - "\xE3\x8B\x8E" => "\x65\x76", - "\xE3\x8B\x8F" => "\x6C\x74\x64", - "\xE3\x8D\xB1" => "\x68\x70\x61", - "\xE3\x8D\xB3" => "\x61\x75", - "\xE3\x8D\xB5" => "\x6F\x76", - "\xE3\x8D\xBA" => "\x69\x75", - "\xE3\x8E\x80" => "\x70\x61", - "\xE3\x8E\x81" => "\x6E\x61", - "\xE3\x8E\x82" => "\xCE\xBC\x61", - "\xE3\x8E\x83" => "\x6D\x61", - "\xE3\x8E\x84" => "\x6B\x61", - "\xE3\x8E\x85" => "\x6B\x62", - "\xE3\x8E\x86" => "\x6D\x62", - "\xE3\x8E\x87" => "\x67\x62", - "\xE3\x8E\x8A" => "\x70\x66", - "\xE3\x8E\x8B" => "\x6E\x66", - "\xE3\x8E\x8C" => "\xCE\xBC\x66", - "\xE3\x8E\x90" => "\x68\x7A", - "\xE3\x8E\x91" => "\x6B\x68\x7A", - "\xE3\x8E\x92" => "\x6D\x68\x7A", - "\xE3\x8E\x93" => "\x67\x68\x7A", - "\xE3\x8E\x94" => "\x74\x68\x7A", - "\xE3\x8E\xA9" => "\x70\x61", - "\xE3\x8E\xAA" => "\x6B\x70\x61", - "\xE3\x8E\xAB" => "\x6D\x70\x61", - "\xE3\x8E\xAC" => "\x67\x70\x61", - "\xE3\x8E\xB4" => "\x70\x76", - "\xE3\x8E\xB5" => "\x6E\x76", - "\xE3\x8E\xB6" => "\xCE\xBC\x76", - "\xE3\x8E\xB7" => "\x6D\x76", - "\xE3\x8E\xB8" => "\x6B\x76", - "\xE3\x8E\xB9" => "\x6D\x76", - "\xE3\x8E\xBA" => "\x70\x77", - "\xE3\x8E\xBB" => "\x6E\x77", - "\xE3\x8E\xBC" => "\xCE\xBC\x77", - "\xE3\x8E\xBD" => "\x6D\x77", - "\xE3\x8E\xBE" => "\x6B\x77", - "\xE3\x8E\xBF" => "\x6D\x77", - "\xE3\x8F\x80" => "\x6B\xCF\x89", - "\xE3\x8F\x81" => "\x6D\xCF\x89", - "\xE3\x8F\x83" => "\x62\x71", - "\xE3\x8F\x86" => "\x63\xE2\x88\x95\x6B\x67", - "\xE3\x8F\x87" => "\x63\x6F\x2E", - "\xE3\x8F\x88" => "\x64\x62", - "\xE3\x8F\x89" => "\x67\x79", - "\xE3\x8F\x8B" => "\x68\x70", - "\xE3\x8F\x8D" => "\x6B\x6B", - "\xE3\x8F\x8E" => "\x6B\x6D", - "\xE3\x8F\x97" => "\x70\x68", - "\xE3\x8F\x99" => "\x70\x70\x6D", - "\xE3\x8F\x9A" => "\x70\x72", - "\xE3\x8F\x9C" => "\x73\x76", - "\xE3\x8F\x9D" => "\x77\x62", - "\xE3\x8F\x9E" => "\x76\xE2\x88\x95\x6D", - "\xE3\x8F\x9F" => "\x61\xE2\x88\x95\x6D", - "\xF0\x9D\x90\x80" => "\x61", - "\xF0\x9D\x90\x81" => "\x62", - "\xF0\x9D\x90\x82" => "\x63", - "\xF0\x9D\x90\x83" => "\x64", - "\xF0\x9D\x90\x84" => "\x65", - "\xF0\x9D\x90\x85" => "\x66", - "\xF0\x9D\x90\x86" => "\x67", - "\xF0\x9D\x90\x87" => "\x68", - "\xF0\x9D\x90\x88" => "\x69", - "\xF0\x9D\x90\x89" => "\x6A", - "\xF0\x9D\x90\x8A" => "\x6B", - "\xF0\x9D\x90\x8B" => "\x6C", - "\xF0\x9D\x90\x8C" => "\x6D", - "\xF0\x9D\x90\x8D" => "\x6E", - "\xF0\x9D\x90\x8E" => "\x6F", - "\xF0\x9D\x90\x8F" => "\x70", - "\xF0\x9D\x90\x90" => "\x71", - "\xF0\x9D\x90\x91" => "\x72", - "\xF0\x9D\x90\x92" => "\x73", - "\xF0\x9D\x90\x93" => "\x74", - "\xF0\x9D\x90\x94" => "\x75", - "\xF0\x9D\x90\x95" => "\x76", - "\xF0\x9D\x90\x96" => "\x77", - "\xF0\x9D\x90\x97" => "\x78", - "\xF0\x9D\x90\x98" => "\x79", - "\xF0\x9D\x90\x99" => "\x7A", - "\xF0\x9D\x90\xB4" => "\x61", - "\xF0\x9D\x90\xB5" => "\x62", - "\xF0\x9D\x90\xB6" => "\x63", - "\xF0\x9D\x90\xB7" => "\x64", - "\xF0\x9D\x90\xB8" => "\x65", - "\xF0\x9D\x90\xB9" => "\x66", - "\xF0\x9D\x90\xBA" => "\x67", - "\xF0\x9D\x90\xBB" => "\x68", - "\xF0\x9D\x90\xBC" => "\x69", - "\xF0\x9D\x90\xBD" => "\x6A", - "\xF0\x9D\x90\xBE" => "\x6B", - "\xF0\x9D\x90\xBF" => "\x6C", - "\xF0\x9D\x91\x80" => "\x6D", - "\xF0\x9D\x91\x81" => "\x6E", - "\xF0\x9D\x91\x82" => "\x6F", - "\xF0\x9D\x91\x83" => "\x70", - "\xF0\x9D\x91\x84" => "\x71", - "\xF0\x9D\x91\x85" => "\x72", - "\xF0\x9D\x91\x86" => "\x73", - "\xF0\x9D\x91\x87" => "\x74", - "\xF0\x9D\x91\x88" => "\x75", - "\xF0\x9D\x91\x89" => "\x76", - "\xF0\x9D\x91\x8A" => "\x77", - "\xF0\x9D\x91\x8B" => "\x78", - "\xF0\x9D\x91\x8C" => "\x79", - "\xF0\x9D\x91\x8D" => "\x7A", - "\xF0\x9D\x91\xA8" => "\x61", - "\xF0\x9D\x91\xA9" => "\x62", - "\xF0\x9D\x91\xAA" => "\x63", - "\xF0\x9D\x91\xAB" => "\x64", - "\xF0\x9D\x91\xAC" => "\x65", - "\xF0\x9D\x91\xAD" => "\x66", - "\xF0\x9D\x91\xAE" => "\x67", - "\xF0\x9D\x91\xAF" => "\x68", - "\xF0\x9D\x91\xB0" => "\x69", - "\xF0\x9D\x91\xB1" => "\x6A", - "\xF0\x9D\x91\xB2" => "\x6B", - "\xF0\x9D\x91\xB3" => "\x6C", - "\xF0\x9D\x91\xB4" => "\x6D", - "\xF0\x9D\x91\xB5" => "\x6E", - "\xF0\x9D\x91\xB6" => "\x6F", - "\xF0\x9D\x91\xB7" => "\x70", - "\xF0\x9D\x91\xB8" => "\x71", - "\xF0\x9D\x91\xB9" => "\x72", - "\xF0\x9D\x91\xBA" => "\x73", - "\xF0\x9D\x91\xBB" => "\x74", - "\xF0\x9D\x91\xBC" => "\x75", - "\xF0\x9D\x91\xBD" => "\x76", - "\xF0\x9D\x91\xBE" => "\x77", - "\xF0\x9D\x91\xBF" => "\x78", - "\xF0\x9D\x92\x80" => "\x79", - "\xF0\x9D\x92\x81" => "\x7A", - "\xF0\x9D\x92\x9C" => "\x61", - "\xF0\x9D\x92\x9E" => "\x63", - "\xF0\x9D\x92\x9F" => "\x64", - "\xF0\x9D\x92\xA2" => "\x67", - "\xF0\x9D\x92\xA5" => "\x6A", - "\xF0\x9D\x92\xA6" => "\x6B", - "\xF0\x9D\x92\xA9" => "\x6E", - "\xF0\x9D\x92\xAA" => "\x6F", - "\xF0\x9D\x92\xAB" => "\x70", - "\xF0\x9D\x92\xAC" => "\x71", - "\xF0\x9D\x92\xAE" => "\x73", - "\xF0\x9D\x92\xAF" => "\x74", - "\xF0\x9D\x92\xB0" => "\x75", - "\xF0\x9D\x92\xB1" => "\x76", - "\xF0\x9D\x92\xB2" => "\x77", - "\xF0\x9D\x92\xB3" => "\x78", - "\xF0\x9D\x92\xB4" => "\x79", - "\xF0\x9D\x92\xB5" => "\x7A", - "\xF0\x9D\x93\x90" => "\x61", - "\xF0\x9D\x93\x91" => "\x62", - "\xF0\x9D\x93\x92" => "\x63", - "\xF0\x9D\x93\x93" => "\x64", - "\xF0\x9D\x93\x94" => "\x65", - "\xF0\x9D\x93\x95" => "\x66", - "\xF0\x9D\x93\x96" => "\x67", - "\xF0\x9D\x93\x97" => "\x68", - "\xF0\x9D\x93\x98" => "\x69", - "\xF0\x9D\x93\x99" => "\x6A", - "\xF0\x9D\x93\x9A" => "\x6B", - "\xF0\x9D\x93\x9B" => "\x6C", - "\xF0\x9D\x93\x9C" => "\x6D", - "\xF0\x9D\x93\x9D" => "\x6E", - "\xF0\x9D\x93\x9E" => "\x6F", - "\xF0\x9D\x93\x9F" => "\x70", - "\xF0\x9D\x93\xA0" => "\x71", - "\xF0\x9D\x93\xA1" => "\x72", - "\xF0\x9D\x93\xA2" => "\x73", - "\xF0\x9D\x93\xA3" => "\x74", - "\xF0\x9D\x93\xA4" => "\x75", - "\xF0\x9D\x93\xA5" => "\x76", - "\xF0\x9D\x93\xA6" => "\x77", - "\xF0\x9D\x93\xA7" => "\x78", - "\xF0\x9D\x93\xA8" => "\x79", - "\xF0\x9D\x93\xA9" => "\x7A", - "\xF0\x9D\x94\x84" => "\x61", - "\xF0\x9D\x94\x85" => "\x62", - "\xF0\x9D\x94\x87" => "\x64", - "\xF0\x9D\x94\x88" => "\x65", - "\xF0\x9D\x94\x89" => "\x66", - "\xF0\x9D\x94\x8A" => "\x67", - "\xF0\x9D\x94\x8D" => "\x6A", - "\xF0\x9D\x94\x8E" => "\x6B", - "\xF0\x9D\x94\x8F" => "\x6C", - "\xF0\x9D\x94\x90" => "\x6D", - "\xF0\x9D\x94\x91" => "\x6E", - "\xF0\x9D\x94\x92" => "\x6F", - "\xF0\x9D\x94\x93" => "\x70", - "\xF0\x9D\x94\x94" => "\x71", - "\xF0\x9D\x94\x96" => "\x73", - "\xF0\x9D\x94\x97" => "\x74", - "\xF0\x9D\x94\x98" => "\x75", - "\xF0\x9D\x94\x99" => "\x76", - "\xF0\x9D\x94\x9A" => "\x77", - "\xF0\x9D\x94\x9B" => "\x78", - "\xF0\x9D\x94\x9C" => "\x79", - "\xF0\x9D\x94\xB8" => "\x61", - "\xF0\x9D\x94\xB9" => "\x62", - "\xF0\x9D\x94\xBB" => "\x64", - "\xF0\x9D\x94\xBC" => "\x65", - "\xF0\x9D\x94\xBD" => "\x66", - "\xF0\x9D\x94\xBE" => "\x67", - "\xF0\x9D\x95\x80" => "\x69", - "\xF0\x9D\x95\x81" => "\x6A", - "\xF0\x9D\x95\x82" => "\x6B", - "\xF0\x9D\x95\x83" => "\x6C", - "\xF0\x9D\x95\x84" => "\x6D", - "\xF0\x9D\x95\x86" => "\x6F", - "\xF0\x9D\x95\x8A" => "\x73", - "\xF0\x9D\x95\x8B" => "\x74", - "\xF0\x9D\x95\x8C" => "\x75", - "\xF0\x9D\x95\x8D" => "\x76", - "\xF0\x9D\x95\x8E" => "\x77", - "\xF0\x9D\x95\x8F" => "\x78", - "\xF0\x9D\x95\x90" => "\x79", - "\xF0\x9D\x95\xAC" => "\x61", - "\xF0\x9D\x95\xAD" => "\x62", - "\xF0\x9D\x95\xAE" => "\x63", - "\xF0\x9D\x95\xAF" => "\x64", - "\xF0\x9D\x95\xB0" => "\x65", - "\xF0\x9D\x95\xB1" => "\x66", - "\xF0\x9D\x95\xB2" => "\x67", - "\xF0\x9D\x95\xB3" => "\x68", - "\xF0\x9D\x95\xB4" => "\x69", - "\xF0\x9D\x95\xB5" => "\x6A", - "\xF0\x9D\x95\xB6" => "\x6B", - "\xF0\x9D\x95\xB7" => "\x6C", - "\xF0\x9D\x95\xB8" => "\x6D", - "\xF0\x9D\x95\xB9" => "\x6E", - "\xF0\x9D\x95\xBA" => "\x6F", - "\xF0\x9D\x95\xBB" => "\x70", - "\xF0\x9D\x95\xBC" => "\x71", - "\xF0\x9D\x95\xBD" => "\x72", - "\xF0\x9D\x95\xBE" => "\x73", - "\xF0\x9D\x95\xBF" => "\x74", - "\xF0\x9D\x96\x80" => "\x75", - "\xF0\x9D\x96\x81" => "\x76", - "\xF0\x9D\x96\x82" => "\x77", - "\xF0\x9D\x96\x83" => "\x78", - "\xF0\x9D\x96\x84" => "\x79", - "\xF0\x9D\x96\x85" => "\x7A", - "\xF0\x9D\x96\xA0" => "\x61", - "\xF0\x9D\x96\xA1" => "\x62", - "\xF0\x9D\x96\xA2" => "\x63", - "\xF0\x9D\x96\xA3" => "\x64", - "\xF0\x9D\x96\xA4" => "\x65", - "\xF0\x9D\x96\xA5" => "\x66", - "\xF0\x9D\x96\xA6" => "\x67", - "\xF0\x9D\x96\xA7" => "\x68", - "\xF0\x9D\x96\xA8" => "\x69", - "\xF0\x9D\x96\xA9" => "\x6A", - "\xF0\x9D\x96\xAA" => "\x6B", - "\xF0\x9D\x96\xAB" => "\x6C", - "\xF0\x9D\x96\xAC" => "\x6D", - "\xF0\x9D\x96\xAD" => "\x6E", - "\xF0\x9D\x96\xAE" => "\x6F", - "\xF0\x9D\x96\xAF" => "\x70", - "\xF0\x9D\x96\xB0" => "\x71", - "\xF0\x9D\x96\xB1" => "\x72", - "\xF0\x9D\x96\xB2" => "\x73", - "\xF0\x9D\x96\xB3" => "\x74", - "\xF0\x9D\x96\xB4" => "\x75", - "\xF0\x9D\x96\xB5" => "\x76", - "\xF0\x9D\x96\xB6" => "\x77", - "\xF0\x9D\x96\xB7" => "\x78", - "\xF0\x9D\x96\xB8" => "\x79", - "\xF0\x9D\x96\xB9" => "\x7A", - "\xF0\x9D\x97\x94" => "\x61", - "\xF0\x9D\x97\x95" => "\x62", - "\xF0\x9D\x97\x96" => "\x63", - "\xF0\x9D\x97\x97" => "\x64", - "\xF0\x9D\x97\x98" => "\x65", - "\xF0\x9D\x97\x99" => "\x66", - "\xF0\x9D\x97\x9A" => "\x67", - "\xF0\x9D\x97\x9B" => "\x68", - "\xF0\x9D\x97\x9C" => "\x69", - "\xF0\x9D\x97\x9D" => "\x6A", - "\xF0\x9D\x97\x9E" => "\x6B", - "\xF0\x9D\x97\x9F" => "\x6C", - "\xF0\x9D\x97\xA0" => "\x6D", - "\xF0\x9D\x97\xA1" => "\x6E", - "\xF0\x9D\x97\xA2" => "\x6F", - "\xF0\x9D\x97\xA3" => "\x70", - "\xF0\x9D\x97\xA4" => "\x71", - "\xF0\x9D\x97\xA5" => "\x72", - "\xF0\x9D\x97\xA6" => "\x73", - "\xF0\x9D\x97\xA7" => "\x74", - "\xF0\x9D\x97\xA8" => "\x75", - "\xF0\x9D\x97\xA9" => "\x76", - "\xF0\x9D\x97\xAA" => "\x77", - "\xF0\x9D\x97\xAB" => "\x78", - "\xF0\x9D\x97\xAC" => "\x79", - "\xF0\x9D\x97\xAD" => "\x7A", - "\xF0\x9D\x98\x88" => "\x61", - "\xF0\x9D\x98\x89" => "\x62", - "\xF0\x9D\x98\x8A" => "\x63", - "\xF0\x9D\x98\x8B" => "\x64", - "\xF0\x9D\x98\x8C" => "\x65", - "\xF0\x9D\x98\x8D" => "\x66", - "\xF0\x9D\x98\x8E" => "\x67", - "\xF0\x9D\x98\x8F" => "\x68", - "\xF0\x9D\x98\x90" => "\x69", - "\xF0\x9D\x98\x91" => "\x6A", - "\xF0\x9D\x98\x92" => "\x6B", - "\xF0\x9D\x98\x93" => "\x6C", - "\xF0\x9D\x98\x94" => "\x6D", - "\xF0\x9D\x98\x95" => "\x6E", - "\xF0\x9D\x98\x96" => "\x6F", - "\xF0\x9D\x98\x97" => "\x70", - "\xF0\x9D\x98\x98" => "\x71", - "\xF0\x9D\x98\x99" => "\x72", - "\xF0\x9D\x98\x9A" => "\x73", - "\xF0\x9D\x98\x9B" => "\x74", - "\xF0\x9D\x98\x9C" => "\x75", - "\xF0\x9D\x98\x9D" => "\x76", - "\xF0\x9D\x98\x9E" => "\x77", - "\xF0\x9D\x98\x9F" => "\x78", - "\xF0\x9D\x98\xA0" => "\x79", - "\xF0\x9D\x98\xA1" => "\x7A", - "\xF0\x9D\x98\xBC" => "\x61", - "\xF0\x9D\x98\xBD" => "\x62", - "\xF0\x9D\x98\xBE" => "\x63", - "\xF0\x9D\x98\xBF" => "\x64", - "\xF0\x9D\x99\x80" => "\x65", - "\xF0\x9D\x99\x81" => "\x66", - "\xF0\x9D\x99\x82" => "\x67", - "\xF0\x9D\x99\x83" => "\x68", - "\xF0\x9D\x99\x84" => "\x69", - "\xF0\x9D\x99\x85" => "\x6A", - "\xF0\x9D\x99\x86" => "\x6B", - "\xF0\x9D\x99\x87" => "\x6C", - "\xF0\x9D\x99\x88" => "\x6D", - "\xF0\x9D\x99\x89" => "\x6E", - "\xF0\x9D\x99\x8A" => "\x6F", - "\xF0\x9D\x99\x8B" => "\x70", - "\xF0\x9D\x99\x8C" => "\x71", - "\xF0\x9D\x99\x8D" => "\x72", - "\xF0\x9D\x99\x8E" => "\x73", - "\xF0\x9D\x99\x8F" => "\x74", - "\xF0\x9D\x99\x90" => "\x75", - "\xF0\x9D\x99\x91" => "\x76", - "\xF0\x9D\x99\x92" => "\x77", - "\xF0\x9D\x99\x93" => "\x78", - "\xF0\x9D\x99\x94" => "\x79", - "\xF0\x9D\x99\x95" => "\x7A", - "\xF0\x9D\x99\xB0" => "\x61", - "\xF0\x9D\x99\xB1" => "\x62", - "\xF0\x9D\x99\xB2" => "\x63", - "\xF0\x9D\x99\xB3" => "\x64", - "\xF0\x9D\x99\xB4" => "\x65", - "\xF0\x9D\x99\xB5" => "\x66", - "\xF0\x9D\x99\xB6" => "\x67", - "\xF0\x9D\x99\xB7" => "\x68", - "\xF0\x9D\x99\xB8" => "\x69", - "\xF0\x9D\x99\xB9" => "\x6A", - "\xF0\x9D\x99\xBA" => "\x6B", - "\xF0\x9D\x99\xBB" => "\x6C", - "\xF0\x9D\x99\xBC" => "\x6D", - "\xF0\x9D\x99\xBD" => "\x6E", - "\xF0\x9D\x99\xBE" => "\x6F", - "\xF0\x9D\x99\xBF" => "\x70", - "\xF0\x9D\x9A\x80" => "\x71", - "\xF0\x9D\x9A\x81" => "\x72", - "\xF0\x9D\x9A\x82" => "\x73", - "\xF0\x9D\x9A\x83" => "\x74", - "\xF0\x9D\x9A\x84" => "\x75", - "\xF0\x9D\x9A\x85" => "\x76", - "\xF0\x9D\x9A\x86" => "\x77", - "\xF0\x9D\x9A\x87" => "\x78", - "\xF0\x9D\x9A\x88" => "\x79", - "\xF0\x9D\x9A\x89" => "\x7A", - "\xF0\x9D\x9A\xA8" => "\xCE\xB1", - "\xF0\x9D\x9A\xA9" => "\xCE\xB2", - "\xF0\x9D\x9A\xAA" => "\xCE\xB3", - "\xF0\x9D\x9A\xAB" => "\xCE\xB4", - "\xF0\x9D\x9A\xAC" => "\xCE\xB5", - "\xF0\x9D\x9A\xAD" => "\xCE\xB6", - "\xF0\x9D\x9A\xAE" => "\xCE\xB7", - "\xF0\x9D\x9A\xAF" => "\xCE\xB8", - "\xF0\x9D\x9A\xB0" => "\xCE\xB9", - "\xF0\x9D\x9A\xB1" => "\xCE\xBA", - "\xF0\x9D\x9A\xB2" => "\xCE\xBB", - "\xF0\x9D\x9A\xB3" => "\xCE\xBC", - "\xF0\x9D\x9A\xB4" => "\xCE\xBD", - "\xF0\x9D\x9A\xB5" => "\xCE\xBE", - "\xF0\x9D\x9A\xB6" => "\xCE\xBF", - "\xF0\x9D\x9A\xB7" => "\xCF\x80", - "\xF0\x9D\x9A\xB8" => "\xCF\x81", - "\xF0\x9D\x9A\xB9" => "\xCE\xB8", - "\xF0\x9D\x9A\xBA" => "\xCF\x83", - "\xF0\x9D\x9A\xBB" => "\xCF\x84", - "\xF0\x9D\x9A\xBC" => "\xCF\x85", - "\xF0\x9D\x9A\xBD" => "\xCF\x86", - "\xF0\x9D\x9A\xBE" => "\xCF\x87", - "\xF0\x9D\x9A\xBF" => "\xCF\x88", - "\xF0\x9D\x9B\x80" => "\xCF\x89", - "\xF0\x9D\x9B\x93" => "\xCF\x83", - "\xF0\x9D\x9B\xA2" => "\xCE\xB1", - "\xF0\x9D\x9B\xA3" => "\xCE\xB2", - "\xF0\x9D\x9B\xA4" => "\xCE\xB3", - "\xF0\x9D\x9B\xA5" => "\xCE\xB4", - "\xF0\x9D\x9B\xA6" => "\xCE\xB5", - "\xF0\x9D\x9B\xA7" => "\xCE\xB6", - "\xF0\x9D\x9B\xA8" => "\xCE\xB7", - "\xF0\x9D\x9B\xA9" => "\xCE\xB8", - "\xF0\x9D\x9B\xAA" => "\xCE\xB9", - "\xF0\x9D\x9B\xAB" => "\xCE\xBA", - "\xF0\x9D\x9B\xAC" => "\xCE\xBB", - "\xF0\x9D\x9B\xAD" => "\xCE\xBC", - "\xF0\x9D\x9B\xAE" => "\xCE\xBD", - "\xF0\x9D\x9B\xAF" => "\xCE\xBE", - "\xF0\x9D\x9B\xB0" => "\xCE\xBF", - "\xF0\x9D\x9B\xB1" => "\xCF\x80", - "\xF0\x9D\x9B\xB2" => "\xCF\x81", - "\xF0\x9D\x9B\xB3" => "\xCE\xB8", - "\xF0\x9D\x9B\xB4" => "\xCF\x83", - "\xF0\x9D\x9B\xB5" => "\xCF\x84", - "\xF0\x9D\x9B\xB6" => "\xCF\x85", - "\xF0\x9D\x9B\xB7" => "\xCF\x86", - "\xF0\x9D\x9B\xB8" => "\xCF\x87", - "\xF0\x9D\x9B\xB9" => "\xCF\x88", - "\xF0\x9D\x9B\xBA" => "\xCF\x89", - "\xF0\x9D\x9C\x8D" => "\xCF\x83", - "\xF0\x9D\x9C\x9C" => "\xCE\xB1", - "\xF0\x9D\x9C\x9D" => "\xCE\xB2", - "\xF0\x9D\x9C\x9E" => "\xCE\xB3", - "\xF0\x9D\x9C\x9F" => "\xCE\xB4", - "\xF0\x9D\x9C\xA0" => "\xCE\xB5", - "\xF0\x9D\x9C\xA1" => "\xCE\xB6", - "\xF0\x9D\x9C\xA2" => "\xCE\xB7", - "\xF0\x9D\x9C\xA3" => "\xCE\xB8", - "\xF0\x9D\x9C\xA4" => "\xCE\xB9", - "\xF0\x9D\x9C\xA5" => "\xCE\xBA", - "\xF0\x9D\x9C\xA6" => "\xCE\xBB", - "\xF0\x9D\x9C\xA7" => "\xCE\xBC", - "\xF0\x9D\x9C\xA8" => "\xCE\xBD", - "\xF0\x9D\x9C\xA9" => "\xCE\xBE", - "\xF0\x9D\x9C\xAA" => "\xCE\xBF", - "\xF0\x9D\x9C\xAB" => "\xCF\x80", - "\xF0\x9D\x9C\xAC" => "\xCF\x81", - "\xF0\x9D\x9C\xAD" => "\xCE\xB8", - "\xF0\x9D\x9C\xAE" => "\xCF\x83", - "\xF0\x9D\x9C\xAF" => "\xCF\x84", - "\xF0\x9D\x9C\xB0" => "\xCF\x85", - "\xF0\x9D\x9C\xB1" => "\xCF\x86", - "\xF0\x9D\x9C\xB2" => "\xCF\x87", - "\xF0\x9D\x9C\xB3" => "\xCF\x88", - "\xF0\x9D\x9C\xB4" => "\xCF\x89", - "\xF0\x9D\x9D\x87" => "\xCF\x83", - "\xF0\x9D\x9D\x96" => "\xCE\xB1", - "\xF0\x9D\x9D\x97" => "\xCE\xB2", - "\xF0\x9D\x9D\x98" => "\xCE\xB3", - "\xF0\x9D\x9D\x99" => "\xCE\xB4", - "\xF0\x9D\x9D\x9A" => "\xCE\xB5", - "\xF0\x9D\x9D\x9B" => "\xCE\xB6", - "\xF0\x9D\x9D\x9C" => "\xCE\xB7", - "\xF0\x9D\x9D\x9D" => "\xCE\xB8", - "\xF0\x9D\x9D\x9E" => "\xCE\xB9", - "\xF0\x9D\x9D\x9F" => "\xCE\xBA", - "\xF0\x9D\x9D\xA0" => "\xCE\xBB", - "\xF0\x9D\x9D\xA1" => "\xCE\xBC", - "\xF0\x9D\x9D\xA2" => "\xCE\xBD", - "\xF0\x9D\x9D\xA3" => "\xCE\xBE", - "\xF0\x9D\x9D\xA4" => "\xCE\xBF", - "\xF0\x9D\x9D\xA5" => "\xCF\x80", - "\xF0\x9D\x9D\xA6" => "\xCF\x81", - "\xF0\x9D\x9D\xA7" => "\xCE\xB8", - "\xF0\x9D\x9D\xA8" => "\xCF\x83", - "\xF0\x9D\x9D\xA9" => "\xCF\x84", - "\xF0\x9D\x9D\xAA" => "\xCF\x85", - "\xF0\x9D\x9D\xAB" => "\xCF\x86", - "\xF0\x9D\x9D\xAC" => "\xCF\x87", - "\xF0\x9D\x9D\xAD" => "\xCF\x88", - "\xF0\x9D\x9D\xAE" => "\xCF\x89", - "\xF0\x9D\x9E\x81" => "\xCF\x83", - "\xF0\x9D\x9E\x90" => "\xCE\xB1", - "\xF0\x9D\x9E\x91" => "\xCE\xB2", - "\xF0\x9D\x9E\x92" => "\xCE\xB3", - "\xF0\x9D\x9E\x93" => "\xCE\xB4", - "\xF0\x9D\x9E\x94" => "\xCE\xB5", - "\xF0\x9D\x9E\x95" => "\xCE\xB6", - "\xF0\x9D\x9E\x96" => "\xCE\xB7", - "\xF0\x9D\x9E\x97" => "\xCE\xB8", - "\xF0\x9D\x9E\x98" => "\xCE\xB9", - "\xF0\x9D\x9E\x99" => "\xCE\xBA", - "\xF0\x9D\x9E\x9A" => "\xCE\xBB", - "\xF0\x9D\x9E\x9B" => "\xCE\xBC", - "\xF0\x9D\x9E\x9C" => "\xCE\xBD", - "\xF0\x9D\x9E\x9D" => "\xCE\xBE", - "\xF0\x9D\x9E\x9E" => "\xCE\xBF", - "\xF0\x9D\x9E\x9F" => "\xCF\x80", - "\xF0\x9D\x9E\xA0" => "\xCF\x81", - "\xF0\x9D\x9E\xA1" => "\xCE\xB8", - "\xF0\x9D\x9E\xA2" => "\xCF\x83", - "\xF0\x9D\x9E\xA3" => "\xCF\x84", - "\xF0\x9D\x9E\xA4" => "\xCF\x85", - "\xF0\x9D\x9E\xA5" => "\xCF\x86", - "\xF0\x9D\x9E\xA6" => "\xCF\x87", - "\xF0\x9D\x9E\xA7" => "\xCF\x88", - "\xF0\x9D\x9E\xA8" => "\xCF\x89", - "\xF0\x9D\x9E\xBB" => "\xCF\x83", - "\xF0\x9D\x9F\x8A" => "\xCF\x9D", - ); - global $phpbb_root_path, $phpEx; - - // do the case fold - $text = utf8_new_case_fold($text, $option); - - // convert to NFKC - $text = Normalizer::normalize($text, Normalizer::NFKC); - - // FC_NFKC_Closure, http://www.unicode.org/Public/5.0.0/ucd/DerivedNormalizationProps.txt - $text = strtr($text, $fc_nfkc_closure); - - return $text; -} - -return array('Ā”'=>'i','ǃ'=>'!','α'=>'a','įš€'=>' ','Ā­'=>'','Ū'=>'','܏'=>'','į †'=>'','į Ž'=>'','​'=>'','ā€Œ'=>'','ā€'=>'','
'=>'','
'=>'','⁠'=>'','⁔'=>'','⁢'=>'','⁣'=>'',''=>'',''=>'',''=>'',''=>'',''=>'',''=>'',''=>'','ļæ¹'=>'','ļæŗ'=>'','ļæ»'=>'','ļæ¼'=>'','š…³'=>'','š…“'=>'','š…µ'=>'','š…¶'=>'','š…·'=>'','š…ø'=>'','š…¹'=>'','š…ŗ'=>'','Ū¬'=>'۟','̓'=>'Ģ“','Ł'=>'Ģ“','֜'=>'́','́'=>'́','݇'=>'́','ą„”'=>'́','Ķ€'=>'Ģ€','ą„“'=>'Ģ€','̌'=>'̆','Ģ‘'=>'Ģ‚','ÖÆ'=>'̊','ஂ'=>'̊','ą¹'=>'̊','ą»'=>'̊','ံ'=>'̊','įŸ†'=>'̊','įŸ“'=>'̊','悚'=>'̊','゚'=>'̊','ͦ'=>'̊','Ķ‚'=>'̃','ׄ'=>'̇','Ö¹'=>'̇','ׂ'=>'̇','ׁ'=>'̇','݁'=>'̇','ं'=>'̇','ਂ'=>'̇','ąŖ‚'=>'̇','ąÆ'=>'̇','Ģ…'=>'Ģ„','怬'=>'̉','̱'=>'Ģ ','ą„’'=>'Ģ ','̧'=>'Ģ”','̦'=>'Ģ”','ĢØ'=>'Ģ¢','़'=>'Ģ£','়'=>'Ģ£','਼'=>'Ģ£','ąŖ¼'=>'Ģ£','଼'=>'Ģ£','͇'=>'̳','̶'=>'̵','ļ±ž'=>'ﹲّ','ﱟ'=>'﹓ّ','ļ³²'=>'ļ¹·Ł‘','ļ± '=>'ļ¹¶Ł‘','ļ³³'=>'ﹹّ','ļ±”'=>'ļ¹øŁ‘','ﳓ'=>'ﹻّ','ļ±¢'=>'ļ¹ŗŁ‘','ļ±£'=>'ﹼٰ','Ł“'=>'Ł”','Ż‚'=>'ܼ','౦'=>'o','೦'=>'o','ļ¾ž'=>'悙','怀'=>' ',' '=>' ',' '=>' ',' '=>' ','ā€ƒ'=>' ',' '=>' ',' '=>' ',' '=>' ','ā€ˆ'=>' ',' '=>' ','ā€Š'=>' ',' '=>' ','Ā '=>' ',' '=>' ',' '=>' ','`'=>'`','ļ½€'=>'`','῀'=>'˜','ļ¼¾'=>'^','ļøæ'=>'^','_'=>'_','ļ¹'=>'_','ļ¹Ž'=>'_','ļ¹'=>'_','āŒ‡'=>'ļø“','ļ¼'=>'-','‐'=>'-','‑'=>'-','‒'=>'-','–'=>'-','﹘'=>'-','∼'=>'⁓','d'=>'惻','•'=>'惻',','=>',','ā€š'=>',','٬'=>'،','、'=>'态',';'=>';','ļ¼›'=>';',':'=>':','։'=>':','ļø°'=>':','׃'=>':','ā©“'=>'::=','ļ¼Ž'=>'.','․'=>'.','܂'=>'.',' '=>'..','…'=>'...','ļ½”'=>'怂','·'=>'Ā·','‧'=>'Ā·','āˆ™'=>'Ā·','ā‹…'=>'Ā·','ᐧ'=>'Ā·','ᔯ'=>'Ā·4','ᐌ'=>'·ᐁ','įŽ'=>'·ᐃ','ᐐ'=>'·ᐄ','ᐒ'=>'·ᐅ','ᐔ'=>'·ᐆ','ᐗ'=>'·ᐊ','ᐙ'=>'·ᐋ','ᐷ'=>'·ᐳ','į‘€'=>'·ᐳ','į‘‚'=>'·ᐓ','į‘„'=>'·ᐸ','ᑆ'=>'·ᐹ','į‘—'=>'Ā·į‘Œ','į‘™'=>'Ā·į‘Ž','į‘›'=>'Ā·į‘','į‘”'=>'·ᑐ','į‘'=>'·ᑐ','į‘Ÿ'=>'Ā·į‘‘','į‘”'=>'Ā·į‘•','į‘£'=>'Ā·į‘–','į‘“'=>'Ā·į‘«','ᑸ'=>'Ā·į‘®','ᑼ'=>'Ā·į‘°','ᑾ'=>'·ᑲ','į’€'=>'·ᑳ','į’’'=>'Ā·į’‰','į’”'=>'Ā·į’‹','į’–'=>'Ā·į’Œ','į’š'=>'Ā·į’Ž','į’œ'=>'·ᒐ','į’ž'=>'Ā·į’‘','į’¬'=>'Ā·į’£','į’®'=>'Ā·į’„','į’°'=>'Ā·į’¦','į’²'=>'Ā·į’§','į’“'=>'Ā·į’Ø','į’¶'=>'Ā·L','į’ø'=>'Ā·į’«','ᓉ'=>'Ā·į“€','į“‹'=>'·ᓇ','į“'=>'Ā·į“ˆ','į“œ'=>'Ā·į““','į“ž'=>'Ā·į“•','į“ '=>'Ā·į“–','į“¢'=>'Ā·į“—','ᓤ'=>'Ā·į“˜','ᓦ'=>'Ā·į“š','ᓨ'=>'Ā·į“›','į“¶'=>'Ā·į“­','ᓸ'=>'·ᓯ','ᓺ'=>'Ā·į“°','ᓼ'=>'·ᓱ','ᓾ'=>'·ᓲ','ᔀ'=>'Ā·į““','ᔂ'=>'·ᓵ','į”—'=>'·ᔐ','į”™'=>'·ᔑ','į”›'=>'Ā·į”’','į”'=>'·ᔓ','į”Ÿ'=>'Ā·į””','į””'=>'·ᔕ','ᔣ'=>'Ā·į”–','į”±'=>'·ᔨ','ᔳ'=>'·ᔩ','ᔵ'=>'·ᔪ','į”·'=>'·ᔫ','ᔹ'=>'Ā·į”­','į”»'=>'Ā·į”®','į•Ž'=>'Ā·į•Œ','į•›'=>'Ā·į•š','ᕨ'=>'Ā·į•§','('=>'(','ā‘“'=>'(1)','ā’§'=>'(l)','⑽'=>'(10)','⑾'=>'(11)','⑿'=>'(12)','ā’€'=>'(13)','⒁'=>'(14)','ā’‚'=>'(15)','ā’ƒ'=>'(16)','ā’„'=>'(17)','ā’…'=>'(18)','ā’†'=>'(19)','⑵'=>'(2)','ā’‡'=>'(20)','ā‘¶'=>'(3)','ā‘·'=>'(4)','⑸'=>'(5)','⑹'=>'(6)','⑺'=>'(7)','ā‘»'=>'(8)','⑼'=>'(9)','ā’œ'=>'(a)','ā’'=>'(b)','ā’ž'=>'(c)','ā’Ÿ'=>'(d)','ā’ '=>'(e)','ā’”'=>'(f)','ā’¢'=>'(g)','ā’£'=>'(h)','ā’¤'=>'(i)','ā’„'=>'(j)','ā’¦'=>'(k)','ā’Ø'=>'(m)','ā’©'=>'(n)','ā’Ŗ'=>'(o)','ā’«'=>'(p)','ā’¬'=>'(q)','ā’­'=>'(r)','ā’®'=>'(s)','ā’Æ'=>'(t)','ā’°'=>'(u)','ā’±'=>'(v)','ā’²'=>'(w)','ā’³'=>'(x)','ā’“'=>'(y)','ā’µ'=>'(z)','戀'=>'(į„€)','戎'=>'(ź°€)','戁'=>'(į„‚)','戏'=>'(ė‚˜)','戂'=>'(į„ƒ)','成'=>'(다)','戃'=>'(į„…)','我'=>'(ė¼)','戄'=>'(ᄆ)','戒'=>'(마)','戅'=>'(ᄇ)','戓'=>'(ė°”)','戆'=>'(ᄉ)','戔'=>'(사)','戇'=>'(į„‹)','戕'=>'(ģ•„)','戝'=>'(ģ˜¤ģ „)','戞'=>'(ģ˜¤ķ›„)','戈'=>'(į„Œ)','或'=>'(ģž)','㈜'=>'(주)','戉'=>'(į„Ž)','戗'=>'(ģ°Ø)','㈊'=>'(į„)','战'=>'(칓)','戋'=>'(ᄐ)','戙'=>'(ķƒ€)','㈌'=>'(į„‘)','㈚'=>'(파)','戍'=>'(į„’)','戛'=>'(ķ•˜)','戠'=>'(äø€)','戦'=>'(七)','㈢'=>'(äø‰)','㈨'=>'(九)','戔'=>'(二)','戤'=>'(äŗ”)','㈹'=>'(代)','㈽'=>'(企)','扁'=>'(休)','戧'=>'(八)','戄'=>'(六)','㈸'=>'(劓)','戩'=>'(十)','㈿'=>'(協)','戓'=>'(名)','㈺'=>'(呼)','㈣'=>'(四)','㈯'=>'(土)','戻'=>'(å­¦)','戰'=>'(ę—„)','㈪'=>'(月)','㈲'=>'(꜉)','戭'=>'(木)','戱'=>'(ę Ŗ)','戬'=>'(ę°“)','戫'=>'(火)','戵'=>'(特)','㈼'=>'(監)','㈳'=>'(社)','户'=>'(ē„)','所'=>'(ē„­)','扂'=>'(自)','扃'=>'(至)','戶'=>'(č²”)','㈾'=>'(資)','戮'=>'(金)',')'=>')','ļ¼»'=>'[','怔'=>'[','ļ¼½'=>']','怕'=>']','ļ½›'=>'{','ļ½'=>'}','⦅'=>'⦅','ļ½ '=>'⦆','ļ½¢'=>'怌','ļ½£'=>'怍','ļ¼ '=>'@','*'=>'*','ļ¼'=>'/','⁄'=>'/','āˆ•'=>'/','ļ¼¼'=>'\\','&'=>'&','#'=>'#','ļ¼…'=>'%','‶'=>'‵‵','‷'=>'‵‵‵','༌'=>'་','Ā“'=>'ʹ','Ī„'=>'ʹ','įæ½'=>'ʹ','\''=>'ʹ','''=>'ʹ','′'=>'ʹ','׳'=>'ʹ','Ķ“'=>'ʹ','ˊ'=>'ʹ','"'=>'ʹʹ','"'=>'ʹʹ','″'=>'ʹʹ','怃'=>'ʹʹ','ד'=>'ʹʹ','Źŗ'=>'ʹʹ','–'=>'ʹʹʹ','⁗'=>'ʹʹʹʹ','ĀÆ'=>'ˉ',' ̄'=>'ˉ','‾'=>'ˉ','﹉'=>'ˉ','﹊'=>'ˉ','﹋'=>'ˉ','﹌'=>'ˉ','˚'=>'°','௵'=>'௳','ļæ©'=>'←','ļæ«'=>'→','ļæŖ'=>'↑','↓'=>'↓','↵'=>'↲','⨔'=>'↾','š››'=>'āˆ‚','šœ•'=>'āˆ‚','š'=>'āˆ‚','šž‰'=>'āˆ‚','šŸƒ'=>'āˆ‚','š›'=>'āˆ‡','š›»'=>'āˆ‡','šœµ'=>'āˆ‡','šÆ'=>'āˆ‡','šž©'=>'āˆ‡','+'=>'+','﬩'=>'+','‹'=>'<','<'=>'<','ļ¼'=>'=','⩵'=>'==','ā©¶'=>'===','›'=>'>','ļ¼ž'=>'>','¬'=>'¬','¦'=>'¦','怜'=>'~','ļ½ž'=>'~','﹨'=>'āˆ–','ā‹€'=>'∧','⋁'=>'∨','ā‹‚'=>'∩','ā‹ƒ'=>'∪','∯'=>'∮∮','∰'=>'∮∮∮','≣'=>'≔','♁'=>'āŠ•','ā˜‰'=>'āŠ™','āŸ‚'=>'⊄','ā–·'=>'⊲','āØ'=>'ā‹ˆ','⨽'=>'āŒ™','☸'=>'āŽˆ','āŽ®'=>'āŽ„','│'=>'│','▐'=>'ā–Œ','ļæ­'=>'ā– ','☐'=>'ā–”','ļæ®'=>'ā—‹','⦾'=>'ā—Ž','怛'=>'⟧','〈'=>'⟨','怈'=>'⟨','〉'=>'⟩','怉'=>'⟩','ā§™'=>'⦚','怶'=>'怒','ļ½°'=>'ー','ļæ '=>'Ā¢','$'=>'$','ļæ”'=>'Ā£','ļæ„'=>'Y̵','₩'=>'W̵','0'=>'0','šŸŽ'=>'0','šŸ˜'=>'0','šŸ¢'=>'0','šŸ¬'=>'0','šŸ¶'=>'0','০'=>'0','ą­¦'=>'0','௦'=>'0','᠐'=>'0','怇'=>'0','šŽ'=>'0','š‘‚'=>'0','š‘¶'=>'0','š’Ŗ'=>'0','š“ž'=>'0','š”’'=>'0','š•†'=>'0','š•ŗ'=>'0','š–®'=>'0','š—¢'=>'0','š˜–'=>'0','š™Š'=>'0','š™¾'=>'0','šš¶'=>'0','š›°'=>'0','šœŖ'=>'0','š¤'=>'0','šžž'=>'0','āµ”'=>'0','ą“ '=>'0','āŠ–'=>'0̵','ššÆ'=>'0̵','šš¹'=>'0̵','š›©'=>'0̵','š›³'=>'0̵','šœ£'=>'0̵','šœ­'=>'0̵','š'=>'0̵','š§'=>'0̵','šž—'=>'0̵','šž”'=>'0̵','⓱'=>'0̵','įŽ¾'=>'0̵','Ū°'=>'Ł ','᭜'=>'᭐','捘'=>'0点','1'=>'1','šŸ'=>'1','šŸ™'=>'1','šŸ£'=>'1','šŸ­'=>'1','šŸ·'=>'1','ℐ'=>'1','ā„‘'=>'1','šˆ'=>'1','š¼'=>'1','š‘°'=>'1','š“˜'=>'1','š•€'=>'1','š•“'=>'1','š–Ø'=>'1','š—œ'=>'1','š˜'=>'1','š™„'=>'1','š™ø'=>'1','l'=>'l','l'=>'l','ā…¼'=>'1','ā„“'=>'l','š„'=>'l','š‘™'=>'l','š’'=>'l','š“'=>'l','š“µ'=>'l','š”©'=>'l','š•'=>'l','š–‘'=>'l','š—…'=>'l','š—¹'=>'l','š˜­'=>'l','š™”'=>'l','šš•'=>'l','šš°'=>'l','š›Ŗ'=>'l','šœ¤'=>'l','šž'=>'l','šž˜'=>'l','ā‘ '=>'āž€','É­'=>'lĢ¢','É«'=>'lĢ“','ƚ'=>'l̵','ł'=>'lĢ·','Ū±'=>'Ł”','ā’ˆ'=>'1.','ŀ'=>'lĀ·','į’·'=>'1Ā·','ā‘©'=>'āž‰','ā’‘'=>'10.','ć©'=>'10ę—„','拉'=>'10月','ć¢'=>'10点','ā’’'=>'11.','ćŖ'=>'11ę—„','拊'=>'11月','ć£'=>'11点','ā’“'=>'12.','ć«'=>'12ę—„','拋'=>'12月','捤'=>'12点','ā’”'=>'13.','ć¬'=>'13ę—„','ć„'=>'13点','ā’•'=>'14.','揭'=>'14ę—„','ć¦'=>'14点','ā’–'=>'15.','ć®'=>'15ę—„','捧'=>'15点','ā’—'=>'16.','ćÆ'=>'16ę—„','ćØ'=>'16点','ā’˜'=>'17.','揰'=>'17ę—„','ć©'=>'17点','ā’™'=>'18.','ć±'=>'18ę—„','ćŖ'=>'18点','ā’š'=>'19.','ć²'=>'19ę—„','ć«'=>'19点','lj'=>'lj','揠'=>'1ę—„','拀'=>'1月','捙'=>'1点','ļ¼’'=>'2','šŸ'=>'2','šŸš'=>'2','šŸ¤'=>'2','šŸ®'=>'2','šŸø'=>'2','į’æ'=>'2','ā‘”'=>'āž','Ū²'=>'Ł¢','ā’‰'=>'2.','ā’›'=>'20.','ć³'=>'20ę—„','ć¬'=>'20点','ć“'=>'21ę—„','捭'=>'21点','ćµ'=>'22ę—„','ć®'=>'22点','ć¶'=>'23ę—„','ćÆ'=>'23点','ć·'=>'24ę—„','捰'=>'24点','ćø'=>'25ę—„','ć¹'=>'26ę—„','ćŗ'=>'27ę—„','ć»'=>'28ę—„','ć¼'=>'29ę—„','ć”'=>'2ę—„','拁'=>'2月','捚'=>'2点','3'=>'3','šŸ‘'=>'3','šŸ›'=>'3','šŸ„'=>'3','šŸÆ'=>'3','šŸ¹'=>'3','ā‘¢'=>'āž‚','Ū³'=>'Ł£','ā’Š'=>'3.','ć½'=>'30ę—„','ć¾'=>'31ę—„','ć¢'=>'3ę—„','拂'=>'3月','捛'=>'3点','ļ¼”'=>'4','šŸ’'=>'4','šŸœ'=>'4','šŸ¦'=>'4','šŸ°'=>'4','šŸŗ'=>'4','įŽ'=>'4','ā‘£'=>'āžƒ','ā’‹'=>'4.','į”°'=>'4Ā·','ć£'=>'4ę—„','拃'=>'4月','捜'=>'4点','5'=>'5','šŸ“'=>'5','šŸ'=>'5','šŸ§'=>'5','šŸ±'=>'5','šŸ»'=>'5','⑤'=>'āž„','ā’Œ'=>'5.','揤'=>'5ę—„','拄'=>'5月','捝'=>'5点','ļ¼–'=>'6','šŸ”'=>'6','šŸž'=>'6','šŸØ'=>'6','šŸ²'=>'6','šŸ¼'=>'6','б'=>'6','ā‘„'=>'āž…','ā’'=>'6.','ć„'=>'6ę—„','担'=>'6月','捞'=>'6点','ļ¼—'=>'7','šŸ•'=>'7','šŸŸ'=>'7','šŸ©'=>'7','šŸ³'=>'7','šŸ½'=>'7','⑦'=>'āž†','Ū·'=>'٧','ā’Ž'=>'7.','ć¦'=>'7ę—„','拆'=>'7月','损'=>'7点','ଃ'=>'8','ą§Ŗ'=>'8','੪'=>'8','8'=>'8','šŸ–'=>'8','šŸ '=>'8','šŸŖ'=>'8','šŸ“'=>'8','šŸ¾'=>'8','Č£'=>'8','ā‘§'=>'āž‡','Ūø'=>'ŁØ','ā’'=>'8.','揧'=>'8ę—„','拇'=>'8月','捠'=>'8点','ą©§'=>'9','ą­Ø'=>'9','ą§­'=>'9','ļ¼™'=>'9','šŸ—'=>'9','šŸ”'=>'9','šŸ«'=>'9','šŸµ'=>'9','šŸæ'=>'9','⑨'=>'āžˆ','Ū¹'=>'Ł©','⒐'=>'9.','ćØ'=>'9ę—„','拈'=>'9月','ć”'=>'9点','a'=>'a','šš'=>'a','š‘Ž'=>'a','š’‚'=>'a','š’¶'=>'a','š“Ŗ'=>'a','š”ž'=>'a','š•’'=>'a','š–†'=>'a','š–ŗ'=>'a','š—®'=>'a','š˜¢'=>'a','š™–'=>'a','ššŠ'=>'a','ā„€'=>'a/c','℁'=>'a/s','Ʀ'=>'ae','b'=>'b','š›'=>'b','š‘'=>'b','š’ƒ'=>'b','š’·'=>'b','š“«'=>'b','š”Ÿ'=>'b','š•“'=>'b','š–‡'=>'b','š–»'=>'b','š—Æ'=>'b','š˜£'=>'b','š™—'=>'b','šš‹'=>'b','ɓ'=>'bĢ”','ʃ'=>'bĢ„','ʀ'=>'b̵','c'=>'c','ā…½'=>'c','šœ'=>'c','š‘'=>'c','š’„'=>'c','š’ø'=>'c','š“¬'=>'c','š” '=>'c','š•”'=>'c','š–ˆ'=>'c','š–¼'=>'c','š—°'=>'c','š˜¤'=>'c','š™˜'=>'c','ššŒ'=>'c','š›“'=>'c','šœ'=>'c','š‡'=>'c','šž'=>'c','šž»'=>'c','ā„…'=>'c/o','℆'=>'c/u','d'=>'d','ā…¾'=>'d','ā…†'=>'d','š'=>'d','š‘‘'=>'d','š’…'=>'d','š’¹'=>'d','š“­'=>'d','š””'=>'d','š••'=>'d','š–‰'=>'d','š–½'=>'d','š—±'=>'d','š˜„'=>'d','š™™'=>'d','šš'=>'d','ɗ'=>'dĢ”','ƌ'=>'dĢ„','ɖ'=>'dĢ¢','đ'=>'d̵','dz'=>'dz','dž'=>'dž','ļ½…'=>'e','ℯ'=>'e','ā…‡'=>'e','šž'=>'e','š‘’'=>'e','š’†'=>'e','š“®'=>'e','š”¢'=>'e','š•–'=>'e','š–Š'=>'e','š–¾'=>'e','š—²'=>'e','š˜¦'=>'e','š™š'=>'e','ššŽ'=>'e','⓹'=>'E','ə'=>'Ē','ɚ'=>'ĒĖž','ā‹“'=>'ɛ','š›†'=>'ɛ','š›œ'=>'ɛ','šœ€'=>'ɛ','šœ–'=>'ɛ','šœŗ'=>'ɛ','š'=>'ɛ','š“'=>'ɛ','šžŠ'=>'ɛ','šž®'=>'ɛ','šŸ„'=>'ɛ','f'=>'f','šŸ'=>'f','š‘“'=>'f','š’‡'=>'f','š’»'=>'f','š“Æ'=>'f','š”£'=>'f','š•—'=>'f','š–‹'=>'f','š–æ'=>'f','š—³'=>'f','š˜§'=>'f','š™›'=>'f','šš'=>'f','ʒ'=>'fĢ”','g'=>'g','ā„Š'=>'g','š '=>'g','š‘”'=>'g','š’ˆ'=>'g','š“°'=>'g','š”¤'=>'g','š•˜'=>'g','š–Œ'=>'g','š—€'=>'g','š—“'=>'g','š˜Ø'=>'g','š™œ'=>'g','šš'=>'g','É”'=>'g','É '=>'gĢ”','Ē„'=>'g̵','h'=>'h','ā„Ž'=>'h','š”'=>'h','š’‰'=>'h','š’½'=>'h','š“±'=>'h','š”„'=>'h','š•™'=>'h','š–'=>'h','š—'=>'h','š—µ'=>'h','š˜©'=>'h','š™'=>'h','šš‘'=>'h','ɦ'=>'hĢ”','ħ'=>'h̵','ā„'=>'h̵','įæ¾'=>'Ź»','ā€˜'=>'Ź»','‛'=>'Ź»','ʽ'=>'Ź»','ā³'=>'i','i'=>'i','ā…°'=>'i','ℹ'=>'i','ā…ˆ'=>'i','š¢'=>'i','š‘–'=>'i','š’Š'=>'i','š’¾'=>'i','š“²'=>'i','š”¦'=>'i','š•š'=>'i','š–Ž'=>'i','š—‚'=>'i','š—¶'=>'i','š˜Ŗ'=>'i','š™ž'=>'i','šš’'=>'i','ı'=>'i','šš¤'=>'i','ÉŖ'=>'i','É©'=>'i','š›Š'=>'i','šœ„'=>'i','šœ¾'=>'i','šø'=>'i','šž²'=>'i','ÉØ'=>'i̵','ā…±'=>'ii','ā…²'=>'iii','ij'=>'ij','ā…³'=>'iv','ā…ø'=>'ix','j'=>'j','ā…‰'=>'j','š£'=>'j','š‘—'=>'j','š’‹'=>'j','š’æ'=>'j','š“³'=>'j','š”§'=>'j','š•›'=>'j','š–'=>'j','š—ƒ'=>'j','š—·'=>'j','š˜«'=>'j','š™Ÿ'=>'j','šš“'=>'j','ϳ'=>'j','šš„'=>'Č·','k'=>'k','š¤'=>'k','š‘˜'=>'k','š’Œ'=>'k','š“€'=>'k','š““'=>'k','š”Ø'=>'k','š•œ'=>'k','š–'=>'k','š—„'=>'k','š—ø'=>'k','š˜¬'=>'k','š™ '=>'k','šš”'=>'k','ʙ'=>'kĢ”','ļ½'=>'m','ā…æ'=>'m','š¦'=>'m','š‘š'=>'m','š’Ž'=>'m','š“‚'=>'m','š“¶'=>'m','š”Ŗ'=>'m','š•ž'=>'m','š–’'=>'m','š—†'=>'m','š—ŗ'=>'m','š˜®'=>'m','š™¢'=>'m','šš–'=>'m','ɱ'=>'mĢ”','ļ½Ž'=>'n','š§'=>'n','š‘›'=>'n','š’'=>'n','š“ƒ'=>'n','š“·'=>'n','š”«'=>'n','š•Ÿ'=>'n','š–“'=>'n','š—‡'=>'n','š—»'=>'n','š˜Æ'=>'n','š™£'=>'n','šš—'=>'n','š'=>'N','š‘'=>'N','š‘µ'=>'N','š’©'=>'N','š“'=>'N','š”‘'=>'N','š•¹'=>'N','š–­'=>'N','š—”'=>'N','š˜•'=>'N','š™‰'=>'N','š™½'=>'N','šš“'=>'N','š›®'=>'N','šœØ'=>'N','š¢'=>'N','šžœ'=>'N','ɲ'=>'ņ','ɳ'=>'nĢ¢','ʞ'=>'nĢ©','š›ˆ'=>'nĢ©','šœ‚'=>'nĢ©','šœ¼'=>'nĢ©','š¶'=>'nĢ©','šž°'=>'nĢ©','nj'=>'nj','ļ½'=>'o','ā„“'=>'o','šØ'=>'o','š‘œ'=>'o','š’'=>'o','š“ø'=>'o','š”¬'=>'o','š• '=>'o','š–”'=>'o','š—ˆ'=>'o','š—¼'=>'o','š˜°'=>'o','š™¤'=>'o','šš˜'=>'o','į“'=>'o','š›'=>'o','šœŠ'=>'o','š„'=>'o','š¾'=>'o','šžø'=>'o','ɵ'=>'o̵','Ēæ'=>'ó̵','Ćø'=>'oĢ·','œ'=>'oe','Ę”'=>'oʼ','ā“'=>'p','p'=>'p','š©'=>'p','š‘'=>'p','š’‘'=>'p','š“…'=>'p','š“¹'=>'p','š”­'=>'p','š•”'=>'p','š–•'=>'p','š—‰'=>'p','š—½'=>'p','š˜±'=>'p','š™„'=>'p','šš™'=>'p','š›’'=>'p','š› '=>'p','šœŒ'=>'p','šœš'=>'p','š†'=>'p','š”'=>'p','šž€'=>'p','šžŽ'=>'p','šžŗ'=>'p','šŸˆ'=>'p','Ę„'=>'pĢ”','q'=>'q','šŖ'=>'q','š‘ž'=>'q','š’’'=>'q','š“†'=>'q','š“ŗ'=>'q','š”®'=>'q','š•¢'=>'q','š––'=>'q','š—Š'=>'q','š—¾'=>'q','š˜²'=>'q','š™¦'=>'q','ššš'=>'q','š'=>'Q','š‘„'=>'Q','š‘ø'=>'Q','š’¬'=>'Q','š“ '=>'Q','š””'=>'Q','š•¼'=>'Q','š–°'=>'Q','š—¤'=>'Q','š˜˜'=>'Q','š™Œ'=>'Q','šš€'=>'Q','Ź '=>'qĢ”','š›‹'=>'Äø','š›ž'=>'Äø','šœ…'=>'Äø','šœ˜'=>'Äø','šœæ'=>'Äø','š’'=>'Äø','š¹'=>'Äø','šžŒ'=>'Äø','šž³'=>'Äø','šŸ†'=>'Äø','ļ½’'=>'r','š«'=>'r','š‘Ÿ'=>'r','š’“'=>'r','š“‡'=>'r','š“»'=>'r','š”Æ'=>'r','š•£'=>'r','š–—'=>'r','š—‹'=>'r','š—æ'=>'r','š˜³'=>'r','š™§'=>'r','šš›'=>'r','ɽ'=>'rĢ¢','ɼ'=>'rĢ©','s'=>'s','š¬'=>'s','š‘ '=>'s','š’”'=>'s','š“ˆ'=>'s','š“¼'=>'s','š”°'=>'s','š•¤'=>'s','š–˜'=>'s','š—Œ'=>'s','š˜€'=>'s','š˜“'=>'s','š™Ø'=>'s','ššœ'=>'s','ƽ'=>'s','Ź‚'=>'sĢ¢','∫'=>'ʃ','∬'=>'ʃʃ','∭'=>'ʃʃʃ','⨌'=>'ʃʃʃʃ','ļ½”'=>'t','š­'=>'t','š‘”'=>'t','š’•'=>'t','š“‰'=>'t','š“½'=>'t','š”±'=>'t','š•„'=>'t','š–™'=>'t','š—'=>'t','š˜'=>'t','š˜µ'=>'t','š™©'=>'t','šš'=>'t','š‘‡'=>'T','š‘»'=>'T','š’Æ'=>'T','š“£'=>'T','š”—'=>'T','š•‹'=>'T','š•æ'=>'T','š–³'=>'T','š—§'=>'T','š˜›'=>'T','š™'=>'T','ššƒ'=>'T','šš»'=>'T','š›µ'=>'T','šœÆ'=>'T','š©'=>'T','šž£'=>'T','Ę­'=>'tĢ”','ț'=>'Å£','Ę«'=>'Å£','ŧ'=>'t̵','u'=>'u','š®'=>'u','š‘¢'=>'u','š’–'=>'u','š“Š'=>'u','š“¾'=>'u','š”²'=>'u','š•¦'=>'u','š–š'=>'u','š—Ž'=>'u','š˜‚'=>'u','š˜¶'=>'u','š™Ŗ'=>'u','ššž'=>'u','ʊ'=>'u','Ź‹'=>'u','š›–'=>'u','šœ'=>'u','šŠ'=>'u','šž„'=>'u','šž¾'=>'u','š‘ˆ'=>'U','š‘¼'=>'U','š’°'=>'U','š“¤'=>'U','š”˜'=>'U','š•Œ'=>'U','š–€'=>'U','š–“'=>'U','š—Ø'=>'U','š˜œ'=>'U','š™'=>'U','šš„'=>'U','ļ½–'=>'v','ā…“'=>'v','šÆ'=>'v','š‘£'=>'v','š’—'=>'v','š“‹'=>'v','š“æ'=>'v','š”³'=>'v','š•§'=>'v','š–›'=>'v','š—'=>'v','š˜ƒ'=>'v','š˜·'=>'v','š™«'=>'v','ššŸ'=>'v','š›Ž'=>'v','šœˆ'=>'v','š‚'=>'v','š¼'=>'v','šž¶'=>'v','ā…µ'=>'vi','ā…¶'=>'vii','ā…·'=>'viii','ÉÆ'=>'w','ļ½—'=>'w','š°'=>'w','š‘¤'=>'w','š’˜'=>'w','š“Œ'=>'w','š”€'=>'w','š”“'=>'w','š•Ø'=>'w','š–œ'=>'w','š—'=>'w','š˜„'=>'w','š˜ø'=>'w','š™¬'=>'w','šš '=>'w','š‘Š'=>'W','š‘¾'=>'W','š’²'=>'W','š“¦'=>'W','š”š'=>'W','š•Ž'=>'W','š–‚'=>'W','š–¶'=>'W','š—Ŗ'=>'W','š˜ž'=>'W','š™’'=>'W','šš†'=>'W','Ɨ'=>'x','x'=>'x','ā…¹'=>'x','š±'=>'x','š‘„'=>'x','š’™'=>'x','š“'=>'x','š”'=>'x','š”µ'=>'x','š•©'=>'x','š–'=>'x','š—‘'=>'x','š˜…'=>'x','š˜¹'=>'x','š™­'=>'x','šš”'=>'x','į™­'=>'X','š‘‹'=>'X','š‘æ'=>'X','š’³'=>'X','š“§'=>'X','š”›'=>'X','š•'=>'X','š–ƒ'=>'X','š–·'=>'X','š—«'=>'X','š˜Ÿ'=>'X','š™“'=>'X','šš‡'=>'X','šš¾'=>'X','š›ø'=>'X','šœ²'=>'X','š¬'=>'X','šž¦'=>'X','ā…ŗ'=>'xi','ā…»'=>'xii','ļ½™'=>'y','š²'=>'y','š‘¦'=>'y','š’š'=>'y','š“Ž'=>'y','š”‚'=>'y','š”¶'=>'y','š•Ŗ'=>'y','š–ž'=>'y','š—’'=>'y','š˜†'=>'y','š˜ŗ'=>'y','š™®'=>'y','šš¢'=>'y','Ę“'=>'yĢ”','z'=>'z','š³'=>'z','š‘§'=>'z','š’›'=>'z','š“'=>'z','š”ƒ'=>'z','š”·'=>'z','š•«'=>'z','š–Ÿ'=>'z','š—“'=>'z','š˜‡'=>'z','š˜»'=>'z','š™Æ'=>'z','šš£'=>'z','Č„'=>'zĢ”','ʐ'=>'zĢ¢','ʶ'=>'z̵','ȝ'=>'Ź’','?'=>'Ź”','?'=>'Ź”','⁇'=>'ʔʔ','⁈'=>'Ź”Ēƒ','į¾½'=>'ʼ','᾿'=>'ʼ','’'=>'ʼ','ʾ'=>'ʼ','!'=>'ǃ','!'=>'ǃ','⁉'=>'ĒƒŹ”','‼'=>'ǃǃ','āŗ'=>'α','š›‚'=>'α','š›¼'=>'α','šœ¶'=>'α','š°'=>'α','šžŖ'=>'α','š›ƒ'=>'β','š›½'=>'β','šœ·'=>'β','š±'=>'β','šž«'=>'β','ℽ'=>'γ','š›„'=>'γ','š›¾'=>'γ','šœø'=>'γ','š²'=>'γ','šž¬'=>'γ','š›…'=>'Ī“','š›æ'=>'Ī“','šœ¹'=>'Ī“','š³'=>'Ī“','šž­'=>'Ī“','šŸ‹'=>'Ļ','š›‡'=>'ζ','šœ'=>'ζ','šœ»'=>'ζ','šµ'=>'ζ','šžÆ'=>'ζ','ā¬'=>'Īø','š›‰'=>'Īø','š›'=>'Īø','šœƒ'=>'Īø','šœ—'=>'Īø','šœ½'=>'Īø','š‘'=>'Īø','š·'=>'Īø','šž‹'=>'Īø','šž±'=>'Īø','šŸ…'=>'Īø','š›Œ'=>'Ī»','šœ†'=>'Ī»','š€'=>'Ī»','šŗ'=>'Ī»','šž“'=>'Ī»','š›¬'=>'Ī›','šœ¦'=>'Ī›','š '=>'Ī›','šžš'=>'Ī›','š›'=>'μ','šœ‡'=>'μ','š'=>'μ','š»'=>'μ','šžµ'=>'μ','š›'=>'ξ','šœ‰'=>'ξ','šƒ'=>'ξ','š½'=>'ξ','šž·'=>'ξ','š›Æ'=>'Īž','šœ©'=>'Īž','š£'=>'Īž','šž'=>'Īž','ℼ'=>'Ļ€','š›‘'=>'Ļ€','š›”'=>'Ļ€','šœ‹'=>'Ļ€','šœ›'=>'Ļ€','š…'=>'Ļ€','š•'=>'Ļ€','šæ'=>'Ļ€','šž'=>'Ļ€','šž¹'=>'Ļ€','šŸ‰'=>'Ļ€','ᓨ'=>'Ļ€','āˆ'=>'Ī ','šš·'=>'Ī ','š›±'=>'Ī ','šœ«'=>'Ī ','š„'=>'Ī ','šžŸ'=>'Ī ','š›”'=>'σ','šœŽ'=>'σ','šˆ'=>'σ','šž‚'=>'σ','šž¼'=>'σ','š›•'=>'Ļ„','šœ'=>'Ļ„','š‰'=>'Ļ„','šžƒ'=>'Ļ„','šž½'=>'Ļ„','š˜'=>'Y','š‘Œ'=>'Y','š’€'=>'Y','š’“'=>'Y','š“Ø'=>'Y','š”œ'=>'Y','š•'=>'Y','š–„'=>'Y','š–ø'=>'Y','š—¬'=>'Y','š˜ '=>'Y','š™”'=>'Y','ššˆ'=>'Y','šš¼'=>'Y','š›¶'=>'Y','šœ°'=>'Y','šŖ'=>'Y','šž¤'=>'Y','š›—'=>'φ','š›Ÿ'=>'φ','šœ‘'=>'φ','šœ™'=>'φ','š‹'=>'φ','š“'=>'φ','šž…'=>'φ','šž'=>'φ','šžæ'=>'φ','šŸ‡'=>'φ','š›·'=>'Φ','šœ±'=>'Φ','š«'=>'Φ','šž„'=>'Φ','š›˜'=>'χ','šœ’'=>'χ','šŒ'=>'χ','šž†'=>'χ','šŸ€'=>'χ','š›™'=>'ψ','šœ“'=>'ψ','š'=>'ψ','šž‡'=>'ψ','šŸ'=>'ψ','š›¹'=>'ĪØ','šœ³'=>'ĪØ','š­'=>'ĪØ','šž§'=>'ĪØ','āµ'=>'ω','š›š'=>'ω','šœ”'=>'ω','šŽ'=>'ω','šžˆ'=>'ω','šŸ‚'=>'ω','ӕ'=>'ae','Ņ“'=>'r̵','Ņ‘'=>'rį‘Š','Ņ—'=>'ж̩','Ņ™'=>'Š·Ģ”','ӏ'=>'i','Ņ‹'=>'й̔','Ņ›'=>'ÄøĢ©','ҟ'=>'ĸ̵','į“«'=>'Š»','ӆ'=>'л̔','ӎ'=>'м̔','ӊ'=>'н̔','ӈ'=>'н̔','Ņ£'=>'н̩','Ó©'=>'o̵','ѳ'=>'o̵','Ņ«'=>'cĢ”','Ņ­'=>'т̩','ŅÆ'=>'y','ұ'=>'y̵','ћ'=>'h̵','ѽ'=>'є҃','ӌ'=>'Ņ·','Ņæ'=>'ҽ̢','Ņ'=>'Ь̵','Õ¦'=>'q','Õ¼'=>'n','ℵ'=>'א','ﬔ'=>'א','אָ'=>'אַ','אּ'=>'אַ','ļ­'=>'אל','ā„¶'=>'ב','ā„·'=>'ג','ℸ'=>'ד','ﬢ'=>'ד','ﬣ'=>'ה','ﬤ'=>'כ','ffl'=>'ל','ﬦ'=>'ם','ﬠ'=>'×¢','ﬧ'=>'ר','ﬨ'=>'×Ŗ','ļŗ€'=>'Ų”','ļŗ‚'=>'Ų¢','ﺁ'=>'Ų¢','ļŗ„'=>'Ų£','ﺃ'=>'Ų£','ٵ'=>'Ų§Ł”','ļ­‘'=>'ٱ','ﭐ'=>'ٱ','ļŗ†'=>'Ų¤','ļŗ…'=>'Ų¤','ٶ'=>'ŁˆŁ”','ﺈ'=>'Ų„','ļŗ‡'=>'Ų„','ļŗ‹'=>'Ų¦','ﺌ'=>'Ų¦','ﺊ'=>'Ų¦','ļŗ‰'=>'Ų¦','ﯫ'=>'Ų¦Ų§','ﯪ'=>'Ų¦Ų§','ﯸ'=>'ئٻ','ﯷ'=>'ئٻ','ﯶ'=>'ئٻ','ļ²—'=>'Ų¦Ų¬','ļ°€'=>'Ų¦Ų¬','ﲘ'=>'Ų¦Ų­','ﰁ'=>'Ų¦Ų­','ļ²™'=>'Ų¦Ų®','ﱤ'=>'Ų¦Ų±','ﱄ'=>'Ų¦Ų²','ﲚ'=>'ئم','ﳟ'=>'ئم','ﱦ'=>'ئم','ļ°‚'=>'ئم','ļ±§'=>'ئن','ļ²›'=>'ئه','ļ³ '=>'ئه','ﯭ'=>'ئه','ﯬ'=>'ئه','ﯯ'=>'ئو','ﯮ'=>'ئو','ﯳ'=>'Ų¦Ū†','ﯲ'=>'Ų¦Ū†','ﯱ'=>'Ų¦Ū‡','ﯰ'=>'Ų¦Ū‡','ﯵ'=>'ئۈ','ﯓ'=>'ئۈ','ﯻ'=>'ئى','ﯺ'=>'ئى','ﱨ'=>'ئى','ﯹ'=>'ئى','ﰃ'=>'ئى','ﱩ'=>'ئى','ļ°„'=>'ئى','ļŗŽ'=>'Ų§','ļŗ'=>'Ų§',''=>'Ų§Ł‹',''=>'Ų§Ł‹','ļ·³'=>'اكبر','ļ·²'=>'الله','ļŗ‘'=>'ŲØ','ļŗ’'=>'ŲØ','ﺐ'=>'ŲØ','ļŗ'=>'ŲØ','ﲜ'=>'ŲØŲ¬','ļ°…'=>'ŲØŲ¬','ļ²'=>'ŲØŲ­','ļ°†'=>'ŲØŲ­','ļ·‚'=>'بحى','ļ²ž'=>'ŲØŲ®','ļ°‡'=>'ŲØŲ®','ļ¶ž'=>'بخى','ļ±Ŗ'=>'ŲØŲ±','ﱫ'=>'ŲØŲ²','ﲟ'=>'ŲØŁ…','ļ³”'=>'ŲØŁ…','ﱬ'=>'ŲØŁ…','ﰈ'=>'ŲØŁ…','ļ±­'=>'بن','ļ² '=>'به','ļ³¢'=>'به','ļ±®'=>'بى','ļ°‰'=>'بى','ﱯ'=>'بى','ﰊ'=>'بى','ļ­”'=>'Ł»','ļ­•'=>'Ł»','ļ­“'=>'Ł»','ļ­’'=>'Ł»','ې'=>'Ł»','ﯦ'=>'Ł»','ﯧ'=>'Ł»','﯄'=>'Ł»','ﯤ'=>'Ł»','ﭘ'=>'پ','ļ­™'=>'پ','ļ­—'=>'پ','ļ­–'=>'پ','ﭜ'=>'Ś€','ļ­'=>'Ś€','ļ­›'=>'Ś€','ﭚ'=>'Ś€','ļŗ”'=>'Ų©','ļŗ“'=>'Ų©','ļŗ—'=>'ŲŖ','ﺘ'=>'ŲŖ','ļŗ–'=>'ŲŖ','ļŗ•'=>'ŲŖ','ļ²”'=>'ŲŖŲ¬','ļ°‹'=>'ŲŖŲ¬','ﵐ'=>'تجم','ļ¶ '=>'تجى','ﶟ'=>'تجى','ļ²¢'=>'ŲŖŲ­','ﰌ'=>'ŲŖŲ­','ļµ’'=>'ŲŖŲ­Ų¬','ﵑ'=>'ŲŖŲ­Ų¬','ﵓ'=>'ŲŖŲ­Ł…','ļ²£'=>'ŲŖŲ®','ļ°'=>'ŲŖŲ®','ļµ”'=>'تخم','ļ¶¢'=>'تخى','ļ¶”'=>'تخى','ļ±°'=>'ŲŖŲ±','ļ±±'=>'ŲŖŲ²','ﲤ'=>'ŲŖŁ…','ļ³£'=>'ŲŖŁ…','ļ±²'=>'ŲŖŁ…','ļ°Ž'=>'ŲŖŁ…','ﵕ'=>'ŲŖŁ…Ų¬','ļµ–'=>'ŲŖŁ…Ų­','ļµ—'=>'ŲŖŁ…Ų®','ﶤ'=>'تمى','ļ¶£'=>'تمى','ļ±³'=>'تن','ﲄ'=>'ته','ﳤ'=>'ته','ﱓ'=>'تى','ļ°'=>'تى','ļ±µ'=>'تى','ﰐ'=>'تى','ļŗ›'=>'Ų«','ﺜ'=>'Ų«','ﺚ'=>'Ų«','ļŗ™'=>'Ų«','ļ°‘'=>'Ų«Ų¬','ļ±¶'=>'Ų«Ų±','ļ±·'=>'Ų«Ų²','ﲦ'=>'Ų«Ł…','ﳄ'=>'Ų«Ł…','ļ±ø'=>'Ų«Ł…','ļ°’'=>'Ų«Ł…','ļ±¹'=>'ثن','ﳦ'=>'ثه','ļ±ŗ'=>'ثى','ļ°“'=>'ثى','ļ±»'=>'ثى','ļ°”'=>'ثى','ļ­Ø'=>'ٹ','ļ­©'=>'ٹ','ļ­§'=>'ٹ','ļ­¦'=>'ٹ','Ś»'=>'ٹ','ﮢ'=>'ٹ','ﮣ'=>'ٹ','ļ®”'=>'ٹ','ļ® '=>'ٹ','ļ­ '=>'Łŗ','ļ­”'=>'Łŗ','ﭟ'=>'Łŗ','ļ­ž'=>'Łŗ','ļ­¤'=>'Łæ','ļ­„'=>'Łæ','ļ­£'=>'Łæ','ļ­¢'=>'Łæ','ﺟ'=>'Ų¬','ļŗ '=>'Ų¬','ļŗž'=>'Ų¬','ļŗ'=>'Ų¬','ļ²§'=>'Ų¬Ų­','ļ°•'=>'Ų¬Ų­','ﶦ'=>'جحى','ļ¶¾'=>'جحى','ļ·»'=>'جل جلاله','ﲨ'=>'جم','ļ°–'=>'جم','ļµ™'=>'جمح','ﵘ'=>'جمح','ļ¶§'=>'جمى','ļ¶„'=>'جمى','ļ“'=>'جى',''=>'جى','ļ“ž'=>'جى','ļ“‚'=>'جى','ļ­ø'=>'ڃ','ļ­¹'=>'ڃ','ļ­·'=>'ڃ','ļ­¶'=>'ڃ','ļ­“'=>'Ś„','ļ­µ'=>'Ś„','ļ­³'=>'Ś„','ļ­²'=>'Ś„','ļ­¼'=>'چ','ļ­½'=>'چ','ļ­»'=>'چ','ļ­ŗ'=>'چ','ﮀ'=>'ڇ','ﮁ'=>'ڇ','ļ­æ'=>'ڇ','ļ­¾'=>'ڇ','ļŗ£'=>'Ų­','ļŗ¤'=>'Ų­','ļŗ¢'=>'Ų­','ļŗ”'=>'Ų­','ﲩ'=>'Ų­Ų¬','ļ°—'=>'Ų­Ų¬','ļ¶æ'=>'حجى','ļ²Ŗ'=>'Ų­Ł…','ﰘ'=>'Ų­Ł…','ļµ›'=>'حمى','ﵚ'=>'حمى','ļ“›'=>'حى','ﳿ'=>'حى',''=>'حى','ļ“€'=>'حى','ļŗ§'=>'Ų®','ļŗØ'=>'Ų®','ļŗ¦'=>'Ų®','ļŗ„'=>'Ų®','ﲫ'=>'Ų®Ų¬','ļ°™'=>'Ų®Ų¬','ﰚ'=>'Ų®Ų­','ﲬ'=>'خم','ļ°›'=>'خم',''=>'خى',''=>'خى','ļ“ '=>'خى','ļ“„'=>'خى','ļŗŖ'=>'ŲÆ','ļŗ©'=>'ŲÆ','ļŗ¬'=>'Ų°','ļŗ«'=>'Ų°','ļ±›'=>'ذٰ','ﮉ'=>'ڈ','ﮈ'=>'ڈ','ļ®…'=>'ڌ','ﮄ'=>'ڌ','ﮃ'=>'Ś','ﮂ'=>'Ś','ﮇ'=>'ŚŽ','ﮆ'=>'ŚŽ','ļŗ®'=>'Ų±','ļŗ­'=>'Ų±','ﱜ'=>'رٰ','ļ·¶'=>'Ų±Ų³ŁˆŁ„','ļ·¼'=>'رىال','ļŗ°'=>'Ų²','ļŗÆ'=>'Ų²','ļ®'=>'Ś‘','ﮌ'=>'Ś‘','ﮋ'=>'ژ','ﮊ'=>'ژ','ļŗ³'=>'Ų³','ļŗ“'=>'Ų³','ļŗ²'=>'Ų³','ļŗ±'=>'Ų³','ļ²­'=>'Ų³Ų¬','ļ““'=>'Ų³Ų¬','ﰜ'=>'Ų³Ų¬','ļµ'=>'Ų³Ų¬Ų­','ļµž'=>'سجى','ļ²®'=>'Ų³Ų­',''=>'Ų³Ų­','ļ°'=>'Ų³Ų­','ﵜ'=>'Ų³Ų­Ų¬','ﲯ'=>'Ų³Ų®','ļ“¶'=>'Ų³Ų®','ļ°ž'=>'Ų³Ų®','ļ¶Ø'=>'سخى','ļ·†'=>'سخى',''=>'Ų³Ų±','ļ“Ž'=>'Ų³Ų±','ļ²°'=>'سم','ļ³§'=>'سم','ﰟ'=>'سم','ļµ”'=>'سمج','ļµ '=>'سمح','ﵟ'=>'سمح','ļµ£'=>'سمم','ļµ¢'=>'سمم',''=>'سه','ﳨ'=>'سه','ļ“—'=>'سى','ļ³»'=>'سى',''=>'سى','ļ³¼'=>'سى','ļŗ·'=>'Ų“','ļŗø'=>'Ų“','ļŗ¶'=>'Ų“','ļŗµ'=>'Ų“','ļ“­'=>'Ų“Ų¬','ļ“·'=>'Ų“Ų¬','ļ“„'=>'Ų“Ų¬',''=>'Ų“Ų¬','ﵩ'=>'ؓجى','ļ“®'=>'Ų“Ų­',''=>'Ų“Ų­',''=>'Ų“Ų­',''=>'Ų“Ų­','ﵨ'=>'Ų“Ų­Ł…','ļµ§'=>'Ų“Ų­Ł…','ļ¶Ŗ'=>'ؓحى',''=>'Ų“Ų®',''=>'Ų“Ų®','ļ“§'=>'Ų“Ų®','ļ“‹'=>'Ų“Ų®','ļ“©'=>'Ų“Ų±','ļ“'=>'Ų“Ų±','ļ“°'=>'Ų“Ł…','ﳩ'=>'Ų“Ł…',''=>'Ų“Ł…',''=>'Ų“Ł…','ﵫ'=>'Ų“Ł…Ų®','ļµŖ'=>'Ų“Ł…Ų®','ļµ­'=>'Ų“Ł…Ł…','ﵬ'=>'Ų“Ł…Ł…',''=>'ؓه','ļ³Ŗ'=>'ؓه','ļ“™'=>'ؓى','ļ³½'=>'ؓى',''=>'ؓى','ļ³¾'=>'ؓى','ļŗ»'=>'Ųµ','ļŗ¼'=>'Ųµ','ļŗŗ'=>'Ųµ','ļŗ¹'=>'Ųµ','ļ²±'=>'ŲµŲ­','ļ° '=>'ŲµŲ­','﵄'=>'ŲµŲ­Ų­','ﵤ'=>'ŲµŲ­Ų­','ļ¶©'=>'صحى','ļ²²'=>'ŲµŲ®','ļ“«'=>'ŲµŲ±','ļ“'=>'ŲµŲ±','ļ·µ'=>'صلعم','ļ·¹'=>'صلى','ļ·ŗ'=>'صلى الله علىه ŁˆŲ³Ł„Ł…','ļ·°'=>'صلے','ļ²³'=>'صم','ļ°”'=>'صم','ļ·…'=>'صمم','ﵦ'=>'صمم','ļ“”'=>'صى','ļ“…'=>'صى','ļ“¢'=>'صى',''=>'صى','ļŗæ'=>'Ų¶','ﻀ'=>'Ų¶','ļŗ¾'=>'Ų¶','ļŗ½'=>'Ų¶','ﲓ'=>'Ų¶Ų¬','ļ°¢'=>'Ų¶Ų¬','ļ²µ'=>'Ų¶Ų­','ļ°£'=>'Ų¶Ų­','ļµ®'=>'ضحى','ļ¶«'=>'ضحى','ļ²¶'=>'Ų¶Ų®','ļ°¤'=>'Ų¶Ų®','ļµ°'=>'ضخم','ﵯ'=>'ضخم',''=>'Ų¶Ų±',''=>'Ų¶Ų±','ļ²·'=>'Ų¶Ł…','ļ°„'=>'Ų¶Ł…','ļ“£'=>'ضى',''=>'ضى',''=>'ضى',''=>'ضى','ﻃ'=>'Ų·','ﻄ'=>'Ų·','ﻂ'=>'Ų·','ﻁ'=>'Ų·','ļ²ø'=>'Ų·Ų­','ļ°¦'=>'Ų·Ų­',''=>'Ų·Ł…',''=>'Ų·Ł…','ļ°§'=>'Ų·Ł…','ļµ²'=>'Ų·Ł…Ų­','ļµ±'=>'Ų·Ł…Ų­','ļµ³'=>'Ų·Ł…Ł…','ﵓ'=>'طمى','ļ“‘'=>'طى','ļ³µ'=>'طى','ļ“’'=>'طى','ļ³¶'=>'طى','ﻇ'=>'Ųø','ﻈ'=>'Ųø','ﻆ'=>'Ųø','ļ»…'=>'Ųø','ļ²¹'=>'ŲøŁ…','ļ“»'=>'ŲøŁ…','ļ°Ø'=>'ŲøŁ…','ﻋ'=>'Ų¹','ﻌ'=>'Ų¹','ﻊ'=>'Ų¹','ﻉ'=>'Ų¹','ļ²ŗ'=>'Ų¹Ų¬','ļ°©'=>'Ų¹Ų¬','ļ·„'=>'عجم','ļµµ'=>'عجم','ļ··'=>'علىه','ļ²»'=>'عم','ļ°Ŗ'=>'عم','ļµ·'=>'عمم','ļµ¶'=>'عمم','ļµø'=>'عمى','ļ¶¶'=>'عمى','ļ““'=>'عى','ļ³·'=>'عى','ļ“”'=>'عى','ļ³ø'=>'عى','ļ»'=>'Ųŗ','ﻐ'=>'Ųŗ','ļ»Ž'=>'Ųŗ','ļ»'=>'Ųŗ','ļ²¼'=>'ŲŗŲ¬','ļ°«'=>'ŲŗŲ¬','ļ²½'=>'ŲŗŁ…','ļ°¬'=>'ŲŗŁ…','ļµ¹'=>'ŲŗŁ…Ł…','ļµ»'=>'غمى','ļµŗ'=>'غمى','ļ“•'=>'غى','ļ³¹'=>'غى','ļ“–'=>'غى','ļ³ŗ'=>'غى','ﻓ'=>'ف','ļ»”'=>'ف','ļ»’'=>'ف','ﻑ'=>'ف','ļ²¾'=>'فج','ļ°­'=>'فج','ﲿ'=>'فح','ļ°®'=>'فح','ļ³€'=>'فخ','ļ°Æ'=>'فخ','ļµ½'=>'فخم','ļµ¼'=>'فخم','ﳁ'=>'فم','ļ°°'=>'فم','ﷁ'=>'فمى','ļ±¼'=>'فى','ļ°±'=>'فى','ļ±½'=>'فى','ļ°²'=>'فى','ļ­¬'=>'ڤ','ļ­­'=>'ڤ','ļ­«'=>'ڤ','ļ­Ŗ'=>'ڤ','ļ­°'=>'ڦ','ļ­±'=>'ڦ','ļ­Æ'=>'ڦ','ļ­®'=>'ڦ','ļ»—'=>'Ł‚','ﻘ'=>'Ł‚','ļ»–'=>'Ł‚','ﻕ'=>'Ł‚','ﳂ'=>'قح','ļ°³'=>'قح','ļ·±'=>'قلے','ﳃ'=>'قم','ļ°“'=>'قم','ļ¶“'=>'قمح','ļµ¾'=>'قمح','ﵿ'=>'قمم','ļ¶²'=>'قمى','ļ±¾'=>'قى','ļ°µ'=>'قى','ﱿ'=>'قى','ļ°¶'=>'قى','ļ»›'=>'ك','ﻜ'=>'ك','ﻚ'=>'ك','ļ»™'=>'ك','Ś©'=>'ك','ﮐ'=>'ك','ﮑ'=>'ك','ļ®'=>'ك','ļ®Ž'=>'ك','ļ²€'=>'كا','ļ°·'=>'كا','ﳄ'=>'كج','ļ°ø'=>'كج','ļ³…'=>'كح','ļ°¹'=>'كح','ﳆ'=>'كخ','ļ°ŗ'=>'كخ','ﳇ'=>'ŁƒŁ„','ﳫ'=>'ŁƒŁ„','ﲁ'=>'ŁƒŁ„','ļ°»'=>'ŁƒŁ„','ﳈ'=>'ŁƒŁ…','ﳬ'=>'ŁƒŁ…','ﲂ'=>'ŁƒŁ…','ļ°¼'=>'ŁƒŁ…','ﷃ'=>'ŁƒŁ…Ł…','ļ¶»'=>'ŁƒŁ…Ł…','ļ¶·'=>'ŁƒŁ…Ł‰','ﲃ'=>'ŁƒŁ‰','ļ°½'=>'ŁƒŁ‰','ﲄ'=>'ŁƒŁ‰','ļ°¾'=>'ŁƒŁ‰','ﯕ'=>'Ś­','ﯖ'=>'Ś­','ﯔ'=>'Ś­','ﯓ'=>'Ś­','ļ®”'=>'ŚÆ','ﮕ'=>'ŚÆ','ﮓ'=>'ŚÆ','ļ®’'=>'ŚÆ','ﮜ'=>'ڱ','ļ®'=>'ڱ','ļ®›'=>'ڱ','ﮚ'=>'ڱ','ﮘ'=>'ڳ','ļ®™'=>'ڳ','ļ®—'=>'ڳ','ļ®–'=>'ڳ','ﻟ'=>'Ł„','ļ» '=>'Ł„','ļ»ž'=>'Ł„','ļ»'=>'Ł„','ļ»¶'=>'لآ','ﻵ'=>'لآ','ﻸ'=>'لأ','ļ»·'=>'لأ','ﻺ'=>'ل؄','ﻹ'=>'ل؄','ﻼ'=>'لا','ļ»»'=>'لا','ﳉ'=>'لج','ļ°æ'=>'لج','ﶃ'=>'لجج','ļ¶„'=>'لجج','ļ¶ŗ'=>'لجم','ļ¶¼'=>'لجم','ﶬ'=>'لجى','ﳊ'=>'لح','ļ±€'=>'لح','ļ¶µ'=>'لحم','ļ¶€'=>'لحم','ļ¶‚'=>'لحى','ﶁ'=>'لحى','ﳋ'=>'لخ','ﱁ'=>'لخ','ﶆ'=>'لخم','ļ¶…'=>'لخم','ﳌ'=>'لم','ļ³­'=>'لم','ļ²…'=>'لم','ﱂ'=>'لم','ﶈ'=>'لمح','ﶇ'=>'لمح','ļ¶­'=>'لمى','ļ³'=>'له','ﲆ'=>'لى','ﱃ'=>'لى','ﲇ'=>'لى','ﱄ'=>'لى','ﻣ'=>'Ł…','ﻤ'=>'Ł…','ﻢ'=>'Ł…','ļ»”'=>'Ł…','ﲈ'=>'Ł…Ų§','ļ³Ž'=>'Ł…Ų¬','ļ±…'=>'Ł…Ų¬','ﶌ'=>'Ł…Ų¬Ų­','ļ¶’'=>'Ł…Ų¬Ų®','ļ¶'=>'مجم','ļ·€'=>'مجى','ļ³'=>'Ł…Ų­','ﱆ'=>'Ł…Ų­','ﶉ'=>'Ł…Ų­Ų¬','ﶊ'=>'Ł…Ų­Ł…','ļ·“'=>'Ł…Ų­Ł…ŲÆ','ļ¶‹'=>'محى','ﳐ'=>'Ł…Ų®','ﱇ'=>'Ł…Ų®','ļ¶Ž'=>'Ł…Ų®Ų¬','ļ¶'=>'مخم','ļ¶¹'=>'مخى','ﳑ'=>'Ł…Ł…','ﲉ'=>'Ł…Ł…','ﱈ'=>'Ł…Ł…','ļ¶±'=>'ممى','ﱉ'=>'مى','ﱊ'=>'مى','ļ»§'=>'ن','ﻨ'=>'ن','ﻦ'=>'ن','ﻄ'=>'ن','ļ³’'=>'نج','ﱋ'=>'نج','ļ¶ø'=>'نجح','ļ¶½'=>'نجح','ﶘ'=>'نجم','ļ¶—'=>'نجم','ļ¶™'=>'نجى','ļ·‡'=>'نجى','ﳓ'=>'نح','ﱌ'=>'نح','ļ¶•'=>'نحم','ļ¶–'=>'نحى','ļ¶³'=>'نحى','ļ³”'=>'نخ','ļ±'=>'نخ','ﲊ'=>'نر','ﲋ'=>'نز','ﳕ'=>'نم','ļ³®'=>'نم','ﲌ'=>'نم','ļ±Ž'=>'نم','ļ¶›'=>'نمى','ﶚ'=>'نمى','ļ²'=>'نن','ļ³–'=>'نه','ﳯ'=>'نه','ļ²Ž'=>'نى','ļ±'=>'نى','ļ²'=>'نى','ﱐ'=>'نى','ﮟ'=>'Śŗ','ļ®ž'=>'Śŗ','ﻫ'=>'ه','ﻬ'=>'ه','ﻪ'=>'ه','ﻩ'=>'ه','ھ'=>'ه','ﮬ'=>'ه','ļ®­'=>'ه','ﮫ'=>'ه','ﮪ'=>'ه','ہ'=>'ه','ﮨ'=>'ه','ﮩ'=>'ه','ļ®§'=>'ه','ﮦ'=>'ه','Ū•'=>'ه','ļ³™'=>'هٰ','ļ³—'=>'هج','ﱑ'=>'هج','ﳘ'=>'هم','ļ±’'=>'هم','ļ¶“'=>'همج','ļ¶”'=>'همم','ﱓ'=>'هى','ļ±”'=>'هى','ﮄ'=>'Ū€','ﮤ'=>'Ū€','ļ»®'=>'و','ļ»­'=>'و','ļ·ø'=>'ŁˆŲ³Ł„Ł…','ﯔ'=>'Ū…','ﯠ'=>'Ū…','ﯚ'=>'Ū†','ﯙ'=>'Ū†','ﯘ'=>'Ū‡','ﯗ'=>'Ū‡','Ł·'=>'ۇٔ','ļÆ'=>'ۇٔ','ﯜ'=>'ۈ','ﯛ'=>'ۈ','ﯣ'=>'Ū‰','ﯢ'=>'Ū‰','ﯟ'=>'Ū‹','ļÆž'=>'Ū‹','ﯨ'=>'ى','ﯩ'=>'ى','ļ»°'=>'ى','ﻯ'=>'ى','ي'=>'ى','ﻳ'=>'ى','ﻓ'=>'ى','ﻲ'=>'ى','ļ»±'=>'ى','ی'=>'ى','ﯾ'=>'ى','ﯿ'=>'ى','ﯽ'=>'ى','ﯼ'=>'ى','Łø'=>'ىٔ','ﲐ'=>'ىٰ','ļ±'=>'ىٰ','ﳚ'=>'ىج','ﱕ'=>'ىج','ļ¶Æ'=>'ىجى','ļ³›'=>'ىح','ļ±–'=>'ىح','ļ¶®'=>'ىحى','ﳜ'=>'ىخ','ļ±—'=>'ىخ','ﲑ'=>'ىر','ļ²’'=>'ىز','ļ³'=>'ىم','ļ³°'=>'ىم','ﲓ'=>'ىم','ﱘ'=>'ىم','ļ¶'=>'ىمم','ﶜ'=>'ىمم','ļ¶°'=>'ىمى','ļ²”'=>'ىن','ļ³ž'=>'ىه','ļ³±'=>'ىه','ﲕ'=>'ىى','ļ±™'=>'ىى','ļ²–'=>'ىى','ﱚ'=>'ىى','Ū§'=>'Ū¦','ﮯ'=>'Ū’','ļ®®'=>'Ū’','ļ®±'=>'Ū“','ļ®°'=>'Ū“','∃'=>'⓺','आ'=>'अा','ऒ'=>'ą¤…ą¤¾ą„†','ओ'=>'ą¤…ą¤¾ą„‡','औ'=>'ą¤…ą¤¾ą„ˆ','ऄ'=>'ą¤…ą„†','ऑ'=>'ą¤…ą„‰','ą¤'=>'ą¤ą„…','ą¤Ž'=>'ą¤ą„†','ऐ'=>'ą¤ą„‡','ई'=>'ą¤°ą„ą¤‡','আ'=>'অা','ą§ '=>'ą¦‹ą§ƒ','ą§”'=>'ঌৢ','ਉ'=>'ੳੁ','ਊ'=>'ੳੂ','ਆ'=>'ਅਾ','ਐ'=>'ąØ…ą©ˆ','ਔ'=>'ąØ…ą©Œ','ਇ'=>'ੲਿ','ਈ'=>'ੲੀ','ąØ'=>'ੲੇ','ąŖ†'=>'ąŖ…ąŖ¾','ąŖ‘'=>'અાૅ','ąŖ“'=>'અાે','ąŖ”'=>'ąŖ…ąŖ¾ą«ˆ','ąŖ'=>'ąŖ…ą«…','ąŖ'=>'અે','ઐ'=>'ąŖ…ą«ˆ','ଆ'=>'ଅା','௮'=>'ą®…','ą®°'=>'ஈ','ா'=>'ஈ','௫'=>'ஈு','௨'=>'உ','ஊ'=>'உள','௭'=>'ą®Ž','௷'=>'ą®Žą®µ','ஜ'=>'ஐ','௧'=>'க','௪'=>'ச','௬'=>'சு','௲'=>'ą®šąÆ‚','௺'=>'நீ','ை'=>'ன','௓'=>'மீ','௰'=>'ய','ௗ'=>'ள','௸'=>'ą®·','ொ'=>'ąÆ†ą®ˆ','ௌ'=>'ெள','ோ'=>'ąÆ‡ą®ˆ','ą± '=>'ą°‹ą°¾','ą±”'=>'ఌా','ą°”'=>'ą°’ą±Œ','ą°“'=>'ఒౕ','ą°¢'=>'ఔ̣','ą°­'=>'బ̣','ą°·'=>'వ̣','ą°¹'=>'వా','ą°®'=>'వు','ూ'=>'ుా','ౄ'=>'ృా','ą³”'=>'ಌಾ','ą²”'=>'ą°’ą±Œ','ą“ˆ'=>'ą“‡ąµ—','ą“Š'=>'உൗ','ą“'=>'ą“Žąµ†','ą““'=>'ą“’ą“¾','ą“”'=>'ą“’ąµ—','ąµ”'=>'ą“ž','൫'=>'ą“¦ąµą“°','ą“Œ'=>'ą“ØąÆ‚','ą“™'=>'ą“ØąÆ‚','൯'=>'ą“Øąµ','ą“±'=>'ą“°','ąµŖ'=>'ą“°ąµ','ąµ®'=>'ą“µąµ','ąµ€'=>'ி','ൂ'=>'ூ','ൃ'=>'ூ','ൈ'=>'െെ','ฃ'=>'ąø‚','ąø”'=>'ąø„','ąø•'=>'ąø„','ąø”'=>'ąø†','ąø‹'=>'ช','ąø'=>'ąøŽ','ąø—'=>'ąø‘','ą¹…'=>'ąø²','ąø³'=>'̊า','แ'=>'เเ','ໜ'=>'ąŗ«ąŗ™','ą»'=>'ąŗ«ąŗ”','ąŗ³'=>'̊າ','ą½·'=>'ྲཱྀ','ą½¹'=>'ླཱྀ','၀'=>'o','įž£'=>'įž¢','᧐'=>'į¦ž','į­’'=>'į¬','į­“'=>'ᬑ','᭘'=>'ᬨ','ᢖ'=>'ᔜ','ᔕ'=>'į µ','į’'=>'įŽ”','įŽ½'=>'y','š€'=>'A','š“'=>'A','š‘Ø'=>'A','š’œ'=>'A','š“'=>'A','š”„'=>'A','š”ø'=>'A','š•¬'=>'A','š– '=>'A','š—”'=>'A','š˜ˆ'=>'A','š˜¼'=>'A','š™°'=>'A','ššØ'=>'A','š›¢'=>'A','šœœ'=>'A','š–'=>'A','šž'=>'A','š‰'=>'J','š½'=>'J','š‘±'=>'J','š’„'=>'J','š“™'=>'J','š”'=>'J','š•'=>'J','š•µ'=>'J','š–©'=>'J','š—'=>'J','š˜‘'=>'J','š™…'=>'J','š™¹'=>'J','į§'=>'J','⋿'=>'E','ā„°'=>'E','š„'=>'E','šø'=>'E','š‘¬'=>'E','š“”'=>'E','š”ˆ'=>'E','š”¼'=>'E','š•°'=>'E','š–¤'=>'E','š—˜'=>'E','š˜Œ'=>'E','š™€'=>'E','š™“'=>'E','šš¬'=>'E','š›¦'=>'E','šœ '=>'E','šš'=>'E','šž”'=>'E','ℾ'=>'įŽ±','ššŖ'=>'įŽ±','š›¤'=>'įŽ±','šœž'=>'įŽ±','š˜'=>'įŽ±','šž’'=>'įŽ±','į”'=>'w','ℳ'=>'M','šŒ'=>'M','š‘€'=>'M','š‘“'=>'M','š“œ'=>'M','š”'=>'M','š•„'=>'M','š•ø'=>'M','š–¬'=>'M','š— '=>'M','š˜”'=>'M','š™ˆ'=>'M','š™¼'=>'M','šš³'=>'M','š›­'=>'M','šœ§'=>'M','š”'=>'M','šž›'=>'M','ā„‹'=>'H','ā„Œ'=>'H','ā„'=>'H','š‡'=>'H','š»'=>'H','š‘Æ'=>'H','š“—'=>'H','š•³'=>'H','š–§'=>'H','š—›'=>'H','š˜'=>'H','š™ƒ'=>'H','š™·'=>'H','šš®'=>'H','š›Ø'=>'H','šœ¢'=>'H','šœ'=>'H','šž–'=>'H','š†'=>'G','šŗ'=>'G','š‘®'=>'G','š’¢'=>'G','š“–'=>'G','š”Š'=>'G','š”¾'=>'G','š•²'=>'G','š–¦'=>'G','š—š'=>'G','š˜Ž'=>'G','š™‚'=>'G','š™¶'=>'G','į³'=>'G','ℤ'=>'Z','ℨ'=>'Z','š™'=>'Z','š‘'=>'Z','š’'=>'Z','š’µ'=>'Z','š“©'=>'Z','š–…'=>'Z','š–¹'=>'Z','š—­'=>'Z','š˜”'=>'Z','š™•'=>'Z','šš‰'=>'Z','šš­'=>'Z','š›§'=>'Z','šœ”'=>'Z','š›'=>'Z','šž•'=>'Z','š’'=>'S','š‘†'=>'S','š‘ŗ'=>'S','š’®'=>'S','š“¢'=>'S','š”–'=>'S','š•Š'=>'S','š•¾'=>'S','š–²'=>'S','š—¦'=>'S','š˜š'=>'S','š™Ž'=>'S','šš‚'=>'S','įš'=>'S','š•'=>'V','š‘‰'=>'V','š‘½'=>'V','š’±'=>'V','š“„'=>'V','š”™'=>'V','š•'=>'V','š–'=>'V','š–µ'=>'V','š—©'=>'V','š˜'=>'V','š™‘'=>'V','šš…'=>'V','ā„’'=>'L','š‹'=>'L','šæ'=>'L','š‘³'=>'L','š“›'=>'L','š”'=>'L','š•ƒ'=>'L','š•·'=>'L','š–«'=>'L','š—Ÿ'=>'L','š˜“'=>'L','š™‡'=>'L','š™»'=>'L','āˆ‘'=>'C','ā…€'=>'C','ā„‚'=>'C','ā„­'=>'C','š‚'=>'C','š¶'=>'C','š‘Ŗ'=>'C','š’ž'=>'C','š“’'=>'C','š•®'=>'C','š–¢'=>'C','š—–'=>'C','š˜Š'=>'C','š˜¾'=>'C','š™²'=>'C','ššŗ'=>'C','š›“'=>'C','šœ®'=>'C','šØ'=>'C','šž¢'=>'C','ā„™'=>'P','š'=>'P','š‘ƒ'=>'P','š‘·'=>'P','š’«'=>'P','š“Ÿ'=>'P','š”“'=>'P','š•»'=>'P','š–Æ'=>'P','š—£'=>'P','š˜—'=>'P','š™‹'=>'P','š™æ'=>'P','ššø'=>'P','š›²'=>'P','šœ¬'=>'P','š¦'=>'P','šž '=>'P','šŠ'=>'K','š¾'=>'K','š‘²'=>'K','š’¦'=>'K','š“š'=>'K','š”Ž'=>'K','š•‚'=>'K','š•¶'=>'K','š–Ŗ'=>'K','š—ž'=>'K','š˜’'=>'K','š™†'=>'K','š™ŗ'=>'K','šš±'=>'K','š›«'=>'K','šœ„'=>'K','šŸ'=>'K','šž™'=>'K','ℬ'=>'B','š'=>'B','šµ'=>'B','š‘©'=>'B','š“‘'=>'B','š”…'=>'B','š”¹'=>'B','š•­'=>'B','š–”'=>'B','š—•'=>'B','š˜‰'=>'B','š˜½'=>'B','š™±'=>'B','šš©'=>'B','š›£'=>'B','šœ'=>'B','š—'=>'B','šž‘'=>'B','į'=>'ᐁ·','āˆ†'=>'ᐃ','šš«'=>'ᐃ','š›„'=>'ᐃ','šœŸ'=>'ᐃ','š™'=>'ᐃ','šž“'=>'ᐃ','į'=>'ᐃ·','ᐑ'=>'ᐄ·','ᐓ'=>'ᐅ·','ᐕ'=>'ᐆ·','ᐘ'=>'ᐊ·','ᐚ'=>'ᐋ·','į“‘'=>'ᐔ','į‘¶'=>'Ā·P','ᑺ'=>'Ā·d','į’˜'=>'Ā·J','ᑁ'=>'ᐳ·','į‘ƒ'=>'ᐓ·','į‘…'=>'ᐸ·','ᑇ'=>'ᐹ·','ˈ'=>'į‘Š','į‘˜'=>'į‘ŒĀ·','į‘§'=>'į‘Œį‘Š','į‘š'=>'į‘ŽĀ·','ᑨ'=>'į‘Žį‘Š','į‘œ'=>'į‘Ā·','į‘ž'=>'ᑐ·','į‘©'=>'į‘į‘Š','į‘ '=>'į‘‘Ā·','į‘¢'=>'į‘•Ā·','ᑪ'=>'į‘•į‘Š','ᑤ'=>'į‘–Ā·','ᑵ'=>'į‘«Ā·','į’…'=>'į‘«į‘Š','į‘·'=>'PĀ·','į’†'=>'Pį‘Š','ᑹ'=>'ᑮ·','į‘»'=>'dĀ·','į’‡'=>'dį‘Š','ᑽ'=>'į‘°Ā·','ᑿ'=>'ᑲ·','į’ˆ'=>'į‘²į‘Š','ᒁ'=>'ᑳ·','ᘃ'=>'į’‰','į’“'=>'ᒉ·','į’•'=>'į’‹Ā·','į’—'=>'į’ŒĀ·','į’™'=>'JĀ·','į’›'=>'į’ŽĀ·','į˜‚'=>'ᒐ','į’'=>'ᒐ·','į’Ÿ'=>'į’‘Ā·','į’­'=>'ᒣ·','į’Æ'=>'į’„Ā·','į’±'=>'ᒦ·','į’³'=>'į’§Ā·','į’µ'=>'į’ØĀ·','į’¹'=>'į’«Ā·','į“Š'=>'ᓀ·','į“Œ'=>'ᓇ·','į“Ž'=>'į“ˆį’«','į˜„'=>'į““','į“'=>'į““Ā·','į“Ÿ'=>'į“•Ā·','į“”'=>'į“–Ā·','į“£'=>'į“—Ā·','į“„'=>'į“˜Ā·','į˜‡'=>'į“š','į“§'=>'į“šĀ·','į“©'=>'ᓛ·','į“·'=>'į“­Ā·','ᓹ'=>'ᓯ·','į“»'=>'į“°Ā·','ᓽ'=>'ᓱ·','ᓿ'=>'ᓲ·','ᔁ'=>'į““Ā·','į”ƒ'=>'ᓵ·','į”Œ'=>'ᔋᐸ','į”'=>'ᔋᑕ','į”Ž'=>'ᔋᑲ','į”'=>'ᔋᒐ','į”˜'=>'ᔐ·','į”š'=>'ᔑ·','į”œ'=>'į”’Ā·','į”ž'=>'ᔓ·','į” '=>'ᔔ·','ᔢ'=>'ᔕ·','ᔤ'=>'į”–Ā·','ᔲ'=>'ᔨ·','ᔓ'=>'ᔩ·','į”¶'=>'ᔪ·','ᔸ'=>'ᔫ·','ᔺ'=>'į”­Ā·','ᔼ'=>'ᔮ·','į™®'=>'x','ᕽ'=>'x','ᘢ'=>'į•ƒ','ᘣ'=>'ᕆ','ᘤ'=>'į•Š','į•'=>'į•ŒĀ·','ᙯ'=>'ᕐᑫ','ᕾ'=>'ᕐᑬ','ᕿ'=>'ᕐP','į–€'=>'ᕐᑮ','ᖁ'=>'ᕐd','į–‚'=>'ᕐᑰ','į–ƒ'=>'ᕐᑲ','į–„'=>'ᕐᑳ','į–…'=>'į•į’ƒ','į•œ'=>'į•šĀ·','į•©'=>'į•§Ā·','ā„›'=>'R','ā„œ'=>'R','ā„'=>'R','š‘'=>'R','š‘…'=>'R','š‘¹'=>'R','š“”'=>'R','š•½'=>'R','š–±'=>'R','š—„'=>'R','š˜™'=>'R','š™'=>'R','šš'=>'R','į™°'=>'į–•į’‰','į–Ž'=>'į–•į’Š','į–'=>'į–•į’‹','ᖐ'=>'į–•į’Œ','į–‘'=>'į–•J','į–’'=>'į–•į’Ž','į–“'=>'ᖕᒐ','į–”'=>'į–•į’‘','į™±'=>'į––į’‹','ᙲ'=>'į––į’Œ','ᙳ'=>'į––J','ᙓ'=>'į––į’Ž','ᙵ'=>'ᖖᒐ','į™¶'=>'į––į’‘','ℱ'=>'F','š…'=>'F','š¹'=>'F','š‘­'=>'F','š“•'=>'F','š”‰'=>'F','š”½'=>'F','š•±'=>'F','š–„'=>'F','š—™'=>'F','š˜'=>'F','š™'=>'F','š™µ'=>'F','šŸŠ'=>'F','ā……'=>'D','šƒ'=>'D','š·'=>'D','š‘«'=>'D','š’Ÿ'=>'D','š““'=>'D','š”‡'=>'D','š”»'=>'D','š•Æ'=>'D','š–£'=>'D','š——'=>'D','š˜‹'=>'D','š˜æ'=>'D','š™³'=>'D','į—Ŗ'=>'D','ā„§'=>'ᘮ','ᘓ'=>'ᘮ','š›€'=>'ᘯ','š›ŗ'=>'ᘯ','šœ“'=>'ᘯ','š®'=>'ᘯ','šžØ'=>'ᘯ','ᘵ'=>'ᘯ','愱'=>'į„€','ļ¾”'=>'į„€','ᆨ'=>'į„€','ㄲ'=>'ᄁ','ļ¾¢'=>'ᄁ','ᆩ'=>'ᄁ','ć„“'=>'į„‚','ᄂ'=>'į„‚','ᆫ'=>'į„‚','ć„·'=>'į„ƒ','ļ¾§'=>'į„ƒ','ᆮ'=>'į„ƒ','ㄸ'=>'į„„','ᄄ'=>'į„„','ㄹ'=>'į„…','ᄅ'=>'į„…','ᆯ'=>'į„…','慁'=>'ᄆ','ļ¾±'=>'ᄆ','ᆷ'=>'ᄆ','慂'=>'ᄇ','ļ¾²'=>'ᄇ','ᆸ'=>'ᄇ','慃'=>'į„ˆ','ļ¾³'=>'į„ˆ','慅'=>'ᄉ','ļ¾µ'=>'ᄉ','ᆺ'=>'ᄉ','慆'=>'į„Š','ļ¾¶'=>'į„Š','ᆻ'=>'į„Š','慇'=>'į„‹','ļ¾·'=>'į„‹','ᆼ'=>'į„‹','慈'=>'į„Œ','ļ¾ø'=>'į„Œ','ᆽ'=>'į„Œ','慉'=>'į„','ļ¾¹'=>'į„','慊'=>'į„Ž','ļ¾ŗ'=>'į„Ž','ᆾ'=>'į„Ž','態'=>'į„','ļ¾»'=>'į„','ᆿ'=>'į„','慌'=>'ᄐ','ļ¾¼'=>'ᄐ','ᇀ'=>'ᄐ','慍'=>'į„‘','ļ¾½'=>'į„‘','ᇁ'=>'į„‘','慎'=>'į„’','ļ¾¾'=>'į„’','ᇂ'=>'į„’','ᇅ'=>'į„“','ć…„'=>'į„”','ć…¦'=>'į„•','ᇆ'=>'į„•','į‡Š'=>'į„—','į‡'=>'į„˜','ᇐ'=>'į„™','慀'=>'į„š','ļ¾°'=>'į„š','į„»'=>'į„š','ᆶ'=>'į„š','ć…®'=>'į„œ','į‡œ'=>'į„œ','ć…±'=>'į„','ᇢ'=>'į„','ć…²'=>'į„ž','ć…³'=>'į„ ','慄'=>'į„”','モ'=>'į„”','ᆹ'=>'į„”','ć…“'=>'į„¢','ć…µ'=>'į„£','ć…¶'=>'į„§','ć…·'=>'į„©','ć…ø'=>'į„«','ᇦ'=>'į„«','ć…¹'=>'ᄬ','ć…ŗ'=>'į„­','ᇧ'=>'į„­','ć…»'=>'į„®','ć…¼'=>'ᄯ','ᇨ'=>'ᄯ','ᇩ'=>'į„°','ć…½'=>'ᄲ','ᇪ'=>'ᄲ','ć…¾'=>'į„¶','ć…æ'=>'į…€','ᇫ'=>'į…€','ᇬ'=>'ᅁ','ᇱ'=>'į……','憂'=>'į……','ᇲ'=>'į…†','憃'=>'į…†','憀'=>'į…‡','ᇮ'=>'į…‡','憁'=>'į…Œ','ᇰ'=>'į…Œ','ᇳ'=>'į…–','憄'=>'į…—','ᇓ'=>'į…—','憅'=>'į…˜','憆'=>'į…™','ᇹ'=>'į…™','慤'=>'į… ','ļ¾ '=>'į… ','慏'=>'į…”','ļæ‚'=>'į…”','慐'=>'į…¢','ᅢ'=>'į…¢','慑'=>'į…£','ļæ„'=>'į…£','慒'=>'į…¤','ļæ…'=>'į…¤','慓'=>'į…„','ᅥ'=>'į…„','慔'=>'į…¦','ᅦ'=>'į…¦','慕'=>'į…§','ᅧ'=>'į…§','慖'=>'į…Ø','ļæ‹'=>'į…Ø','慗'=>'į…©','ᅩ'=>'į…©','慘'=>'į…Ŗ','ļæ'=>'į…Ŗ','慙'=>'į…«','ļæŽ'=>'į…«','慚'=>'į…¬','ļæ'=>'į…¬','慛'=>'į…­','ļæ’'=>'į…­','慜'=>'į…®','ļæ“'=>'į…®','慝'=>'į…Æ','ļæ”'=>'į…Æ','慞'=>'į…°','ļæ•'=>'į…°','慟'=>'į…±','ļæ–'=>'į…±','慠'=>'į…²','ļæ—'=>'į…²','ć…”'=>'äø€','ᅳ'=>'äø€','ć…¢'=>'į…“','ļæ›'=>'į…“','ć…£'=>'äøØ','ᅵ'=>'äøØ','憇'=>'ᆄ','ᆆ'=>'ᆄ','憈'=>'ᆅ','憉'=>'į†ˆ','憊'=>'ᆑ','憋'=>'ᆒ','憌'=>'ᆔ','憍'=>'į†ž','憎'=>'ᆔ','ㄳ'=>'ᆪ','ļ¾£'=>'ᆪ','愵'=>'ᆬ','ト'=>'ᆬ','ć„¶'=>'ᆭ','ᆭ'=>'ᆭ','ㄺ'=>'ᆰ','ļ¾Ŗ'=>'ᆰ','ć„»'=>'ᆱ','ᆱ'=>'ᆱ','ㄼ'=>'ᆲ','ᆲ'=>'ᆲ','ㄽ'=>'ᆳ','ļ¾­'=>'ᆳ','ㄾ'=>'ᆓ','ļ¾®'=>'ᆓ','ㄿ'=>'ᆵ','ᆵ'=>'ᆵ','慧'=>'ᇇ','ć…Ø'=>'į‡ˆ','ć…©'=>'į‡Œ','ć…Ŗ'=>'į‡Ž','ć…«'=>'ᇓ','ć…¬'=>'ᇗ','慭'=>'ᇙ','ć…Æ'=>'į‡','慰'=>'į‡Ÿ','ļ½§'=>'ć‚”','ļ½±'=>'ć‚¢','ィ'=>'ć‚£','ļ½²'=>'悤','ゥ'=>'ć‚„','ļ½³'=>'悦','ļ½Ŗ'=>'悧','s'=>'エ','ォ'=>'ć‚©','ļ½µ'=>'オ','ļ½¶'=>'ć‚«','ļ½·'=>'悭','ļ½ø'=>'ク','ļ½¹'=>'悱','ļ½ŗ'=>'コ','ļ½»'=>'悵','ļ½¼'=>'ć‚·','ļ½½'=>'ス','ļ½¾'=>'ć‚»','ソ'=>'ソ','ļ¾€'=>'タ','チ'=>'惁','ッ'=>'惃','ツ'=>'惄','テ'=>'惆','ト'=>'惈','ļ¾…'=>'ナ','ニ'=>'惋','ヌ'=>'ヌ','ネ'=>'惍','ノ'=>'惎','ハ'=>'惏','ヒ'=>'惒','フ'=>'惕','ļ¾'=>'へ','ļ¾Ž'=>'惛','ļ¾'=>'惞','ā§„'=>'〼','ミ'=>'ミ','ム'=>'惠','ļ¾’'=>'惔','モ'=>'モ','ャ'=>'ャ','ļ¾”'=>'惤','ļ½­'=>'惄','ユ'=>'惦','ļ½®'=>'惧','ļ¾–'=>'ヨ','ļ¾—'=>'惩','リ'=>'リ','ļ¾™'=>'惫','レ'=>'惬','ļ¾›'=>'惭','ワ'=>'ワ','ヲ'=>'ヲ','ļ¾'=>'ン','ź’ž'=>'ꁊ','ź’¬'=>'ꁐ','ź’œ'=>'źƒ€','ź’æ'=>'ꉙ','ź’¾'=>'ꊱ','ź“€'=>'źŽ«','ź“‚'=>'źŽµ','ź’ŗ'=>'źŽæ','ź’°'=>'ź‚','𐒠'=>'𐒆','—'=>'äø€','―'=>'äø€','āˆ’'=>'äø€','─'=>'äø€','ā¼€'=>'äø€','ļ„§'=>'äø','ļ©°'=>'äø¦','|'=>'äøØ','|'=>'äøØ','∣'=>'äøØ','⼁'=>'äøØ','‖'=>'äøØäøØ','∄'=>'äøØäøØ','串'=>'äø²','⼂'=>'äø¶','丸'=>'äøø','ļ„ž'=>'äø¹','丽'=>'äø½','⼃'=>'äøæ','乁'=>'乁','⼄'=>'乙','亂'=>'äŗ‚','ā¼…'=>'äŗ…','了'=>'äŗ†','⼆'=>'二','⼇'=>'äŗ ','ļ„·'=>'äŗ®','⼈'=>'äŗŗ','ļ§½'=>'什','仌'=>'仌','令'=>'令','你'=>'ä½ ','倂'=>'ä½µ','倂'=>'ä½µ','侀'=>'侀','來'=>'來','例'=>'例','侮'=>'ä¾®','侮'=>'ä¾®','侻'=>'ä¾»','ļ„„'=>'便','值'=>'値','ļ§”'=>'倫','偺'=>'偺','備'=>'備','像'=>'像','僚'=>'僚','僧'=>'僧','僧'=>'僧','⼉'=>'儿','兀'=>'兀','ļ©“'=>'充','免'=>'免','šÆ Ž'=>'免','šÆ '=>'兔','兤'=>'兤','⼊'=>'å…„','內'=>'內','全'=>'å…Ø',''=>'兩','⼋'=>'八','ļ§‘'=>'六','具'=>'具','冀'=>'冀','⼌'=>'冂','再'=>'再','冒'=>'冒','冕'=>'冕','ā¼'=>'冖','冗'=>'冗','冤'=>'冤','ā¼Ž'=>'冫','冬'=>'冬','况'=>'况','况'=>'况','冷'=>'冷',''=>'凉','ļ„•'=>'凌','ļ„”'=>'凜','凞'=>'凞','ā¼'=>'几','šÆ '=>'凵','⼐'=>'凵','⼑'=>'刀','šÆ ž'=>'刃','切'=>'切','𯔐'=>'切','列'=>'列','ļ§'=>'利','ļ§æ'=>'刺','刻'=>'刻','內'=>'剆','割'=>'割','剷'=>'剷','劉'=>'劉','力'=>'力','ā¼’'=>'力','ļ¦'=>'劣','劳'=>'劳','ļ©¶'=>'勇','你'=>'勇','勉'=>'勉','勉'=>'勉','ļ„’'=>'勒','勞'=>'勞','﨓'=>'勤','勤'=>'勤',''=>'勵','⼓'=>'勹','ļ©·'=>'勺','勺'=>'勺','包'=>'包','匆'=>'匆','ā¼”'=>'匕','ļ„£'=>'北','北'=>'北','⼕'=>'匚','ā¼–'=>'匸','ļ§«'=>'匿','ā¼—'=>'十','〸'=>'十','〹'=>'卄','〺'=>'卅','卉'=>'卉','卑'=>'卑','卑'=>'卑','博'=>'博','⼘'=>'卜','ā¼™'=>'卩','即'=>'即','卵'=>'卵','卽'=>'卽','卿'=>'åæ','卿'=>'åæ','卿'=>'åæ','⼚'=>'厂','ā¼›'=>'厶','ļ„«'=>'參','⼜'=>'又','及'=>'及','叟'=>'叟','ā¼'=>'口','句'=>'叄','叫'=>'叫','叱'=>'叱','吆'=>'吆','ļ§ž'=>'吏','ļ§­'=>'吝','吸'=>'吸','呂'=>'呂','呈'=>'呈','周'=>'周','咞'=>'咞','𯔀'=>'咢','ļ¦ž'=>'咽','𯔁'=>'哶','𯔂'=>'唐','𯔃'=>'啓','啟'=>'啓','啕'=>'啕','𯔄'=>'啣','𯔅'=>'善','𯔆'=>'善','喇'=>'喇','喙'=>'喙','𯔇'=>'喙','喝'=>'喝','喝'=>'喝','𯔈'=>'喫','𯔉'=>'喳','ļØ'=>'嗀','𯔊'=>'嗂','ļ©»'=>'嗢','嘆'=>'嘆','𯔌'=>'嘆','šÆ”Ž'=>'噑','器'=>'器','šÆ”'=>'噓','ā¼ž'=>'囗','囹'=>'囹','𯔋'=>'圖','šÆ”'=>'圗','⼟'=>'土','𯔕'=>'型','𯔒'=>'城','𯔓'=>'埓','𯔔'=>'堍','𯔗'=>'å ±','𯔖'=>'å ²','塀'=>'唀','塚'=>'唚','塚'=>'唚',''=>'唞','唫'=>'å””','墨'=>'墨','壿'=>'墫','𯔘'=>'墬','墳'=>'墳',''=>'壘','ļ„‚'=>'壟','ā¼ '=>'士','𯔑'=>'壮','𯔚'=>'売','𯔛'=>'壷','ā¼”'=>'夂','𯔜'=>'夆','ā¼¢'=>'夊','ā¼£'=>'夕','šÆ”'=>'多','šÆ”ž'=>'夢','⼤'=>'大','奄'=>'å„„','奈'=>'儈','契'=>'å„‘','奔'=>'å„”','𯔟'=>'å„¢','女'=>'儳','⼄'=>'儳','𯔄'=>'姘','𯔢'=>'姬','𯔣'=>'娛','𯔤'=>'娧','ļŖ€'=>'å©¢','𯔦'=>'婦','嬀'=>'åŖÆ','媵'=>'åŖµ','𯔩'=>'嬈','嬨'=>'嬨','𯔪'=>'嬾','𯔫'=>'嬾','⼦'=>'子','ā¼§'=>'宀','宅'=>'宅','𯔭'=>'寃','𯔮'=>'寘',''=>'寧','寧'=>'寧','𯔯'=>'寧','寮'=>'寮','𯔰'=>'寳','⼨'=>'寸','𯔲'=>'寿','𯔳'=>'将','⼩'=>'小','𯔵'=>'å°¢','ā¼Ŗ'=>'å°¢','⼫'=>'å°ø','尿'=>'å°æ','𯔷'=>'å± ','ļ„‹'=>'å±¢','層'=>'層','履'=>'屄','屮'=>'å±®','𯔸'=>'å±®','⼬'=>'å±®','ā¼­'=>'å±±','𯔺'=>'岍','𯔹'=>'峀','ļ§•'=>'å“™','𯔼'=>'嵃','樂'=>'嵐','𯔿'=>'嵫','𯔾'=>'åµ®','嵼'=>'åµ¼','𧲨'=>'å¶²','嶺'=>'å¶ŗ','ā¼®'=>'巛','巡'=>'å·”','巢'=>'å·¢','⼯'=>'å·„','ā¼°'=>'å·±','巽'=>'å·½','ā¼±'=>'å·¾','åø²'=>'åø”','帨'=>'åøØ','帽'=>'åø½','幩'=>'幩','ā¼²'=>'å¹²','ļ¦Ž'=>'幓','ā¼³'=>'å¹ŗ','⼓'=>'广','度'=>'åŗ¦','庰'=>'åŗ°','庳'=>'åŗ³','šÆ¢'=>'åŗ¶','廉'=>'廉','廊'=>'廊','šÆ¢Ž'=>'廊','ļŖ‚'=>'廒','廓'=>'廓','廙'=>'廙','廬'=>'廬','ā¼µ'=>'廓','廾'=>'廾','ā¼¶'=>'廾',''=>'弄','ā¼·'=>'弋','ā¼ø'=>'弓','弢'=>'å¼¢','弢'=>'å¼¢','ā¼¹'=>'彐','𯔓'=>'当','ā¼ŗ'=>'å½”','形'=>'å½¢','ļŖ„'=>'彩','彫'=>'彫','ā¼»'=>'å½³','律'=>'律','徚'=>'徚',''=>'復','ļŖ…'=>'å¾­','ā¼¼'=>'心','šÆ¢'=>'åæ','šÆ¢ž'=>'åæ—','念'=>'åæµ','忹'=>'åæ¹','ļ„ '=>'ꀒ','怜'=>'ꀜ','悁'=>'ꂁ','悔'=>'ꂔ','悔'=>'ꂔ','巽'=>'ꃇ','ļŖ†'=>'ꃘ','惡'=>'ꃔ','愈'=>'ꄈ','ļ§™'=>'ꅄ','慈'=>'ꅈ','慌'=>'ꅌ','慌'=>'ꅌ','ļŖ‡'=>'ꅎ','慎'=>'ꅎ','慠'=>'ꅠ','慨'=>'ę…Ø','慺'=>'ę…ŗ','憎'=>'ꆎ','ļŖ‰'=>'ꆎ','憎'=>'ꆎ','ļ¦'=>'ꆐ','憤'=>'ꆤ','憯'=>'憯','憲'=>'憲','懞'=>'ꇞ','ļ©€'=>'懲','ļŖ‹'=>'懲','懲'=>'懲','ļ¤'=>'ꇶ','懶'=>'ꇶ','戀'=>'ꈀ','ā¼½'=>'ꈈ','成'=>'ꈐ','戛'=>'ꈛ','ļ§’'=>'ꈮ','戴'=>'ꈓ','ā¼¾'=>'ꈶ','⼿'=>'ꉋ','舁'=>'ꉝ','抱'=>'抱','滑'=>'ꋉ','ļ„›'=>'ꋏ','拓'=>'ꋓ','拔'=>'ꋔ','拼'=>'拼',''=>'拾','挽'=>'挽','捐'=>'ꍐ','捨'=>'ęØ','捻'=>'ę»','掃'=>'ꎃ',''=>'ꎠ','掩'=>'ꎩ','ļŖ'=>'ꏄ','揅'=>'ꏅ','揤'=>'ꏤ','橁'=>'ꐉ','ļŖŽ'=>'搜','搢'=>'搢','ļŖ'=>'ꑒ','摩'=>'ę‘©','摷'=>'ę‘·','摾'=>'摾','撚'=>'꒚','撝'=>'꒝','擄'=>'꓄','ā½€'=>'支','⽁'=>'ꔓ','敏'=>'ꕏ','敏'=>'ꕏ','敖'=>'ꕖ','敬'=>'ꕬ','ļ„©'=>'數','⽂'=>'ꖇ','⽃'=>'ꖗ','料'=>'ꖙ','⽄'=>'ꖤ','ā½…'=>'ę–¹','旅'=>'ꗅ','⽆'=>'ꗠ','ļ©‚'=>'ę—¢','旣'=>'ę—£','⽇'=>'ę—„','ļ§ '=>'ꘓ','šÆ£'=>'ꙉ','ꙩ'=>'Ꙛ','䀿'=>'晣','晴'=>'ꙓ','ļŖ‘'=>'ꙓ','ļ§…'=>'暈','暑'=>'ꚑ','šÆ£'=>'ꚑ','暜'=>'暜','暴'=>'暓','曆'=>'ꛆ','⽈'=>'꛰','更'=>'ꛓ','㫚'=>'ę›¶','書'=>'書','最'=>'꜀','⽉'=>'月','肦'=>'朌','胐'=>'꜏','胊'=>'朐','脁'=>'꜓','朗'=>'ꜗ','ļŖ’'=>'ꜗ','朗'=>'ꜗ','脧'=>'朘','ļŖ“'=>'ꜛ','望'=>'ꜛ','朡'=>'朔','膧'=>'朣','⽊'=>'木','ļ§”'=>'Ꝏ','杓'=>'ꝓ','ļŖ”'=>'Ꝗ','杞'=>'Ꝟ','柿'=>'ę®','杻'=>'ę»','枅'=>'ꞅ','ļ§“'=>'ꞗ','柳'=>'柳','柺'=>'柺','栗'=>'ꠗ','摾'=>'栟','最'=>'ę”’',''=>'梁','ļ©„'=>'梅','梅'=>'梅','梎'=>'ę¢Ž','ļ§¢'=>'梨','椔'=>'ꤔ','楂'=>'ę„‚','樧'=>'ę¦','榣'=>'榣','槪'=>'ę§Ŗ','樂'=>'樂',''=>'樂','樂'=>'樂',''=>'樓','檨'=>'ęŖØ','櫓'=>'ę«“','櫛'=>'ę«›','ļ¤'=>'ꬄ','⽋'=>'ꬠ','次'=>'ꬔ','歔'=>'ꭔ','⽌'=>'ę­¢','歲'=>'ę­²','歷'=>'ę­·','ļŖ•'=>'ę­¹','ā½'=>'ę­¹','冕'=>'殟','濾'=>'ę®®','ā½Ž'=>'殳','ļ„°'=>'殺','ļŖ–'=>'殺','殺'=>'殺','殻'=>'ę®»','ā½'=>'毋','⺟'=>'ęÆ','⽐'=>'比','⽑'=>'毛','ā½’'=>'갏','⽓'=>'갔','ā½”'=>'ę°“','汎'=>'걎','汧'=>'ę±§',''=>'沈','沿'=>'沿',''=>'泌','泍'=>'ę³','ļ§£'=>'泄','洖'=>'ę“–','洛'=>'ę“›','洞'=>'ꓞ','洴'=>'ę““','派'=>'擾','流'=>'굁','ļŖ—'=>'굁','流'=>'굁','浩'=>'굩','浪'=>'ęµŖ','ļ©…'=>'ęµ·','海'=>'ęµ·','浸'=>'ęµø','涅'=>'ę¶…','ļ§µ'=>'ę·‹','ļ„'=>'淚','ļ§–'=>'ę·Ŗ','šÆ¤Ž'=>'ę·¹','渚'=>'渚','港'=>'ęøÆ','湮'=>'ę¹®','ę½™'=>'溈','ļ§‹'=>'溜','溺'=>'ęŗŗ','滇'=>'껇','ļŖ™'=>'껋','滋'=>'껋','滑'=>'껑','滛'=>'ę»›','ļ„Ž'=>'ę¼','漢'=>'ę¼¢','漢'=>'ę¼¢','漣'=>'ę¼£','šÆ¤'=>'ę½®','濆'=>'濆','濫'=>'ęæ«','濾'=>'ęæ¾','瀛'=>'瀛','ļŖ›'=>'ē€ž','瀞'=>'ē€ž','瀹'=>'瀹','灊'=>'灊','⽕'=>'火','灰'=>'灰','灷'=>'灷','災'=>'災','ļ§»'=>'ē‚™','炭'=>'ē‚­','烈'=>'烈','烙'=>'ēƒ™','煅'=>'ē……','煉'=>'ē…‰','煮'=>'ē…®','煮'=>'ē…®','šÆ¤ž'=>'ē†œ','ļ§€'=>'ē‡Ž','ļ§®'=>'燐','爐'=>'爐','ļ¤ž'=>'ēˆ›','爨'=>'爨','ā½–'=>'爪','爫'=>'爫','āŗ¤'=>'爫','ļŖž'=>'爵','瀞'=>'爵','ā½—'=>'父','⽘'=>'爻','ā½™'=>'爿','⽚'=>'片','牐'=>'牐','ā½›'=>'牙','⽜'=>'牛',''=>'牢','犀'=>'ēŠ€','浸'=>'ēŠ•','ā½'=>'犬','犯'=>'犯','ļ§ŗ'=>'ē‹€','狼'=>'狼','猪'=>'猪','ļŖ '=>'猪','獵'=>'ēµ','獺'=>'ēŗ','ā½ž'=>'ēŽ„','ļ„”'=>'ēŽ‡','ļ§›'=>'ēŽ‡','⽟'=>'ēŽ‰','王'=>'ēŽ‹','玥'=>'ēŽ„','玲'=>'ēŽ²','珞'=>'ēž','理'=>'理','琉'=>'琉','琢'=>'琢','瑇'=>'瑇','瑜'=>'ē‘œ','瑩'=>'ē‘©','ļŖ”'=>'瑱','瑱'=>'瑱','璅'=>'ē’…','璉'=>'ē’‰','ļ§Æ'=>'ē’˜','瓊'=>'ē“Š','ā½ '=>'ē“œ','ā½”'=>'瓦','ļŖ¢'=>'甆','ā½¢'=>'ē”˜','ā½£'=>'ē”Ÿ','瀹'=>'甤','⽤'=>'用','⽄'=>'ē”°','ļŖ£'=>'ē”»','甾'=>'甾','ļ§'=>'ē•™','ļ„¶'=>'ē•„','ļ„¢'=>'ē•°','異'=>'ē•°','⽦'=>'ē–‹','ā½§'=>'ē–’','ļ§„'=>'ē—¢','瘐'=>'瘐','ļŖ¤'=>'ē˜','ļŖ„'=>'瘟','療'=>'療','ļ¤Ž'=>'癩','⽨'=>'ē™¶','⽩'=>'白','ā½Ŗ'=>'皮','⽫'=>'皿','益'=>'ē›Š','ļŖ¦'=>'ē›Š','ļŖ§'=>'ē››','盧'=>'ē›§','⽬'=>'ē›®','ļŖØ'=>'盓','𯄀'=>'盓','ļ„­'=>'省','𯄅'=>'ēœž','𯄆'=>'真','𯄇'=>'真','ļŖŖ'=>'ē€','ļŖ©'=>'ēŠ','𯄈'=>'ēŠ','𯄊'=>'ēž‹','ļŖ'=>'ēž§','ā½­'=>'ēŸ›','ā½®'=>'矢','⽯'=>'石','ē”'=>'ē ”','šÆ„Ž'=>'ē”Ž','ļ§Ž'=>'甫','碌'=>'碌','šÆ„'=>'碌','ļ©‹'=>'碑',''=>'磊','ļŖ«'=>'磌','𯄐'=>'磌',''=>'磻','礪'=>'礪','ā½°'=>'示','礼'=>'礼','社'=>'社','ļ©Ž'=>'焈','ļ©'=>'焉','ļ©'=>'焐','祖'=>'ē„–','𯄓'=>'ē„–','ļ©‘'=>'ē„','神'=>'ē„ž','祥'=>'ē„„','祿'=>'焿','ļ©’'=>'ē¦','ļ©“'=>'ē¦Ž','福'=>'ē¦','𯄖'=>'ē¦','禮'=>'禮','ā½±'=>'禸','ā½²'=>'禾','秊'=>'秊','𯄗'=>'ē§«','ļ„–'=>'稜','ļ©”'=>'ē©€','𯄙'=>'ē©€','𯄚'=>'穊','𯄛'=>'ē©','ā½³'=>'ē©“','ļ©•'=>'突','ļŖ¬'=>'ēŖ±','ļ§·'=>'ē«‹','⽓'=>'ē«‹','𯄟'=>'ē«®','ā½µ'=>'竹','ļ§ø'=>'笠','ļ©–'=>'節','ļŖ­'=>'節','𯄢'=>'篆','𯄣'=>'築','簾'=>'ē°¾','ļ„„'=>'ē± ','ā½¶'=>'ē±³','ļŖ®'=>'ē±»','ļ§¹'=>'ē²’','ļØ'=>'ē²¾','𯄦'=>'ē³’','糖'=>'ē³–','𯄩'=>'ē³£','ļ„»'=>'ē³§','𯄨'=>'糨','ā½·'=>'ē³ø','𯄪'=>'ē“€','ļ§'=>'瓐',''=>'ē“¢','ļ„'=>'瓯','ēµ¶'=>'絕','ļŖÆ'=>'ēµ›','𯄬'=>'ēµ£','綠'=>'ē¶ ','ļ„—'=>'ē¶¾','𯄮'=>'ē·‡','練'=>'ē·“','ļ©—'=>'ē·“','ļŖ°'=>'ē·“','𯄯'=>'ēø‚','縉'=>'ēø‰',''=>'ēø·','ļ©™'=>'繁','𯄰'=>'ē¹…','ā½ø'=>'ē¼¶','ļŖ±'=>'ē¼¾','ā½¹'=>'网','āŗ«'=>'ē½’','署'=>'ē½²','罹'=>'ē½¹','𯄶'=>'ē½ŗ','ļ¤'=>'ē¾…','ā½ŗ'=>'羊','𯄸'=>'羕','羚'=>'羚','ļØž'=>'ē¾½','ā½»'=>'ē¾½','𯄹'=>'ēæŗ','邏'=>'老','ā½¼'=>'老','ļ©›'=>'者','ļŖ²'=>'者','𯄺'=>'者','ā½½'=>'而','ā½¾'=>'耒','⽿'=>'耳','聆'=>'聆','𯄽'=>'聠','聯'=>'聯','𯄿'=>'聰','ļ„…'=>'聾','ā¾€'=>'聿','⾁'=>'肉','ļ„“'=>'肋','肭'=>'肭','育'=>'育','欵'=>'胶','腁'=>'胼','脃'=>'脃','脾'=>'脾','臘'=>'臘','⾂'=>'臣','ļ§¶'=>'臨','⾃'=>'自','臭'=>'臭','⾄'=>'至','ā¾…'=>'臼','舁'=>'舁','舁'=>'舁','舄'=>'舄','⾆'=>'舌','⾇'=>'舛','⾈'=>'舟','⾉'=>'艮',''=>'良','⾊'=>'色','⾋'=>'艸','ļ©'=>'艹','ļ©ž'=>'艹','芋'=>'芋','šÆ¦'=>'芑','芝'=>'芝','花'=>'花','芳'=>'芳','芽'=>'芽','ļ„“'=>'č‹„','若'=>'č‹„','苦'=>'苦','茝'=>'茝','茣'=>'茣','ļ§¾'=>'茶','ļŖ³'=>'荒','荓'=>'荓','荣'=>'č£','莭'=>'莭','šÆ¦'=>'čŽ½','菉'=>'菉','芳'=>'菊','菌'=>'菌','菜'=>'菜','šÆ¦ž'=>'菧','ļŖ“'=>'čÆ',''=>'č±','落'=>'落','ļ„®'=>'葉','著'=>'著','著'=>'著','蔿'=>'蒍','蓮'=>'č“®','蓱'=>'蓱','蓳'=>'蓳','ļ§‚'=>'蓼','蔖'=>'蔖','蕤'=>'蕤','藍'=>'藍','ļ§°'=>'č—ŗ','蘆'=>'蘆','蘒'=>'蘒','蘭'=>'蘭','虁'=>'蘷','蘿'=>'蘿','⾌'=>'虍','虐'=>'虐','虜'=>'虜','花'=>'虜','虧'=>'虧','虩'=>'虩','ā¾'=>'虫','蚈'=>'蚈','蚩'=>'蚩','蛢'=>'蛢','蜎'=>'蜎','蜨'=>'蜨','蝫'=>'č«','ļŖµ'=>'č¹','蝹'=>'č¹','螆'=>'螆','螺'=>'čžŗ','蟡'=>'蟔','蠁'=>'蠁','蠟'=>'蠟','ā¾Ž'=>'蔀','行'=>'蔌','ā¾'=>'蔌','衠'=>'č” ','衣'=>'蔣','⾐'=>'蔣','裂'=>'裂','ļ§§'=>'č£','裗'=>'裗','裞'=>'č£ž','ļ§Ø'=>'裔','裸'=>'裸','裺'=>'裺','ļ© '=>'褐','ļŖ¶'=>'脁','襤'=>'脤','⾑'=>'脾','ļŖ·'=>'覆','見'=>'見','ā¾’'=>'見','ļ©”'=>'視','ļŖø'=>'視','⾓'=>'角','ā¾”'=>'言','䚶'=>'čØž','詽'=>'訮','šÆ§'=>'čŖ ',''=>'čŖŖ','璉'=>'čŖŖ','ļŖ¹'=>'čŖæ','ļŖ»'=>'č«‹',''=>'č«’',''=>'č«–','ļŖ¾'=>'č«­','諭'=>'č«­','諸'=>'諸','ļŖŗ'=>'諸','ļ„'=>'諾','ļŖ½'=>'諾','ļ©¢'=>'謁','ļŖ¼'=>'謁','ļ©£'=>'謹','ļŖæ'=>'謹','ļ§¼'=>'識',''=>'讀','č®'=>'讆','ļ«€'=>'變','變'=>'變','⾕'=>'č°·','ā¾–'=>'豆','豈'=>'豈','豕'=>'豕','ā¾—'=>'豕','⾘'=>'č±ø','ā¾™'=>'č²','貫'=>'貫','賁'=>'賁',''=>'賂','賈'=>'賈','賓'=>'賓','ļ©„'=>'蓈','贈'=>'蓈','贛'=>'č“›','⾚'=>'赤','ā¾›'=>'čµ°','起'=>'čµ·','趆'=>'赿','⾜'=>'č¶³','趼'=>'č¶¼','跋'=>'č·‹','č·ŗ'=>'č·„','路'=>'č·Æ','跰'=>'č·°','čŗ›'=>'čŗ—','ā¾'=>'čŗ«','車'=>'車','ā¾ž'=>'車','šÆ§ž'=>'č»”','č¼§'=>'軿','輦'=>'輦','ļ§—'=>'č¼Ŗ','ļ«‚'=>'č¼ø','輸'=>'č¼ø','輻'=>'č¼»','ļ¦'=>'č½¢','⾟'=>'č¾›','šÆ¦'=>'č¾ž',''=>'č¾°','ā¾ '=>'č¾°','ā¾”'=>'č¾µ','辶'=>'č¾¶','⻌'=>'č¾¶','連'=>'連','宅'=>'逸','ļ©§'=>'逸','遲'=>'遲','遼'=>'遼','邏'=>'邏','ā¾¢'=>'邑','邔'=>'邔','郎'=>'郎','郱'=>'郱','都'=>'都','鄑'=>'鄑','鄛'=>'鄛','ā¾£'=>'酉','酪'=>'é…Ŗ','ļ«„'=>'醙','醴'=>'醓','⾤'=>'釆','ļ§©'=>'里','⾄'=>'里',''=>'量','金'=>'金','⾦'=>'金','鈴'=>'鈓','鈸'=>'鈸','ļ«…'=>'鉶','鉼'=>'鉼','鋗'=>'鋗','鋘'=>'鋘','錄'=>'錄','鍊'=>'鍊','鎮'=>'鎭','鏹'=>'鏹','鐕'=>'鐕','ā¾§'=>'長','⾨'=>'門','開'=>'開','閭'=>'閭','閷'=>'閷','⾩'=>'阜','阮'=>'阮','ļ„‘'=>'陋','降'=>'降','ļ„™'=>'陵','ļ§“'=>'陸','陼'=>'陼','隆'=>'隆','ļ§±'=>'隣','ā¾Ŗ'=>'隶','隸'=>'隸','⾫'=>'隹','雃'=>'雃','ļ§Ŗ'=>'離','難'=>'難','難'=>'難','⾬'=>'雨','零'=>'零',''=>'雷','霣'=>'霣','露'=>'露','靈'=>'靈','ā¾­'=>'靑','靖'=>'靖','靖'=>'靖','ā¾®'=>'非','⾯'=>'面','ā¾°'=>'革','ā¾±'=>'韋','韛'=>'韛','韠'=>'韠','ā¾²'=>'韭','ā¾³'=>'音','ļ©©'=>'響','響'=>'響','⾓'=>'頁','ļ«‹'=>'頋','頋'=>'頋','頋'=>'頋','煉'=>'領','頩'=>'é ©','頻'=>'é »','頻'=>'é »','類'=>'锞','ā¾µ'=>'風','ā¾¶'=>'飛','ā»'=>'食','ā¾·'=>'食','飢'=>'飢','飯'=>'飯','飼'=>'飼','館'=>'館','餩'=>'餩','ā¾ø'=>'首','ā¾¹'=>'香','馧'=>'馧','ā¾ŗ'=>'馬','駂'=>'駂','駱'=>'é§±','駾'=>'é§¾','驪'=>'驪','ā¾»'=>'éŖØ','ā¾¼'=>'高','ā¾½'=>'髟','ļ«'=>'鬒','鬒'=>'鬒','ā¾¾'=>'鬄','⾿'=>'鬯','⿀'=>'鬲','⿁'=>'鬼','āæ‚'=>'魚','魯'=>'é­Æ','鱀'=>'鱀','ļ§²'=>'鱗','⿃'=>'鳄','鳽'=>'é³½','šÆØ'=>'éµ§','鶴'=>'é¶“','鷺'=>'é·ŗ','鸞'=>'éøž','鹃'=>'鹂','āæ„'=>'é¹µ','ļ„€'=>'鹿','āæ…'=>'鹿','麗'=>'éŗ—','ļ§³'=>'麟','⿆'=>'éŗ„','麻'=>'éŗ»','⿇'=>'éŗ»','⿈'=>'黃','⿉'=>'黍','黎'=>'黎','⿊'=>'黑','黹'=>'黹','āæ‹'=>'黹','⿌'=>'黽','黾'=>'黾','鼅'=>'鼅','āæ'=>'鼎','鼏'=>'鼏','āæŽ'=>'鼓','鼖'=>'鼖','āæ'=>'é¼ ','鼻'=>'é¼»','⿐'=>'é¼»','齃'=>'齃','āæ‘'=>'齊','āæ’'=>'齒','ļ§„'=>'龍','āæ“'=>'龍','ļ«™'=>'龎','龜'=>'龜','龜'=>'龜','ļ«Ž'=>'龜','āæ”'=>'龜','⻳'=>'龟','āæ•'=>'é¾ ','㒞'=>'撞','㒹'=>'ć’¹','㒻'=>'ć’»','㓟'=>'擟','㔕'=>'攕','䎛'=>'斈','𯔧'=>'ć›®','𯔨'=>'㛼','𯔶'=>'极','㠯'=>'ć Æ','㡢'=>'㔢','㡼'=>'㔼','㣇'=>'㣇','㣣'=>'㣣','㤜'=>'㤜','弢'=>'㤺','㨮'=>'㨮','㩬'=>'橬','㫤'=>'櫤','㬈'=>'欈','šÆ£Ž'=>'欙','䐠'=>'欻','šÆ£ž'=>'歉','ļ«’'=>'ć®','㮝'=>'ć®','㰘'=>'氘','㱎'=>'汎','㴳'=>'㓳','㶖'=>'ć¶–','㺬'=>'ćŗ¬','㺸'=>'ćŗø','㺸'=>'ćŗø','㼛'=>'ć¼›','㿼'=>'ćæ¼','䀈'=>'䀈','ļ«“'=>'䀘','ļ«”'=>'䀹','𯄉'=>'䀹','𯄋'=>'䁆','𯄌'=>'䂖','𯄑'=>'䃣','𯄘'=>'䄯','𯄠'=>'䈂','𯄤'=>'䈧','𯄧'=>'䊠','𯄭'=>'䌁','𯄱'=>'䌓','𯄓'=>'䍙','䏕'=>'䏕','䏙'=>'䏙','䐋'=>'䐋','šÆ¦Ž'=>'䑫','䔫'=>'䔫','䕝'=>'䕝','䕡'=>'ä•”','䕫'=>'䕫','䗗'=>'䗗','䗹'=>'䗹','䘵'=>'䘵','šÆ§'=>'䚾','šÆ§Ž'=>'䛇','䦕'=>'䦕','䧦'=>'䧦','䩮'=>'ä©®','䩶'=>'ä©¶','䪲'=>'äŖ²','䬳'=>'䬳','䯎'=>'äÆŽ','šÆØ'=>'䳎','šÆØŽ'=>'ä³­','䳸'=>'ä³ø','䵖'=>'䵖','𠄢'=>'š „¢','𠔜'=>'š ”œ','𠔥'=>'š ”„','𠕋'=>'š •‹','šÆ '=>'𠘺','𠠄'=>'š  „','šÆ§'=>'š £ž','㒹'=>'𠨬','𠭣'=>'š ­£','𯔙'=>'𔓤','𯔠'=>'𔚨','𯔔'=>'š”›Ŗ','𯔬'=>'𔧈','𯔱'=>'𔬘','𡴋'=>'𔓋','𯔻'=>'š”·¤','𯔽'=>'š”·¦','𢆃'=>'š¢†ƒ','𢆟'=>'š¢†Ÿ','𢌱'=>'𢌱','𢌱'=>'𢌱','𢛔'=>'𢛔','𢡄'=>'𢔄','ļ«'=>'𢔊','𢬌'=>'𢬌','𢯱'=>'𢯱','𣀊'=>'š£€Š','𣊸'=>'𣊸','𣍟'=>'š£Ÿ','𣎓'=>'š£Ž“','𣎜'=>'š£Žœ','šÆ£'=>'š£ƒ','ļ«‘'=>'š£•','𣑭'=>'𣑭','𣚣'=>'𣚣','𣢧'=>'𣢧','𣪍'=>'š£Ŗ','𣫺'=>'𣫺','𣲼'=>'𣲼','𣴞'=>'š£“ž','šÆ¤'=>'𣻑','𣽞'=>'š£½ž','𣾎'=>'š£¾Ž','šÆ¤'=>'𤉣','𤎫'=>'š¤Ž«','𤘈'=>'𤘈','𤜵'=>'𤜵','𤠔'=>'𤠔','𤰶'=>'𤰶','𤲒'=>'𤲒','𤾡'=>'𤾔','𤾸'=>'𤾸','𥁄'=>'š„„','𯄂'=>'š„ƒ²','𯄁'=>'š„ƒ³','𯄃'=>'š„„™','𯄄'=>'š„„³','ļ«•'=>'š„‰‰','šÆ„'=>'š„','𯄒'=>'š„˜¦','𯄔'=>'š„šš','𯄕'=>'š„›…','𯄜'=>'š„„¼','šÆ„'=>'š„Ŗ§','šÆ„ž'=>'š„Ŗ§','𯄔'=>'š„®«','𯄄'=>'š„²€','ļ«–'=>'š„³','𯄫'=>'š„¾†','𦇚'=>'š¦‡š','𯄲'=>'𦈨','𯄳'=>'𦉇','𯄵'=>'𦋙','𯄷'=>'𦌾','𯄻'=>'š¦“š','𯄼'=>'𦔣','𯄾'=>'𦖨','𦞧'=>'š¦ž§','𦞵'=>'š¦žµ','𦬼'=>'𦬼','𦰶'=>'𦰶','𦳕'=>'𦳕','䐋'=>'𦵫','𦼬'=>'𦼬','𦾱'=>'𦾱','𧃒'=>'š§ƒ’','𧏊'=>'š§Š','𧙧'=>'š§™§','𧢮'=>'š§¢®','𧥦'=>'𧄦','𧲨'=>'𧲨','ļ«—'=>'𧻓','𧼯'=>'𧼯','𨗒'=>'𨗒','貫'=>'𨗭','衣'=>'𨜮','𨯺'=>'𨯺','𨵷'=>'𨵷','𩅅'=>'š©……','𩇟'=>'š©‡Ÿ','𩈚'=>'𩈚','𩐊'=>'𩐊','𩒖'=>'š©’–','𩖶'=>'š©–¶','𩬰'=>'𩬰','𪃎'=>'šŖƒŽ','𪄅'=>'šŖ„…','𪈎'=>'šŖˆŽ','𪊑'=>'šŖŠ‘','šÆ¢'=>'šŖŽ’','šÆØ'=>'šŖ˜€','ā„ƒ'=>'°C','℉'=>'°F','ℇ'=>'ʐ','ā„»'=>'FAX','ā„•'=>'N','ā„–'=>'No','ā„š'=>'Q','₨'=>'Rs','š“'=>'T','ā„”'=>'TEL','š”'=>'U','š–'=>'W','ā‚©'=>'W̵','š—'=>'X','Ā„'=>'Y̵','šš²'=>'Ī›','ššµ'=>'Īž','ℿ'=>'Ī ','ϲ'=>'c','Ļ’'=>'Y','šš½'=>'Φ','ššæ'=>'ĪØ','Ń£'=>'Ь̵','ਃ'=>'ঃ','ಃ'=>'ః','່'=>'่','įŸ‹'=>'่','້'=>'้','໊'=>'๊','໋'=>'๋','įŸ•'=>'๚','៚'=>'ą¹›','ъ'=>'ˉb','įŸ™'=>'ą¹','ą³§'=>'ą±§','૨'=>'ą„Ø','೨'=>'౨','ą«©'=>'ą„©','૪'=>'ą„Ŗ','ą«®'=>'ą„®','೯'=>'౯','а'=>'a','į'=>'b','į–Æ'=>'b','с'=>'c','ԁ'=>'d','ᑯ'=>'d','е'=>'e','ә'=>'Ē','ε'=>'ɛ','є'=>'ɛ','ք'=>'f','ց'=>'g','Ņ»'=>'h','Õ°'=>'h','į‚'=>'h','į²'=>'hĢ”','ι'=>'i','і'=>'i','įŽ„'=>'i','ј'=>'j','Õµ'=>'j','į—°'=>'m','Õø'=>'n','Ī·'=>'nĢ©','ą°‚'=>'o','ಂ'=>'o','ą“‚'=>'o','ą„¦'=>'o','੦'=>'o','૦'=>'o','๐'=>'o','໐'=>'o','Īæ'=>'o','о'=>'o','օ'=>'o','į€'=>'o','ρ'=>'p','р'=>'p','į“©'=>'ᓘ','Õ£'=>'q','Īŗ'=>'Äø','Šŗ'=>'Äø','ᓦ'=>'r','г'=>'r','ѕ'=>'s','Ļ…'=>'u','Õ½'=>'u','ν'=>'v','ѵ'=>'v','įŽ³'=>'w','į—Æ'=>'w','х'=>'x','ᕁ'=>'x','у'=>'y','įŽ©'=>'y','Ó”'=>'Ź’','ჳ'=>'Ź’','Ļ©'=>'ĘØ','ь'=>'ʅ','ы'=>'ʅi','ɑ'=>'α','Õ®'=>'Ī“','į•·'=>'Ī“','Šæ'=>'Ļ€','Éø'=>'φ','ф'=>'φ','Ź™'=>'в','ɜ'=>'Š·','į“'=>'м','ʜ'=>'н','É¢'=>'Ō','į“›'=>'т','į“™'=>'я','ąŖ½'=>'ऽ','ુ'=>'ą„','ą«‚'=>'ą„‚','ą©‹'=>'ą„†','ą©'=>'ą„','ą«'=>'ą„','ą“‰'=>'உ','ą“œ'=>'ஐ','ą“£'=>'ண','ą““'=>'ஓ','ą“æ'=>'ி','ു'=>'ூ','ą²…'=>'ą°…','ಆ'=>'ą°†','ಇ'=>'ą°‡','ą²’'=>'ą°’','ಓ'=>'ఒౕ','ಜ'=>'జ','ą²ž'=>'ą°ž','ą²£'=>'ą°£','ą°„'=>'ą°§Ö¼','ಯ'=>'ą°Æ','ą° '=>'ą°°Ö¼','ą²±'=>'ą°±','ą²²'=>'ą°²','ඌ'=>'ą“Øąµą“Ø','ą®¶'=>'ą“¶','ຈ'=>'จ','ບ'=>'บ','ąŗ›'=>'ąø›','ąŗ'=>'ąø','ąŗž'=>'ąøž','ຟ'=>'ฟ','ąŗ'=>'ąø¢','įŸ”'=>'ąøÆ','įž·'=>'ąø“','įžø'=>'ąøµ','įž¹'=>'ąø¶','įžŗ'=>'ąø·','ąŗø'=>'ąøø','ąŗ¹'=>'ąø¹','į—…'=>'A','į’'=>'J','ᕼ'=>'H','ᐯ'=>'V','į‘­'=>'P','į—·'=>'B','惘'=>'へ','š‘'=>'šŽ‚','š“'=>'šŽ“','š’€ø'=>'šŽš','į…³'=>'äø€','Ē€'=>'äøØ','į…µ'=>'äøØ','įŽŖ'=>'A','į“'=>'B','įŸ'=>'C','į—ž'=>'D','įŽ¬'=>'E','į–“'=>'F','į€'=>'G','įŽ»'=>'H','įŽ«'=>'J','į¦'=>'K','įž'=>'L','įŽ·'=>'M','į¢'=>'P','į–‡'=>'R','į•'=>'S','į™'=>'V','įƒ'=>'Z'); diff --git a/phpBB/install_old/database_update.php b/phpBB/install_old/database_update.php deleted file mode 100644 index 853848d637..0000000000 --- a/phpBB/install_old/database_update.php +++ /dev/null @@ -1,267 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -$update_start_time = time(); - -/** -* @ignore -*/ -define('IN_PHPBB', true); -define('IN_INSTALL', true); -$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; -$phpEx = substr(strrchr(__FILE__, '.'), 1); - -function phpbb_end_update($cache, $config) -{ - $cache->purge(); - - $config->increment('assets_version', 1); - -?> -

-
-
- -
-
-
- - -
- - - -register(); - -$phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx); -extract($phpbb_config_php_file->get_all()); - -if (!defined('PHPBB_INSTALLED') || empty($dbms) || empty($acm_type)) -{ - die("Please read: INSTALL.html before attempting to update."); -} - -// In case $phpbb_adm_relative_path is not set (in case of an update), use the default. -$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/'; -$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path; - -// Include files -require($phpbb_root_path . 'includes/functions.' . $phpEx); -require($phpbb_root_path . 'includes/functions_content.' . $phpEx); - -require($phpbb_root_path . 'includes/constants.' . $phpEx); -require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); - -// Set PHP error handler to ours -set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); - -// Set up container (must be done here because extensions table may not exist) -$phpbb_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); -$phpbb_container = $phpbb_container_builder - ->with_config($phpbb_config_php_file) - ->without_extensions() - ->without_cache() - ->get_container() -; - -// set up caching -/* @var $cache \phpbb\cache\service */ -$cache = $phpbb_container->get('cache'); - -// Instantiate some basic classes -/* @var $phpbb_dispatcher \phpbb\event\dispatcher */ -$phpbb_dispatcher = $phpbb_container->get('dispatcher'); - -/* @var $request \phpbb\request\request_interface */ -$request = $phpbb_container->get('request'); - -/* @var $user \phpbb\user */ -$user = $phpbb_container->get('user'); - -/* @var $auth \phpbb\auth\auth */ -$auth = $phpbb_container->get('auth'); - -/* @var $db \phpbb\db\driver\driver_interface */ -$db = $phpbb_container->get('dbal.conn'); - -/* @var $phpbb_log \phpbb\log\log_interface */ -$phpbb_log = $phpbb_container->get('log'); - -// Grab global variables, re-cache if necessary -/* @var $config \phpbb\config\config */ -$config = $phpbb_container->get('config'); - -if (!isset($config['version_update_from'])) -{ - $config->set('version_update_from', $config['version']); -} - -$orig_version = $config['version_update_from']; - -$user->add_lang(array('common', 'acp/common', 'install', 'migrator')); - -// Add own hook handler, if present. :o -if (file_exists($phpbb_root_path . 'includes/hooks/index.' . $phpEx)) -{ - require($phpbb_root_path . 'includes/hooks/index.' . $phpEx); - $phpbb_hook = new phpbb_hook(array('exit_handler', 'phpbb_user_session_handler', 'append_sid', array('template', 'display'))); - - /* @var $phpbb_hook_finder \phpbb\hook\finder */ - $phpbb_hook_finder = $phpbb_container->get('hook_finder'); - foreach ($phpbb_hook_finder->find() as $hook) - { - @include($phpbb_root_path . 'includes/hooks/' . $hook . '.' . $phpEx); - } -} -else -{ - $phpbb_hook = false; -} - -header('Content-type: text/html; charset=UTF-8'); -?> - - - - - -<?php echo $user->lang['UPDATING_TO_LATEST_STABLE']; ?> - - - - - - -
- - -
-
-
- -
-
- -

lang['UPDATING_TO_LATEST_STABLE']; ?>

- -
- -

lang['DATABASE_TYPE']; ?> :: get_sql_layer(); ?>
- lang['PREVIOUS_VERSION']; ?> ::
- -get('migrator'); - -/** @var \phpbb\filesystem\filesystem_interface $phpbb_filesystem */ -$phpbb_filesystem = $phpbb_container->get('filesystem'); -$migrator->set_output_handler(new \phpbb\db\log_wrapper_migrator_output_handler($user, new \phpbb\db\html_migrator_output_handler($user), $phpbb_root_path . 'store/migrations_' . time() . '.log', $phpbb_filesystem)); - -$migrator->create_migrations_table(); - -/* @var $phpbb_extension_manager \phpbb\extension\manager */ -$phpbb_extension_manager = $phpbb_container->get('ext.manager'); - -$migrations = $phpbb_extension_manager - ->get_finder() - ->core_path('phpbb/db/migration/data/') - ->extension_directory('/migrations') - ->get_classes(); - -$migrator->set_migrations($migrations); - -// What is a safe limit of execution time? Half the max execution time should be safe. -// No more than 15 seconds so the user isn't sitting and waiting for a very long time -$phpbb_ini = new \phpbb\php\ini(); -$safe_time_limit = min(15, ($phpbb_ini->get_int('max_execution_time') / 2)); - -// While we're going to try limit this to half the max execution time, -// we want to try and take additional measures to prevent hitting the -// max execution time (if, say, one migration step takes much longer -// than the max execution time) -@set_time_limit(0); - -while (!$migrator->finished()) -{ - try - { - $migrator->update(); - } - catch (\phpbb\db\migration\exception $e) - { - echo $e->getLocalisedMessage($user); - - phpbb_end_update($cache, $config); - } - - $state = array_merge(array( - 'migration_schema_done' => false, - 'migration_data_done' => false, - ), - $migrator->last_run_migration['state'] - ); - - // Are we approaching the time limit? If so we want to pause the update and continue after refreshing - if ((time() - $update_start_time) >= $safe_time_limit) - { - echo '
' . $user->lang['DATABASE_UPDATE_NOT_COMPLETED'] . '

'; - echo '' . $user->lang['DATABASE_UPDATE_CONTINUE'] . ''; - - phpbb_end_update($cache, $config); - } -} - -if ($orig_version != $config['version']) -{ - $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_UPDATE_DATABASE', false, array($orig_version, $config['version'])); -} - -echo $user->lang['DATABASE_UPDATE_COMPLETE'] . '
'; - -if ($request->variable('type', 0)) -{ - echo $user->lang['INLINE_UPDATE_SUCCESSFUL'] . '

'; - echo '' . $user->lang['CONTINUE_UPDATE_NOW'] . ''; -} -else -{ - echo '

' . $user->lang['UPDATE_FILES_NOTICE'] . '
'; - echo $user->lang['COMPLETE_LOGIN_TO_BOARD']; -} - -$config->delete('version_update_from'); - -phpbb_end_update($cache, $config); diff --git a/phpBB/install_old/index.php b/phpBB/install_old/index.php deleted file mode 100644 index 3559a10971..0000000000 --- a/phpBB/install_old/index.php +++ /dev/null @@ -1,867 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -/**#@+ -* @ignore -*/ -define('IN_PHPBB', true); -define('IN_INSTALL', true); -define('PHPBB_ENVIRONMENT', 'production'); -/**#@-*/ - -$phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH : './../'; -$phpEx = substr(strrchr(__FILE__, '.'), 1); - -if (version_compare(PHP_VERSION, '5.3.9') < 0) -{ - die('You are running an unsupported PHP version. Please upgrade to PHP 5.3.9 or higher before trying to install phpBB 3.1'); -} - -function phpbb_require_updated($path, $optional = false) -{ - global $phpbb_root_path, $table_prefix; - - $new_path = $phpbb_root_path . 'install/update/new/' . $path; - $old_path = $phpbb_root_path . $path; - - if (file_exists($new_path)) - { - require($new_path); - } - else if (!$optional || file_exists($old_path)) - { - require($old_path); - } -} - -function phpbb_include_updated($path, $optional = false) -{ - global $phpbb_root_path; - - $new_path = $phpbb_root_path . 'install/update/new/' . $path; - $old_path = $phpbb_root_path . $path; - - if (file_exists($new_path)) - { - include($new_path); - } - else if (!$optional || file_exists($old_path)) - { - include($old_path); - } -} - -phpbb_require_updated('includes/startup.' . $phpEx); - -// Try to override some limits - maybe it helps some... -@set_time_limit(0); -$mem_limit = @ini_get('memory_limit'); -if (!empty($mem_limit)) -{ - $unit = strtolower(substr($mem_limit, -1, 1)); - $mem_limit = (int) $mem_limit; - - if ($unit == 'k') - { - $mem_limit = floor($mem_limit / 1024); - } - else if ($unit == 'g') - { - $mem_limit *= 1024; - } - else if (is_numeric($unit)) - { - $mem_limit = floor((int) ($mem_limit . $unit) / 1048576); - } - $mem_limit = max(128, $mem_limit) . 'M'; -} -else -{ - $mem_limit = '128M'; -} -@ini_set('memory_limit', $mem_limit); - -// In case $phpbb_adm_relative_path is not set (in case of an update), use the default. -$phpbb_adm_relative_path = (isset($phpbb_adm_relative_path)) ? $phpbb_adm_relative_path : 'adm/'; -$phpbb_admin_path = (defined('PHPBB_ADMIN_PATH')) ? PHPBB_ADMIN_PATH : $phpbb_root_path . $phpbb_adm_relative_path; - -// Include essential scripts -phpbb_require_updated('phpbb/class_loader.' . $phpEx); - -phpbb_require_updated('includes/functions.' . $phpEx); - -phpbb_require_updated('includes/functions_content.' . $phpEx, true); - -phpbb_include_updated('includes/functions_admin.' . $phpEx); -phpbb_include_updated('includes/utf/utf_tools.' . $phpEx); -phpbb_require_updated('includes/functions_install.' . $phpEx); - -// Setup class loader first -$phpbb_class_loader_new = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}install/update/new/phpbb/", $phpEx); -$phpbb_class_loader_new->register(); -$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx); -$phpbb_class_loader->register(); -$phpbb_class_loader_ext = new \phpbb\class_loader('\\', "{$phpbb_root_path}ext/", $phpEx); -$phpbb_class_loader_ext->register(); - -// Set up container -$phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx); -$phpbb_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); -$phpbb_container_builder - ->without_extensions() - ->without_cache() - ->without_compiled_container() -; - -$other_config_path = $phpbb_root_path . 'install/update/new/config/'; -$config_path = file_exists($other_config_path . 'services.yml') ? $other_config_path : $phpbb_root_path . 'config/'; -$phpbb_container_builder->with_config_path($config_path); - -$phpbb_container_builder->with_custom_parameters(array( - 'core.root_path' => $phpbb_root_path, - 'core.adm_relative_path' => $phpbb_adm_relative_path, - 'core.php_ext' => $phpEx, - 'core.table_prefix' => '', - 'cache.driver.class' => 'phpbb\cache\driver\file', -)); - -$phpbb_container = $phpbb_container_builder->get_container(); -$phpbb_container->register('dbal.conn.driver')->setSynthetic(true); -$phpbb_container->register('template.twig.environment')->setSynthetic(true); -$phpbb_container->register('language.loader')->setSynthetic(true); -$phpbb_container->compile(); - -$phpbb_class_loader->set_cache($phpbb_container->get('cache.driver')); -$phpbb_class_loader_ext->set_cache($phpbb_container->get('cache.driver')); - -/* @var $phpbb_dispatcher \phpbb\event\dispatcher */ -$phpbb_dispatcher = $phpbb_container->get('dispatcher'); - -/* @var $request \phpbb\request\request_interface */ -$request = $phpbb_container->get('request'); - -// Try and load an appropriate language if required -$language = basename($request->variable('language', '')); - -if ($request->header('Accept-Language') && !$language) -{ - $accept_lang_ary = explode(',', strtolower($request->header('Accept-Language'))); - foreach ($accept_lang_ary as $accept_lang) - { - // Set correct format ... guess full xx_yy form - $accept_lang = substr($accept_lang, 0, 2) . '_' . substr($accept_lang, 3, 2); - - if (file_exists($phpbb_root_path . 'language/' . $accept_lang) && is_dir($phpbb_root_path . 'language/' . $accept_lang)) - { - $language = $accept_lang; - break; - } - else - { - // No match on xx_yy so try xx - $accept_lang = substr($accept_lang, 0, 2); - if (file_exists($phpbb_root_path . 'language/' . $accept_lang) && is_dir($phpbb_root_path . 'language/' . $accept_lang)) - { - $language = $accept_lang; - break; - } - } - } -} - -// No appropriate language found ... so let's use the first one in the language -// dir, this may or may not be English -if (!$language) -{ - $dir = @opendir($phpbb_root_path . 'language'); - - if (!$dir) - { - die('Unable to access the language directory'); - exit; - } - - while (($file = readdir($dir)) !== false) - { - $path = $phpbb_root_path . 'language/' . $file; - - if (!is_file($path) && !is_link($path) && file_exists($path . '/iso.txt')) - { - $language = $file; - break; - } - } - closedir($dir); -} - -if (!file_exists($phpbb_root_path . 'language/' . $language) || !is_dir($phpbb_root_path . 'language/' . $language)) -{ - die('No language found!'); -} - -// And finally, load the relevant language files -$load_lang_files = array('common', 'acp/common', 'acp/board', 'install', 'posting'); -$new_path = $phpbb_root_path . 'install/update/new/language/' . $language . '/'; -$old_path = $phpbb_root_path . 'language/' . $language . '/'; - -// NOTE: we can not use "phpbb_include_updated" as the files uses vars which would be required -// to be global while loading. -foreach ($load_lang_files as $lang_file) -{ - if (file_exists($new_path . $lang_file . '.' . $phpEx)) - { - include($new_path . $lang_file . '.' . $phpEx); - } - else - { - include($old_path . $lang_file . '.' . $phpEx); - } -} - -// usually we would need every single constant here - and it would be consistent. For 3.0.x, use a dirty hack... :( - -// Define needed constants -define('CHMOD_ALL', 7); -define('CHMOD_READ', 4); -define('CHMOD_WRITE', 2); -define('CHMOD_EXECUTE', 1); - -$mode = $request->variable('mode', 'overview'); -$sub = $request->variable('sub', ''); - -// Set PHP error handler to ours -set_error_handler(defined('PHPBB_MSG_HANDLER') ? PHPBB_MSG_HANDLER : 'msg_handler'); - -$lang_service = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)); -$user = new \phpbb\user($lang_service, '\phpbb\datetime'); -$auth = new \phpbb\auth\auth(); - -// Add own hook handler, if present. :o -if (file_exists($phpbb_root_path . 'includes/hooks/index.' . $phpEx)) -{ - require($phpbb_root_path . 'includes/hooks/index.' . $phpEx); - $phpbb_hook = new phpbb_hook(array('exit_handler', 'phpbb_user_session_handler', 'append_sid', array('template', 'display'))); - - /* @var $phpbb_hook_finder \phpbb\hook\finder */ - $phpbb_hook_finder = $phpbb_container->get('hook_finder'); - foreach ($phpbb_hook_finder->find() as $hook) - { - @include($phpbb_root_path . 'includes/hooks/' . $hook . '.' . $phpEx); - } -} -else -{ - $phpbb_hook = false; -} - -// Set some standard variables we want to force -$config = new \phpbb\config\config(array( - 'load_tplcompile' => '1' -)); - -/* @var $symfony_request \phpbb\symfony_request */ -$symfony_request = $phpbb_container->get('symfony_request'); - -/* @var $phpbb_filesystem \phpbb\filesystem\filesystem_interface */ -$phpbb_filesystem = $phpbb_container->get('filesystem'); - -/* @var $phpbb_path_helper \phpbb\path_helper */ -$phpbb_path_helper = $phpbb_container->get('path_helper'); -$cache_path = $phpbb_root_path . 'cache/'; - -$twig_environment = new \phpbb\template\twig\environment( - $config, - $phpbb_filesystem, - $phpbb_path_helper, - $phpbb_container, - $cache_path, - null, - $phpbb_container->get('template.twig.loader') -); - -$language_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx); -$phpbb_container->set('template.twig.environment', $twig_environment); -$phpbb_container->set('language.loader', $language_loader); -$twig_context = new \phpbb\template\context(); -$template = new \phpbb\template\twig\twig( - $phpbb_path_helper, - $config, - $twig_context, - $twig_environment, - $cache_path, - $user, - array($phpbb_container->get('template.twig.extensions.phpbb')) -); - -$paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style'); -$paths = array_filter($paths, 'is_dir'); -$template->set_custom_style(array( - array( - 'name' => 'adm', - 'ext_path' => 'adm/style/', - ), -), $paths); - -$path = array_shift($paths); - -$template->assign_var('T_ASSETS_PATH', $path . '/../../assets'); -$template->assign_var('T_TEMPLATE_PATH', $path); - -$install = new module(); - -$install->create('install', "index.$phpEx", $mode, $sub); -$install->load(); - -// Generate the page -$install->page_header(); -$install->generate_navigation(); - -$template->set_filenames(array( - 'body' => $install->get_tpl_name()) -); - -$install->page_footer(); - -class module -{ - var $id = 0; - var $type = 'install'; - var $module_ary = array(); - var $filename; - var $module_url = ''; - var $tpl_name = ''; - var $mode; - var $sub; - - /** - * Private methods, should not be overwritten - */ - function create($module_type, $module_url, $selected_mod = false, $selected_submod = false) - { - global $db, $config, $phpEx, $phpbb_root_path; - - $module = array(); - - // Grab module information using Bart's "neat-o-module" system (tm) - $dir = @opendir('.'); - - if (!$dir) - { - $this->error('Unable to access the installation directory', __LINE__, __FILE__); - } - - $setmodules = 1; - while (($file = readdir($dir)) !== false) - { - if (preg_match('#^install_(.*?)\.' . $phpEx . '$#', $file)) - { - include($file); - } - } - closedir($dir); - - unset($setmodules); - - if (!sizeof($module)) - { - $this->error('No installation modules found', __LINE__, __FILE__); - } - - // Order to use and count further if modules get assigned to the same position or not having an order - $max_module_order = 1000; - - foreach ($module as $row) - { - // Module order not specified or module already assigned at this position? - if (!isset($row['module_order']) || isset($this->module_ary[$row['module_order']])) - { - $row['module_order'] = $max_module_order; - $max_module_order++; - } - - $this->module_ary[$row['module_order']]['name'] = $row['module_title']; - $this->module_ary[$row['module_order']]['filename'] = $row['module_filename']; - $this->module_ary[$row['module_order']]['subs'] = $row['module_subs']; - $this->module_ary[$row['module_order']]['stages'] = $row['module_stages']; - - if (strtolower($selected_mod) == strtolower($row['module_title'])) - { - $this->id = (int) $row['module_order']; - $this->filename = (string) $row['module_filename']; - $this->module_url = (string) $module_url; - $this->mode = (string) $selected_mod; - // Check that the sub-mode specified is valid or set a default if not - if (is_array($row['module_subs'])) - { - $this->sub = strtolower((in_array(strtoupper($selected_submod), $row['module_subs'])) ? $selected_submod : $row['module_subs'][0]); - } - else if (is_array($row['module_stages'])) - { - $this->sub = strtolower((in_array(strtoupper($selected_submod), $row['module_stages'])) ? $selected_submod : $row['module_stages'][0]); - } - else - { - $this->sub = ''; - } - } - } // END foreach - } // END create - - /** - * Load and run the relevant module if applicable - */ - function load($mode = false, $run = true) - { - global $phpbb_root_path, $phpEx; - - if ($run) - { - if (!empty($mode)) - { - $this->mode = $mode; - } - - $module = $this->filename; - if (!class_exists($module)) - { - $this->error('Module "' . htmlspecialchars($module) . '" not accessible.', __LINE__, __FILE__); - } - $this->module = new $module($this); - - if (method_exists($this->module, 'main')) - { - $this->module->main($this->mode, $this->sub); - } - } - } - - /** - * Output the standard page header - */ - function page_header() - { - if (defined('HEADER_INC')) - { - return; - } - - define('HEADER_INC', true); - global $template, $lang, $stage, $phpbb_admin_path, $path; - - $template->assign_vars(array( - 'L_CHANGE' => $lang['CHANGE'], - 'L_COLON' => $lang['COLON'], - 'L_INSTALL_PANEL' => $lang['INSTALL_PANEL'], - 'L_SELECT_LANG' => $lang['SELECT_LANG'], - 'L_SKIP' => $lang['SKIP'], - 'PAGE_TITLE' => $this->get_page_title(), - 'T_IMAGE_PATH' => htmlspecialchars($phpbb_admin_path) . 'images/', - 'T_JQUERY_LINK' => $path . '/../../assets/javascript/jquery.min.js', - - 'S_CONTENT_DIRECTION' => $lang['DIRECTION'], - 'S_CONTENT_FLOW_BEGIN' => ($lang['DIRECTION'] == 'ltr') ? 'left' : 'right', - 'S_CONTENT_FLOW_END' => ($lang['DIRECTION'] == 'ltr') ? 'right' : 'left', - 'S_CONTENT_ENCODING' => 'UTF-8', - - 'S_USER_LANG' => $lang['USER_LANG'], - ) - ); - - header('Content-type: text/html; charset=UTF-8'); - header('Cache-Control: private, no-cache="set-cookie"'); - header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT'); - - return; - } - - /** - * Output the standard page footer - */ - function page_footer() - { - global $db, $template; - - $template->display('body'); - - // Close our DB connection. - if (!empty($db) && is_object($db)) - { - $db->sql_close(); - } - - if (function_exists('exit_handler')) - { - exit_handler(); - } - } - - /** - * Returns desired template name - */ - function get_tpl_name() - { - return $this->module->tpl_name . '.html'; - } - - /** - * Returns the desired page title - */ - function get_page_title() - { - global $lang; - - if (!isset($this->module->page_title)) - { - return ''; - } - - return (isset($lang[$this->module->page_title])) ? $lang[$this->module->page_title] : $this->module->page_title; - } - - /** - * Generate an HTTP/1.1 header to redirect the user to another page - * This is used during the installation when we do not have a database available to call the normal redirect function - * @param string $page The page to redirect to relative to the installer root path - */ - function redirect($page) - { - global $request; - - // HTTP_HOST is having the correct browser url in most cases... - $server_name = strtolower(htmlspecialchars_decode($request->header('Host', $request->server('SERVER_NAME')))); - $server_port = $request->server('SERVER_PORT', 0); - $secure = $request->is_secure() ? 1 : 0; - - $script_name = htmlspecialchars_decode($request->server('PHP_SELF')); - if (!$script_name) - { - $script_name = htmlspecialchars_decode($request->server('REQUEST_URI')); - } - - // Replace backslashes and doubled slashes (could happen on some proxy setups) - $script_name = str_replace(array('\\', '//'), '/', $script_name); - $script_path = trim(dirname($script_name)); - - $url = (($secure) ? 'https://' : 'http://') . $server_name; - - if ($server_port && (($secure && $server_port <> 443) || (!$secure && $server_port <> 80))) - { - // HTTP HOST can carry a port number... - if (strpos($server_name, ':') === false) - { - $url .= ':' . $server_port; - } - } - - $url .= $script_path . '/' . $page; - header('Location: ' . $url); - exit; - } - - /** - * Generate the navigation tabs - */ - function generate_navigation() - { - global $lang, $template, $phpEx, $language; - - if (is_array($this->module_ary)) - { - @ksort($this->module_ary); - foreach ($this->module_ary as $cat_ary) - { - $cat = $cat_ary['name']; - $l_cat = (!empty($lang['CAT_' . $cat])) ? $lang['CAT_' . $cat] : preg_replace('#_#', ' ', $cat); - $cat = strtolower($cat); - $url = $this->module_url . "?mode=$cat&language=$language"; - - if ($this->mode == $cat) - { - $template->assign_block_vars('t_block1', array( - 'L_TITLE' => $l_cat, - 'S_SELECTED' => true, - 'U_TITLE' => $url, - )); - - if (is_array($this->module_ary[$this->id]['subs'])) - { - $subs = $this->module_ary[$this->id]['subs']; - foreach ($subs as $option) - { - $l_option = (!empty($lang['SUB_' . $option])) ? $lang['SUB_' . $option] : preg_replace('#_#', ' ', $option); - $option = strtolower($option); - $url = $this->module_url . '?mode=' . $this->mode . "&sub=$option&language=$language"; - - $template->assign_block_vars('l_block1', array( - 'L_TITLE' => $l_option, - 'S_SELECTED' => ($this->sub == $option), - 'U_TITLE' => $url, - )); - } - } - - if (is_array($this->module_ary[$this->id]['stages'])) - { - $subs = $this->module_ary[$this->id]['stages']; - $matched = false; - foreach ($subs as $option) - { - $l_option = (!empty($lang['STAGE_' . $option])) ? $lang['STAGE_' . $option] : preg_replace('#_#', ' ', $option); - $option = strtolower($option); - $matched = ($this->sub == $option) ? true : $matched; - - $template->assign_block_vars('l_block2', array( - 'L_TITLE' => $l_option, - 'S_SELECTED' => ($this->sub == $option), - 'S_COMPLETE' => !$matched, - )); - } - } - } - else - { - $template->assign_block_vars('t_block1', array( - 'L_TITLE' => $l_cat, - 'S_SELECTED' => false, - 'U_TITLE' => $url, - )); - } - } - } - } - - /** - * Output an error message - * If skip is true, return and continue execution, else exit - */ - function error($error, $line, $file, $skip = false) - { - global $lang, $db, $template, $phpbb_admin_path; - - if ($skip) - { - $template->assign_block_vars('checks', array( - 'S_LEGEND' => true, - 'LEGEND' => $lang['INST_ERR'], - )); - - $template->assign_block_vars('checks', array( - 'TITLE' => basename($file) . ' [ ' . $line . ' ]', - 'RESULT' => '' . $error . '', - )); - - return; - } - - echo ''; - echo ''; - echo ''; - echo ''; - echo '' . $lang['INST_ERR_FATAL'] . ''; - echo ''; - echo ''; - echo ''; - echo '
'; - echo ' '; - echo '
'; - echo '
'; - echo '
'; - echo ' '; - echo '
'; - echo '

' . $lang['INST_ERR_FATAL'] . '

'; - echo '

' . $lang['INST_ERR_FATAL'] . "

\n"; - echo '

' . basename($file) . ' [ ' . $line . " ]

\n"; - echo '

' . $error . "

\n"; - echo '
'; - echo ' '; - echo '
'; - echo '
'; - echo '
'; - echo ' '; - echo '
'; - echo ''; - echo ''; - - if (!empty($db) && is_object($db)) - { - $db->sql_close(); - } - - exit_handler(); - } - - /** - * Output an error message for a database related problem - * If skip is true, return and continue execution, else exit - */ - function db_error($error, $sql, $line, $file, $skip = false) - { - global $lang, $db, $template; - - if ($skip) - { - $template->assign_block_vars('checks', array( - 'S_LEGEND' => true, - 'LEGEND' => $lang['INST_ERR_FATAL'], - )); - - $template->assign_block_vars('checks', array( - 'TITLE' => basename($file) . ' [ ' . $line . ' ]', - 'RESULT' => '' . $error . '
» SQL:' . $sql, - )); - - return; - } - - $template->set_filenames(array( - 'body' => 'install_error.html') - ); - $this->page_header(); - $this->generate_navigation(); - - $template->assign_vars(array( - 'MESSAGE_TITLE' => $lang['INST_ERR_FATAL_DB'], - 'MESSAGE_TEXT' => '

' . basename($file) . ' [ ' . $line . ' ]

SQL : ' . $sql . '

' . $error . '

', - )); - - // Rollback if in transaction - if ($db->get_transaction()) - { - $db->sql_transaction('rollback'); - } - - $this->page_footer(); - } - - /** - * Generate the relevant HTML for an input field and the associated label and explanatory text - */ - function input_field($name, $type, $value = '', $options = '') - { - global $lang; - $tpl_type = explode(':', $type); - $tpl = ''; - - switch ($tpl_type[0]) - { - case 'text': - case 'password': - // HTML5 text-like input types - case 'color': - case 'date': - case 'time': - case 'datetime': - case 'datetime-local': - case 'email': - case 'month': - case 'number': - case 'range': - case 'search': - case 'tel': - case 'url': - case 'week': - - $size = (int) $tpl_type[1]; - $maxlength = (int) $tpl_type[2]; - $autocomplete = (isset($options['autocomplete']) && $options['autocomplete'] == 'off') ? ' autocomplete="off"' : ''; - - $tpl = ''; - break; - - case 'textarea': - $rows = (int) $tpl_type[1]; - $cols = (int) $tpl_type[2]; - - $tpl = ''; - break; - - case 'radio': - $key_yes = ($value) ? ' checked="checked" id="' . $name . '"' : ''; - $key_no = (!$value) ? ' checked="checked" id="' . $name . '"' : ''; - - $tpl_type_cond = explode('_', $tpl_type[1]); - $type_no = ($tpl_type_cond[0] == 'disabled' || $tpl_type_cond[0] == 'enabled') ? false : true; - - $tpl_no = ''; - $tpl_yes = ''; - - $tpl = ($tpl_type_cond[0] == 'yes' || $tpl_type_cond[0] == 'enabled') ? $tpl_yes . '  ' . $tpl_no : $tpl_no . '  ' . $tpl_yes; - break; - - case 'select': - // @codingStandardsIgnoreStart - eval('$s_options = ' . str_replace('{VALUE}', $value, $options) . ';'); - // @codingStandardsIgnoreEnd - $tpl = ''; - break; - - case 'custom': - // @codingStandardsIgnoreStart - eval('$tpl = ' . str_replace('{VALUE}', $value, $options) . ';'); - // @codingStandardsIgnoreEnd - break; - - default: - break; - } - - return $tpl; - } - - /** - * Generate the drop down of available language packs - */ - function inst_language_select($default = '') - { - global $phpbb_root_path, $phpEx; - - $dir = @opendir($phpbb_root_path . 'language'); - - if (!$dir) - { - $this->error('Unable to access the language directory', __LINE__, __FILE__); - } - - while ($file = readdir($dir)) - { - $path = $phpbb_root_path . 'language/' . $file; - - if ($file == '.' || $file == '..' || is_link($path) || is_file($path) || $file == 'CVS') - { - continue; - } - - if (file_exists($path . '/iso.txt')) - { - list($displayname, $localname) = @file($path . '/iso.txt'); - $lang[$localname] = $file; - } - } - closedir($dir); - - @asort($lang); - @reset($lang); - - $user_select = ''; - foreach ($lang as $displayname => $filename) - { - $selected = (strtolower($default) == strtolower($filename)) ? ' selected="selected"' : ''; - $user_select .= ''; - } - - return $user_select; - } -} diff --git a/phpBB/install_old/install_convert.php b/phpBB/install_old/install_convert.php deleted file mode 100644 index d72ee1a633..0000000000 --- a/phpBB/install_old/install_convert.php +++ /dev/null @@ -1,2153 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -/** -*/ - -if (!defined('IN_INSTALL')) -{ - // Someone has tried to access the file direct. This is not a good idea, so exit - exit; -} - -if (!empty($setmodules)) -{ - $module[] = array( - 'module_type' => 'install', - 'module_title' => 'CONVERT', - 'module_filename' => substr(basename(__FILE__), 0, -strlen($phpEx)-1), - 'module_order' => 20, - 'module_subs' => '', - 'module_stages' => array('INTRO', 'SETTINGS', 'IN_PROGRESS', 'FINAL'), - 'module_reqs' => '' - ); -} - -/** -* Class holding all convertor-specific details. -*/ -class convert -{ - var $options = array(); - - var $convertor_tag = ''; - var $src_dbms = ''; - var $src_dbhost = ''; - var $src_dbport = ''; - var $src_dbuser = ''; - var $src_dbpasswd = ''; - var $src_dbname = ''; - var $src_table_prefix = ''; - - var $convertor_data = array(); - var $tables = array(); - var $config_schema = array(); - var $convertor = array(); - var $src_truncate_statement = 'DELETE FROM '; - var $truncate_statement = 'DELETE FROM '; - - var $fulltext_search; - - // Batch size, can be adjusted by the conversion file - // For big boards a value of 6000 seems to be optimal - var $batch_size = 2000; - // Number of rows to be inserted at once (extended insert) if supported - // For installations having enough memory a value of 60 may be good. - var $num_wait_rows = 20; - - // Mysqls internal recoding engine messing up with our (better) functions? We at least support more encodings than mysql so should use it in favor. - var $mysql_convert = false; - - var $p_master; - - function convert(&$p_master) - { - $this->p_master = &$p_master; - } -} - -/** -* Convert class for conversions -*/ -class install_convert extends module -{ - /** @var array */ - protected $lang; - - /** @var string */ - protected $language; - - /** @var \phpbb\template\template */ - protected $template; - - /** @var string */ - protected $phpbb_root_path; - - /** @var string */ - protected $php_ext; - - /** @var \phpbb\filesystem\filesystem_interface */ - protected $filesystem; - - /** - * Variables used while converting, they are accessible from the global variable $convert - */ - function install_convert(&$p_master) - { - $this->p_master = &$p_master; - } - - function main($mode, $sub) - { - global $lang, $template, $phpbb_root_path, $phpEx, $cache, $config, $language, $table_prefix; - global $convert, $request, $phpbb_container, $phpbb_config_php_file; - - $this->tpl_name = 'install_convert'; - $this->mode = $mode; - $this->lang = $lang; - $this->language = $language; - $this->template = $template; - $this->phpbb_root_path = $phpbb_root_path; - $this->php_ext = $phpEx; - $this->filesystem = new \phpbb\filesystem\filesystem(); - - if (!$this->check_phpbb_installed()) - { - return; - } - - $convert = new convert($this->p_master); - - // Enable super globals to prevent issues with the new \phpbb\request\request object - $request->enable_super_globals(); - // Create a normal container now - $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); - $phpbb_container = $phpbb_container_builder->with_config($phpbb_config_php_file)->get_container(); - - // Create cache - /* @var $cache \phpbb\cache\service */ - $cache = $phpbb_container->get('cache'); - - switch ($sub) - { - case 'intro': - 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); - - // Detect if there is already a conversion in progress at this point and offer to resume - // It's quite possible that the user will get disconnected during a large conversion so they need to be able to resume it - $new_conversion = $request->variable('new_conv', 0); - - if ($new_conversion) - { - $config['convert_progress'] = ''; - $config['convert_db_server'] = ''; - $config['convert_db_user'] = ''; - $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " - WHERE config_name = 'convert_progress' - OR config_name = 'convert_db_server' - OR config_name = 'convert_db_user'" - ); - } - - // Let's see if there is a conversion in the works... - $options = array(); - if (!empty($config['convert_progress']) && !empty($config['convert_db_server']) && !empty($config['convert_db_user']) && !empty($config['convert_options'])) - { - $options = unserialize($config['convert_progress']); - $options = array_merge($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($options) && !empty($options['tag']) && - isset($options['dbms']) && - isset($options['dbhost']) && - isset($options['dbport']) && - isset($options['dbuser']) && - isset($options['dbpasswd']) && - isset($options['dbname']) && - isset($options['table_prefix'])) - { - $this->page_title = $lang['CONTINUE_CONVERT']; - - $template->assign_vars(array( - 'TITLE' => $lang['CONTINUE_CONVERT'], - 'BODY' => $lang['CONTINUE_CONVERT_BODY'], - 'L_NEW' => $lang['CONVERT_NEW_CONVERSION'], - 'L_CONTINUE' => $lang['CONTINUE_OLD_CONVERSION'], - 'S_CONTINUE' => true, - - 'U_NEW_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=intro&new_conv=1&language=$language", - 'U_CONTINUE_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$options['tag']}{$options['step']}&language=$language", - )); - - return; - } - - $this->list_convertors($sub); - - break; - - case 'settings': - $this->get_convert_settings($sub); - break; - - case 'in_progress': - $this->convert_data($sub); - break; - - case 'final': - $this->page_title = $lang['CONVERT_COMPLETE']; - - $template->assign_vars(array( - 'TITLE' => $lang['CONVERT_COMPLETE'], - 'BODY' => $lang['CONVERT_COMPLETE_EXPLAIN'], - )); - - // If we reached this step (conversion completed) we want to purge the cache and log the user out. - // This is for making sure the session get not screwed due to the 3.0.x users table being completely new. - $cache->purge(); - - 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); - - $sql = 'SELECT config_value - FROM ' . CONFIG_TABLE . ' - WHERE config_name = \'search_type\''; - $result = $db->sql_query($sql); - - if ($db->sql_fetchfield('config_value') != 'fulltext_mysql') - { - $template->assign_vars(array( - 'S_ERROR_BOX' => true, - 'ERROR_TITLE' => $lang['SEARCH_INDEX_UNCONVERTED'], - 'ERROR_MSG' => $lang['SEARCH_INDEX_UNCONVERTED_EXPLAIN'], - )); - } - - switch ($db->get_sql_layer()) - { - case 'sqlite': - case 'sqlite3': - $db->sql_query('DELETE FROM ' . SESSIONS_KEYS_TABLE); - $db->sql_query('DELETE FROM ' . SESSIONS_TABLE); - break; - - default: - $db->sql_query('TRUNCATE TABLE ' . SESSIONS_KEYS_TABLE); - $db->sql_query('TRUNCATE TABLE ' . SESSIONS_TABLE); - break; - } - - break; - } - } - - /** - * Check whether phpBB is installed. - * Assigns error template vars if not installed. - * - * @return bool Returns true if phpBB is installed. - */ - public function check_phpbb_installed() - { - if (phpbb_check_installation_exists($this->phpbb_root_path, $this->php_ext)) - { - return true; - } - - $this->page_title = 'BOARD_NOT_INSTALLED'; - $install_url = append_sid($this->phpbb_root_path . 'install/index.' . $this->php_ext, 'mode=install&language=' . $this->language); - - $this->template->assign_vars(array( - 'S_NOT_INSTALLED' => true, - 'BODY' => sprintf($this->lang['BOARD_NOT_INSTALLED_EXPLAIN'], $install_url), - )); - - return false; - } - - /** - * Generate a list of all available conversion modules - */ - function list_convertors($sub) - { - global $lang, $language, $template, $phpbb_root_path, $phpEx; - - $this->page_title = $lang['SUB_INTRO']; - - $template->assign_vars(array( - 'TITLE' => $lang['CONVERT_INTRO'], - 'BODY' => $lang['CONVERT_INTRO_BODY'], - - 'L_AUTHOR' => $lang['AUTHOR'], - 'L_AVAILABLE_CONVERTORS' => $lang['AVAILABLE_CONVERTORS'], - 'L_CONVERT' => $lang['CONVERT'], - 'L_NO_CONVERTORS' => $lang['NO_CONVERTORS'], - 'L_OPTIONS' => $lang['CONVERT_OPTIONS'], - 'L_SOFTWARE' => $lang['SOFTWARE'], - 'L_VERSION' => $lang['VERSION'], - - 'S_LIST' => true, - )); - - $convertors = $sort = array(); - $get_info = true; - - $handle = @opendir('./convertors/'); - - if (!$handle) - { - $this->error('Unable to access the convertors directory', __LINE__, __FILE__); - } - - while ($entry = readdir($handle)) - { - if (preg_match('/^convert_([a-z0-9_]+).' . $phpEx . '$/i', $entry, $m)) - { - include('./convertors/' . $entry); - if (isset($convertor_data)) - { - $sort[strtolower($convertor_data['forum_name'])] = sizeof($convertors); - - $convertors[] = array( - 'tag' => $m[1], - 'forum_name' => $convertor_data['forum_name'], - 'version' => $convertor_data['version'], - 'dbms' => $convertor_data['dbms'], - 'dbhost' => $convertor_data['dbhost'], - 'dbport' => $convertor_data['dbport'], - 'dbuser' => $convertor_data['dbuser'], - 'dbpasswd' => $convertor_data['dbpasswd'], - 'dbname' => $convertor_data['dbname'], - 'table_prefix' => $convertor_data['table_prefix'], - 'author' => $convertor_data['author'] - ); - } - unset($convertor_data); - } - } - closedir($handle); - - @ksort($sort); - - foreach ($sort as $void => $index) - { - $template->assign_block_vars('convertors', array( - 'AUTHOR' => $convertors[$index]['author'], - 'SOFTWARE' => $convertors[$index]['forum_name'], - 'VERSION' => $convertors[$index]['version'], - - 'U_CONVERT' => $this->p_master->module_url . "?mode={$this->mode}&language=$language&sub=settings&tag=" . $convertors[$index]['tag'], - )); - } - } - - /** - */ - function get_convert_settings($sub) - { - global $lang, $language, $template, $db, $phpbb_root_path, $phpEx, $config, $cache, $phpbb_config_php_file; - - 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); - - $this->page_title = $lang['STAGE_SETTINGS']; - - // 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); - - $convertor_tag = $request->variable('tag', ''); - - if (empty($convertor_tag)) - { - $this->p_master->error($lang['NO_CONVERT_SPECIFIED'], __LINE__, __FILE__); - } - $get_info = true; - - // check security implications of direct inclusion - $convertor_tag = basename($convertor_tag); - if (!file_exists('./convertors/convert_' . $convertor_tag . '.' . $phpEx)) - { - $this->p_master->error($lang['CONVERT_NOT_EXIST'], __LINE__, __FILE__); - } - - include('./convertors/convert_' . $convertor_tag . '.' . $phpEx); - - // The test_file is a file that should be present in the location of the old board. - if (!isset($test_file)) - { - $this->p_master->error($lang['DEV_NO_TEST_FILE'], __LINE__, __FILE__); - } - - $submit = (isset($_POST['submit'])) ? true : false; - - $src_dbms = $request->variable('src_dbms', $convertor_data['dbms']); - $src_dbhost = $request->variable('src_dbhost', $convertor_data['dbhost']); - $src_dbport = $request->variable('src_dbport', $convertor_data['dbport']); - $src_dbuser = $request->variable('src_dbuser', $convertor_data['dbuser']); - $src_dbpasswd = $request->variable('src_dbpasswd', $convertor_data['dbpasswd']); - $src_dbname = $request->variable('src_dbname', $convertor_data['dbname']); - $src_table_prefix = $request->variable('src_table_prefix', $convertor_data['table_prefix']); - $forum_path = $request->variable('forum_path', $convertor_data['forum_path']); - $refresh = $request->variable('refresh', 1); - - // Default URL of the old board - // @todo Are we going to use this for attempting to convert URL references in posts, or should we remove it? - // -> We should convert old urls to the new relative urls format - // $src_url = $request->variable('src_url', 'Not in use at the moment'); - - // strip trailing slash from old forum path - $forum_path = (strlen($forum_path) && $forum_path[strlen($forum_path) - 1] == '/') ? substr($forum_path, 0, -1) : $forum_path; - - $error = array(); - if ($submit) - { - if (!@file_exists('./../' . $forum_path . '/' . $test_file)) - { - $error[] = sprintf($lang['COULD_NOT_FIND_PATH'], $forum_path); - } - - $connect_test = false; - $available_dbms = get_available_dbms(false, true, true); - - if (!isset($available_dbms[$src_dbms]) || !$available_dbms[$src_dbms]['AVAILABLE']) - { - $error[] = $lang['INST_ERR_NO_DB']; - $connect_test = false; - } - else - { - $connect_test = connect_check_db(true, $error, $available_dbms[$src_dbms], $src_table_prefix, $src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd), $src_dbname, $src_dbport, true, ($src_dbms == $dbms) ? false : true, false); - } - - // The forum prefix of the old and the new forum can only be the same if two different databases are used. - if ($src_table_prefix == $table_prefix && $src_dbms == $dbms && $src_dbhost == $dbhost && $src_dbport == $dbport && $src_dbname == $dbname) - { - $error[] = sprintf($lang['TABLE_PREFIX_SAME'], $src_table_prefix); - } - - $src_dbms = $phpbb_config_php_file->convert_30_dbms_to_31($src_dbms); - - // Check table prefix - if (!sizeof($error)) - { - // initiate database connection to old db if old and new db differ - global $src_db, $same_db; - $src_db = $same_db = false; - - if ($src_dbms != $dbms || $src_dbhost != $dbhost || $src_dbport != $dbport || $src_dbname != $dbname || $src_dbuser != $dbuser) - { - $src_db = new $src_dbms(); - $src_db->sql_connect($src_dbhost, $src_dbuser, htmlspecialchars_decode($src_dbpasswd), $src_dbname, $src_dbport, false, true); - $same_db = false; - } - else - { - $src_db = $db; - $same_db = true; - } - - $src_db->sql_return_on_error(true); - $db->sql_return_on_error(true); - - // Try to select one row from the first table to see if the prefix is OK - $result = $src_db->sql_query_limit('SELECT * FROM ' . $src_table_prefix . $tables[0], 1); - - if (!$result) - { - $prefixes = array(); - - $db_tools_factory = new \phpbb\db\tools\factory(); - $db_tools = $db_tools_factory->get($src_db); - $tables_existing = $db_tools->sql_list_tables(); - $tables_existing = array_map('strtolower', $tables_existing); - foreach ($tables_existing as $table_name) - { - compare_table($tables, $table_name, $prefixes); - } - unset($tables_existing); - - foreach ($prefixes as $prefix => $count) - { - if ($count >= sizeof($tables)) - { - $possible_prefix = $prefix; - break; - } - } - - $msg = ''; - if (!empty($convertor_data['table_prefix'])) - { - $msg .= sprintf($lang['DEFAULT_PREFIX_IS'], $convertor_data['forum_name'], $convertor_data['table_prefix']); - } - - if (!empty($possible_prefix)) - { - $msg .= '
'; - $msg .= ($possible_prefix == '*') ? $lang['BLANK_PREFIX_FOUND'] : sprintf($lang['PREFIX_FOUND'], $possible_prefix); - $src_table_prefix = ($possible_prefix == '*') ? '' : $possible_prefix; - } - - $error[] = $msg; - } - $src_db->sql_freeresult($result); - $src_db->sql_return_on_error(false); - } - - if (!sizeof($error)) - { - // Save convertor Status - $config->set('convert_progress', serialize(array( - 'step' => '', - 'table_prefix' => $src_table_prefix, - 'tag' => $convertor_tag, - )), false); - $config->set('convert_db_server', serialize(array( - 'dbms' => $src_dbms, - 'dbhost' => $src_dbhost, - 'dbport' => $src_dbport, - 'dbname' => $src_dbname, - )), false); - $config->set('convert_db_user', serialize(array( - 'dbuser' => $src_dbuser, - 'dbpasswd' => $src_dbpasswd, - )), false); - - // Save options - $config->set('convert_options', serialize(array( - 'forum_path' => './../' . $forum_path, - 'refresh' => $refresh - )), false); - - $template->assign_block_vars('checks', array( - 'TITLE' => $lang['VERIFY_OPTIONS'], - 'RESULT' => $lang['CONVERT_SETTINGS_VERIFIED'], - )); - - $template->assign_vars(array( - 'L_SUBMIT' => $lang['BEGIN_CONVERT'], -// 'S_HIDDEN' => $s_hidden_fields, - 'U_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag=$convertor_tag&language=$language", - )); - - return; - } - else - { - $template->assign_block_vars('checks', array( - 'TITLE' => $lang['VERIFY_OPTIONS'], - 'RESULT' => '' . implode('
', $error) . '
', - )); - } - } // end submit - - foreach ($this->convert_options as $config_key => $vars) - { - if (!is_array($vars) && strpos($config_key, 'legend') === false) - { - continue; - } - - if (strpos($config_key, 'legend') !== false) - { - $template->assign_block_vars('options', array( - 'S_LEGEND' => true, - 'LEGEND' => $lang[$vars]) - ); - - continue; - } - - $options = isset($vars['options']) ? $vars['options'] : ''; - - $template->assign_block_vars('options', array( - 'KEY' => $config_key, - 'TITLE' => $lang[$vars['lang']], - 'S_EXPLAIN' => $vars['explain'], - 'S_LEGEND' => false, - 'TITLE_EXPLAIN' => ($vars['explain']) ? $lang[$vars['lang'] . '_EXPLAIN'] : '', - 'CONTENT' => $this->p_master->input_field($config_key, $vars['type'], ${$config_key}, $options), - ) - ); - } - - $template->assign_vars(array( - 'TITLE' => $lang['STAGE_SETTINGS'], - 'BODY' => $lang['CONV_OPTIONS_BODY'], - 'L_SUBMIT' => $lang['BEGIN_CONVERT'], - 'U_ACTION' => $this->p_master->module_url . "?mode={$this->mode}&sub=settings&tag=$convertor_tag&language=$language", - )); - } - - /** - * 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... - 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('
', $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}&sub=in_progress&tag={$convert->convertor_tag}&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]; - } - } - } - } - // 'left_join' => 'topics LEFT JOIN vote_desc ON topics.topic_id = vote_desc.topic_id AND topics.topic_vote = 1' - 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)) . '

' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__); - } - - $url = $this->save_convert_progress('&confirm=1'); - $msg = $user->lang['PRE_CONVERT_COMPLETE']; - - if ($convert->convertor_data['author_notes']) - { - $msg .= '

' . 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) . '

' . 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) . '

' . 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) . '

' . 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/* && !defined('DEBUG')*/) - { - $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('&current_table=' . $current_table . '&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('&jump=1'); - - $template->assign_vars(array( - 'L_SUBMIT' => $user->lang['FINAL_STEP'], - 'U_ACTION' => $url, - )); - - $this->meta_refresh($url); - return; - } - - /** - * Sync function being executed at the middle, some functions need to be executed after a successful sync. - */ - function sync_forums($sync_batch) - { - global $template, $user, $db, $phpbb_root_path, $phpEx, $config, $cache; - global $convert; - - $template->assign_block_vars('checks', array( - 'S_LEGEND' => true, - 'LEGEND' => $user->lang['SYNC_TOPICS'], - )); - - $batch_size = $convert->batch_size; - - $sql = 'SELECT MIN(topic_id) as min_value, MAX(topic_id) AS max_value - FROM ' . TOPICS_TABLE; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - // Set values of minimum/maximum primary value for this table. - $primary_min = $row['min_value']; - $primary_max = $row['max_value']; - - if ($sync_batch == 0) - { - $sync_batch = (int) $primary_min; - } - - if ($sync_batch == 0) - { - $sync_batch = 1; - } - - // Fetch a batch of rows, process and insert them. - while ($sync_batch <= $primary_max && still_on_time()) - { - $end = ($sync_batch + $batch_size - 1); - - // Sync all topics in batch mode... - sync('topic', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, true); - - $template->assign_block_vars('checks', array( - 'TITLE' => sprintf($user->lang['SYNC_TOPIC_ID'], $sync_batch, ($sync_batch + $batch_size)) . ((defined('DEBUG') && function_exists('memory_get_usage')) ? ' [' . ceil(memory_get_usage()/1024) . ' ' . $user->lang['KIB'] . ']' : ''), - 'RESULT' => $user->lang['DONE'], - )); - - $sync_batch += $batch_size; - } - - if ($sync_batch >= $primary_max) - { - $url = $this->save_convert_progress('&final_jump=1'); - - $template->assign_vars(array( - 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], - 'U_ACTION' => $url, - )); - - $this->meta_refresh($url); - return; - } - else - { - $sync_batch--; - } - - $url = $this->save_convert_progress('&sync_batch=' . $sync_batch); - - $template->assign_vars(array( - 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], - 'U_ACTION' => $url, - )); - - $this->meta_refresh($url); - return; - } - - /** - * Save the convertor status - */ - function save_convert_progress($step) - { - global $config, $convert, $language; - - // Save convertor Status - $config->set('convert_progress', serialize(array( - 'step' => $step, - 'table_prefix' => $convert->src_table_prefix, - 'tag' => $convert->convertor_tag, - )), false); - - $config->set('convert_db_server', serialize(array( - 'dbms' => $convert->src_dbms, - 'dbhost' => $convert->src_dbhost, - 'dbport' => $convert->src_dbport, - 'dbname' => $convert->src_dbname, - )), false); - - $config->set('convert_db_user', serialize(array( - 'dbuser' => $convert->src_dbuser, - 'dbpasswd' => $convert->src_dbpasswd, - )), false); - - return $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}$step&language=$language"; - } - - /** - * Finish conversion, the last function to be called. - */ - function finish_conversion() - { - global $db, $phpbb_root_path, $phpEx, $convert, $config, $language, $user, $template; - global $cache, $auth, $phpbb_container, $phpbb_log; - - $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " - WHERE config_name = 'convert_progress' - OR config_name = 'convert_options' - OR config_name = 'convert_db_server' - OR config_name = 'convert_db_user'"); - $db->sql_query('DELETE FROM ' . SESSIONS_TABLE); - - @unlink($phpbb_root_path . 'cache/data_global.' . $phpEx); - phpbb_cache_moderators($db, $cache, $auth); - - // And finally, add a note to the log - $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_INSTALL_CONVERTED', false, array($convert->convertor_data['forum_name'], $config['version'])); - - $url = $this->p_master->module_url . "?mode={$this->mode}&sub=final&language=$language"; - - $template->assign_vars(array( - 'L_SUBMIT' => $user->lang['FINAL_STEP'], - 'U_ACTION' => $url, - )); - - $this->meta_refresh($url); - return; - } - - /** - * This function marks the steps after syncing - */ - function final_jump($final_jump) - { - global $template, $user, $src_db, $same_db, $db, $phpbb_root_path, $phpEx, $config, $cache; - global $convert; - - $template->assign_block_vars('checks', array( - 'S_LEGEND' => true, - 'LEGEND' => $user->lang['PROCESS_LAST'], - )); - - if ($final_jump == 1) - { - $db->sql_return_on_error(true); - - update_topics_posted(); - - $template->assign_block_vars('checks', array( - 'TITLE' => $user->lang['UPDATE_TOPICS_POSTED'], - 'RESULT' => $user->lang['DONE'], - )); - - if ($db->get_sql_error_triggered()) - { - $template->assign_vars(array( - 'S_ERROR_BOX' => true, - 'ERROR_TITLE' => $user->lang['UPDATE_TOPICS_POSTED'], - 'ERROR_MSG' => $user->lang['UPDATE_TOPICS_POSTED_ERR'], - )); - } - $db->sql_return_on_error(false); - - $this->finish_conversion(); - return; - } - } - - /** - * This function marks the steps before syncing (jump=1) - */ - function jump($jump, $last_statement) - { - global $template, $user, $src_db, $same_db, $db, $phpbb_root_path, $phpEx, $config, $cache; - global $convert; - - $template->assign_block_vars('checks', array( - 'S_LEGEND' => true, - 'LEGEND' => $user->lang['PROCESS_LAST'], - )); - - if ($jump == 1) - { - // Execute 'last' statements/queries - if (!empty($convert->convertor['execute_last'])) - { - if (!is_array($convert->convertor['execute_last'])) - { - // @codingStandardsIgnoreStart - eval($convert->convertor['execute_last']); - // @codingStandardsIgnoreEnd - } - else - { - while ($last_statement < sizeof($convert->convertor['execute_last'])) - { - // @codingStandardsIgnoreStart - eval($convert->convertor['execute_last'][$last_statement]); - // @codingStandardsIgnoreEnd - - $template->assign_block_vars('checks', array( - 'TITLE' => $convert->convertor['execute_last'][$last_statement], - 'RESULT' => $user->lang['DONE'], - )); - - $last_statement++; - $url = $this->save_convert_progress('&jump=1&last=' . $last_statement); - - $percentage = ($last_statement == 0) ? 0 : floor(100 / (sizeof($convert->convertor['execute_last']) / $last_statement)); - $msg = sprintf($user->lang['STEP_PERCENT_COMPLETED'], $last_statement, sizeof($convert->convertor['execute_last']), $percentage); - - $template->assign_vars(array( - 'L_SUBMIT' => $user->lang['CONTINUE_LAST'], - 'L_MESSAGE' => $msg, - 'U_ACTION' => $url, - )); - - $this->meta_refresh($url); - return; - } - } - } - - if (!empty($convert->convertor['query_last'])) - { - if (!is_array($convert->convertor['query_last'])) - { - $convert->convertor['query_last'] = array('target', array($convert->convertor['query_last'])); - } - else if (!is_array($convert->convertor['query_last'][0])) - { - $convert->convertor['query_last'] = array(array($convert->convertor['query_last'][0], $convert->convertor['query_last'][1])); - } - - foreach ($convert->convertor['query_last'] as $query_last) - { - if ($query_last[0] == 'src') - { - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'binary'"); - } - - $src_db->sql_query($query_last[1]); - - if ($convert->mysql_convert && $same_db) - { - $src_db->sql_query("SET NAMES 'utf8'"); - } - } - else - { - $db->sql_query($query_last[1]); - } - } - } - - // Sanity check - $db->sql_return_on_error(false); - $src_db->sql_return_on_error(false); - - fix_empty_primary_groups(); - - $sql = 'SELECT MIN(user_regdate) AS board_startdate - FROM ' . USERS_TABLE; - $result = $db->sql_query($sql); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - if (!isset($config['board_startdate']) || ($row['board_startdate'] < $config['board_startdate'] && $row['board_startdate'] > 0)) - { - $config->set('board_startdate', $row['board_startdate']); - $db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_regdate = ' . $row['board_startdate'] . ' WHERE user_id = ' . ANONYMOUS); - } - - update_dynamic_config(); - - $template->assign_block_vars('checks', array( - 'TITLE' => $user->lang['CLEAN_VERIFY'], - 'RESULT' => $user->lang['DONE'], - )); - - $url = $this->save_convert_progress('&jump=2'); - - $template->assign_vars(array( - 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], - 'U_ACTION' => $url, - )); - - $this->meta_refresh($url); - return; - } - - if ($jump == 2) - { - $db->sql_query('UPDATE ' . USERS_TABLE . " SET user_permissions = ''"); - - // TODO: sync() is likely going to bomb out on forums with a considerable amount of topics. - // TODO: the sync function is able to handle FROM-TO values, we should use them here (batch processing) - sync('forum', '', '', false, true); - $cache->destroy('sql', FORUMS_TABLE); - - $template->assign_block_vars('checks', array( - 'TITLE' => $user->lang['SYNC_FORUMS'], - 'RESULT' => $user->lang['DONE'], - )); - - // Continue with synchronizing the forums... - $url = $this->save_convert_progress('&sync_batch=0'); - - $template->assign_vars(array( - 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], - 'U_ACTION' => $url, - )); - - $this->meta_refresh($url); - return; - } - } - - function build_insert_query(&$schema, &$sql_data, $current_table) - { - global $db, $user; - global $convert; - - // Can we use IGNORE with this DBMS? - $sql_ignore = (strpos($db->get_sql_layer(), 'mysql') === 0 && !defined('DEBUG')) ? 'IGNORE ' : ''; - $insert_query = 'INSERT ' . $sql_ignore . 'INTO ' . $schema['target'] . ' ('; - - $aliases = array(); - - $sql_data = array( - 'source_fields' => array(), - 'target_fields' => array(), - 'source_tables' => array(), - 'select_fields' => array(), - ); - - foreach ($schema as $key => $val) - { - // Example: array('group_name', 'extension_groups.group_name', 'htmlspecialchars'), - if (is_int($key)) - { - if (!empty($val[0])) - { - // Target fields - $sql_data['target_fields'][$val[0]] = $key; - $insert_query .= $val[0] . ', '; - } - - if (!is_array($val[1])) - { - $val[1] = array($val[1]); - } - - foreach ($val[1] as $valkey => $value_1) - { - // This should cover about any case: - // - // table.field => SELECT table.field FROM table - // table.field AS alias => SELECT table.field AS alias FROM table - // table.field AS table2.alias => SELECT table2.field AS alias FROM table table2 - // table.field AS table2.field => SELECT table2.field FROM table table2 - // - if (preg_match('/^([a-z0-9_]+)\.([a-z0-9_]+)( +AS +(([a-z0-9_]+?)\.)?([a-z0-9_]+))?$/i', $value_1, $m)) - { - // There is 'AS ...' in the field names - if (!empty($m[3])) - { - $value_1 = ($m[2] == $m[6]) ? $m[1] . '.' . $m[2] : $m[1] . '.' . $m[2] . ' AS ' . $m[6]; - - // Table alias: store it then replace the source table with it - if (!empty($m[5]) && $m[5] != $m[1]) - { - $aliases[$m[5]] = $m[1]; - $value_1 = str_replace($m[1] . '.' . $m[2], $m[5] . '.' . $m[2], $value_1); - } - } - else - { - // No table alias - $sql_data['source_tables'][$m[1]] = (empty($convert->src_table_prefix)) ? $m[1] : $convert->src_table_prefix . $m[1] . ' ' . $m[1]; - } - - $sql_data['select_fields'][$value_1] = $value_1; - $sql_data['source_fields'][$key][$valkey] = (!empty($m[6])) ? $m[6] : $m[2]; - } - } - } - else if ($key == 'where' || $key == 'group_by' || $key == 'order_by' || $key == 'having') - { - if (@preg_match_all('/([a-z0-9_]+)\.([a-z0-9_]+)/i', $val, $m)) - { - foreach ($m[1] as $value) - { - $sql_data['source_tables'][$value] = (empty($convert->src_table_prefix)) ? $value : $convert->src_table_prefix . $value . ' ' . $value; - } - } - } - } - - // Add the aliases to the list of tables - foreach ($aliases as $alias => $table) - { - $sql_data['source_tables'][$alias] = $convert->src_table_prefix . $table . ' ' . $alias; - } - - // 'left_join' => 'forums LEFT JOIN forum_prune ON forums.forum_id = forum_prune.forum_id', - if (!empty($schema['left_join'])) - { - if (!is_array($schema['left_join'])) - { - $schema['left_join'] = array($schema['left_join']); - } - - foreach ($schema['left_join'] as $left_join) - { - // This won't handle concatened LEFT JOINs - if (!preg_match('/([a-z0-9_]+) LEFT JOIN ([a-z0-9_]+) A?S? ?([a-z0-9_]*?) ?(ON|USING)(.*)/i', $left_join, $m)) - { - $this->p_master->error(sprintf($user->lang['NOT_UNDERSTAND'], 'LEFT JOIN', $left_join, $current_table, $schema['target']), __LINE__, __FILE__); - } - - if (!empty($aliases[$m[2]])) - { - if (!empty($m[3])) - { - $this->p_master->error(sprintf($user->lang['NAMING_CONFLICT'], $m[2], $m[3], $schema['left_join']), __LINE__, __FILE__); - } - - $m[2] = $aliases[$m[2]]; - $m[3] = $m[2]; - } - - $right_table = $convert->src_table_prefix . $m[2]; - if (!empty($m[3])) - { - unset($sql_data['source_tables'][$m[3]]); - } - else if ($m[2] != $m[1]) - { - unset($sql_data['source_tables'][$m[2]]); - } - - if (strpos($sql_data['source_tables'][$m[1]], "\nLEFT JOIN") !== false) - { - $sql_data['source_tables'][$m[1]] = '(' . $sql_data['source_tables'][$m[1]] . ")\nLEFT JOIN $right_table"; - } - else - { - $sql_data['source_tables'][$m[1]] .= "\nLEFT JOIN $right_table"; - } - - if (!empty($m[3])) - { - unset($sql_data['source_tables'][$m[3]]); - $sql_data['source_tables'][$m[1]] .= ' AS ' . $m[3]; - } - else if (!empty($convert->src_table_prefix)) - { - $sql_data['source_tables'][$m[1]] .= ' AS ' . $m[2]; - } - $sql_data['source_tables'][$m[1]] .= ' ' . $m[4] . $m[5]; - } - } - - // Remove ", " from the end of the insert query - $insert_query = substr($insert_query, 0, -2) . ') VALUES '; - - return $insert_query; - } - - /** - * Function for processing the currently handled row - */ - function process_row(&$schema, &$sql_data, &$insert_values) - { - global $template, $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache; - global $convert, $convert_row; - - $sql_flag = false; - - foreach ($schema as $key => $fields) - { - // We are only interested in the lines with: - // array('comment', 'attachments_desc.comment', 'htmlspecialchars'), - if (is_int($key)) - { - if (!is_array($fields[1])) - { - $fields[1] = array($fields[1]); - } - - $firstkey_set = false; - $firstkey = 0; - - foreach ($fields[1] as $inner_key => $inner_value) - { - if (!$firstkey_set) - { - $firstkey = $inner_key; - $firstkey_set = true; - } - - $src_field = isset($sql_data['source_fields'][$key][$inner_key]) ? $sql_data['source_fields'][$key][$inner_key] : ''; - - if (!empty($src_field)) - { - $fields[1][$inner_key] = $convert->row[$src_field]; - } - } - - if (!empty($fields[0])) - { - // We have a target field, if we haven't set $sql_flag yet it will be set to TRUE. - // If a function has already set it to FALSE it won't change it. - if ($sql_flag === false) - { - $sql_flag = true; - } - - // No function assigned? - if (empty($fields[2])) - { - $value = $fields[1][$firstkey]; - } - else if (is_array($fields[2]) && !is_callable($fields[2])) - { - // Execute complex function/eval/typecast - $value = $fields[1]; - - foreach ($fields[2] as $type => $execution) - { - if (strpos($type, 'typecast') === 0) - { - if (!is_array($value)) - { - $value = array($value); - } - $value = $value[0]; - settype($value, $execution); - } - else if (strpos($type, 'function') === 0) - { - if (!is_array($value)) - { - $value = array($value); - } - - $value = call_user_func_array($execution, $value); - } - else if (strpos($type, 'execute') === 0) - { - if (!is_array($value)) - { - $value = array($value); - } - - $execution = str_replace('{RESULT}', '$value', $execution); - $execution = str_replace('{VALUE}', '$value', $execution); - // @codingStandardsIgnoreStart - eval($execution); - // @codingStandardsIgnoreEnd - } - } - } - else - { - $value = call_user_func_array($fields[2], $fields[1]); - } - - if (is_null($value)) - { - $value = ''; - } - - $insert_values[] = $db->_sql_validate_value($value); - } - else if (!empty($fields[2])) - { - if (is_array($fields[2])) - { - // Execute complex function/eval/typecast - $value = ''; - - foreach ($fields[2] as $type => $execution) - { - if (strpos($type, 'typecast') === 0) - { - $value = settype($value, $execution); - } - else if (strpos($type, 'function') === 0) - { - if (!is_array($value)) - { - $value = array($value); - } - - $value = call_user_func_array($execution, $value); - } - else if (strpos($type, 'execute') === 0) - { - if (!is_array($value)) - { - $value = array($value); - } - - $execution = str_replace('{RESULT}', '$value', $execution); - $execution = str_replace('{VALUE}', '$value', $execution); - // @codingStandardsIgnoreStart - eval($execution); - // @codingStandardsIgnoreEnd - } - } - } - else - { - call_user_func_array($fields[2], $fields[1]); - } - } - } - } - - return $sql_flag; - } - - /** - * Own meta refresh function to be able to change the global time used - */ - function meta_refresh($url) - { - global $convert, $template; - - if ($convert->options['refresh']) - { - // Because we should not rely on correct settings, we simply use the relative path here directly. - $template->assign_vars(array( - 'S_REFRESH' => true, - 'META' => '') - ); - } - } - - /** - * The information below will be used to build the input fields presented to the user - */ - var $convert_options = array( - 'legend1' => 'SPECIFY_OPTIONS', - 'src_dbms' => array('lang' => 'DBMS', 'type' => 'select', 'options' => 'dbms_select(\'{VALUE}\', true)', 'explain' => false), - 'src_dbhost' => array('lang' => 'DB_HOST', 'type' => 'text:25:100', 'explain' => true), - 'src_dbport' => array('lang' => 'DB_PORT', 'type' => 'text:25:100', 'explain' => true), - 'src_dbname' => array('lang' => 'DB_NAME', 'type' => 'text:25:100', 'explain' => false), - 'src_dbuser' => array('lang' => 'DB_USERNAME', 'type' => 'text:25:100', 'explain' => false), - 'src_dbpasswd' => array('lang' => 'DB_PASSWORD', 'type' => 'password:25:100', 'explain' => false), - 'src_table_prefix' => array('lang' => 'TABLE_PREFIX', 'type' => 'text:25:100', 'explain' => false), - //'src_url' => array('lang' => 'FORUM_ADDRESS', 'type' => 'text:50:100', 'explain' => true), - 'forum_path' => array('lang' => 'FORUM_PATH', 'type' => 'text:25:100', 'explain' => true), - 'refresh' => array('lang' => 'REFRESH_PAGE', 'type' => 'radio:yes_no', 'explain' => true), - ); -} diff --git a/phpBB/install_old/install_update.php b/phpBB/install_old/install_update.php deleted file mode 100644 index d9ba2e7fe9..0000000000 --- a/phpBB/install_old/install_update.php +++ /dev/null @@ -1,1790 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -/** -* @todo check for writable cache/store/files directory -*/ - -if (!defined('IN_INSTALL')) -{ - // Someone has tried to access the file directly. This is not a good idea, so exit - exit; -} - -if (!empty($setmodules)) -{ - // If phpBB is not installed we do not include this module - if (!phpbb_check_installation_exists($phpbb_root_path, $phpEx) || file_exists($phpbb_root_path . 'cache/install_lock')) - { - return; - } - - $module[] = array( - 'module_type' => 'update', - 'module_title' => 'UPDATE', - 'module_filename' => substr(basename(__FILE__), 0, -strlen($phpEx)-1), - 'module_order' => 30, - 'module_subs' => '', - 'module_stages' => array('INTRO', 'VERSION_CHECK', 'FILE_CHECK', 'UPDATE_FILES', 'UPDATE_DB'), - 'module_reqs' => '' - ); -} - -/** -* Update Installation -*/ -class install_update extends module -{ - var $p_master; - var $update_info; - - var $old_location; - var $new_location; - var $latest_version; - var $current_version; - - var $update_to_version; - - protected $filesystem; - - // Set to false - var $test_update = false; - - function install_update(&$p_master) - { - $this->p_master = &$p_master; - } - - function main($mode, $sub) - { - global $template, $phpEx, $phpbb_root_path, $user, $db, $config, $cache, $auth, $language; - global $request, $phpbb_admin_path, $phpbb_adm_relative_path, $phpbb_container, $phpbb_config_php_file; - - // We must enable super globals, otherwise creating a new instance of the request class, - // using the new container with a dbal connection will fail with the following PHP Notice: - // Object of class phpbb_request_deactivated_super_global could not be converted to int - $request->enable_super_globals(); - - // Create a normal container now - $phpbb_container_builder = new \phpbb\di\container_builder($phpbb_root_path, $phpEx); - $phpbb_container = $phpbb_container_builder - ->with_config($phpbb_config_php_file) - ->without_cache() - ->without_extensions() - ; - - if (file_exists($phpbb_root_path . 'install/update/new/config')) - { - $phpbb_container_builder->with_config_path($phpbb_root_path . 'install/update/new/config'); - } - $phpbb_container = $phpbb_container_builder->get_container(); - - // Writes into global $cache - /* @var $cache \phpbb\cache\service */ - $cache = $phpbb_container->get('cache'); - - $this->filesystem = $phpbb_container->get('filesystem'); - - $this->tpl_name = 'install_update'; - $this->page_title = 'UPDATE_INSTALLATION'; - - $this->old_location = $phpbb_root_path . 'install/update/old/'; - $this->new_location = $phpbb_root_path . 'install/update/new/'; - - // Init DB - extract($phpbb_config_php_file->get_all()); - require($phpbb_root_path . 'includes/constants.' . $phpEx); - - // Special options for conflicts/modified files - define('MERGE_NO_MERGE_NEW', 1); - define('MERGE_NO_MERGE_MOD', 2); - define('MERGE_NEW_FILE', 3); - define('MERGE_MOD_FILE', 4); - - $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms); - - $db = new $dbms(); - - // Connect to DB - $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false); - - // We do not need this any longer, unset for safety purposes - 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); - - // Force template recompile - $config['load_tplcompile'] = 1; - - // First of all, init the user session - $user->session_begin(); - $auth->acl($user->data); - - // Overwrite user's language with the selected one. - // Config needs to be changed to ensure that guests also get the selected language. - $config_default_lang = $config['default_lang']; - $config['default_lang'] = $language; - $user->data['user_lang'] = $language; - - $user->add_lang(array('common', 'acp/common', 'acp/board', 'install', 'posting')); - - // Reset the default_lang - $config['default_lang'] = $config_default_lang; - unset($config_default_lang); - - // If we are within the intro page we need to make sure we get up-to-date version info - if ($sub == 'intro') - { - $cache->destroy('_version_info'); - } - - // Set custom template again. ;) - $paths = array($phpbb_root_path . 'install/update/new/adm/style', $phpbb_admin_path . 'style'); - $paths = array_filter($paths, 'is_dir'); - $template->set_custom_style(array( - array( - 'name' => 'adm', - 'ext_path' => 'adm/style/', - ), - ), $paths); - - $template->assign_vars(array( - 'S_USER_LANG' => $user->lang['USER_LANG'], - 'S_CONTENT_DIRECTION' => $user->lang['DIRECTION'], - 'S_CONTENT_ENCODING' => 'UTF-8', - 'S_CONTENT_FLOW_BEGIN' => ($user->lang['DIRECTION'] == 'ltr') ? 'left' : 'right', - 'S_CONTENT_FLOW_END' => ($user->lang['DIRECTION'] == 'ltr') ? 'right' : 'left', - )); - - // Get current and latest version - /* @var $version_helper \phpbb\version_helper */ - $version_helper = $phpbb_container->get('version_helper'); - try - { - $this->latest_version = $version_helper->get_latest_on_current_branch(true); - } - catch (\RuntimeException $e) - { - $this->latest_version = false; - - $update_info = array(); - include($phpbb_root_path . 'install/update/index.' . $phpEx); - $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info; - - if ($info !== false) - { - $this->latest_version = (!empty($info['version']['to'])) ? trim($info['version']['to']) : false; - } - } - - // For the current version we trick a bit. ;) - $this->current_version = (!empty($config['version_update_from'])) ? $config['version_update_from'] : $config['version']; - - $up_to_date = (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->latest_version)), '<')) ? false : true; - - // Check for a valid update directory, else point the user to the phpbb.com website - if (!file_exists($phpbb_root_path . 'install/update') || !file_exists($phpbb_root_path . 'install/update/index.' . $phpEx) || !file_exists($this->old_location) || !file_exists($this->new_location)) - { - $template->assign_vars(array( - 'S_ERROR' => true, - 'ERROR_MSG' => ($up_to_date) ? $user->lang['NO_UPDATE_FILES_UP_TO_DATE'] : sprintf($user->lang['NO_UPDATE_FILES_OUTDATED'], $config['version'], $this->current_version, $this->latest_version)) - ); - - return; - } - - $this->update_info = $this->get_file('update_info'); - - // Make sure the update directory holds the correct information - // Since admins are able to run the update/checks more than once we only check if the current version is lower or equal than the version to which we update to. - if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '>')) - { - $template->assign_vars(array( - 'S_ERROR' => true, - 'ERROR_MSG' => sprintf($user->lang['INCOMPATIBLE_UPDATE_FILES'], $config['version'], $this->update_info['version']['from'], $this->update_info['version']['to'])) - ); - - return; - } - - // Check if the update files are actually meant to update from the current version - if ($this->current_version != $this->update_info['version']['from']) - { - $template->assign_vars(array( - 'S_ERROR' => true, - 'ERROR_MSG' => sprintf($user->lang['INCOMPATIBLE_UPDATE_FILES'], $this->current_version, $this->update_info['version']['from'], $this->update_info['version']['to']), - )); - } - - // Check if the update files stored are for the latest version... - if (version_compare(strtolower($this->latest_version), strtolower($this->update_info['version']['to']), '>')) - { - $template->assign_vars(array( - 'S_WARNING' => true, - 'WARNING_MSG' => sprintf($user->lang['OLD_UPDATE_FILES'], $this->update_info['version']['from'], $this->update_info['version']['to'], $this->latest_version)) - ); - } - - // We store the "update to" version, because it is not always the latest. ;) - $this->update_to_version = $this->update_info['version']['to']; - - // Fill DB version - if (empty($config['dbms_version'])) - { - $config->set('dbms_version', $db->sql_server_info(true)); - } - - if ($this->test_update === false) - { - // What about the language file? Got it updated? - if (in_array('language/' . $language . '/install.' . $phpEx, $this->update_info['files'])) - { - $lang = array(); - include($this->new_location . 'language/' . $language . '/install.' . $phpEx); - // this is the user's language.. just merge it - $user->lang = array_merge($user->lang, $lang); - } - if ($language != 'en' && in_array('language/en/install.' . $phpEx, $this->update_info['files'])) - { - $lang = array(); - include($this->new_location . 'language/en/install.' . $phpEx); - // only add new keys to user's language in english - $new_keys = array_diff(array_keys($lang), array_keys($user->lang)); - foreach ($new_keys as $i => $new_key) - { - $user->lang[$new_key] = $lang[$new_key]; - } - } - } - - // Include renderer and engine - $this->include_file('includes/diff/diff.' . $phpEx); - $this->include_file('includes/diff/engine.' . $phpEx); - $this->include_file('includes/diff/renderer.' . $phpEx); - - // Make sure we stay at the file check if checking the files again - if ($request->variable('check_again', false, false, \phpbb\request\request_interface::POST)) - { - $sub = $this->p_master->sub = 'file_check'; - } - - switch ($sub) - { - case 'intro': - $this->page_title = 'UPDATE_INSTALLATION'; - - $template->assign_vars(array( - 'S_INTRO' => true, - 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=version_check"), - )); - - // Make sure the update list is destroyed. - $cache->destroy('_update_list'); - $cache->destroy('_diff_files'); - $cache->destroy('_expected_files'); - break; - - case 'version_check': - $this->page_title = 'STAGE_VERSION_CHECK'; - - $template->assign_vars(array( - 'S_VERSION_CHECK' => true, - - 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check"), - - 'S_UP_TO_DATE' => $up_to_date, - 'LATEST_VERSION' => $this->latest_version, - 'CURRENT_VERSION' => $this->current_version, - )); - - // Print out version the update package updates to - if ($this->latest_version != $this->update_info['version']['to']) - { - $template->assign_var('PACKAGE_VERSION', $this->update_info['version']['to']); - } - - // Since some people try to update to RC releases, but phpBB.com tells them the last version is the version they currently run - // we are faced with the updater thinking the database schema is up-to-date; which it is, but should be updated none-the-less - // We now try to cope with this by triggering the update process - if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '<')) - { - $template->assign_vars(array( - 'S_UP_TO_DATE' => false, - )); - } - - break; - - case 'update_db': - // Redirect the user to the database update script with some explanations... - $template->assign_vars(array( - 'S_DB_UPDATE' => true, - 'S_DB_UPDATE_FINISHED' => ($config['version'] == $this->update_info['version']['to']) ? true : false, - 'U_DB_UPDATE' => append_sid($phpbb_root_path . 'install/database_update.' . $phpEx, 'type=1&language=' . $user->data['user_lang']), - 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_db"), - 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check"), - 'L_EVERYTHING_UP_TO_DATE' => $user->lang('EVERYTHING_UP_TO_DATE', append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login'), append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=login&redirect=' . $phpbb_adm_relative_path . 'index.php%3Fi=send_statistics%26mode=send_statistics')), - )); - - // Do not display incompatible package note after successful update - if ($config['version'] == $this->update_info['version']['to']) - { - $template->assign_var('S_ERROR', false); - } - break; - - case 'file_check': - - // retrieve info on what changes should have already been made to the files. - $expected_files = $cache->get('_expected_files'); - if (!$expected_files) - { - $expected_files = array(); - } - - // Now make sure the previous file collection is no longer valid... - $cache->destroy('_diff_files'); - - $this->page_title = 'STAGE_FILE_CHECK'; - - // Now make sure our update list is correct if the admin refreshes - $action = $request->variable('action', ''); - - // We are directly within an update. To make sure our update list is correct we check its status. - $update_list = ($request->variable('check_again', false, false, \phpbb\request\request_interface::POST)) ? false : $cache->get('_update_list'); - $modified = ($update_list !== false) ? @filemtime($cache->get_driver()->cache_dir . 'data_update_list.' . $phpEx) : 0; - - // Make sure the list is up-to-date - if ($update_list !== false) - { - $get_new_list = false; - foreach ($this->update_info['files'] as $file) - { - if (file_exists($phpbb_root_path . $file) && filemtime($phpbb_root_path . $file) > $modified) - { - $get_new_list = true; - break; - } - } - } - else - { - $get_new_list = true; - } - - if (!$get_new_list && $update_list['status'] != -1) - { - $get_new_list = true; - } - - if ($get_new_list) - { - $this->get_update_structure($update_list, $expected_files); - $cache->put('_update_list', $update_list); - - // Refresh the page if we are still not finished... - if ($update_list['status'] != -1) - { - $refresh_url = append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check"); - meta_refresh(2, $refresh_url); - - $template->assign_vars(array( - 'S_IN_PROGRESS' => true, - 'S_COLLECTED' => (int) $update_list['status'], - 'S_TO_COLLECT' => sizeof($this->update_info['files']), - 'L_IN_PROGRESS' => $user->lang['COLLECTING_FILE_DIFFS'], - 'L_IN_PROGRESS_EXPLAIN' => sprintf($user->lang['NUMBER_OF_FILES_COLLECTED'], (int) $update_list['status'], sizeof($this->update_info['files']) + sizeof($this->update_info['deleted'])), - )); - - return; - } - } - - if ($action == 'diff') - { - $this->show_diff($update_list); - return; - } - - if (sizeof($update_list['no_update'])) - { - $template->assign_vars(array( - 'S_NO_UPDATE_FILES' => true, - 'NO_UPDATE_FILES' => implode(', ', array_map('htmlspecialchars', $update_list['no_update']))) - ); - } - - $new_expected_files = array(); - - // Now assign the list to the template - foreach ($update_list as $status => $filelist) - { - if ($status == 'no_update' || !sizeof($filelist) || $status == 'status' || $status == 'status_deleted') - { - continue; - } - -/* $template->assign_block_vars('files', array( - 'S_STATUS' => true, - 'STATUS' => $status, - 'L_STATUS' => $user->lang['STATUS_' . strtoupper($status)], - 'TITLE' => $user->lang['FILES_' . strtoupper($status)], - 'EXPLAIN' => $user->lang['FILES_' . strtoupper($status) . '_EXPLAIN'], - ) - );*/ - - foreach ($filelist as $file_struct) - { - $s_binary = (!empty($this->update_info['binary']) && in_array($file_struct['filename'], $this->update_info['binary'])) ? true : false; - - $filename = htmlspecialchars($file_struct['filename']); - if (strrpos($filename, '/') !== false) - { - $dir_part = substr($filename, 0, strrpos($filename, '/') + 1); - $file_part = substr($filename, strrpos($filename, '/') + 1); - } - else - { - $dir_part = ''; - $file_part = $filename; - } - - $diff_url = append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check&action=diff&status=$status&file=" . urlencode($file_struct['filename'])); - - if (isset($file_struct['as_expected']) && $file_struct['as_expected']) - { - $new_expected_files[$file_struct['filename']] = $expected_files[$file_struct['filename']]; - } - else - { - $template->assign_block_vars($status, array( - 'STATUS' => $status, - - 'FILENAME' => $filename, - 'DIR_PART' => $dir_part, - 'FILE_PART' => $file_part, - 'NUM_CONFLICTS' => (isset($file_struct['conflicts'])) ? $file_struct['conflicts'] : 0, - - 'S_CUSTOM' => ($file_struct['custom']) ? true : false, - 'S_BINARY' => $s_binary, - 'CUSTOM_ORIGINAL' => ($file_struct['custom']) ? $file_struct['original'] : '', - - 'U_SHOW_DIFF' => $diff_url, - 'L_SHOW_DIFF' => ($status != 'up_to_date') ? $user->lang['SHOW_DIFF_' . strtoupper($status)] : '', - - 'U_VIEW_MOD_FILE' => $diff_url . '&op=' . MERGE_MOD_FILE, - 'U_VIEW_NEW_FILE' => $diff_url . '&op=' . MERGE_NEW_FILE, - 'U_VIEW_NO_MERGE_MOD' => $diff_url . '&op=' . MERGE_NO_MERGE_MOD, - 'U_VIEW_NO_MERGE_NEW' => $diff_url . '&op=' . MERGE_NO_MERGE_NEW, - )); - } - } - } - - $cache->put('_expected_files', $new_expected_files); - - $all_up_to_date = true; - foreach ($update_list as $status => $filelist) - { - if ($status != 'up_to_date' && $status != 'custom' && $status != 'status' && $status != 'status_deleted' && sizeof($filelist)) - { - $all_up_to_date = false; - break; - } - } - - $template->assign_vars(array( - 'S_FILE_CHECK' => true, - 'S_ALL_UP_TO_DATE' => $all_up_to_date, - 'S_VERSION_UP_TO_DATE' => $up_to_date, - 'S_UP_TO_DATE' => $up_to_date, - 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check"), - 'U_UPDATE_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files"), - 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_db"), - )); - - // Since some people try to update to RC releases, but phpBB.com tells them the last version is the version they currently run - // we are faced with the updater thinking the database schema is up-to-date; which it is, but should be updated none-the-less - // We now try to cope with this by triggering the update process - if (version_compare(str_replace('rc', 'RC', strtolower($this->current_version)), str_replace('rc', 'RC', strtolower($this->update_info['version']['to'])), '<')) - { - $template->assign_vars(array( - 'S_UP_TO_DATE' => false, - )); - } - - if ($all_up_to_date) - { - global $phpbb_container; - - /* @var $phpbb_log \phpbb\log\log_interface */ - $phpbb_log = $phpbb_container->get('log'); - - // Add database update to log - $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_UPDATE_PHPBB', time(), array($this->current_version, $this->update_to_version)); - - $db->sql_return_on_error(true); - $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'"); - $db->sql_return_on_error(false); - - $cache->purge(); - } - - break; - - case 'update_files': - - $this->page_title = 'STAGE_UPDATE_FILES'; - - $s_hidden_fields = ''; - $params = array(); - $conflicts = $request->variable('conflict', array('' => 0)); - $modified = $request->variable('modified', array('' => 0)); - - foreach ($conflicts as $filename => $merge_option) - { - $s_hidden_fields .= ''; - $params[] = 'conflict[' . urlencode($filename) . ']=' . urlencode($merge_option); - } - - foreach ($modified as $filename => $merge_option) - { - if (!$merge_option) - { - continue; - } - $s_hidden_fields .= ''; - $params[] = 'modified[' . urlencode($filename) . ']=' . urlencode($merge_option); - } - - $no_update = $request->variable('no_update', array(0 => '')); - - foreach ($no_update as $index => $filename) - { - $s_hidden_fields .= ''; - $params[] = 'no_update[]=' . urlencode($filename); - } - - // Before the user is choosing his preferred method, let's create the content list... - $update_list = $cache->get('_update_list'); - - if ($update_list === false) - { - trigger_error($user->lang['NO_UPDATE_INFO'], E_USER_ERROR); - } - - // Check if the conflicts data is valid - if (sizeof($conflicts)) - { - $conflict_filenames = array(); - foreach ($update_list['conflict'] as $files) - { - $conflict_filenames[] = $files['filename']; - } - - $new_conflicts = array(); - foreach ($conflicts as $filename => $diff_method) - { - if (in_array($filename, $conflict_filenames)) - { - $new_conflicts[$filename] = $diff_method; - } - } - - $conflicts = $new_conflicts; - } - - // Build list for modifications - if (sizeof($modified)) - { - $modified_filenames = array(); - foreach ($update_list['modified'] as $files) - { - $modified_filenames[] = $files['filename']; - } - - $new_modified = array(); - foreach ($modified as $filename => $diff_method) - { - if (in_array($filename, $modified_filenames)) - { - $new_modified[$filename] = $diff_method; - } - } - - $modified = $new_modified; - } - - // Check number of conflicting files, they need to be equal. For modified files the number can differ - if (sizeof($update_list['conflict']) != sizeof($conflicts)) - { - trigger_error($user->lang['MERGE_SELECT_ERROR'], E_USER_ERROR); - } - - // Before we do anything, let us diff the files and store the raw file information "somewhere" - $get_files = false; - $file_list = $cache->get('_diff_files'); - $expected_files = $cache->get('_expected_files'); - - if ($file_list === false || $file_list['status'] != -1) - { - $get_files = true; - } - - if ($get_files) - { - if ($file_list === false) - { - $file_list = array( - 'status' => 0, - ); - } - - if (!isset($expected_files) || $expected_files === false) - { - $expected_files = array(); - } - - $processed = 0; - foreach ($update_list as $status => $files) - { - if (!is_array($files)) - { - continue; - } - - foreach ($files as $file_struct) - { - // Skip this file if the user selected to not update it - if (in_array($file_struct['filename'], $no_update)) - { - $expected_files[$file_struct['filename']] = false; - continue; - } - - // Already handled... then skip of course... - if (isset($file_list[$file_struct['filename']])) - { - continue; - } - - // Refresh if we reach 5 diffs... - if ($processed >= 5) - { - $cache->put('_diff_files', $file_list); - - if ($request->variable('download', false)) - { - $params[] = 'download=1'; - } - - $redirect_url = append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files&" . implode('&', $params)); - meta_refresh(3, $redirect_url); - - $template->assign_vars(array( - 'S_IN_PROGRESS' => true, - 'L_IN_PROGRESS' => $user->lang['MERGING_FILES'], - 'L_IN_PROGRESS_EXPLAIN' => $user->lang['MERGING_FILES_EXPLAIN'], - )); - - return; - } - - if (file_exists($phpbb_root_path . $file_struct['filename'])) - { - $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); - if (isset($expected_files[$file_struct['filename']]) && md5($contents) == $expected_files[$file_struct['filename']]) - { - continue; - } - } - - $original_filename = ($file_struct['custom']) ? $file_struct['original'] : $file_struct['filename']; - - switch ($status) - { - case 'modified': - - $option = (isset($modified[$file_struct['filename']])) ? $modified[$file_struct['filename']] : 0; - - switch ($option) - { - case MERGE_NO_MERGE_NEW: - $contents = file_get_contents($this->new_location . $original_filename); - break; - - case MERGE_NO_MERGE_MOD: - $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); - break; - - default: - $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); - - $contents = implode("\n", $diff->merged_output()); - unset($diff); - break; - } - - $expected_files[$file_struct['filename']] = md5($contents); - $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']); - $cache->put($file_list[$file_struct['filename']], base64_encode($contents)); - - $file_list['status']++; - $processed++; - - break; - - case 'conflict': - - $option = $conflicts[$file_struct['filename']]; - $contents = ''; - - switch ($option) - { - case MERGE_NO_MERGE_NEW: - $contents = file_get_contents($this->new_location . $original_filename); - break; - - case MERGE_NO_MERGE_MOD: - $contents = file_get_contents($phpbb_root_path . $file_struct['filename']); - break; - - default: - - $diff = $this->return_diff($this->old_location . $original_filename, $phpbb_root_path . $file_struct['filename'], $this->new_location . $original_filename); - - if ($option == MERGE_NEW_FILE) - { - $contents = implode("\n", $diff->merged_new_output()); - } - else if ($option == MERGE_MOD_FILE) - { - $contents = implode("\n", $diff->merged_orig_output()); - } - else - { - unset($diff); - break 2; - } - - unset($diff); - break; - } - - $expected_files[$file_struct['filename']] = md5($contents); - $file_list[$file_struct['filename']] = '_file_' . md5($file_struct['filename']); - $cache->put($file_list[$file_struct['filename']], base64_encode($contents)); - - $file_list['status']++; - $processed++; - - break; - } - } - } - $cache->put('_expected_files', $expected_files); - } - - $file_list['status'] = -1; - $cache->put('_diff_files', $file_list); - - if ($request->variable('download', false)) - { - $this->include_file('includes/functions_compress.' . $phpEx); - - $use_method = $request->variable('use_method', ''); - $methods = array('.tar'); - - $available_methods = array('.tar.gz' => 'zlib', '.tar.bz2' => 'bz2', '.zip' => 'zlib'); - foreach ($available_methods as $type => $module) - { - if (!@extension_loaded($module)) - { - continue; - } - - $methods[] = $type; - } - - // Let the user decide in which format he wants to have the pack - if (!$use_method) - { - $this->page_title = 'SELECT_DOWNLOAD_FORMAT'; - - $radio_buttons = ''; - foreach ($methods as $method) - { - $radio_buttons .= ''; - } - - $template->assign_vars(array( - 'S_DOWNLOAD_FILES' => true, - 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files"), - 'RADIO_BUTTONS' => $radio_buttons, - 'S_HIDDEN_FIELDS' => $s_hidden_fields) - ); - - // To ease the update process create a file location map - $update_list = $cache->get('_update_list'); - $script_path = ($config['force_server_vars']) ? (($config['script_path'] == '/') ? '/' : $config['script_path'] . '/') : $user->page['root_script_path']; - - foreach ($update_list as $status => $files) - { - if ($status == 'up_to_date' || $status == 'no_update' || $status == 'status' || $status == 'status_deleted') - { - continue; - } - - foreach ($files as $file_struct) - { - if (in_array($file_struct['filename'], $no_update)) - { - continue; - } - - $template->assign_block_vars('location', array( - 'SOURCE' => htmlspecialchars($file_struct['filename']), - 'DESTINATION' => $script_path . htmlspecialchars($file_struct['filename']), - )); - } - } - return; - } - - if (!in_array($use_method, $methods)) - { - $use_method = '.tar'; - } - - $update_mode = 'download'; - } - else - { - $this->include_file('includes/functions_transfer.' . $phpEx); - - // Choose FTP, if not available use fsock... - $method = basename($request->variable('method', '')); - $submit = (isset($_POST['submit'])) ? true : false; - $test_ftp_connection = $request->variable('test_connection', ''); - - if (!$method || !class_exists($method)) - { - $method = 'ftp'; - $methods = transfer::methods(); - - if (!in_array('ftp', $methods)) - { - $method = $methods[0]; - } - } - - $test_connection = false; - if ($test_ftp_connection || $submit) - { - $transfer = new $method( - $request->variable('host', ''), - $request->variable('username', ''), - htmlspecialchars_decode($request->untrimmed_variable('password', '')), - $request->variable('root_path', ''), - $request->variable('port', ''), - $request->variable('timeout', '') - ); - $test_connection = $transfer->open_session(); - - // Make sure that the directory is correct by checking for the existence of common.php - if ($test_connection === true) - { - // Check for common.php file - if (!$transfer->file_exists($phpbb_root_path, 'common.' . $phpEx)) - { - $test_connection = 'ERR_WRONG_PATH_TO_PHPBB'; - } - } - - $transfer->close_session(); - - // Make sure the login details are correct before continuing - if ($submit && $test_connection !== true) - { - $submit = false; - $test_ftp_connection = true; - } - } - - $s_hidden_fields .= build_hidden_fields(array('method' => $method)); - - if (!$submit) - { - $this->page_title = 'SELECT_FTP_SETTINGS'; - - if (!class_exists($method)) - { - trigger_error('Method does not exist.', E_USER_ERROR); - } - - $requested_data = call_user_func(array($method, 'data')); - foreach ($requested_data as $data => $default) - { - $template->assign_block_vars('data', array( - 'DATA' => $data, - 'NAME' => $user->lang[strtoupper($method . '_' . $data)], - 'EXPLAIN' => $user->lang[strtoupper($method . '_' . $data) . '_EXPLAIN'], - 'DEFAULT' => $request->variable($data, (string) $default), - )); - } - - $template->assign_vars(array( - 'S_CONNECTION_SUCCESS' => ($test_ftp_connection && $test_connection === true) ? true : false, - 'S_CONNECTION_FAILED' => ($test_ftp_connection && $test_connection !== true) ? true : false, - 'ERROR_MSG' => ($test_ftp_connection && $test_connection !== true) ? $user->lang[$test_connection] : '', - - 'S_FTP_UPLOAD' => true, - 'UPLOAD_METHOD' => $method, - 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files"), - 'U_DOWNLOAD_METHOD' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=update_files&download=1"), - 'S_HIDDEN_FIELDS' => $s_hidden_fields, - )); - - return; - } - - $update_mode = 'upload'; - } - - // Now update the installation or download the archive... - $download_filename = 'update_' . $this->update_info['version']['from'] . '_to_' . $this->update_info['version']['to']; - $archive_filename = $download_filename . '_' . time() . '_' . unique_id(); - - // Now init the connection - if ($update_mode == 'download') - { - if ($this->filesystem->is_writable($phpbb_root_path . 'store/')) - { - trigger_error(sprintf('The directory ā€œ%sā€ is not writable.', $phpbb_root_path . 'store/'), E_USER_ERROR); - } - - if ($use_method == '.zip') - { - $compress = new compress_zip('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method); - } - else - { - $compress = new compress_tar('w', $phpbb_root_path . 'store/' . $archive_filename . $use_method, $use_method); - } - } - else - { - $transfer = new $method( - $request->variable('host', ''), - $request->variable('username', ''), - htmlspecialchars_decode($request->untrimmed_variable('password', '')), - $request->variable('root_path', ''), - $request->variable('port', ''), - $request->variable('timeout', '') - ); - $transfer->open_session(); - } - - // Ok, go through the update list and do the operations based on their status - foreach ($update_list as $status => $files) - { - if (!is_array($files)) - { - continue; - } - - foreach ($files as $file_struct) - { - // Skip this file if the user selected to not update it - if (in_array($file_struct['filename'], $no_update)) - { - continue; - } - - $original_filename = ($file_struct['custom']) ? $file_struct['original'] : $file_struct['filename']; - - switch ($status) - { - case 'new': - case 'new_conflict': - case 'not_modified': - - if ($update_mode == 'download') - { - $compress->add_custom_file($this->new_location . $original_filename, $file_struct['filename']); - } - else - { - if ($status != 'new') - { - $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); - } - - // New directory too? - $dirname = dirname($file_struct['filename']); - - if ($dirname && !file_exists($phpbb_root_path . $dirname)) - { - $transfer->make_dir($dirname); - } - - $transfer->copy_file($this->new_location . $original_filename, $file_struct['filename']); - } - break; - - case 'modified': - - $contents = base64_decode($cache->get($file_list[$file_struct['filename']])); - - if ($update_mode == 'download') - { - $compress->add_data($contents, $file_struct['filename']); - } - else - { - // @todo add option to specify if a backup file should be created? - $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); - $transfer->write_file($file_struct['filename'], $contents); - } - break; - - case 'conflict': - - $contents = base64_decode($cache->get($file_list[$file_struct['filename']])); - - if ($update_mode == 'download') - { - $compress->add_data($contents, $file_struct['filename']); - } - else - { - $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); - $transfer->write_file($file_struct['filename'], $contents); - } - break; - - case 'deleted': - - if ($update_mode != 'download') - { - $transfer->rename($file_struct['filename'], $file_struct['filename'] . '.bak'); - } - break; - } - } - } - - if ($update_mode == 'download') - { - $compress->close(); - - $compress->download($archive_filename, $download_filename); - @unlink($phpbb_root_path . 'store/' . $archive_filename . $use_method); - - exit; - } - else - { - $transfer->close_session(); - - $template->assign_vars(array( - 'S_UPLOAD_SUCCESS' => true, - 'U_ACTION' => append_sid($this->p_master->module_url, "language=$language&mode=$mode&sub=file_check")) - ); - return; - } - - break; - - } - } - - /** - * Show file diff - */ - function show_diff(&$update_list) - { - global $phpbb_root_path, $template, $user, $request, $phpbb_adm_relative_path; - - $this->tpl_name = 'install_update_diff'; - - $this->page_title = 'VIEWING_FILE_DIFF'; - - $status = $request->variable('status', ''); - $file = $request->variable('file', ''); - $diff_mode = $request->variable('diff_mode', 'inline'); - - // First of all make sure the file is within our file update list with the correct status - $found_entry = array(); - foreach ($update_list[$status] as $index => $file_struct) - { - if ($file_struct['filename'] === $file) - { - $found_entry = $update_list[$status][$index]; - } - } - - if (empty($found_entry)) - { - trigger_error($user->lang['FILE_DIFF_NOT_ALLOWED'], E_USER_ERROR); - } - - // If the status is 'up_to_date' then we do not need to show a diff - if ($status == 'up_to_date') - { - trigger_error($user->lang['FILE_ALREADY_UP_TO_DATE'], E_USER_ERROR); - } - - $original_file = ($found_entry['custom']) ? $found_entry['original'] : $file; - - // Get the correct diff - switch ($status) - { - case 'conflict': - $option = $request->variable('op', 0); - - switch ($option) - { - case MERGE_NO_MERGE_NEW: - case MERGE_NO_MERGE_MOD: - - $diff = $this->return_diff(array(), ($option == MERGE_NO_MERGE_NEW) ? $this->new_location . $original_file : $phpbb_root_path . $file); - - $template->assign_var('S_DIFF_NEW_FILE', true); - $diff_mode = 'inline'; - $this->page_title = 'VIEWING_FILE_CONTENTS'; - - break; - - // Merge differences and use new phpBB code for conflicted blocks - case MERGE_NEW_FILE: - case MERGE_MOD_FILE: - - $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $file, $this->new_location . $original_file); - - $template->assign_vars(array( - 'S_DIFF_CONFLICT_FILE' => true, - 'NUM_CONFLICTS' => $diff->get_num_conflicts()) - ); - - $diff = $this->return_diff($phpbb_root_path . $file, ($option == MERGE_NEW_FILE) ? $diff->merged_new_output() : $diff->merged_orig_output()); - break; - - // Download conflict file - default: - - $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $file, $this->new_location . $original_file); - - header('Pragma: no-cache'); - header("Content-Type: application/octetstream; name=\"$file\""); - header("Content-disposition: attachment; filename=$file"); - - @set_time_limit(0); - - echo implode("\n", $diff->get_conflicts_content()); - - flush(); - exit; - - break; - } - - break; - - case 'modified': - $option = $request->variable('op', 0); - - switch ($option) - { - case MERGE_NO_MERGE_NEW: - case MERGE_NO_MERGE_MOD: - - $diff = $this->return_diff(array(), ($option == MERGE_NO_MERGE_NEW) ? $this->new_location . $original_file : $phpbb_root_path . $file); - - $template->assign_var('S_DIFF_NEW_FILE', true); - $diff_mode = 'inline'; - $this->page_title = 'VIEWING_FILE_CONTENTS'; - - break; - - default: - $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $original_file, $this->new_location . $file); - $diff = $this->return_diff($phpbb_root_path . $file, $diff->merged_output()); - break; - } - break; - - case 'not_modified': - case 'new_conflict': - $diff = $this->return_diff($phpbb_root_path . $file, $this->new_location . $original_file); - break; - - case 'new': - - $diff = $this->return_diff(array(), $this->new_location . $original_file); - - $template->assign_var('S_DIFF_NEW_FILE', true); - $diff_mode = 'inline'; - $this->page_title = 'VIEWING_FILE_CONTENTS'; - - break; - - case 'deleted': - - $diff = $this->return_diff(array(), $phpbb_root_path . $original_file); - - $template->assign_var('S_DIFF_NEW_FILE', true); - $diff_mode = 'inline'; - $this->page_title = 'VIEWING_FILE_CONTENTS'; - - break; - } - - $diff_mode_options = ''; - foreach (array('side_by_side', 'inline', 'unified', 'raw') as $option) - { - $diff_mode_options .= ''; - } - - // Now the correct renderer - $render_class = 'diff_renderer_' . $diff_mode; - - if (!class_exists($render_class)) - { - trigger_error('Chosen diff mode is not supported', E_USER_ERROR); - } - - $renderer = new $render_class(); - - $template->assign_vars(array( - 'DIFF_CONTENT' => $renderer->get_diff_content($diff), - 'DIFF_MODE' => $diff_mode, - 'S_DIFF_MODE_OPTIONS' => $diff_mode_options, - 'S_SHOW_DIFF' => true, - )); - - unset($diff, $renderer); - } - - /** - * Collect all file status infos we need for the update by diffing all files - */ - function get_update_structure(&$update_list, $expected_files) - { - global $phpbb_root_path, $phpEx, $user; - - if ($update_list === false) - { - $update_list = array( - 'up_to_date' => array(), - 'new' => array(), - 'not_modified' => array(), - 'modified' => array(), - 'new_conflict' => array(), - 'conflict' => array(), - 'no_update' => array(), - 'deleted' => array(), - 'status' => 0, - 'status_deleted'=> 0, - ); - } - - /* if (!empty($this->update_info['custom'])) - { - foreach ($this->update_info['custom'] as $original_file => $file_ary) - { - foreach ($file_ary as $index => $file) - { - $this->make_update_diff($update_list, $original_file, $file, true); - } - } - } */ - - // Get a list of those files which are completely new by checking with file_exists... - $num_bytes_processed = 0; - - foreach ($this->update_info['files'] as $index => $file) - { - if (is_int($update_list['status']) && $index < $update_list['status']) - { - continue; - } - - if ($num_bytes_processed >= 500 * 1024) - { - return; - } - - if (!file_exists($phpbb_root_path . $file)) - { - // Make sure the update files are consistent by checking if the file is in new_files... - if (!file_exists($this->new_location . $file)) - { - trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR); - } - - // If the file exists within the old directory the file got removed and we will write it back - // not a biggie, but we might want to state this circumstance separately later. - // if (file_exists($this->old_location . $file)) - // { - // $update_list['removed'][] = $file; - // } - - /* Only include a new file as new if the underlying path exist - // The path normally do not exist if the original style or language has been removed - if (file_exists($phpbb_root_path . dirname($file))) - { - $this->get_custom_info($update_list['new'], $file); - $update_list['new'][] = array('filename' => $file, 'custom' => false); - } - else - { - // Do not include style-related or language-related content - if (strpos($file, 'styles/') !== 0 && strpos($file, 'language/') !== 0) - { - $update_list['no_update'][] = $file; - } - }*/ - - if (!phpbb_ignore_new_file_on_update($phpbb_root_path, $file)) - { - $this->get_custom_info($update_list['new'], $file); - $update_list['new'][] = array('filename' => $file, 'custom' => false); - } - - // unset($this->update_info['files'][$index]); - } - else - { - // not modified? - $this->make_update_diff($update_list, $file, $file, $expected_files); - } - - $num_bytes_processed += (file_exists($this->new_location . $file)) ? filesize($this->new_location . $file) : 100 * 1024; - $update_list['status']++; - } - - foreach ($this->update_info['deleted'] as $index => $file) - { - if (is_int($update_list['status_deleted']) && $index < $update_list['status_deleted']) - { - continue; - } - - if ($num_bytes_processed >= 500 * 1024) - { - return; - } - - if (file_exists($phpbb_root_path . $file)) - { - $update_list['deleted'][] = array('filename' => $file, 'custom' => false, 'as_expected' => false); - $num_bytes_processed += filesize($phpbb_root_path . $file); - } - - $update_list['status_deleted']++; - $update_list['status']++; - } - - $update_list['status_deleted'] = -1; - $update_list['status'] = -1; - -/* if (!sizeof($this->update_info['files'])) - { - return $update_list; - } - - // Now diff the remaining files to get information about their status (not modified/modified/up-to-date) - - // not modified? - foreach ($this->update_info['files'] as $index => $file) - { - $this->make_update_diff($update_list, $file, $file); - } - - // Now to the styles... - if (empty($this->update_info['custom'])) - { - return $update_list; - } - - foreach ($this->update_info['custom'] as $original_file => $file_ary) - { - foreach ($file_ary as $index => $file) - { - $this->make_update_diff($update_list, $original_file, $file, true); - } - } - - return $update_list;*/ - } - - /** - * Compare files for storage in update_list - */ - function make_update_diff(&$update_list, $original_file, $file, $expected_files, $custom = false) - { - global $phpbb_root_path, $user; - - $update_ary = array('filename' => $file, 'custom' => $custom, 'as_expected' => false); - - if ($custom) - { - $update_ary['original'] = $original_file; - } - - if (file_exists($phpbb_root_path . $file)) - { - $content = file_get_contents($phpbb_root_path . $file); - - if (isset($expected_files[$file]) && // the user already selected what to do with this file - ($expected_files[$file] === false || // the user wanted this file to stay the same, so just assume it's alright - $expected_files[$file] === md5($content))) - { - // the file contains what it was supposed to contain after the merge - $update_ary['as_expected'] = true; - $update_ary['was_ignored'] = ($expected_files[$file] === false); - $update_list['up_to_date'][] = $update_ary; - - return; - } - } - - // we only want to know if the files are successfully merged and newlines could result in errors (duplicate addition of lines and such things) - // Therefore we check for empty diffs with two methods, preserving newlines and not preserving them (which mostly works best, therefore the first option) - - // On a successfull update the new location file exists but the old one does not exist. - // Check for this circumstance, the new file need to be up-to-date with the current file then... - if (!file_exists($this->old_location . $original_file) && file_exists($this->new_location . $original_file) && file_exists($phpbb_root_path . $file)) - { - $tmp = array( - 'file1' => file_get_contents($this->new_location . $original_file), - 'file2' => $content, - ); - - // We need to diff the contents here to make sure the file is really the one we expect - $diff = new diff($tmp['file1'], $tmp['file2'], false); - $empty = $diff->is_empty(); - - unset($tmp, $diff); - - // if there are no differences we have an up-to-date file... - if ($empty) - { - $update_list['up_to_date'][] = $update_ary; - return; - } - - // If no other status matches we have another file in the way... - $update_list['new_conflict'][] = $update_ary; - return; - } - - // Old file removed? - if (file_exists($this->old_location . $original_file) && !file_exists($this->new_location . $original_file)) - { - return; - } - - // Check for existance, else abort immediately - if (!file_exists($this->old_location . $original_file) || !file_exists($this->new_location . $original_file)) - { - trigger_error($user->lang['INCOMPLETE_UPDATE_FILES'], E_USER_ERROR); - } - - $preserve_cr_ary = array(false, true); - - foreach ($preserve_cr_ary as $preserve_cr) - { - $tmp = array( - 'file1' => file_get_contents($this->old_location . $original_file), - 'file2' => $content, - ); - - // We need to diff the contents here to make sure the file is really the one we expect - $diff = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); - $empty_1 = $diff->is_empty(); - - unset($tmp, $diff); - - $tmp = array( - 'file1' => file_get_contents($this->new_location . $original_file), - 'file2' => $content, - ); - - $diff = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); - $empty_2 = $diff->is_empty(); - - unset($tmp, $diff); - - // If the file is not modified we are finished here... - if ($empty_1) - { - // Further check if it is already up to date - it could happen that non-modified files - // slip through - if ($empty_2) - { - $update_list['up_to_date'][] = $update_ary; - return; - } - - $update_list['not_modified'][] = $update_ary; - return; - } - - // If the file had been modified then we need to check if it is already up to date - - // if there are no differences we have an up-to-date file... - if ($empty_2) - { - $update_list['up_to_date'][] = $update_ary; - return; - } - } - - $conflicts = false; - - foreach ($preserve_cr_ary as $preserve_cr) - { - // if the file is modified we try to make sure a merge succeed - $tmp = array( - 'orig' => file_get_contents($this->old_location . $original_file), - 'final1' => file_get_contents($phpbb_root_path . $file), - 'final2' => file_get_contents($this->new_location . $original_file), - ); - - $diff = new diff3($tmp['orig'], $tmp['final1'], $tmp['final2'], $preserve_cr); - unset($tmp); - - if (!$diff->get_num_conflicts()) - { - $tmp = array( - 'file1' => file_get_contents($phpbb_root_path . $file), - 'file2' => implode("\n", $diff->merged_output()), - ); - - // now compare the merged output with the original file to see if the modified file is up to date - $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); - $empty = $diff2->is_empty(); - - unset($diff, $diff2); - - if ($empty) - { - $update_list['up_to_date'][] = $update_ary; - return; - } - - // If we preserve cr tag it as modified because the conflict would not show in this mode anyway - if ($preserve_cr) - { - $update_list['modified'][] = $update_ary; - return; - } - } - else - { - // There is one special case... users having merged with a conflicting file... we need to check this - $tmp = array( - 'file1' => file_get_contents($phpbb_root_path . $file), - 'file2' => implode("\n", $diff->merged_new_output()), - ); - - $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); - $empty = $diff2->is_empty(); - - if (!$empty) - { - unset($tmp, $diff2); - - // We check if the user merged with his output - $tmp = array( - 'file1' => file_get_contents($phpbb_root_path . $file), - 'file2' => implode("\n", $diff->merged_orig_output()), - ); - - $diff2 = new diff($tmp['file1'], $tmp['file2'], $preserve_cr); - $empty = $diff2->is_empty(); - } - - if (!$empty) - { - $conflicts = $diff->get_num_conflicts(); - } - - unset($diff, $diff2); - - if ($empty) - { - // A conflict got resolved... - $update_list['up_to_date'][] = $update_ary; - return; - } - } - } - - if ($conflicts !== false) - { - $update_ary['conflicts'] = $conflicts; - $update_list['conflict'][] = $update_ary; - return; - } - - // If no other status matches we have a modified file... - $update_list['modified'][] = $update_ary; - } - - /** - * Update update_list with custom new files - */ - function get_custom_info(&$update_list, $file) - { - if (empty($this->update_info['custom'])) - { - return; - } - - if (isset($this->update_info['custom'][$file])) - { - foreach ($this->update_info['custom'][$file] as $_file) - { - $update_list[] = array('filename' => $_file, 'custom' => true, 'original' => $file); - } - } - } - - /** - * Get remote file - */ - function get_file($mode) - { - global $user, $db; - - $errstr = ''; - $errno = 0; - - switch ($mode) - { - case 'update_info': - global $phpbb_root_path, $phpEx; - - $update_info = array(); - include($phpbb_root_path . 'install/update/index.' . $phpEx); - - $info = (empty($update_info) || !is_array($update_info)) ? false : $update_info; - $errstr = ($info === false) ? $user->lang['WRONG_INFO_FILE_FORMAT'] : ''; - - if ($info !== false) - { - // We assume that all file extensions have been renamed to .$phpEx, - // if someone is using a non .php file extension for php files. - // However, in $update_info['files'] we use hardcoded .php. - // We therefore replace .php with .$phpEx. - $info['files'] = preg_replace('/\.php$/i', ".$phpEx", $info['files']); - - // Adjust the update info file to hold some specific style-related information - $info['custom'] = array(); -/* - // Get custom installed styles... - $sql = 'SELECT style_name, style_path - FROM ' . STYLES_TABLE . " - WHERE LOWER(style_name) NOT IN ('prosilver')"; - $result = $db->sql_query($sql); - - $templates = array(); - while ($row = $db->sql_fetchrow($result)) - { - $templates[] = $row; - } - $db->sql_freeresult($result); - - if (sizeof($templates)) - { - foreach ($info['files'] as $filename) - { - // Template update? - if (strpos(strtolower($filename), 'styles/prosilver/template/') === 0) - { - foreach ($templates as $row) - { - $info['custom'][$filename][] = str_replace('/prosilver/', '/' . $row['style_path'] . '/', $filename); - } - } - } - } -*/ - } - break; - - default: - trigger_error('Mode for getting remote file not specified', E_USER_ERROR); - break; - } - - if ($info === false) - { - trigger_error($errstr, E_USER_ERROR); - } - - return $info; - } - - /** - * Function for including files... - */ - function include_file($filename) - { - global $phpbb_root_path, $phpEx; - - if (!empty($this->update_info['files']) && in_array($filename, $this->update_info['files'])) - { - include_once($this->new_location . $filename); - } - else - { - include_once($phpbb_root_path . $filename); - } - } - - /** - * Wrapper for returning a diff object - */ - function return_diff() - { - $args = func_get_args(); - $three_way_diff = (func_num_args() > 2) ? true : false; - - $file1 = array_shift($args); - $file2 = array_shift($args); - - $tmp['file1'] = (!empty($file1) && is_string($file1)) ? file_get_contents($file1) : $file1; - $tmp['file2'] = (!empty($file2) && is_string($file2)) ? file_get_contents($file2) : $file2; - - if ($three_way_diff) - { - $file3 = array_shift($args); - $tmp['file3'] = (!empty($file3) && is_string($file3)) ? file_get_contents($file3) : $file3; - - $diff = new diff3($tmp['file1'], $tmp['file2'], $tmp['file3']); - } - else - { - $diff = new diff($tmp['file1'], $tmp['file2']); - } - - unset($tmp); - - return $diff; - } -} diff --git a/phpBB/install_old/phpinfo.php b/phpBB/install_old/phpinfo.php deleted file mode 100644 index 1512b00563..0000000000 --- a/phpBB/install_old/phpinfo.php +++ /dev/null @@ -1,14 +0,0 @@ - -* @license GNU General Public License, version 2 (GPL-2.0) -* -* For full copyright and license information, please see -* the docs/CREDITS.txt file. -* -*/ - -phpinfo(); -- cgit v1.2.1