diff options
| author | Nils Adermann <naderman@naderman.de> | 2010-03-02 01:05:34 +0100 |
|---|---|---|
| committer | Nils Adermann <naderman@naderman.de> | 2010-03-02 01:05:34 +0100 |
| commit | 517f25353246f06eec7d1fdef90a04119a45bbbf (patch) | |
| tree | 7837b0e54fcd05f2f49a22a078b0f12cad864b30 /phpBB/install | |
| parent | 89b37954f994a7cd517553d2d16686f91dcaae72 (diff) | |
| parent | 7068d8b462e388ea87883c5203a28fa6a8e4b6dc (diff) | |
| download | forums-517f25353246f06eec7d1fdef90a04119a45bbbf.tar forums-517f25353246f06eec7d1fdef90a04119a45bbbf.tar.gz forums-517f25353246f06eec7d1fdef90a04119a45bbbf.tar.bz2 forums-517f25353246f06eec7d1fdef90a04119a45bbbf.tar.xz forums-517f25353246f06eec7d1fdef90a04119a45bbbf.zip | |
Merge commit 'release-3.0-B5'
Diffstat (limited to 'phpBB/install')
| -rw-r--r-- | phpBB/install/convertors/convert_phpbb20.php | 859 | ||||
| -rw-r--r-- | phpBB/install/convertors/functions_phpbb20.php | 1449 | ||||
| -rw-r--r-- | phpBB/install/database_update.php | 361 | ||||
| -rwxr-xr-x | phpBB/install/index.php | 28 | ||||
| -rw-r--r-- | phpBB/install/install_convert.php | 1736 | ||||
| -rwxr-xr-x | phpBB/install/install_install.php | 231 | ||||
| -rw-r--r-- | phpBB/install/install_update.php | 426 | ||||
| -rw-r--r-- | phpBB/install/schemas/firebird_schema.sql | 10 | ||||
| -rw-r--r-- | phpBB/install/schemas/mssql_schema.sql | 16 | ||||
| -rw-r--r-- | phpBB/install/schemas/mysql_40_schema.sql | 17 | ||||
| -rw-r--r-- | phpBB/install/schemas/mysql_41_schema.sql | 17 | ||||
| -rw-r--r-- | phpBB/install/schemas/oracle_schema.sql | 21 | ||||
| -rw-r--r-- | phpBB/install/schemas/postgres_schema.sql | 15 | ||||
| -rw-r--r-- | phpBB/install/schemas/schema_data.sql | 88 | ||||
| -rw-r--r-- | phpBB/install/schemas/sqlite_schema.sql | 19 |
15 files changed, 5044 insertions, 249 deletions
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php new file mode 100644 index 0000000000..14fde80478 --- /dev/null +++ b/phpBB/install/convertors/convert_phpbb20.php @@ -0,0 +1,859 @@ +<?php +/** +* +* @package install +* @version $Id$ +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +* 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; +} + +/** +* $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' => '0.9', + 'phpbb_version' => '3.0.0', + 'author' => '<a href="http://www.phpbb.com/">phpBB Group</a>', + 'table_prefix' => 'phpbb_', + 'forum_path' => '../forums', + 'author_notes' => 'Avatars may be on a different width/height than with the old forum. This is due to dimensions being stored within phpBB3 but not within phpBB2. The default dimension was set to 80x80 for avatars where dimension settings could not be determined. You might wish to instruct your users to check their profiles after the conversion to ensure that the size is correct.', +); + +/** +* $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 +* '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' => 'sitename', + 'site_desc' => 'site_desc', + 'session_length' => 'session_length', + 'board_email_sig' => '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' => 'default_dateformat', + 'board_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_required') !== false) + { + define('MOD_BIRTHDAY', true); + } + + // TerraFrost's validated birthday mod + if (get_config_value('bday_required') !== 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 + $db->sql_return_on_error(true); + + $sql = "SELECT config_value + FROM {$convert->src_table_prefix}attachments_config + WHERE config_name = 'upload_dir'"; + $result = $db->sql_query($sql); + + if ($result && $row = $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' + ); + + $db->sql_freeresult($result); + } + + /** + * Tests for further MODs can be included here. + * Please use constants for this, prefixing them with MOD_ + */ + + $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 = $db->sql_query($sql); + $user_id = (int) $db->sql_fetchfield('user_id'); + $db->sql_freeresult($result); + + // If there is a user id 1, we need to increment user ids. :/ + if ($user_id === 1) + { + set_config('increment_user_id', 1, true); + } + else + { + set_config('increment_user_id', 0, true); + } + +/** +* 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' => 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( + $convert->truncate_statement . SEARCH_RESULTS_TABLE, + $convert->truncate_statement . SEARCH_WORDLIST_TABLE, + $convert->truncate_statement . SEARCH_WORDMATCH_TABLE, + $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(); } + + 'execute_first' => ' + 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(); + ', ' + phpbb_convert_authentication(\'start\'); + ', ' + phpbb_convert_authentication(\'first\'); + ', ' + phpbb_convert_authentication(\'second\'); + ', ' + phpbb_convert_authentication(\'third\'); + '), + + 'schema' => array( + + array( + 'target' => (defined('MOD_ATTACHMENT')) ? ATTACHMENTS_TABLE : '', + 'primary' => 'attachments.attach_id', + 'query_first' => (defined('MOD_ATTACHMENT')) ? $convert->truncate_statement . ATTACHMENTS_TABLE : '', + + 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', ''), + 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', + + 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', ''), + 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')) ? $convert->truncate_statement . EXTENSIONS_TABLE : '', + + 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')) ? $convert->truncate_statement . EXTENSION_GROUPS_TABLE : '', + + 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, + 'query_first' => $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', ''), + + 'where' => "banlist.ban_ip NOT LIKE '%.%'", + ), + + array( + 'target' => BANLIST_TABLE, + + array('ban_ip', 'banlist.ban_ip', ''), + array('ban_userid', '0', ''), + array('ban_email', '', ''), + + 'where' => "banlist.ban_ip LIKE '%.%'", + ), + + array( + 'target' => DISALLOW_TABLE, + 'query_first' => $convert->truncate_statement . DISALLOW_TABLE, + + array('disallow_username', 'disallow.disallow_username', 'phpbb_set_encoding'), + ), + + array( + 'target' => RANKS_TABLE, + 'query_first' => $convert->truncate_statement . RANKS_TABLE, + + array('rank_id', 'ranks.rank_id', ''), + array('rank_title', 'ranks.rank_title', array('function1' => 'phpbb_set_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' => $convert->truncate_statement . TOPICS_TABLE, + 'primary' => 'topics.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_replies', 'topics.topic_replies', ''), + array('topic_replies_real', 'topics.topic_replies', ''), + 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('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => '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_TABLE, + 'primary' => 'topics.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_replies', 'topics.topic_replies', ''), + array('topic_replies_real', 'topics.topic_replies', ''), + 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('poll_title', 'vote_desc.vote_text', array('function1' => 'null_to_str', 'function2' => 'phpbb_set_encoding', 'function3' => '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' => $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' => $convert->truncate_statement . SMILIES_TABLE, + + array('smiley_id', 'smilies.smilies_id', ''), + array('code', 'smilies.code', 'phpbb_set_encoding'), + 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', array( + 'execute' => '{RESULT} = ({VALUE}[0] <= 20) ? 1 : 0;', + )), + + 'order_by' => 'smilies.smilies_id ASC', + ), + + array( + 'target' => POLL_OPTIONS_TABLE, + 'primary' => 'vote_results.vote_option_id', + 'query_first' => $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' => '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' => $convert->truncate_statement . POLL_VOTES_TABLE, + + array('poll_option_id', 1, ''), + 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' => $convert->truncate_statement . WORDS_TABLE, + + 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', + 'query_first' => $convert->truncate_statement . POSTS_TABLE, + 'execute_first' => ' + $config["max_post_chars"] = 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('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', + 'query_first' => array( + $convert->truncate_statement . PRIVMSGS_TABLE, + $convert->truncate_statement . PRIVMSGS_RULES_TABLE, + ), + + 'execute_first' => ' + $config["max_post_chars"] = 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', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), + 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'), + + 'where' => 'privmsgs.privmsgs_id = privmsgs_text.privmsgs_text_id' + ), + + array( + 'target' => PRIVMSGS_FOLDER_TABLE, + 'primary' => 'users.user_id', + 'query_first' => $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' => $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_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', '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_OUTBOX, ''), + + 'where' => '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_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_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_type = 4', + ), + + array( + 'target' => GROUPS_TABLE, + 'query_first' => $convert->truncate_statement . GROUPS_TABLE, + + array('group_id', 'groups.group_id', ''), + array('group_type', 'groups.group_type', 'phpbb_convert_group_type'), + array('group_display', 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' => $convert->truncate_statement . USER_GROUP_TABLE, + 'execute_first' => ' + add_default_groups(); + ', + + 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', + 'query_first' => array( + 'DELETE FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS, + $convert->truncate_statement . BOTS_TABLE + ), + + 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', ''), + array('user_pass_convert', 1, ''), + array('user_posts', 'users.user_posts', ''), + 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', ''), + array('user_lang', $config['default_lang'], ''), + array('', 'users.user_lang', ''), + array('user_timezone', 'users.user_timezone', ''), + array('user_dateformat', 'users.user_dateformat', ''), + array('user_inactive_reason', '', 'phpbb_inactive_reason'), + array('user_inactive_time', '', 'phpbb_inactive_time'), + + array('user_interests', 'users.user_interests', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), + array('user_occ', 'users.user_occ', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), + array('user_website', 'users.user_website', 'validate_website'), + array('user_jabber', '', ''), + array('user_msnm', 'users.user_msnm', ''), + array('user_yim', 'users.user_yim', ''), + array('user_aim', 'users.user_aim', ''), + array('user_icq', 'users.user_icq', ''), + array('user_from', 'users.user_from', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')), + array('user_rank', 'users.user_rank', ''), + 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', 'get_avatar_width'), + array('user_avatar_height', 'users.user_avatar', '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', ''), + array('user_emailtime', 'users.user_emailtime', 'null_to_zero'), + array('user_notify', 'users.user_notify', ''), + array('user_notify_pm', 'users.user_notify_pm', ''), + array('user_notify_type', NOTIFY_EMAIL, ''), + array('user_allow_pm', 'users.user_allow_pm', ''), + array('user_allow_viewonline', 'users.user_allow_viewonline', ''), + array('user_allow_viewemail', 'users.user_viewemail', ''), + array('user_actkey', 'users.user_actkey', ''), + array('user_newpasswd', 'users.user_newpasswd', ''), + + 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', ''), + + 'where' => 'users.user_id <> -1', + ), + ), + ); +} + +?>
\ No newline at end of file diff --git a/phpBB/install/convertors/functions_phpbb20.php b/phpBB/install/convertors/functions_phpbb20.php new file mode 100644 index 0000000000..05daae473b --- /dev/null +++ b/phpBB/install/convertors/functions_phpbb20.php @@ -0,0 +1,1449 @@ +<?php +/** +* +* @package install +* @version $Id$ +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +* Helper functions for phpBB 2.0.x to phpBB 3.0.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, $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 = $db->sql_query($sql); + $max_forum_id = (int) $db->sql_fetchfield('max_forum_id'); + $db->sql_freeresult($result); + + $max_forum_id++; + + // Insert categories + $sql = 'SELECT cat_id, cat_title + FROM ' . $convert->src_table_prefix . 'categories + ORDER BY cat_order'; + + if ($convert->mysql_convert) + { + $db->sql_query("SET NAMES 'binary'"); + } + + $result = $db->sql_query($sql); + + if ($convert->mysql_convert) + { + $db->sql_query("SET NAMES 'utf8'"); + } + + $cats_added = array(); + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary = array( + 'forum_id' => $max_forum_id, + 'forum_name' => ($row['cat_title']) ? htmlspecialchars(phpbb_set_encoding($row['cat_title'], false), 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'] = $cat_row['right_id'] + 1; + $sql_ary['right_id'] = $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++; + } + $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 = $db->sql_query($sql); + + $unknown_cat_id = false; + while ($row = $db->sql_fetchrow($result)) + { + // Catch those categories not been added before + if (!isset($cats_added[$row['cat_id']])) + { + $unknown_cat_id = true; + } + } + $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' => $max_forum_id, + 'forum_name' => $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'] = $cat_row['right_id'] + 1; + $sql_ary['right_id'] = $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.*, 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 + ORDER BY f.cat_id, f.forum_order'; + + if ($convert->mysql_convert) + { + $db->sql_query("SET NAMES 'binary'"); + } + + $result = $db->sql_query($sql); + + if ($convert->mysql_convert) + { + $db->sql_query("SET NAMES 'utf8'"); + } + + while ($row = $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_encoding($row['forum_name'], false), ENT_COMPAT, 'UTF-8'), + 'parent_id' => $cats_added[$row['cat_id']], + 'forum_parents' => '', + 'forum_desc' => htmlspecialchars(phpbb_set_encoding($row['forum_desc'], false), ENT_COMPAT, 'UTF-8'), + 'forum_type' => FORUM_POST, + 'forum_status' => is_item_locked($row['forum_status']), + 'enable_prune' => $row['prune_enable'], + 'prune_next' => null_to_zero($row['prune_next']), + 'prune_days' => null_to_zero($row['prune_days']), + 'prune_viewed' => 0, + 'prune_freq' => null_to_zero($row['prune_freq']), + + 'forum_flags' => phpbb_forum_flags(), + + // 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' => 0, + 'forum_topics' => 0, + 'forum_topics_real' => 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'] = $cat_row['right_id']; + $sql_ary['right_id'] = $cat_row['right_id'] + 1; + + $sql = 'INSERT INTO ' . FORUMS_TABLE . ' ' . $db->sql_build_array('INSERT', $sql_ary); + $db->sql_query($sql); + } + $db->sql_freeresult($result); +} + +/** +* 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 $db; + + $sql = 'SELECT user_lang + FROM ' . $convert->src_table_prefix . 'users + WHERE user_id = ' . (int) $convert_row['poster_id']; + $result = $db->sql_query($sql); + $get_lang = (string) $db->sql_fetchfield('user_lang'); + $db->sql_freeresult($result); + + $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 = '') +{ + $birthday = (int) $birthday; + + if (defined('MOD_BIRTHDAY_TERRA')) + { + // stored as month, day, year + if (!$birthday) + { + return ' 0- 0- 0'; + } + + $birthday = (string) $birthday; + + $month = substr($birthday, 0, 2); + $day = substr($birthday, 2, 2); + $year = substr($birthday, -4); + + return sprintf('%2d-%2d-%4d', $day, $month, $year); + } + else + { + if (!$birthday || $birthday == 999999 || $birthday < 0) + { + return ' 0- 0- 0'; + } + + // The birthday mod from niels is using this code to transform to day/month/year + return gmdate('d-m-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) +{ + if (!$user_id) + { + return 0; + } + + if ($user_id == -1) + { + return ANONYMOUS; + } + + global $config; + + // Increment user id if the old forum is having a user with the id 1 + if (!isset($config['increment_user_id'])) + { + global $db, $convert; + + // 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 = $db->sql_query($sql); + $id = (int) $db->sql_fetchfield('user_id'); + $db->sql_freeresult($result); + + // If there is a user id 1, we need to increment user ids. :/ + if ($id === 1) + { + set_config('increment_user_id', 1, true); + $config['increment_user_id'] = 1; + } + else + { + set_config('increment_user_id', 0, true); + $config['increment_user_id'] = 0; + } + } + + if (!empty($config['increment_user_id'])) + { + $user_id++; + } + + return $user_id; +} + +/* 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, $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); + + // Grab user id of first user 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 = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $founder_id = phpbb_user_id($row['user_id']); + + // Set a founder admin ... we'll assume it's the first user with admin level access + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_type = ' . USER_FOUNDER . " + WHERE user_id = $founder_id"; + $db->sql_query($sql); + } + + // Grab forum auth information + $sql = "SELECT * + FROM {$convert->src_table_prefix}forums"; + $result = $db->sql_query($sql); + + $forum_access = array(); + while ($row = $db->sql_fetchrow($result)) + { + $forum_access[] = $row; + } + $db->sql_freeresult($result); + + // 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 + WHERE g.group_id = aa.group_id + AND g.group_single_user = 1 + AND ug.group_id = g.group_id"; + $result = $db->sql_query($sql); + + $user_access = array(); + while ($row = $db->sql_fetchrow($result)) + { + $user_access[$row['forum_id']][] = $row; + } + $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 = $db->sql_query($sql); + + $group_access = array(); + while ($row = $db->sql_fetchrow($result)) + { + $group_access[$row['forum_id']][] = $row; + } + $db->sql_freeresult($result); + + // Add Forum Access List + $auth_map = array( + 'auth_view' => array('f_', 'f_list'), + 'auth_read' => 'f_read', + 'auth_post' => array('f_post', 'f_bbcode', 'f_smilies', 'f_img', 'f_sigs', 'f_search', 'f_postcount'), + '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' => 'f_attach', + '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); + user_group_auth('registered', 'SELECT user_id, {REGISTERED} FROM ' . USERS_TABLE . ' WHERE user_id <> ' . ANONYMOUS); + + // Selecting from old table + $auth_sql = 'SELECT '; + $auth_sql .= (!empty($config['increment_user_id'])) ? 'user_id + 1 as user_id' : 'user_id'; + $auth_sql .= ', {ADMINISTRATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1'; + + user_group_auth('administrators', $auth_sql); + + // Put administrators into global moderators group too... + $auth_sql = 'SELECT '; + $auth_sql .= (!empty($config['increment_user_id'])) ? 'user_id + 1 as user_id' : 'user_id'; + $auth_sql .= ', {GLOBAL_MODERATORS} FROM ' . $convert->src_table_prefix . 'users WHERE user_level = 1'; + + user_group_auth('global_moderators', $auth_sql); + } + else if ($mode == 'first') + { + // Go through all 2.0.x forums (we saved those ids for reference) + 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_LIMITED_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, '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 standard access (the founder still have full access) + mass_auth('group_role', 0, 'administrators', 'ADMIN_STANDARD'); + + // 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 = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + mass_auth('user_role', 0, (int) phpbb_user_id($row['user_id']), 'USER_NOAVATAR'); + } + $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 = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + mass_auth('user_role', 0, (int) phpbb_user_id($row['user_id']), 'USER_NOPM'); + } + $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 + 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 ($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'); + } + } + } + + // 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'); + $parent_forums[] = $row; + } + else + { + $forums[] = $row; + } + } + $db->sql_freeresult($result); + + global $auth; + + // Let us see if guests/registered users 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(get_group_id('guests'), 'f_list', $forum_ids); + + if (!empty($hold_ary)) + { + mass_auth('group', $row['forum_id'], 'guests', 'f_list', ACL_YES); + mass_auth('group', $row['forum_id'], 'registered', '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_encoding($group_name, false); +} + +/** +* 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; + } + + return GROUP_SPECIAL; +} + +/** +* 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; +} + +/** +* 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'] != '') + { + $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); + } + + $user_id = $convert->row['poster_id']; + + $message = str_replace('<', '<', $message); + $message = str_replace('>', '>', $message); + $message = str_replace('<br />', "\n", $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('<span style="color:red">' . $user->lang['POST_ID'] . ': ' . $msg_id . ' ' . $user->lang['CONV_ERROR_MESSAGE_PARSER'] . ': <br /><br />' . implode('<br />', $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 $db, $convert, $user, $config, $cache; + + $sql = 'SELECT config_value AS upload_dir + FROM ' . $convert->src_table_prefix . "attachments_config + WHERE config_name = 'upload_dir'"; + $result = $db->sql_query($sql); + $upload_path = $db->sql_fetchfield('upload_dir'); + $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 = $db->sql_query($sql); + $ftp_upload = (int) $db->sql_fetchfield('ftp_upload'); + $db->sql_freeresult($result); + + 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; +} + +/** +* 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; +} + +/** +* 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); + } + 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 ''; +} + +/** +* 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, $convert, $config; + + $sql = 'SELECT * + FROM ' . $convert->src_table_prefix . 'attachments_config'; + $result = $db->sql_query($sql); + + $attach_config = array(); + while ($row = $db->sql_fetchrow($result)) + { + $attach_config[$row['config_name']] = $row['config_value']; + } + $db->sql_freeresult($result); + + set_config('allow_attachments', 1); + + // old attachment mod? Must be very old if this entry do not exist... + if (!empty($attach_config['display_order'])) + { + set_config('display_order', $attach_config['display_order']); + } + set_config('max_filesize', $attach_config['max_filesize']); + set_config('max_filesize_pm', $attach_config['max_filesize_pm']); + set_config('attachment_quota', $attach_config['attachment_quota']); + set_config('max_attachments', $attach_config['max_attachments']); + set_config('max_attachments_pm', $attach_config['max_attachments_pm']); + set_config('allow_pm_attach', $attach_config['allow_pm_attach']); + + set_config('img_display_inlined', $attach_config['img_display_inlined']); + set_config('img_max_width', $attach_config['img_max_width']); + set_config('img_max_height', $attach_config['img_max_height']); + set_config('img_link_width', $attach_config['img_link_width']); + set_config('img_link_height', $attach_config['img_link_height']); + set_config('img_create_thumbnail', $attach_config['img_create_thumbnail']); + set_config('img_max_thumb_width', 400); + set_config('img_min_thumb_filesize', $attach_config['img_min_thumb_filesize']); + set_config('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; +} + +?>
\ No newline at end of file diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 461b5807c2..666cb1aad3 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -8,7 +8,7 @@ * */ -$updates_to_version = '3.0.B4'; +$updates_to_version = '3.0.B5'; if (defined('IN_PHPBB') && defined('IN_INSTALL')) { @@ -27,7 +27,7 @@ $phpEx = substr(strrchr(__FILE__, '.'), 1); //error_reporting(E_ALL ^ E_NOTICE); error_reporting(E_ALL); -@set_time_limit(120); +@set_time_limit(0); // Include essential scripts include($phpbb_root_path . 'config.' . $phpEx); @@ -60,6 +60,7 @@ require($phpbb_root_path . 'includes/constants.' . $phpEx); require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx); require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx); +$user = new user(); $cache = new cache(); $db = new $sql_db(); @@ -85,6 +86,7 @@ include($phpbb_root_path . 'language/' . $row['config_value'] . '/install.' . $p //set_error_handler('msg_handler'); // Define some variables for the database update +$inline_update = (request_var('type', 0)) ? true : false; // Database column types mapping $dbms_type_map = array( @@ -283,7 +285,7 @@ $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP'); // Only an example, but also commented out $database_update_info = array( - // Changes within this version + // Changes from 3.0.b3 to the next version '3.0.b3' => array( // Change the following columns... 'change_columns' => array( @@ -307,8 +309,48 @@ $database_update_info = array( ), ), ), - // Latest version - '3.0.b4' => array(), + // Changes from 3.0.b4 to the next version + '3.0.b4' => array( + // Add the following columns + 'add_columns' => array( + CONFIRM_TABLE => array( + 'seed' => array('UINT:10', 0), + ), + SESSIONS_TABLE => array( + 'session_forwarded_for' => array('VCHAR:255', 0), + ), + ), + 'change_columns' => array( + USERS_TABLE => array( + 'user_options' => array('UINT:11', 895), + ), + FORUMS_TABLE => array( + 'prune_days' => array('UINT', 0), + 'prune_viewed' => array('UINT', 0), + 'prune_freq' => array('UINT', 0), + ), + PRIVMSGS_RULES_TABLE => array( + 'rule_folder_id' => array('INT:11', 0), + ), + PRIVMSGS_TO_TABLE => array( + 'folder_id' => array('INT:11', 0), + ), + ), + // Remove the following keys + 'drop_keys' => array( + ZEBRA_TABLE => array( + 'user_id', + 'zebra_id', + ), + ), + // Add the following primary keys + 'add_primary_keys' => array( + ZEBRA_TABLE => array( + 'user_id', + 'zebra_id', + ), + ), + ), ); // Determine mapping database type @@ -369,18 +411,39 @@ $errored = false; <p><?php echo $lang['DATABASE_TYPE']; ?> :: <strong><?php echo $db->sql_layer; ?></strong><br /> <?php -$sql = "SELECT config_value - FROM " . CONFIG_TABLE . " - WHERE config_name = 'version'"; +// To let set_config() calls succeed, we need to make the config array available globally +$config = array(); +$sql = 'SELECT * + FROM ' . CONFIG_TABLE; $result = $db->sql_query($sql); -$row = $db->sql_fetchrow($result); + +while ($row = $db->sql_fetchrow($result)) +{ + $config[$row['config_name']] = $row['config_value']; +} $db->sql_freeresult($result); -echo $lang['PREVIOUS_VERSION'] . ' :: <strong>' . $row['config_value'] . '</strong><br />'; + +echo $lang['PREVIOUS_VERSION'] . ' :: <strong>' . $config['version'] . '</strong><br />'; echo $lang['UPDATED_VERSION'] . ' :: <strong>' . $updates_to_version . '</strong>'; -$current_version = strtolower($row['config_value']); +$current_version = strtolower($config['version']); $latest_version = strtolower($updates_to_version); +$orig_version = $config['version']; + +// If the latest version and the current version are 'unequal', we will update the version_update_from, else we do not update anything. +if ($inline_update) +{ + if ($current_version !== $latest_version) + { + set_config('version_update_from', $orig_version); + } +} +else +{ + // If not called from the update script, we will actually remove the traces + $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'"); +} // Schema updates ?> @@ -439,6 +502,27 @@ foreach ($database_update_info as $version => $schema_changes) } } } + + // Remove keys? + if (!empty($schema_changes['drop_keys'])) + { + foreach ($schema_changes['drop_keys'] as $table => $indexes) + { + foreach ($indexes as $index_name) + { + sql_index_drop($map_dbms, $index_name, $table); + } + } + } + + // Add primary keys? + if (!empty($schema_changes['add_primary_keys'])) + { + foreach ($schema_changes['add_primary_keys'] as $table => $columns) + { + sql_create_primary_key($map_dbms, $table, $columns); + } + } } _write_result($no_updates, $errored, $error_ary); @@ -461,7 +545,7 @@ flush(); $no_updates = true; // some code magic -if (version_compare($current_version, '3.0.b3', '<')) +if (version_compare($current_version, '3.0.b3', '<=')) { // Set group_founder_manage for administrators group $sql = 'SELECT group_id @@ -483,6 +567,92 @@ if (version_compare($current_version, '3.0.b3', '<')) $no_updates = false; } +if (version_compare($current_version, '3.0.b4', '<=')) +{ + // Add config values + set_config('script_path', '/'); + set_config('forwarded_for_check', '0'); + set_config('ldap_password', ''); + set_config('ldap_user', ''); + set_config('fulltext_native_common_thres', '20'); + + // Remove config variables + $sql = 'DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'send_encoding'"; + _sql($sql, $errored, $error_ary); + + $sql = 'SELECT user_colour + FROM ' . USERS_TABLE . ' + WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ') + ORDER BY user_id DESC'; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + set_config('newest_user_colour', $row['user_colour'], true); + + switch ($config['allow_name_chars']) + { + case '[\w]+': + set_config('allow_name_chars', '[a-z]+'); + break; + + case '[\w_\+\. \-\[\]]+': + set_config('allow_name_chars', '[-\]_+ [a-z]+'); + break; + } + + switch ($config['pass_complex']) + { + case '.*': + set_config('pass_complex', 'PASS_TYPE_ANY'); + break; + + case '[a-zA-Z]': + set_config('pass_complex', 'PASS_TYPE_CASE'); + break; + + case '[a-zA-Z0-9]': + set_config('pass_complex', 'PASS_TYPE_ALPHA'); + break; + + case '[a-zA-Z\W]': + set_config('pass_complex', 'PASS_TYPE_SYMBOL'); + break; + } + + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = 895 WHERE user_options = 893'; + _sql($sql, $errored, $error_ary); + + $sql = 'UPDATE ' . MODULES_TABLE . " SET module_auth = 'acl_a_board' + WHERE module_class = 'acp' AND module_mode = 'version_check' AND module_auth = 'acl_a_'"; + _sql($sql, $errored, $error_ary); + + // Because the email hash could have been calculated wrongly as well as the clean string function changed, + // we will update it for every user. + + // Since this is not used in a live environment there are not much... not used in a live environment, yes! + $sql = 'SELECT user_id, user_email, username + FROM ' . USERS_TABLE; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $sql = 'UPDATE ' . USERS_TABLE . " + SET username_clean = '" . $db->sql_escape(utf8_clean_string($row['username'])) . "'"; + + if ($row['user_email']) + { + $sql .= ', user_email_hash = ' . (crc32($row['user_email']) . strlen($row['user_email'])); + } + + $sql .= ' WHERE user_id = ' . $row['user_id']; + _sql($sql, $errored, $error_ary); + } + $db->sql_freeresult($result); + + $no_updates = false; +} + _write_result($no_updates, $errored, $error_ary); $error_ary = array(); @@ -533,11 +703,33 @@ _write_result($no_updates, $errored, $error_ary); <br /> -<p style="color:red"><?php echo $lang['UPDATE_FILES_NOTICE']; ?></p> +<?php + +if (!$inline_update) +{ +?> + + <p style="color:red"><?php echo $lang['UPDATE_FILES_NOTICE']; ?></p> + + <p><?php echo $lang['COMPLETE_LOGIN_TO_BOARD']; ?></p> + +<?php +} +else +{ +?> + + <p><?php echo ((isset($lang['CONTINUE_INLINE_UPDATE'])) ? $lang['CONTINUE_INLINE_UPDATE'] : 'The database update was successful. Now please close this window and continue the update process as explained.'); ?></p> -<p><?php echo $lang['COMPLETE_LOGIN_TO_BOARD']; ?></p> + <p><a href="#" onclick="window.close();">» <?php echo $lang['CLOSE_WINDOW']; ?></a></p> <?php +} + +// Add database update to log + +$user->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : ''; +add_log('admin', 'LOG_UPDATE_DATABASE', $orig_version, $updates_to_version); // Now we purge the session table as well as all cache files $cache->purge(); @@ -892,6 +1084,117 @@ function sql_column_add($dbms, $table_name, $column_name, $column_data) } } +function sql_index_drop($dbms, $index_name, $table_name) +{ + global $dbms_type_map, $db; + global $errored, $error_ary; + + switch ($dbms) + { + case 'mssql': + $sql = 'DROP INDEX ' . $table_name . '\.' . $index_name . ' ON ' . $table_name; + _sql($sql, $errored, $error_ary); + break; + + case 'mysql_40': + case 'mysql_41': + $sql = 'DROP INDEX ' . $index_name . ' ON ' . $table_name; + _sql($sql, $errored, $error_ary); + break; + + case 'firebird': + case 'oracle': + case 'postgres': + case 'sqlite': + $sql = 'DROP INDEX ' . $table_name . '_' . $index_name; + _sql($sql, $errored, $error_ary); + break; + } +} + +function sql_create_primary_key($dbms, $table_name, $column) +{ + global $dbms_type_map, $db; + global $errored, $error_ary; + + switch ($dbms) + { + case 'firebird': + case 'postgres': + $sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; + _sql($sql, $errored, $error_ary); + break; + + case 'mssql': + $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD "; + $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED ("; + $sql .= '[' . implode("],\n\t\t[", $column) . ']'; + $sql .= ') ON [PRIMARY]'; + _sql($sql, $errored, $error_ary); + break; + + case 'mysql_40': + case 'mysql_41': + $sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')'; + _sql($sql, $errored, $error_ary); + break; + + case 'oracle': + $sql = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')'; + _sql($sql, $errored, $error_ary); + break; + + case 'sqlite': + $sql = "SELECT sql + FROM sqlite_master + WHERE type = 'table' + AND name = '{$table_name}' + ORDER BY type DESC, name;"; + $result = _sql($sql, $errored, $error_ary); + + if (!$result) + { + break; + } + + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + $db->sql_transaction('begin'); + + // Create a backup table and populate it, destroy the existing one + $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql'])); + $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name); + $db->sql_query('DROP TABLE ' . $table_name); + + preg_match('#\((.*)\)#s', $row['sql'], $matches); + + $new_table_cols = trim($matches[1]); + $old_table_cols = preg_split('/,(?=[\\sa-z])/im', $new_table_cols); + $column_list = array(); + + foreach ($old_table_cols as $declaration) + { + $entities = preg_split('#\s+#', trim($declaration)); + if ($entities == 'PRIMARY') + { + continue; + } + $column_list[] = $entities[0]; + } + + $columns = implode(',', $column_list); + + // create a new table and fill it up. destroy the temp one + $db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));'); + $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;'); + $db->sql_query('DROP TABLE ' . $table_name . '_temp'); + + $db->sql_transaction('commit'); + break; + } +} + /** * Change column type (not name!) */ @@ -986,6 +1289,7 @@ function sql_column_change($dbms, $table_name, $column_name, $column_data) /** * Add search robots to the database +* @ignore */ function add_bots() { @@ -1057,6 +1361,12 @@ function add_bots() $db->sql_query($sql); } } + else + { + // If the old bots are missing we can safely assume the user tries to execute the database update twice and + // fiddled around... + return; + } if (!function_exists('user_add')) { @@ -1121,17 +1431,18 @@ function add_bots() foreach ($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' => $config['default_lang'], - 'user_style' => 1, - 'user_timezone' => 0, - 'user_dateformat' => $config['default_dateformat'], + 'user_type' => USER_IGNORE, + 'group_id' => $group_id, + 'username' => $bot_name, + 'user_regdate' => time(), + 'user_password' => '', + 'user_colour' => '9E8DA7', + 'user_email' => '', + 'user_lang' => $config['default_lang'], + 'user_style' => 1, + 'user_timezone' => 0, + 'user_dateformat' => $config['default_dateformat'], + 'user_allow_massemail' => 0, ); $user_id = user_add($user_row); diff --git a/phpBB/install/index.php b/phpBB/install/index.php index bd8ae095a3..0a8a45b771 100755 --- a/phpBB/install/index.php +++ b/phpBB/install/index.php @@ -102,7 +102,7 @@ else define('STRIP', (get_magic_quotes_gpc()) ? true : false); } -@set_time_limit(120); +@set_time_limit(0); // Include essential scripts require($phpbb_root_path . 'includes/functions.' . $phpEx); @@ -148,6 +148,13 @@ if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) && !$language) 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; @@ -158,6 +165,7 @@ if (!$language) break; } } + closedir($dir); } // And finally, load the relevant language files @@ -222,6 +230,11 @@ class module // 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) { @@ -230,7 +243,7 @@ class module include($file); } } - @closedir($dir); + closedir($dir); unset($setmodules); @@ -324,8 +337,6 @@ class module 'S_CONTENT_DIRECTION' => $lang['DIRECTION'], 'S_CONTENT_ENCODING' => 'UTF-8', - 'S_CONTENT_DIR_LEFT' => $lang['LEFT'], - 'S_CONTENT_DIR_RIGHT' => $lang['RIGHT'], 'S_USER_LANG' => $lang['USER_LANG'], ) ); @@ -589,7 +600,7 @@ class module } /** - * Generate the relevant HTML for an input field and the assosciated label and explanatory text + * Generate the relevant HTML for an input field and the associated label and explanatory text */ function input_field($name, $type, $value='', $options='') { @@ -652,6 +663,11 @@ class module $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; @@ -667,7 +683,7 @@ class module $lang[$localname] = $file; } } - @closedir($dir); + closedir($dir); @asort($lang); @reset($lang); diff --git a/phpBB/install/install_convert.php b/phpBB/install/install_convert.php new file mode 100644 index 0000000000..256dd13b67 --- /dev/null +++ b/phpBB/install/install_convert.php @@ -0,0 +1,1736 @@ +<?php +/** +* +* @package install +* @version $Id$ +* @copyright (c) 2006 phpBB Group +* @license http://opensource.org/licenses/gpl-license.php GNU Public License +* +*/ + +/** +*/ + +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. +* @package install +*/ +class convert +{ + var $options = array(); + + var $convertor_tag = ''; + var $src_table_prefix = ''; + + var $convertor_data = array(); + var $tables = array(); + var $config_schema = array(); + var $convertor = array(); + 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 +* @package install +*/ +class install_convert extends module +{ + /** + * 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; + global $convert; + + $this->tpl_name = 'install_convert'; + $this->mode = $mode; + + $convert = new convert($this->p_master); + + switch ($sub) + { + case 'intro': + // Try opening config file + // @todo If phpBB is not installed, we need to do a cut-down installation here + // For now, we redirect to the installation script instead + if (@file_exists($phpbb_root_path . 'config.' . $phpEx)) + { + include($phpbb_root_path . 'config.' . $phpEx); + } + + if (!defined('PHPBB_INSTALLED')) + { + $template->assign_vars(array( + 'S_NOT_INSTALLED' => true, + 'TITLE' => $lang['BOARD_NOT_INSTALLED'], + 'BODY' => sprintf($lang['BOARD_NOT_INSTALLED_EXPLAIN'], append_sid($phpbb_root_path . 'install/index.' . $phpEx, 'mode=install')), + )); + + return; + } + + require($phpbb_root_path . 'config.' . $phpEx); + require($phpbb_root_path . 'includes/constants.' . $phpEx); + require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx); + require($phpbb_root_path . 'includes/functions_convert.' . $phpEx); + + $db = new $sql_db(); + $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false); + unset($dbpasswd); + + // We need to fill the config to let internal functions correctly work + $sql = 'SELECT * + FROM ' . CONFIG_TABLE; + $result = $db->sql_query($sql); + + $config = array(); + while ($row = $db->sql_fetchrow($result)) + { + $config[$row['config_name']] = $row['config_value']; + } + $db->sql_freeresult($result); + + + // 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_var('new_conv', 0); + + if ($new_conversion) + { + $config['convert_progress'] = ''; + $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'convert_progress'"); + } + + // Let's see if there is a conversion in the works... + $options = array(); + if (!empty($config['convert_progress']) && !empty($config['convert_options'])) + { + $options = unserialize($config['convert_progress']); + $options = array_merge($options, 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['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=$mode&sub=intro&new_conv=1", + 'U_CONTINUE_ACTION' => $this->p_master->module_url . "?mode=$mode&sub=in_progress&tag={$options['tag']}{$options['step']}", + )); + + return; + } + + $this->list_convertors($mode, $sub); + + break; + + case 'settings': + $this->get_convert_settings($mode, $sub); + break; + + case 'in_progress': + $this->convert_data($mode, $sub); + break; + + case 'final': + $this->page_title = $lang['CONVERT_COMPLETE']; + + $template->assign_vars(array( + 'TITLE' => $lang['CONVERT_COMPLETE'], + 'BODY' => $lang['CONVERT_COMPLETE_EXPLAIN'], + )); + + break; + } + } + + /** + * Generate a list of all available conversion modules + */ + function list_convertors($mode, $sub) + { + global $lang, $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['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'], + '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=$mode&sub=settings&tag=" . $convertors[$index]['tag'], + )); + } + } + + /** + */ + function get_convert_settings($mode, $sub) + { + global $lang, $template, $db, $phpbb_root_path, $phpEx, $config, $cache; + + require($phpbb_root_path . 'config.' . $phpEx); + require($phpbb_root_path . 'includes/constants.' . $phpEx); + require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx); + require($phpbb_root_path . 'includes/functions_convert.' . $phpEx); + + $db = new $sql_db(); + $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false); + unset($dbpasswd); + + $this->page_title = $lang['STAGE_SETTINGS']; + + // We need to fill the config to let internal functions correctly work + $sql = 'SELECT * + FROM ' . CONFIG_TABLE; + $result = $db->sql_query($sql); + + $config = array(); + while ($row = $db->sql_fetchrow($result)) + { + $config[$row['config_name']] = $row['config_value']; + } + $db->sql_freeresult($result); + + $convertor_tag = request_var('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_table_prefix = request_var('src_table_prefix', $convertor_data['table_prefix']); + $forum_path = request_var('forum_path', $convertor_data['forum_path']); + $refresh = request_var('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_var('src_url', 'Not in use at the moment'); + + $error = array(); + if ($submit) + { + if (!file_exists('./../' . $forum_path . '/' . $test_file)) + { + $error[] = sprintf($lang['COULD_NOT_FIND_PATH'], $forum_path); + } + + // The forum prefix of the old and the new forum can't be the same because the + // convertor requires all tables to be in one database. I.e. there can't be + // two tables named 'phpbb_users' + if ($src_table_prefix == $table_prefix) + { + $error[] = sprintf($lang['TABLE_PREFIX_SAME'], $src_table_prefix); + } + + // Check table prefix + if (!sizeof($error)) + { + $db->sql_return_on_error(true); + + // Try to select one row from the first table to see if the prefix is OK + $result = $db->sql_query_limit('SELECT * FROM ' . $src_table_prefix . $tables[0], 1); + + if (!$result) + { + $prefixes = array(); + if ($result = $db->sql_query('SHOW TABLES')) + { + while ($row = $db->sql_fetchrow($result)) + { + if (sizeof($row) > 1) + { + compare_table($tables, $row[0], $prefixes); + } + else if (list(, $tablename) = @each($row)) + { + compare_table($tables, $tablename, $prefixes); + } + } + $db->sql_freeresult($result); + } + + 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 .= '<br />'; + $msg .= ($possible_prefix == '*') ? $lang['BLANK_PREFIX_FOUND'] : sprintf($lang['PREFIX_FOUND'], $possible_prefix); + $src_table_prefix = ($possible_prefix == '*') ? '' : $possible_prefix; + } + + $error[] = $msg; + } + $db->sql_freeresult($result); + $db->sql_return_on_error(false); + } + + if (!sizeof($error)) + { + // Save convertor Status + set_config('convert_progress', serialize(array('step' => '', 'table_prefix' => $src_table_prefix, 'tag' => $convertor_tag)), true); + + // Save options + set_config('convert_options', serialize(array('forum_path' => './../' . $forum_path, 'refresh' => $refresh)), true); + + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['SPECIFY_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=$mode&sub=in_progress&tag=$convertor_tag", + )); + + return; + } + else + { + $template->assign_block_vars('checks', array( + 'TITLE' => $lang['SPECIFY_OPTIONS'], + 'RESULT' => '<b style="color:red">' . implode('<br />', $error) . '</b>', + )); + } + } // 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( + 'L_SUBMIT' => $lang['BEGIN_CONVERT'], + 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&sub=settings&tag=$convertor_tag", + )); + } + + /** + * The function which does the actual work (or dispatches it to the relevant places) + */ + function convert_data($mode, $sub) + { + global $template, $user, $phpbb_root_path, $phpEx, $db, $lang, $config, $cache; + global $convert, $convert_row, $message_parser, $skip_rows; + + require($phpbb_root_path . 'config.' . $phpEx); + require($phpbb_root_path . 'includes/constants.' . $phpEx); + require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx); + require($phpbb_root_path . 'includes/functions_convert.' . $phpEx); + + $db = new $sql_db(); + $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false); + unset($dbpasswd); + + $sql = 'SELECT * + FROM ' . CONFIG_TABLE; + $result = $db->sql_query($sql); + + $config = array(); + while ($row = $db->sql_fetchrow($result)) + { + $config[$row['config_name']] = $row['config_value']; + } + $db->sql_freeresult($result); + + // 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'] = -1; + + $convert->mysql_convert = false; + + switch ($db->sql_layer) + { + // Thanks MySQL, for silently converting... + case 'mysql': + case 'mysql4': + if (version_compare($db->mysql_version, '4.1.3', '>=')) + { + $convert->mysql_convert = true; + } + break; + + case 'mysqli': + $convert->mysql_convert = true; + break; + } + + // 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_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['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_table_prefix = $convert->options['table_prefix']; + $convert->truncate_statement = ($db->sql_layer != 'sqlite') ? 'TRUNCATE TABLE ' : 'DELETE FROM '; + + $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']; + + if (!file_exists($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx)) + { + trigger_error('NO_SUCH_SEARCH_MODULE'); + } + + require($phpbb_root_path . 'includes/search/' . $search_type . '.' . $phpEx); + + $error = false; + $convert->fulltext_search = new $search_type($error); + + if ($error) + { + trigger_error($error); + } + + include($phpbb_root_path . 'includes/message_parser.' . $phpEx); + $message_parser = new parse_message(); + + $jump = request_var('jump', 0); + $sync_batch = request_var('sync_batch', -1); + $last_statement = request_var('last', 0); + + // We are running sync... + if ($sync_batch >= 0) + { + $this->sync_forums($sync_batch); + return; + } + + if ($jump) + { + $this->jump($jump, $last_statement); + return; + } + + $current_table = request_var('current_table', 0); + $old_current_table = min(-1, $current_table - 1); + $skip_rows = request_var('skip_rows', 0); + + if (!$current_table && !$skip_rows) + { + if (empty($_REQUEST['confirm'])) + { + // 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 || !is_writeable($phpbb_root_path . $local_path)) + { + if (!$local_path) + { + $bad_folders[] = sprintf($user->lang['CONFIG_PHPBB_EMPTY'], $folder); + } + else + { + $bad_folders[] = $local_path; + } + } + } + } + + if (sizeof($bad_folders)) + { + $msg = (sizeof($bad_folders) == 1) ? $user->lang['MAKE_FOLDER_WRITABLE'] : $user->lang['MAKE_FOLDERS_WRITABLE']; + sort($bad_folders); + $this->p_master->error(sprintf($msg, implode('<br />', $bad_folders)), __LINE__, __FILE__, true); + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['INSTALL_TEST'], + 'U_ACTION' => $this->p_master->module_url . "?mode=$mode&sub=in_progress&tag={$convert->convertor_tag}", + )); + 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 + $db->sql_return_on_error(true); + foreach ($tables_list as $table => $null) + { + $sql = 'SELECT 1 FROM ' . $table; + $_result = $db->sql_query_limit($sql, 1); + + if (!$_result) + { + $missing_tables[] = $table; + } + $db->sql_freeresult($_result); + } + $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(', ', $missing_tables)) . '<br /><br />' . $user->lang['CHECK_TABLE_PREFIX'], __LINE__, __FILE__); + } + + $step = '&confirm=1'; + set_config('convert_progress', serialize(array('step' => $step, 'table_prefix' => $convert->src_table_prefix, 'tag' => $convert->convertor_tag)), true); + + $msg = $user->lang['PRE_CONVERT_COMPLETE'] . '</p><p>' . sprintf($user->lang['AUTHOR_NOTES'], $convert->convertor_data['author_notes']); + $url = $this->p_master->module_url . "?mode=$mode&sub=in_progress&tag={$convert->convertor_tag}$step"; + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], + 'L_MESSAGE' => $msg, + 'U_ACTION' => $url, + )); + + return; + } // if (empty($_REQUEST['confirm'])) + + $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); + } + + $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'])) + { + eval($convert->convertor['execute_first']); + } + + if (!empty($convert->convertor['query_first'])) + { + if (!is_array($convert->convertor['query_first'])) + { + $convert->convertor['query_first'] = array($convert->convertor['query_first']); + } + + foreach ($convert->convertor['query_first'] as $query_first) + { + $db->sql_query($query_first); + } + } + + $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'])) + { + eval($schema['execute_first']); + } + + if (!empty($schema['query_first'])) + { + if (!is_array($schema['query_first'])) + { + $schema['query_first'] = array($schema['query_first']); + } + + foreach ($schema['query_first'] as $query_first) + { + $db->sql_query($query_first); + } + } + } + + // 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'])) + { + eval($schema['execute_always']); + } + + // + // 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 + $sql .= (!empty($schema['group_by'])) ? "\nGROUP BY " . $schema['group_by'] : ''; + + // Having + $sql .= (!empty($schema['having'])) ? "\nHAVING " . $schema['having'] : ''; + + // Order By + $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_EXTRA') && function_exists('memory_get_usage')) ? ceil(memory_get_usage()/1024) . ' KB' : ''), + )); + + $mtime = explode(' ', microtime()); + $batch_time = $mtime[0] + $mtime[1]; + + if ($convert->mysql_convert) + { + $db->sql_query("SET NAMES 'binary'"); + } + + // Take skip rows into account and only fetch batch_size amount of rows + $___result = $db->sql_query_limit($sql, $convert->batch_size, $skip_rows); + + if ($convert->mysql_convert) + { + $db->sql_query("SET NAMES 'utf8'"); + } + + // This loop processes each row + $counting = 0; + + $convert->row = $convert_row = array(); + + // Now handle the rows until time is over or no more rows to process... + while (still_on_time()) + { + $convert_row = $db->sql_fetchrow($___result); + + if (!$convert_row) + { + // move to the next batch or table + $db->sql_freeresult($___result); + 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->sql_layer) + { + // If MySQL, we'll wait to have num_wait_rows rows to submit at once + case 'mysql': + case 'mysql4': + case 'mysqli': + $waiting_rows[] = '(' . implode(', ', $insert_values) . ')'; + + if (sizeof($waiting_rows) >= $convert->num_wait_rows) + { + $errored = false; + + $db->sql_return_on_error(true); + + if (!$db->sql_query($insert_query . implode(', ', $waiting_rows))) + { + $errored = true; + } + $db->sql_return_on_error(false); + + if ($errored) + { + $db->sql_return_on_error(true); + + // Because it errored out we will try to insert the rows one by one... most of the time this + // is caused by duplicate entries - but we also do not want to miss one... + foreach ($waiting_rows as $waiting_sql) + { + if (!$db->sql_query($insert_query . $waiting_sql)) + { + $this->p_master->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_query . $waiting_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true); + } + } + + $db->sql_return_on_error(false); + } + + $waiting_rows = array(); + } + + break; + + default: + $insert_sql = $insert_query . '(' . implode(', ', $insert_values) . ')'; + + $db->sql_return_on_error(true); + + if (!$db->sql_query($insert_sql)) + { + $this->p_master->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true); + } + $db->sql_return_on_error(false); + + $waiting_rows = array(); + + break; + } + } + + $skip_rows++; + } + $db->sql_freeresult($___result); + + // We might still have some rows waiting + if (sizeof($waiting_rows)) + { + $errored = false; + $db->sql_return_on_error(true); + + if (!$db->sql_query($insert_query . implode(', ', $waiting_rows))) + { + $errored = true; + } + $db->sql_return_on_error(false); + + if ($errored) + { + $db->sql_return_on_error(true); + + // Because it errored out we will try to insert the rows one by one... most of the time this + // is caused by duplicate entries - but we also do not want to miss one... + foreach ($waiting_rows as $waiting_sql) + { + $db->sql_query($insert_query . $waiting_sql); + $this->p_master->db_error($user->lang['DB_ERR_INSERT'], htmlspecialchars($insert_query . $waiting_sql) . '<br /><br />' . htmlspecialchars(print_r($db->_sql_error(), true)), __LINE__, __FILE__, true); + } + + $db->sql_return_on_error(false); + } + + $waiting_rows = array(); + } + } + + // 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_EXTRA')*/) + { + $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. + $step = '&current_table=' . $current_table . '&skip_rows=' . $skip_rows; + + // Save convertor Status + set_config('convert_progress', serialize(array('step' => $step, 'table_prefix' => $convert->src_table_prefix, 'tag' => $convert->convertor_tag)), true); + + $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'])); + + $url = $this->p_master->module_url . "?mode=$mode&sub=in_progress&tag={$convert->convertor_tag}$step"; + + $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 + $step = '&jump=1'; + + // Save convertor Status + set_config('convert_progress', serialize(array('step' => $step, 'table_prefix' => $convert->src_table_prefix, 'tag' => $convert->convertor_tag)), true); + + $url = $this->p_master->module_url . "?mode=$mode&sub=in_progress&tag={$convert->convertor_tag}$step"; + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['FINAL_STEP'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + + /** + * Sync function being executed at the very end... + */ + 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_approved', 'range', 'topic_id BETWEEN ' . $sync_batch . ' AND ' . $end, true, false); + 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_EXTRA') && function_exists('memory_get_usage')) ? ' [' . ceil(memory_get_usage()/1024) . ' KB]' : ''), + 'RESULT' => $user->lang['DONE'], + )); + + $sync_batch += $batch_size; + } + + if ($sync_batch >= $primary_max) + { + $sync_batch = -1; + + $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " + WHERE config_name = 'convert_progress' OR config_name = 'convert_options'"); + $db->sql_query('DELETE FROM ' . SESSIONS_TABLE); + + @unlink($phpbb_root_path . 'cache/data_global.php'); + cache_moderators(); + + // And finally, add a note to the log + add_log('admin', 'LOG_INSTALL_CONVERTED', $convert->convertor_data['forum_name'], $config['version']); + + $url = $this->p_master->module_url . "?mode={$this->mode}&sub=final"; + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['FINAL_STEP'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + else + { + $sync_batch -= $batch_size; + } + + $step = '&sync_batch=' . $sync_batch; + + // Save convertor Status + set_config('convert_progress', serialize(array('step' => $step, 'table_prefix' => $convert->options['table_prefix'], 'tag' => $convert->convertor_tag)), true); + + $url = $this->p_master->module_url . "?mode=$this->mode&sub=in_progress&tag={$convert->convertor_tag}$step"; + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + + /** + * This function marks the end of conversion (jump=1) + */ + function jump($jump, $last_statement) + { + global $template, $user, $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'])) + { + eval($convert->convertor['execute_last']); + } + else + { + while ($last_statement < sizeof($convert->convertor['execute_last'])) + { + eval($convert->convertor['execute_last'][$last_statement]); + + $template->assign_block_vars('checks', array( + 'TITLE' => $convert->convertor['execute_last'][$last_statement], + 'RESULT' => $user->lang['DONE'], + )); + + $last_statement++; + $step = '&jump=1&last=' . $last_statement; + + // Save convertor Status + set_config('convert_progress', serialize(array('step' => $step, 'table_prefix' => $convert->src_table_prefix, 'tag' => $convert->convertor_tag)), true); + + $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); + $url = $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}$step"; + + $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($convert->convertor['query_last']); + } + + foreach ($convert->convertor['query_last'] as $query_last) + { + $db->sql_query($query_last); + } + } + + // Sanity check + $db->sql_return_on_error(false); + + fix_empty_primary_groups(); + + if (!isset($config['board_startdate'])) + { + $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 (($row['board_startdate'] < $config['board_startdate'] && $row['board_startdate'] > 0) || !isset($config['board_startdate'])) + { + set_config('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'], + )); + + $step = '&jump=2'; + + // Save convertor Status + set_config('convert_progress', serialize(array('step' => $step, 'table_prefix' => $convert->src_table_prefix, 'tag' => $convert->convertor_tag)), true); + + $url = $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}$step"; + + $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'); + $cache->destroy('sql', FORUMS_TABLE); + + $template->assign_block_vars('checks', array( + 'TITLE' => $user->lang['SYNC_FORUMS'], + 'RESULT' => $user->lang['DONE'], + )); + + $step = '&jump=3'; + + // Save convertor Status + set_config('convert_progress', serialize(array('step' => $step, 'table_prefix' => $convert->src_table_prefix, 'tag' => $convert->convertor_tag)), true); + + $url = $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}$step"; + + $template->assign_vars(array( + 'L_SUBMIT' => $user->lang['CONTINUE_CONVERT'], + 'U_ACTION' => $url, + )); + + $this->meta_refresh($url); + return; + } + + if ($jump == 3) + { + update_topics_posted(); + + $template->assign_block_vars('checks', array( + 'TITLE' => $user->lang['UPDATE_TOPICS_POSTED'], + 'RESULT' => $user->lang['DONE'], + )); + + // Continue with synchronizing the forums... + $step = '&sync_batch=0'; + + // Save convertor Status + set_config('convert_progress', serialize(array('step' => $step, 'table_prefix' => $convert->src_table_prefix, 'tag' => $convert->convertor_tag)), true); + + $url = $this->p_master->module_url . "?mode={$this->mode}&sub=in_progress&tag={$convert->convertor_tag}$step"; + + $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->sql_layer, 'mysql') === 0 && !defined('DEBUG_EXTRA')) ? '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])) + { + // 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); + eval($execution); + } + } + } + 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); + eval($execution); + } + } + } + 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']) + { + $template->assign_var('S_REFRESH', true); + meta_refresh(5, $url); + } + } + + /** + * The information below will be used to build the input fields presented to the user + */ + var $convert_options = array( + 'legend1' => 'SPECIFY_OPTIONS', + '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), + ); +} + +?>
\ No newline at end of file diff --git a/phpBB/install/install_install.php b/phpBB/install/install_install.php index 0b4f94a5c2..ba80f40eb2 100755 --- a/phpBB/install/install_install.php +++ b/phpBB/install/install_install.php @@ -97,7 +97,6 @@ class install_install extends module case 'create_table': $this->load_schema($mode, $sub); - break; case 'final' : @@ -134,7 +133,6 @@ class install_install extends module // Test for basic PHP settings $template->assign_block_vars('checks', array( 'S_LEGEND' => true, - 'S_FIRST_ROW' => true, 'LEGEND' => $lang['PHP_SETTINGS'], 'LEGEND_EXPLAIN' => $lang['PHP_SETTINGS_EXPLAIN'], )); @@ -206,10 +204,74 @@ class install_install extends module 'S_LEGEND' => false, )); +/** +* Better not enabling and adding to the loaded extensions due to the specific requirements needed + if (!@extension_loaded('mbstring')) + { + $this->can_load_dll('mbstring'); + } +*/ + + $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', '!=', 'pass'), + array('http_output', '!=', '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 = '<b style="color:red">' . $lang['NO'] . '</b>'; + $passed['mbstring'] = false; + } + else + { + $result = '<b style="color:green">' . $lang['YES'] . '</b>'; + } + break; + + case '!=': + if ($ini_val != $mb_checks[2]) + { + $result = '<b style="color:red">' . $lang['NO'] . '</b>'; + $passed['mbstring'] = false; + } + else + { + $result = '<b style="color:green">' . $lang['YES'] . '</b>'; + } + 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, - 'S_FIRST_ROW' => false, 'LEGEND' => $lang['PHP_SUPPORTED_DB'], 'LEGEND_EXPLAIN' => $lang['PHP_SUPPORTED_DB_EXPLAIN'], )); @@ -248,7 +310,6 @@ class install_install extends module // Test for other modules $template->assign_block_vars('checks', array( 'S_LEGEND' => true, - 'S_FIRST_ROW' => false, 'LEGEND' => $lang['PHP_OPTIONAL_MODULE'], 'LEGEND_EXPLAIN' => $lang['PHP_OPTIONAL_MODULE_EXPLAIN'], )); @@ -280,7 +341,7 @@ class install_install extends module } // Can we find Imagemagick anywhere on the system? - $exe = ((defined('PHP_OS')) && (preg_match('#^win#i', PHP_OS))) ? '.exe' : ''; + $exe = (defined('PHP_OS') && strpos(strtolower(PHP_OS), 'win') === 0) ? '.exe' : ''; $magic_home = getenv('MAGICK_HOME'); $img_imagick = ''; @@ -321,7 +382,6 @@ class install_install extends module // Check permissions on files/directories we need access to $template->assign_block_vars('checks', array( 'S_LEGEND' => true, - 'S_FIRST_ROW' => false, 'LEGEND' => $lang['FILES_REQUIRED'], 'LEGEND_EXPLAIN' => $lang['FILES_REQUIRED_EXPLAIN'], )); @@ -356,11 +416,12 @@ class install_install extends module $fp = @fopen($phpbb_root_path . $dir . 'test_lock', 'wb'); if ($fp !== false) { - @unlink($phpbb_root_path . $dir . 'test_lock'); $write = true; } @fclose($fp); + @unlink($phpbb_root_path . $dir . 'test_lock'); + $passed['files'] = ($exists && $write && $passed['files']) ? true : false; $exists = ($exists) ? '<b style="color:green">' . $lang['FOUND'] . '</b>' : '<b style="color:red">' . $lang['NOT_FOUND'] . '</b>'; @@ -378,7 +439,6 @@ class install_install extends module // Check permissions on files/directories it would be useful access to $template->assign_block_vars('checks', array( 'S_LEGEND' => true, - 'S_FIRST_ROW' => false, 'LEGEND' => $lang['FILES_OPTIONAL'], 'LEGEND_EXPLAIN' => $lang['FILES_OPTIONAL_EXPLAIN'], )); @@ -415,8 +475,8 @@ class install_install extends module // And finally where do we want to go next (well today is taken isn't it :P) $s_hidden_fields = ($img_imagick) ? '<input type="hidden" name="img_imagick" value="' . addslashes($img_imagick) . '" />' : ''; - $url = ($passed['php'] && $passed['db'] && $passed['files'] && $passed['pcre']) ? $this->p_master->module_url . "?mode=$mode&sub=database&language=$language" : $this->p_master->module_url . "?mode=$mode&sub=requirements&language=$language "; - $submit = ($passed['php'] && $passed['db'] && $passed['files'] && $passed['pcre']) ? $lang['INSTALL_START'] : $lang['INSTALL_TEST']; + $url = ($passed['php'] && $passed['db'] && $passed['files'] && $passed['pcre'] && $passed['mbstring']) ? $this->p_master->module_url . "?mode=$mode&sub=database&language=$language" : $this->p_master->module_url . "?mode=$mode&sub=requirements&language=$language "; + $submit = ($passed['php'] && $passed['db'] && $passed['files'] && $passed['pcre'] && $passed['mbstring']) ? $lang['INSTALL_START'] : $lang['INSTALL_TEST']; $template->assign_vars(array( @@ -456,12 +516,10 @@ class install_install extends module } $dbpasswd = htmlspecialchars_decode($dbpasswd); - $connect_test = $this->connect_check_db(true, $error, $dbms, $table_prefix, $dbhost, $dbuser, $dbpasswd, $dbname, $dbport); $template->assign_block_vars('checks', array( 'S_LEGEND' => true, - 'S_FIRST_ROW' => true, 'LEGEND' => $lang['DB_CONNECTION'], 'LEGEND_EXPLAIN' => false, )); @@ -647,7 +705,6 @@ class install_install extends module $template->assign_block_vars('checks', array( 'S_LEGEND' => true, - 'S_FIRST_ROW' => true, 'LEGEND' => $lang['STAGE_ADMINISTRATOR'], 'LEGEND_EXPLAIN' => false, )); @@ -773,6 +830,8 @@ class install_install extends module $load_extensions = array(); $check_exts = array_merge(array($this->available_dbms[$dbms]['MODULE']), $this->php_dlls_other); + $suffix = (defined('PHP_OS') && strpos(strtolower(PHP_OS), 'win') === 0) ? 'dll' : 'so'; + foreach ($check_exts as $dll) { if (!@extension_loaded($dll)) @@ -781,6 +840,7 @@ class install_install extends module { continue; } + $load_extensions[] = "$dll.$suffix"; } } @@ -929,6 +989,19 @@ class install_install extends module $server_protocol = ($server_protocol !== '') ? $server_protocol : ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://'); $cookie_secure = ($cookie_secure !== '') ? $cookie_secure : ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? true : false); + if ($script_path === '') + { + $name = (!empty($_SERVER['PHP_SELF'])) ? $_SERVER['PHP_SELF'] : getenv('PHP_SELF'); + if (!$name) + { + $name = (!empty($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : getenv('REQUEST_URI'); + } + + // Replace backslashes and doubled slashes (could happen on some proxy setups) + $name = str_replace(array('\\', '//', '/install'), '/', $name); + $script_path = trim(dirname($name)); + } + foreach ($this->advanced_config_options as $config_key => $vars) { if (!is_array($vars) && strpos($config_key, 'legend') === false) @@ -1015,7 +1088,7 @@ class install_install extends module // If we get here and the extension isn't loaded it should be safe to just go ahead and load it if (!@extension_loaded($this->available_dbms[$dbms]['MODULE'])) { - @dl($this->available_dbms[$dbms]['MODULE'] . ".$prefix"); + $this->can_load_dll($this->available_dbms[$dbms]['MODULE']); } $dbpasswd = htmlspecialchars_decode($dbpasswd); @@ -1108,6 +1181,22 @@ class install_install extends module $user_ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : ''; + if ($script_path !== '/') + { + // Adjust destination path (no trailing slash) + if (substr($script_path, -1) == '/') + { + $script_path = substr($script_path, 0, -1); + } + + $script_path = str_replace(array('../', './'), '', $script_path); + + if ($script_path[0] != '/') + { + $script_path = '/' . $script_path; + } + } + // Set default config and post data, this applies to all DB's $sql_ary = array( 'INSERT INTO ' . $table_prefix . "config (config_name, config_value) @@ -1177,23 +1266,19 @@ class install_install extends module WHERE config_name = 'force_server_vars'", 'UPDATE ' . $table_prefix . "config - SET config_value = '" . $db->sql_escape($server_name) . "' - WHERE config_name = 'server_name'", + SET config_value = '" . $db->sql_escape($script_path) . "' + WHERE config_name = 'script_path'", 'UPDATE ' . $table_prefix . "config SET config_value = '" . $db->sql_escape($server_protocol) . "' WHERE config_name = 'server_protocol'", 'UPDATE ' . $table_prefix . "config - SET config_value = '" . $db->sql_escape($server_port) . "' - WHERE config_name = 'server_port'", - - 'UPDATE ' . $table_prefix . "config SET config_value = '" . $db->sql_escape($admin_name) . "' WHERE config_name = 'newest_username'", 'UPDATE ' . $table_prefix . "users - SET username = '" . $db->sql_escape($admin_name) . "', user_password='" . $db->sql_escape(md5($admin_pass1)) . "', user_ip = '" . $db->sql_escape($user_ip) . "', user_lang = '" . $db->sql_escape($default_lang) . "', user_email='" . $db->sql_escape($board_email1) . "', user_dateformat='" . $db->sql_escape($lang['default_dateformat']) . "', user_email_hash = " . (int) (crc32(strtolower($board_email1)) . strlen($board_email1)) . ", username_clean = '" . $db->sql_escape(utf8_clean_string($admin_name)) . "' + SET username = '" . $db->sql_escape($admin_name) . "', user_password='" . $db->sql_escape(md5($admin_pass1)) . "', user_ip = '" . $db->sql_escape($user_ip) . "', user_lang = '" . $db->sql_escape($default_lang) . "', user_email='" . $db->sql_escape($board_email1) . "', user_dateformat='" . $db->sql_escape($lang['default_dateformat']) . "', user_email_hash = " . (crc32($board_email1) . strlen($board_email1)) . ", username_clean = '" . $db->sql_escape(utf8_clean_string($admin_name)) . "' WHERE username = 'Admin'", 'UPDATE ' . $table_prefix . "moderator_cache @@ -1222,6 +1307,11 @@ class install_install extends module SET forum_last_post_time = $current_time", ); + if (!@extension_loaded('gd')) + { + $this->can_load_dll('gd'); + } + // This is for people who have TTF and GD if (@extension_loaded('gd') && function_exists('imagettfbbox') && function_exists('imagettftext')) { @@ -1230,9 +1320,17 @@ class install_install extends module WHERE config_name = 'captcha_gd'"; } + // We set a (semi-)unique cookie name to bypass login issues related to the cookie name. + $cookie_name = 'phpbb3_'; + $cookie_name .= strtolower(gen_rand_string(5)); + + $sql_ary[] = 'UPDATE ' . $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)); + //$sql = trim(str_replace('|', ';', $sql)); if (!$db->sql_query($sql)) { @@ -1273,6 +1371,12 @@ class install_install extends module $dbpasswd = htmlspecialchars_decode($dbpasswd); + // If we get here and the extension isn't loaded it should be safe to just go ahead and load it + if (!@extension_loaded($this->available_dbms[$dbms]['MODULE'])) + { + $this->can_load_dll($this->available_dbms[$dbms]['MODULE']); + } + // Load the appropriate database class if not already loaded include($phpbb_root_path . 'includes/db/' . $this->available_dbms[$dbms]['DRIVER'] . '.' . $phpEx); @@ -1501,6 +1605,12 @@ class install_install extends module 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__); + } + while (($file = readdir($dir)) !== false) { $path = $phpbb_root_path . 'language/' . $file; @@ -1526,6 +1636,7 @@ class install_install extends module } } } + closedir($dir); } /** @@ -1574,17 +1685,18 @@ class install_install extends module 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' => $default_lang, - 'user_style' => 1, - 'user_timezone' => 0, - 'user_dateformat' => $lang['default_dateformat'], + 'user_type' => USER_IGNORE, + 'group_id' => $group_id, + 'username' => $bot_name, + 'user_regdate' => time(), + 'user_password' => '', + 'user_colour' => '9E8DA7', + 'user_email' => '', + 'user_lang' => $default_lang, + 'user_style' => 1, + 'user_timezone' => 0, + 'user_dateformat' => $lang['default_dateformat'], + 'user_allow_massemail' => 0, ); $user_id = user_add($user_row); @@ -1653,7 +1765,6 @@ class install_install extends module $messenger->template('installed', $language); - $messenger->replyto($config['board_contact']); $messenger->to($board_email1, $admin_name); $messenger->headers('X-AntiAbuse: Board servername - ' . $config['server_name']); @@ -1687,6 +1798,11 @@ class install_install extends module { global $suffix; + if (empty($suffix)) + { + $suffix = (defined('PHP_OS') && strpos(strtolower(PHP_OS), 'win') === 0) ? 'dll' : 'so'; + } + return ((@ini_get('enable_dl') || strtolower(@ini_get('enable_dl')) == 'on') && (!@ini_get('safe_mode') || strtolower(@ini_get('safe_mode')) == 'off') && @dl($dll . ".$suffix")) ? true : false; } @@ -1816,7 +1932,8 @@ class install_install extends module if ($row = $db->sql_fetchrow($result)) { // Likely matches for an existing phpBB installation - $table_ary = array($table_prefix . 'attachments', $table_prefix . 'config', $table_prefix . 'sessions', $table_prefix . 'topics', $table_prefix . 'users'); + $temp_prefix = strtolower($table_prefix); + $table_ary = array($temp_prefix . 'attachments', $temp_prefix . 'config', $temp_prefix . 'sessions', $temp_prefix . 'topics', $temp_prefix . 'users'); do { @@ -1858,6 +1975,14 @@ class install_install extends module { $error[] = $lang['INST_ERR_DB_NO_FIREBIRD']; } + $db_info = @ibase_db_info($db->service_handle, $dbname, IBASE_STS_HDR_PAGES); + + preg_match('/^\\s*Page size\\s*(\\d+)/m', $db_info, $regs); + $page_size = intval($regs[1]); + if ($page_size < 8192) + { + $error[] = $lang['INST_ERR_DB_NO_FIREBIRD_PS']; + } } else { @@ -1885,6 +2010,39 @@ class install_install extends module } $db->sql_freeresult($result); } + + // Setup the stuff for our random table + $char_array = array_merge(range('A', 'Z'), range('0', '9')); + $char_len = mt_rand(7, 9); + $char_array_len = sizeof($char_array) - 1; + + $final = ''; + + for ($i = 0; $i < $char_len; $i++) + { + $final .= $char_array[mt_rand(0, $char_array_len)]; + } + + // Create some random table + $sql = 'CREATE TABLE ' . $final . " ( + FIELD1 VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, + FIELD2 INTEGER DEFAULT 0 NOT NULL);"; + $db->sql_query($sql); + + // Create an index that should fail if the page size is less than 8192 + $sql = 'CREATE INDEX ' . $final . ' ON ' . $final . '(FIELD1, FIELD2);'; + $db->sql_query($sql); + + if (ibase_errmsg() !== false) + { + $error[] = $lang['INST_ERR_DB_NO_FIREBIRD_PS']; + } + else + { + // Kill the old table + $db->sql_query('DROP TABLE ' . $final . ';'); + } + unset($final); } break; @@ -1967,7 +2125,7 @@ class install_install extends module * The variables that we will be passing between pages * Used to retrieve data quickly on each page */ - var $request_vars = array('language', 'dbms', 'dbhost', 'dbport', 'dbuser', 'dbpasswd', 'dbname', 'table_prefix', 'default_lang', 'admin_name', 'admin_pass1', 'admin_pass2', 'board_email1', 'board_email2', 'img_imagick', 'ftp_path', 'ftp_user', 'ftp_pass', 'email_enable', 'smtp_delivery', 'smtp_host', 'smtp_auth', 'smtp_user', 'smtp_pass', 'cookie_secure', 'force_server_vars', 'server_protocol', 'server_name', 'server_port'); + var $request_vars = array('language', 'dbms', 'dbhost', 'dbport', 'dbuser', 'dbpasswd', 'dbname', 'table_prefix', 'default_lang', 'admin_name', 'admin_pass1', 'admin_pass2', 'board_email1', 'board_email2', 'img_imagick', 'ftp_path', 'ftp_user', 'ftp_pass', 'email_enable', 'smtp_delivery', 'smtp_host', 'smtp_auth', 'smtp_user', 'smtp_pass', 'cookie_secure', 'force_server_vars', 'server_protocol', 'server_name', 'server_port', 'script_path'); /** * The information below will be used to build the input fields presented to the user @@ -2006,6 +2164,7 @@ class install_install extends module '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), ); /** diff --git a/phpBB/install/install_update.php b/phpBB/install/install_update.php index 069022f0e5..3e24cc71ed 100644 --- a/phpBB/install/install_update.php +++ b/phpBB/install/install_update.php @@ -6,6 +6,7 @@ * @copyright (c) 2006 phpBB Group * @license http://opensource.org/licenses/gpl-license.php GNU Public License * +* @todo check for writeable cache/store/files directory */ /** @@ -39,7 +40,7 @@ if (!empty($setmodules)) '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_stages' => array('INTRO', 'VERSION_CHECK', 'UPDATE_DB', 'FILE_CHECK', 'UPDATE_FILES'), 'module_reqs' => '' ); } @@ -71,6 +72,8 @@ class install_update extends module global $template, $phpEx, $phpbb_root_path, $user, $db, $config, $cache, $auth; $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/'; @@ -79,6 +82,12 @@ class install_update extends module require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx); require($phpbb_root_path . 'includes/constants.' . $phpEx); + // Special options for conflicts + define('MERGE_NO_MERGE_NEW', 1); + define('MERGE_NO_MERGE_MOD', 2); + define('MERGE_NEW_FILE', 3); + define('MERGE_MOD_FILE', 4); + $db = new $sql_db(); // Connect to DB @@ -87,28 +96,37 @@ class install_update extends module // We do not need this any longer, unset for safety purposes unset($dbpasswd); - $config = $cache->obtain_config(); + $config = array(); + + $sql = 'SELECT config_name, config_value + FROM ' . CONFIG_TABLE; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $config[$row['config_name']] = $row['config_value']; + } + $db->sql_freeresult($result); // First of all, init the user session $user->session_begin(); $auth->acl($user->data); - $user->setup('install'); - - include_once($phpbb_root_path . 'includes/diff/diff.' . $phpEx); - /** - * Check for user session - * - commented out for beta3 with "broken" install check routine - if (!$user->data['is_registered']) + // Beta4 and below are having a bug displaying an error if the install directory is present. + // This bug got fixed, but we need to get around it by using a tiny 'hack'. + if (!defined('DEBUG_EXTRA')) { - login_box('', $user->lang['LOGIN_UPDATE_EXPLAIN']); + if (version_compare(strtolower($config['version']), '3.0.b4', '<=')) + { + @define('DEBUG_EXTRA', true); + } + else if (!empty($config['version_update_from']) && version_compare(strtolower($config['version_update_from']), '3.0.b4', '<=')) + { + @define('DEBUG_EXTRA', true); + } } - if (!$auth->acl_get('a_')) - { - trigger_error($user->lang['NO_AUTH_UPDATE']); - } - */ + $user->setup('install'); // If we are within the intro page we need to make sure we get up-to-date version info if ($sub == 'intro') @@ -120,8 +138,6 @@ class install_update extends module $template->set_custom_template('../adm/style', 'admin'); // Get current and latest version - $this->current_version = $config['version']; - if (($latest_version = $cache->get('_version_info')) === false) { $this->latest_version = $this->get_file('version_info'); @@ -132,6 +148,9 @@ class install_update extends module $this->latest_version = $latest_version; } + // 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(strtolower($this->current_version), strtolower($this->latest_version), '<')) ? false : true; // Check for a valid update directory, else point the user to the phpbb.com website @@ -170,20 +189,28 @@ class install_update extends module return; } - // Got the updater template itself updated? If so, we are able to directly use it - but only if all three files are present - if (in_array('adm/style/install_update.html', $this->update_info['files'])) + if ($this->test_update === false) { - $this->tpl_name = '../../install/update/new/adm/style/install_update'; - } + // Got the updater template itself updated? If so, we are able to directly use it - but only if all three files are present + if (in_array('adm/style/install_update.html', $this->update_info['files'])) + { + $this->tpl_name = '../../install/update/new/adm/style/install_update'; + } - // What about the language file? Got it updated? - if (in_array('language/en/install.php', $this->update_info['files'])) - { - $lang = array(); - include('./update/new/language/en/install.php'); - $user->lang = array_merge($user->lang, $lang); + // What about the language file? Got it updated? + if (in_array('language/en/install.php', $this->update_info['files'])) + { + $lang = array(); + include($this->new_location . 'language/en/install.php'); + $user->lang = array_merge($user->lang, $lang); + } } + // 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 (!empty($_POST['check_again'])) { @@ -210,14 +237,52 @@ class install_update extends module $template->assign_vars(array( 'S_UP_TO_DATE' => $up_to_date, 'S_VERSION_CHECK' => true, - 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=file_check"), + + 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=file_check"), + 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_db"), 'LATEST_VERSION' => $this->latest_version, - 'CURRENT_VERSION' => $config['version']) + 'CURRENT_VERSION' => $this->current_version) ); break; + case 'update_db': + + // Make sure the database update is valid for the latest version + $valid = false; + $updates_to_version = ''; + + if (file_exists($phpbb_root_path . 'install/database_update.' . $phpEx)) + { + include_once($phpbb_root_path . 'install/database_update.' . $phpEx); + + if ($updates_to_version === $this->latest_version) + { + $valid = true; + } + } + + // Should not happen at all + if (!$valid) + { + trigger_error($user->lang['DATABASE_UPDATE_INFO_OLD'], E_USER_ERROR); + } + + // Just a precaution + $cache->purge(); + + // 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->latest_version) ? true : false, + 'U_DB_UPDATE' => $phpbb_root_path . 'install/database_update.' . $phpEx . '?type=1', + 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_db"), + 'U_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=file_check"), + )); + + break; + case 'file_check': $this->page_title = 'STAGE_FILE_CHECK'; @@ -286,18 +351,41 @@ class install_update extends module 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, "mode=$mode&sub=file_check&action=diff&status=$status&file=" . urlencode($file_struct['filename'])); + $template->assign_block_vars('files', array( 'STATUS' => $status, - 'FILENAME' => htmlspecialchars($file_struct['filename']), + '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' => append_sid($this->p_master->module_url, "mode=$mode&sub=file_check&action=diff&status=$status&file=" . urlencode($file_struct['filename'])), - 'UA_SHOW_DIFF' => append_sid($this->p_master->module_url, "mode=$mode&sub=file_check&action=diff&status=$status&file=" . urlencode($file_struct['filename']), false), + '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, )); } } @@ -321,6 +409,16 @@ class install_update extends module 'U_DB_UPDATE_ACTION' => append_sid($this->p_master->module_url, "mode=$mode&sub=update_db"), )); + if ($all_up_to_date) + { + $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'"); + + // Add database update to log + add_log('admin', 'LOG_UPDATE_PHPBB', $this->current_version, $this->latest_version); + + $cache->purge(); + } + break; case 'update_files': @@ -342,7 +440,7 @@ class install_update extends module if (!empty($_POST['download'])) { - include_once($phpbb_root_path . 'includes/functions_compress.' . $phpEx); + $this->include_file('includes/functions_compress.' . $phpEx); $use_method = request_var('use_method', ''); $methods = array('.tar'); @@ -378,6 +476,7 @@ class install_update extends module // 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) { @@ -395,7 +494,7 @@ class install_update extends module $template->assign_block_vars('location', array( 'SOURCE' => htmlspecialchars($file_struct['filename']), - 'DESTINATION' => $user->page['root_script_path'] . htmlspecialchars($file_struct['filename']), + 'DESTINATION' => $script_path . htmlspecialchars($file_struct['filename']), )); } } @@ -412,7 +511,7 @@ class install_update extends module } else { - include_once($phpbb_root_path . 'includes/functions_transfer.' . $phpEx); + $this->include_file('includes/functions_transfer.' . $phpEx); // Choose FTP, if not available use fsock... $method = request_var('method', ''); @@ -577,8 +676,11 @@ class install_update extends module break; case 'modified': - $diff = &new diff3(file($this->old_location . $original_filename), file($phpbb_root_path . $file_struct['filename']), file($this->new_location . $original_filename)); + + $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); if ($update_mode == 'download') { @@ -586,24 +688,46 @@ class install_update extends module } 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': - $diff = &new diff3(file($this->old_location . $original_filename), file($phpbb_root_path . $file_struct['filename']), file($this->new_location . $original_filename)); - if ($conflicts[$file_struct['filename']] == 1) - { - $contents = implode("\n", $diff->merged_new_output()); - } - else if ($conflicts[$file_struct['filename']] == 2) - { - $contents = implode("\n", $diff->merged_orig_output()); - } - else + $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; } @@ -643,38 +767,6 @@ class install_update extends module break; - case 'update_db': - - // Make sure the database update is valid for the latest version - $valid = false; - $updates_to_version = ''; - - if (file_exists($phpbb_root_path . 'install/database_update.' . $phpEx)) - { - include_once($phpbb_root_path . 'install/database_update.' . $phpEx); - - if ($updates_to_version === $this->latest_version) - { - $valid = true; - } - } - - // Should not happen at all - if (!$valid) - { - trigger_error($user->lang['DATABASE_UPDATE_INFO_OLD'], E_USER_ERROR); - } - - // Because we are done with the file update we purge the cache directory - $cache->purge(); - - // Redirect the user to the database update script with some explanations... - $template->assign_vars(array( - 'S_DB_UPDATE' => true, - 'U_DB_UPDATE' => $phpbb_root_path . 'install/database_update.' . $phpEx) - ); - - break; } } @@ -719,28 +811,71 @@ class install_update extends module switch ($status) { case 'conflict': - $diff = &new diff3(file($this->old_location . $original_file), file($phpbb_root_path . $file), file($this->new_location . $original_file)); + $option = request_var('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; + + 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); + + $tmp = array( + 'file1' => array(), + 'file2' => ($option == MERGE_NEW_FILE) ? implode("\n", $diff->merged_new_output()) : implode("\n", $diff->merged_orig_output()), + ); + + $diff = &new diff($tmp['file1'], $tmp['file2']); + + unset($tmp); + + $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 . $file, $this->new_location . $original_file); + + $template->assign_vars(array( + 'S_DIFF_CONFLICT_FILE' => true, + 'NUM_CONFLICTS' => $diff->merged_output(false, false, false, true)) + ); + break; + } - $template->assign_vars(array( - 'S_DIFF_CONFLICT_FILE' => true, - 'NUM_CONFLICTS' => $diff->merged_output(false, false, false, true)) - ); break; case 'modified': - $diff = &new diff3(file($this->old_location . $original_file), file($phpbb_root_path . $original_file), file($this->new_location . $file)); + $diff = $this->return_diff($this->old_location . $original_file, $phpbb_root_path . $original_file, $this->new_location . $file); break; case 'not_modified': case 'new_conflict': - $diff = &new diff(file($phpbb_root_path . $file), file($this->new_location . $original_file)); + $diff = $this->return_diff($phpbb_root_path . $file, $this->new_location . $original_file); break; case 'new': - $diff = &new diff(array(), file($this->new_location . $original_file)); + + $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; } @@ -762,9 +897,12 @@ class install_update extends module $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); } /** @@ -865,11 +1003,19 @@ class install_update extends module // 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' => file_get_contents($phpbb_root_path . $file), + ); + // We need to diff the contents here to make sure the file is really the one we expect - $diff = &new diff(file($this->new_location . $original_file), file($phpbb_root_path . $file)); + $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 ($diff->is_empty()) + if ($empty) { $update_list['up_to_date'][] = $update_ary; return; @@ -880,22 +1026,40 @@ class install_update extends module return; } - // Check for existance, else abort immediatly + // 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); } - $diff = &new diff(file($this->old_location . $original_file), file($phpbb_root_path . $file)); + $tmp = array( + 'file1' => file_get_contents($this->old_location . $original_file), + 'file2' => file_get_contents($phpbb_root_path . $file), + ); + + // 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_1 = $diff->is_empty(); + + unset($tmp, $diff); + + $tmp = array( + 'file1' => file_get_contents($this->new_location . $original_file), + 'file2' => file_get_contents($phpbb_root_path . $file), + ); + + // 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_2 = $diff->is_empty(); + + unset($tmp, $diff); // If the file is not modified we are finished here... - if ($diff->is_empty()) + if ($empty_1) { // Further check if it is already up to date - it could happen that non-modified files // slip through - $diff = &new diff(file($this->new_location . $original_file), file($phpbb_root_path . $file)); - - if ($diff->is_empty()) + if ($empty_2) { $update_list['up_to_date'][] = $update_ary; return; @@ -906,29 +1070,45 @@ class install_update extends module } // If the file had been modified then we need to check if it is already up to date - $diff = &new diff(file($this->new_location . $original_file), file($phpbb_root_path . $file)); // if there are no differences we have an up-to-date file... - if ($diff->is_empty()) + if ($empty_2) { $update_list['up_to_date'][] = $update_ary; return; } // if the file is modified we try to make sure a merge succeed - $diff = &new diff3(file($this->old_location . $original_file), file($phpbb_root_path . $file), file($this->new_location . $original_file)); + $tmp = array( + 'file1' => file_get_contents($this->old_location . $original_file), + 'file2' => file_get_contents($phpbb_root_path . $file), + 'file3' => file_get_contents($this->new_location . $original_file), + ); + + $diff = &new diff3($tmp['file1'], $tmp['file2'], $tmp['file3'], false); + + unset($tmp); if ($diff->merged_output(false, false, false, true)) { $update_ary['conflicts'] = $diff->_conflicting_blocks; $update_list['conflict'][] = $update_ary; + + unset($diff); + return; } + $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 - $diff = &new diff(file($phpbb_root_path . $file), $diff->merged_output()); + $diff = &new diff($tmp['file1'], $tmp['file2'], false); + $empty = $diff->is_empty(); - if ($diff->is_empty()) + if ($empty) { $update_list['up_to_date'][] = $update_ary; return; @@ -1041,6 +1221,54 @@ class install_update extends module 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; + } } ?>
\ No newline at end of file diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index f06c98b657..dd3e4af9d2 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -226,7 +226,8 @@ CREATE TABLE phpbb_confirm ( confirm_id CHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, session_id CHAR(32) CHARACTER SET NONE DEFAULT '' NOT NULL, confirm_type INTEGER DEFAULT 0 NOT NULL, - code VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL + code VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, + seed INTEGER DEFAULT 0 NOT NULL );; ALTER TABLE phpbb_confirm ADD PRIMARY KEY (session_id, confirm_id);; @@ -960,6 +961,7 @@ CREATE TABLE phpbb_sessions ( session_time INTEGER DEFAULT 0 NOT NULL, session_ip VARCHAR(40) CHARACTER SET NONE DEFAULT '' NOT NULL, session_browser VARCHAR(150) CHARACTER SET NONE DEFAULT '' NOT NULL, + session_forwarded_for VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, session_page VARCHAR(255) CHARACTER SET UTF8 DEFAULT '' NOT NULL COLLATE UNICODE, session_viewonline INTEGER DEFAULT 1 NOT NULL, session_autologin INTEGER DEFAULT 0 NOT NULL, @@ -1409,7 +1411,7 @@ CREATE TABLE phpbb_users ( user_allow_viewonline INTEGER DEFAULT 1 NOT NULL, user_allow_viewemail INTEGER DEFAULT 1 NOT NULL, user_allow_massemail INTEGER DEFAULT 1 NOT NULL, - user_options INTEGER DEFAULT 893 NOT NULL, + user_options INTEGER DEFAULT 895 NOT NULL, user_avatar VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, user_avatar_type INTEGER DEFAULT 0 NOT NULL, user_avatar_width INTEGER DEFAULT 0 NOT NULL, @@ -1500,6 +1502,6 @@ CREATE TABLE phpbb_zebra ( foe INTEGER DEFAULT 0 NOT NULL );; -CREATE INDEX phpbb_zebra_user_id ON phpbb_zebra(user_id);; -CREATE INDEX phpbb_zebra_zebra_id ON phpbb_zebra(zebra_id);; +ALTER TABLE phpbb_zebra ADD PRIMARY KEY (user_id, zebra_id);; + diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 804d5eafc8..7f33783072 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -292,7 +292,8 @@ CREATE TABLE [phpbb_confirm] ( [confirm_id] [char] (32) DEFAULT ('') NOT NULL , [session_id] [char] (32) DEFAULT ('') NOT NULL , [confirm_type] [int] DEFAULT (0) NOT NULL , - [code] [varchar] (8) DEFAULT ('') NOT NULL + [code] [varchar] (8) DEFAULT ('') NOT NULL , + [seed] [int] DEFAULT (0) NOT NULL ) ON [PRIMARY] GO @@ -1140,6 +1141,7 @@ CREATE TABLE [phpbb_sessions] ( [session_time] [int] DEFAULT (0) NOT NULL , [session_ip] [varchar] (40) DEFAULT ('') NOT NULL , [session_browser] [varchar] (150) DEFAULT ('') NOT NULL , + [session_forwarded_for] [varchar] (255) DEFAULT ('') NOT NULL , [session_page] [varchar] (255) DEFAULT ('') NOT NULL , [session_viewonline] [int] DEFAULT (1) NOT NULL , [session_autologin] [int] DEFAULT (0) NOT NULL , @@ -1651,7 +1653,7 @@ CREATE TABLE [phpbb_users] ( [user_allow_viewonline] [int] DEFAULT (1) NOT NULL , [user_allow_viewemail] [int] DEFAULT (1) NOT NULL , [user_allow_massemail] [int] DEFAULT (1) NOT NULL , - [user_options] [int] DEFAULT (893) NOT NULL , + [user_options] [int] DEFAULT (895) NOT NULL , [user_avatar] [varchar] (255) DEFAULT ('') NOT NULL , [user_avatar_type] [int] DEFAULT (0) NOT NULL , [user_avatar_width] [int] DEFAULT (0) NOT NULL , @@ -1742,10 +1744,12 @@ CREATE TABLE [phpbb_zebra] ( ) ON [PRIMARY] GO -CREATE INDEX [user_id] ON [phpbb_zebra]([user_id]) ON [PRIMARY] -GO - -CREATE INDEX [zebra_id] ON [phpbb_zebra]([zebra_id]) ON [PRIMARY] +ALTER TABLE [phpbb_zebra] WITH NOCHECK ADD + CONSTRAINT [PK_phpbb_zebra] PRIMARY KEY CLUSTERED + ( + [user_id], + [zebra_id] + ) ON [PRIMARY] GO diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index cf4d43b768..2b3022a875 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -163,6 +163,7 @@ CREATE TABLE phpbb_confirm ( session_id char(32) DEFAULT '' NOT NULL, confirm_type tinyint(3) DEFAULT '0' NOT NULL, code varchar(8) DEFAULT '' NOT NULL, + seed int(10) UNSIGNED DEFAULT '0' NOT NULL, PRIMARY KEY (session_id, confirm_id), KEY confirm_type (confirm_type) ); @@ -253,9 +254,9 @@ CREATE TABLE phpbb_forums ( enable_icons tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_prune tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, prune_next int(11) UNSIGNED DEFAULT '0' NOT NULL, - prune_days tinyint(4) DEFAULT '0' NOT NULL, - prune_viewed tinyint(4) DEFAULT '0' NOT NULL, - prune_freq tinyint(4) DEFAULT '0' NOT NULL, + prune_days mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + prune_viewed mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + prune_freq mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, PRIMARY KEY (forum_id), KEY left_right_id (left_id, right_id), KEY forum_lastpost_id (forum_last_post_id) @@ -510,7 +511,7 @@ CREATE TABLE phpbb_privmsgs_rules ( rule_user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, rule_group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, rule_action mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_folder_id int(4) DEFAULT '0' NOT NULL, + rule_folder_id int(11) DEFAULT '0' NOT NULL, PRIMARY KEY (rule_id), KEY user_id (user_id) ); @@ -527,7 +528,7 @@ CREATE TABLE phpbb_privmsgs_to ( pm_replied tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, pm_marked tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, pm_forwarded tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - folder_id int(4) DEFAULT '0' NOT NULL, + folder_id int(11) DEFAULT '0' NOT NULL, KEY msg_id (msg_id), KEY author_id (author_id), KEY usr_flder_id (user_id, folder_id) @@ -661,6 +662,7 @@ CREATE TABLE phpbb_sessions ( session_time int(11) UNSIGNED DEFAULT '0' NOT NULL, session_ip varchar(40) DEFAULT '' NOT NULL, session_browser varchar(150) DEFAULT '' NOT NULL, + session_forwarded_for varchar(255) DEFAULT '' NOT NULL, session_page text NOT NULL, session_viewonline tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, session_autologin tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, @@ -1011,7 +1013,7 @@ CREATE TABLE phpbb_users ( user_allow_viewonline tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, user_allow_viewemail tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, user_allow_massemail tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_options int(11) UNSIGNED DEFAULT '893' NOT NULL, + user_options int(11) UNSIGNED DEFAULT '895' NOT NULL, user_avatar varchar(255) DEFAULT '' NOT NULL, user_avatar_type tinyint(2) DEFAULT '0' NOT NULL, user_avatar_width smallint(4) UNSIGNED DEFAULT '0' NOT NULL, @@ -1064,8 +1066,7 @@ CREATE TABLE phpbb_zebra ( zebra_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, friend tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, foe tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - KEY user_id (user_id), - KEY zebra_id (zebra_id) + PRIMARY KEY (user_id, zebra_id) ); diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index aaf00d077e..7ade8bd1a4 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -163,6 +163,7 @@ CREATE TABLE phpbb_confirm ( session_id char(32) DEFAULT '' NOT NULL, confirm_type tinyint(3) DEFAULT '0' NOT NULL, code varchar(8) DEFAULT '' NOT NULL, + seed int(10) UNSIGNED DEFAULT '0' NOT NULL, PRIMARY KEY (session_id, confirm_id), KEY confirm_type (confirm_type) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; @@ -253,9 +254,9 @@ CREATE TABLE phpbb_forums ( enable_icons tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, enable_prune tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, prune_next int(11) UNSIGNED DEFAULT '0' NOT NULL, - prune_days tinyint(4) DEFAULT '0' NOT NULL, - prune_viewed tinyint(4) DEFAULT '0' NOT NULL, - prune_freq tinyint(4) DEFAULT '0' NOT NULL, + prune_days mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + prune_viewed mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, + prune_freq mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, PRIMARY KEY (forum_id), KEY left_right_id (left_id, right_id), KEY forum_lastpost_id (forum_last_post_id) @@ -510,7 +511,7 @@ CREATE TABLE phpbb_privmsgs_rules ( rule_user_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, rule_group_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, rule_action mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, - rule_folder_id int(4) DEFAULT '0' NOT NULL, + rule_folder_id int(11) DEFAULT '0' NOT NULL, PRIMARY KEY (rule_id), KEY user_id (user_id) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; @@ -527,7 +528,7 @@ CREATE TABLE phpbb_privmsgs_to ( pm_replied tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, pm_marked tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, pm_forwarded tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - folder_id int(4) DEFAULT '0' NOT NULL, + folder_id int(11) DEFAULT '0' NOT NULL, KEY msg_id (msg_id), KEY author_id (author_id), KEY usr_flder_id (user_id, folder_id) @@ -661,6 +662,7 @@ CREATE TABLE phpbb_sessions ( session_time int(11) UNSIGNED DEFAULT '0' NOT NULL, session_ip varchar(40) DEFAULT '' NOT NULL, session_browser varchar(150) DEFAULT '' NOT NULL, + session_forwarded_for varchar(255) DEFAULT '' NOT NULL, session_page varchar(255) DEFAULT '' NOT NULL, session_viewonline tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, session_autologin tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, @@ -1011,7 +1013,7 @@ CREATE TABLE phpbb_users ( user_allow_viewonline tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, user_allow_viewemail tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, user_allow_massemail tinyint(1) UNSIGNED DEFAULT '1' NOT NULL, - user_options int(11) UNSIGNED DEFAULT '893' NOT NULL, + user_options int(11) UNSIGNED DEFAULT '895' NOT NULL, user_avatar varchar(255) DEFAULT '' NOT NULL, user_avatar_type tinyint(2) DEFAULT '0' NOT NULL, user_avatar_width smallint(4) UNSIGNED DEFAULT '0' NOT NULL, @@ -1064,8 +1066,7 @@ CREATE TABLE phpbb_zebra ( zebra_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, friend tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, foe tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - KEY user_id (user_id), - KEY zebra_id (zebra_id) + PRIMARY KEY (user_id, zebra_id) ) CHARACTER SET `utf8` COLLATE `utf8_bin`; diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 816d584b97..8634dcd1fe 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -337,6 +337,7 @@ CREATE TABLE phpbb_confirm ( session_id char(32) DEFAULT '' , confirm_type number(3) DEFAULT '0' NOT NULL, code varchar2(8) DEFAULT '' , + seed number(10) DEFAULT '0' NOT NULL, CONSTRAINT pk_phpbb_confirm PRIMARY KEY (session_id, confirm_id) ) / @@ -508,9 +509,9 @@ CREATE TABLE phpbb_forums ( enable_icons number(1) DEFAULT '1' NOT NULL, enable_prune number(1) DEFAULT '0' NOT NULL, prune_next number(11) DEFAULT '0' NOT NULL, - prune_days number(4) DEFAULT '0' NOT NULL, - prune_viewed number(4) DEFAULT '0' NOT NULL, - prune_freq number(4) DEFAULT '0' NOT NULL, + prune_days number(8) DEFAULT '0' NOT NULL, + prune_viewed number(8) DEFAULT '0' NOT NULL, + prune_freq number(8) DEFAULT '0' NOT NULL, CONSTRAINT pk_phpbb_forums PRIMARY KEY (forum_id) ) / @@ -988,7 +989,7 @@ CREATE TABLE phpbb_privmsgs_rules ( rule_user_id number(8) DEFAULT '0' NOT NULL, rule_group_id number(8) DEFAULT '0' NOT NULL, rule_action number(8) DEFAULT '0' NOT NULL, - rule_folder_id number(4) DEFAULT '0' NOT NULL, + rule_folder_id number(11) DEFAULT '0' NOT NULL, CONSTRAINT pk_phpbb_privmsgs_rules PRIMARY KEY (rule_id) ) / @@ -1025,7 +1026,7 @@ CREATE TABLE phpbb_privmsgs_to ( pm_replied number(1) DEFAULT '0' NOT NULL, pm_marked number(1) DEFAULT '0' NOT NULL, pm_forwarded number(1) DEFAULT '0' NOT NULL, - folder_id number(4) DEFAULT '0' NOT NULL + folder_id number(11) DEFAULT '0' NOT NULL ) / @@ -1279,6 +1280,7 @@ CREATE TABLE phpbb_sessions ( session_time number(11) DEFAULT '0' NOT NULL, session_ip varchar2(40) DEFAULT '' , session_browser varchar2(150) DEFAULT '' , + session_forwarded_for varchar2(255) DEFAULT '' , session_page varchar2(765) DEFAULT '' , session_viewonline number(1) DEFAULT '1' NOT NULL, session_autologin number(1) DEFAULT '0' NOT NULL, @@ -1820,7 +1822,7 @@ CREATE TABLE phpbb_users ( user_allow_viewonline number(1) DEFAULT '1' NOT NULL, user_allow_viewemail number(1) DEFAULT '1' NOT NULL, user_allow_massemail number(1) DEFAULT '1' NOT NULL, - user_options number(11) DEFAULT '893' NOT NULL, + user_options number(11) DEFAULT '895' NOT NULL, user_avatar varchar2(255) DEFAULT '' , user_avatar_type number(2) DEFAULT '0' NOT NULL, user_avatar_width number(4) DEFAULT '0' NOT NULL, @@ -1933,12 +1935,9 @@ CREATE TABLE phpbb_zebra ( user_id number(8) DEFAULT '0' NOT NULL, zebra_id number(8) DEFAULT '0' NOT NULL, friend number(1) DEFAULT '0' NOT NULL, - foe number(1) DEFAULT '0' NOT NULL + foe number(1) DEFAULT '0' NOT NULL, + CONSTRAINT pk_phpbb_zebra PRIMARY KEY (user_id, zebra_id) ) / -CREATE INDEX phpbb_zebra_user_id ON phpbb_zebra (user_id) -/ -CREATE INDEX phpbb_zebra_zebra_id ON phpbb_zebra (zebra_id) -/ diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index aa22d5b0fa..d0005a16a7 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -275,6 +275,7 @@ CREATE TABLE phpbb_confirm ( session_id char(32) DEFAULT '' NOT NULL, confirm_type INT2 DEFAULT '0' NOT NULL, code varchar(8) DEFAULT '' NOT NULL, + seed INT4 DEFAULT '0' NOT NULL CHECK (seed >= 0), PRIMARY KEY (session_id, confirm_id) ); @@ -385,9 +386,9 @@ CREATE TABLE phpbb_forums ( enable_icons INT2 DEFAULT '1' NOT NULL CHECK (enable_icons >= 0), enable_prune INT2 DEFAULT '0' NOT NULL CHECK (enable_prune >= 0), prune_next INT4 DEFAULT '0' NOT NULL CHECK (prune_next >= 0), - prune_days INT2 DEFAULT '0' NOT NULL, - prune_viewed INT2 DEFAULT '0' NOT NULL, - prune_freq INT2 DEFAULT '0' NOT NULL, + prune_days INT4 DEFAULT '0' NOT NULL CHECK (prune_days >= 0), + prune_viewed INT4 DEFAULT '0' NOT NULL CHECK (prune_viewed >= 0), + prune_freq INT4 DEFAULT '0' NOT NULL CHECK (prune_freq >= 0), PRIMARY KEY (forum_id) ); @@ -875,6 +876,7 @@ CREATE TABLE phpbb_sessions ( session_time INT4 DEFAULT '0' NOT NULL CHECK (session_time >= 0), session_ip varchar(40) DEFAULT '' NOT NULL, session_browser varchar(150) DEFAULT '' NOT NULL, + session_forwarded_for varchar(255) DEFAULT '' NOT NULL, session_page varchar(255) DEFAULT '' NOT NULL, session_viewonline INT2 DEFAULT '1' NOT NULL CHECK (session_viewonline >= 0), session_autologin INT2 DEFAULT '0' NOT NULL CHECK (session_autologin >= 0), @@ -1271,7 +1273,7 @@ CREATE TABLE phpbb_users ( user_allow_viewonline INT2 DEFAULT '1' NOT NULL CHECK (user_allow_viewonline >= 0), user_allow_viewemail INT2 DEFAULT '1' NOT NULL CHECK (user_allow_viewemail >= 0), user_allow_massemail INT2 DEFAULT '1' NOT NULL CHECK (user_allow_massemail >= 0), - user_options INT4 DEFAULT '893' NOT NULL CHECK (user_options >= 0), + user_options INT4 DEFAULT '895' NOT NULL CHECK (user_options >= 0), user_avatar varchar(255) DEFAULT '' NOT NULL, user_avatar_type INT2 DEFAULT '0' NOT NULL, user_avatar_width INT2 DEFAULT '0' NOT NULL CHECK (user_avatar_width >= 0), @@ -1333,11 +1335,10 @@ CREATE TABLE phpbb_zebra ( user_id INT4 DEFAULT '0' NOT NULL CHECK (user_id >= 0), zebra_id INT4 DEFAULT '0' NOT NULL CHECK (zebra_id >= 0), friend INT2 DEFAULT '0' NOT NULL CHECK (friend >= 0), - foe INT2 DEFAULT '0' NOT NULL CHECK (foe >= 0) + foe INT2 DEFAULT '0' NOT NULL CHECK (foe >= 0), + PRIMARY KEY (user_id, zebra_id) ); -CREATE INDEX phpbb_zebra_user_id ON phpbb_zebra (user_id); -CREATE INDEX phpbb_zebra_zebra_id ON phpbb_zebra (zebra_id); COMMIT;
\ No newline at end of file diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql index c3a438e0de..ce151c020b 100644 --- a/phpBB/install/schemas/schema_data.sql +++ b/phpBB/install/schemas/schema_data.sql @@ -86,9 +86,11 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('enable_post_confir 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 ('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', '20'); 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'); @@ -114,8 +116,10 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('jab_resource', '') 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_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 ('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'); @@ -161,7 +165,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('min_name_chars', ' INSERT INTO phpbb_config (config_name, config_value) VALUES ('min_pass_chars', '6'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('min_search_author_chars', '3'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('override_user_style', '0'); -INSERT INTO phpbb_config (config_name, config_value) VALUES ('pass_complex', '.*'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('pass_complex', 'PASS_TYPE_ANY'); 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'); @@ -170,6 +174,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('print_pm', '1'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('queue_interval', '600'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('ranks_path', 'images/ranks'); INSERT INTO phpbb_config (config_name, config_value) VALUES ('require_activation', '0'); +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_indexing_state', ''); @@ -180,7 +185,6 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('search_store_resul 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 ('send_encoding', '1'); 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', ''); @@ -199,13 +203,14 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page', 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 ('version', '3.0.B4'); +INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.0.B5'); 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 ('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); @@ -349,28 +354,28 @@ INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('u_viewprofile', # -- standard auth roles -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Standard Admin', 'ROLE_DESCRIPTION_ADMIN_STANDARD', 'a_', 1); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Forum Admin', 'ROLE_DESCRIPTION_ADMIN_FORUM', 'a_', 3); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('User and Groups Admin', 'ROLE_DESCRIPTION_ADMIN_USERGROUP', 'a_', 4); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Full Admin', 'ROLE_DESCRIPTION_ADMIN_FULL', 'a_', 2); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('All Features', 'ROLE_DESCRIPTION_USER_FULL', 'u_', 3); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Standard Features', 'ROLE_DESCRIPTION_USER_STANDARD', 'u_', 1); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Limited Features', 'ROLE_DESCRIPTION_USER_LIMITED', 'u_', 2); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('No Private Messages', 'ROLE_DESCRIPTION_USER_NOPM', 'u_', 4); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('No Avatar', 'ROLE_DESCRIPTION_USER_NOAVATAR', 'u_', 5); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Full Moderator', 'ROLE_DESCRIPTION_MOD_FULL', 'm_', 3); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Standard Moderator', 'ROLE_DESCRIPTION_MOD_STANDARD', 'm_', 1); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Simple Moderator', 'ROLE_DESCRIPTION_MOD_SIMPLE', 'm_', 2); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Queue Moderator', 'ROLE_DESCRIPTION_MOD_QUEUE', 'm_', 4); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Full Access', 'ROLE_DESCRIPTION_FORUM_FULL', 'f_', 7); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Standard Access', 'ROLE_DESCRIPTION_FORUM_STANDARD', 'f_', 5); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('No Access', 'ROLE_DESCRIPTION_FORUM_NOACCESS', 'f_', 1); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Read Only Access', 'ROLE_DESCRIPTION_FORUM_READONLY', 'f_', 2); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Limited Access', 'ROLE_DESCRIPTION_FORUM_LIMITED', 'f_', 3); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Bot Access', 'ROLE_DESCRIPTION_FORUM_BOT', 'f_', 9); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('On Moderation Queue', 'ROLE_DESCRIPTION_FORUM_ONQUEUE', 'f_', 8); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Standard Access + Polls', 'ROLE_DESCRIPTION_FORUM_POLLS', 'f_', 6); -INSERT INTO phpbb_acl_roles (role_name, role_description, role_type, role_order) VALUES ('Limited Access + Polls', 'ROLE_DESCRIPTION_FORUM_LIMITED_POLLS', 'f_', 4); +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); # -- phpbb_styles @@ -391,7 +396,7 @@ INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, INSERT INTO phpbb_forums (forum_name, forum_desc, left_id, right_id, parent_id, forum_type, forum_posts, forum_topics, forum_topics_real, 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) VALUES ('Test Forum 1', 'This is just a test forum.', 2, 3, 1, 1, 1, 1, 1, 1, 2, 'Admin', 'AA0000', 'Welcome to phpBB 3', 972086460, '', '', '', '', '', '', '', 0, 0, ''); # -- 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_from, user_icq, user_aim, user_yim, user_msnm, user_jabber, user_website, user_occ, user_interests, user_actkey, user_newpasswd) VALUES (2, 1, 'Anonymous', 'anonymous', 0, '', '', 'en', 1, 0, '', 0, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', '', '', '', '', '', '', '', ''); +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_from, user_icq, user_aim, user_yim, user_msnm, user_jabber, user_website, user_occ, user_interests, 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_from, user_icq, user_aim, user_yim, user_msnm, user_jabber, user_website, user_occ, user_interests, user_actkey, user_newpasswd) VALUES (3, 5, 'Admin', 'admin', 0, '21232f297a57a5a743894a0e4a801fc3', 'admin@yourdomain.com', 'en', 1, 1, 'AA0000', 1, '', '', '', '', '', 't', 'a', 't', 'd', '', '', '', '', '', '', '', '', '', '', '', '', '', ''); @@ -466,13 +471,13 @@ INSERT INTO phpbb_acl_roles_data (role_id, auth_option_id, auth_setting) SELECT 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'); +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'); +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'); @@ -584,13 +589,20 @@ INSERT INTO phpbb_icons (icons_url, icons_width, icons_height, icons_order, disp # -- wordlist +INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('this', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('example', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('post', 0); +INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('your', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('phpbb', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('installation', 0); +INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('you', 0); +INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('may', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('delete', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('topic', 0); +INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('and', 0); +INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('even', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('forum', 0); +INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('like', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('since', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('everything', 0); INSERT INTO phpbb_search_wordlist (word_text, word_common) VALUES ('seems', 0); @@ -609,8 +621,15 @@ INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (8, 1, INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (9, 1, 0); INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (10, 1, 0); INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (11, 1, 0); -INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (12, 1, 1); -INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (3, 1, 1); +INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (12, 1, 0); +INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (13, 1, 0); +INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (14, 1, 0); +INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (15, 1, 0); +INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (16, 1, 0); +INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (17, 1, 0); +INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (18, 1, 0); +INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (5, 1, 1); +INSERT INTO phpbb_search_wordmatch (word_id, post_id, title_match) VALUES (19, 1, 1); # -- reasons @@ -663,12 +682,21 @@ 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'); diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index ee42bfec4b..93e916a234 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -160,6 +160,7 @@ CREATE TABLE phpbb_confirm ( session_id char(32) NOT NULL DEFAULT '', confirm_type tinyint(3) NOT NULL DEFAULT '0', code varchar(8) NOT NULL DEFAULT '', + seed INTEGER UNSIGNED NOT NULL DEFAULT '0', PRIMARY KEY (session_id, confirm_id) ); @@ -246,9 +247,9 @@ CREATE TABLE phpbb_forums ( enable_icons INTEGER UNSIGNED NOT NULL DEFAULT '1', enable_prune INTEGER UNSIGNED NOT NULL DEFAULT '0', prune_next INTEGER UNSIGNED NOT NULL DEFAULT '0', - prune_days tinyint(4) NOT NULL DEFAULT '0', - prune_viewed tinyint(4) NOT NULL DEFAULT '0', - prune_freq tinyint(4) NOT NULL DEFAULT '0' + prune_days INTEGER UNSIGNED NOT NULL DEFAULT '0', + prune_viewed INTEGER UNSIGNED NOT NULL DEFAULT '0', + prune_freq INTEGER UNSIGNED NOT NULL DEFAULT '0' ); CREATE INDEX phpbb_forums_left_right_id ON phpbb_forums (left_id, right_id); @@ -494,7 +495,7 @@ CREATE TABLE phpbb_privmsgs_rules ( rule_user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', rule_group_id INTEGER UNSIGNED NOT NULL DEFAULT '0', rule_action INTEGER UNSIGNED NOT NULL DEFAULT '0', - rule_folder_id int(4) NOT NULL DEFAULT '0' + rule_folder_id int(11) NOT NULL DEFAULT '0' ); CREATE INDEX phpbb_privmsgs_rules_user_id ON phpbb_privmsgs_rules (user_id); @@ -510,7 +511,7 @@ CREATE TABLE phpbb_privmsgs_to ( pm_replied INTEGER UNSIGNED NOT NULL DEFAULT '0', pm_marked INTEGER UNSIGNED NOT NULL DEFAULT '0', pm_forwarded INTEGER UNSIGNED NOT NULL DEFAULT '0', - folder_id int(4) NOT NULL DEFAULT '0' + folder_id int(11) NOT NULL DEFAULT '0' ); CREATE INDEX phpbb_privmsgs_to_msg_id ON phpbb_privmsgs_to (msg_id); @@ -639,6 +640,7 @@ CREATE TABLE phpbb_sessions ( session_time INTEGER UNSIGNED NOT NULL DEFAULT '0', session_ip varchar(40) NOT NULL DEFAULT '', session_browser varchar(150) NOT NULL DEFAULT '', + session_forwarded_for varchar(255) NOT NULL DEFAULT '', session_page varchar(255) NOT NULL DEFAULT '', session_viewonline INTEGER UNSIGNED NOT NULL DEFAULT '1', session_autologin INTEGER UNSIGNED NOT NULL DEFAULT '0', @@ -982,7 +984,7 @@ CREATE TABLE phpbb_users ( user_allow_viewonline INTEGER UNSIGNED NOT NULL DEFAULT '1', user_allow_viewemail INTEGER UNSIGNED NOT NULL DEFAULT '1', user_allow_massemail INTEGER UNSIGNED NOT NULL DEFAULT '1', - user_options INTEGER UNSIGNED NOT NULL DEFAULT '893', + user_options INTEGER UNSIGNED NOT NULL DEFAULT '895', user_avatar varchar(255) NOT NULL DEFAULT '', user_avatar_type tinyint(2) NOT NULL DEFAULT '0', user_avatar_width INTEGER UNSIGNED NOT NULL DEFAULT '0', @@ -1031,11 +1033,10 @@ CREATE TABLE phpbb_zebra ( user_id INTEGER UNSIGNED NOT NULL DEFAULT '0', zebra_id INTEGER UNSIGNED NOT NULL DEFAULT '0', friend INTEGER UNSIGNED NOT NULL DEFAULT '0', - foe INTEGER UNSIGNED NOT NULL DEFAULT '0' + foe INTEGER UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (user_id, zebra_id) ); -CREATE INDEX phpbb_zebra_user_id ON phpbb_zebra (user_id); -CREATE INDEX phpbb_zebra_zebra_id ON phpbb_zebra (zebra_id); COMMIT;
\ No newline at end of file |
