From f817e20f287a21e2dddfba9721f5e02dce162d29 Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 15 Jul 2011 11:57:53 -0400 Subject: [feature/migrations] Basic migrations with schema and data changes The migrator takes care of applying migrations as necessary. RFC: http://area51.phpbb.com/phpBB/viewtopic.php?f=84&t=41337 PHPBB3-9737 --- phpBB/install/schemas/firebird_schema.sql | 12 ++++++++++++ phpBB/install/schemas/mssql_schema.sql | 17 +++++++++++++++++ phpBB/install/schemas/mysql_40_schema.sql | 12 ++++++++++++ phpBB/install/schemas/mysql_41_schema.sql | 12 ++++++++++++ phpBB/install/schemas/oracle_schema.sql | 15 +++++++++++++++ phpBB/install/schemas/postgres_schema.sql | 14 ++++++++++++++ phpBB/install/schemas/sqlite_schema.sql | 12 ++++++++++++ 7 files changed, 94 insertions(+) (limited to 'phpBB/install') diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 767ce68b4a..43099fc33b 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -573,6 +573,18 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts(attempt_forwar CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts(attempt_time);; CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts(user_id);; +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_schema_done INTEGER DEFAULT 0 NOT NULL, + migration_data_done INTEGER DEFAULT 0 NOT NULL, + migration_data_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_start_time INTEGER DEFAULT 0 NOT NULL, + migration_end_time INTEGER DEFAULT 0 NOT NULL +);; + +CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations(migration_name);; + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER DEFAULT 0 NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 84c975942f..1174cdfa3d 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -696,6 +696,23 @@ CREATE INDEX [user_id] ON [phpbb_login_attempts]([user_id]) ON [PRIMARY] GO +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE [phpbb_migrations] ( + [migration_name] [varchar] (255) DEFAULT ('') NOT NULL , + [migration_schema_done] [int] DEFAULT (0) NOT NULL , + [migration_data_done] [int] DEFAULT (0) NOT NULL , + [migration_data_state] [varchar] (8000) DEFAULT ('') NOT NULL , + [migration_start_time] [int] DEFAULT (0) NOT NULL , + [migration_end_time] [int] DEFAULT (0) NOT NULL +) ON [PRIMARY] +GO + +CREATE UNIQUE INDEX [migration_name] ON [phpbb_migrations]([migration_name]) ON [PRIMARY] +GO + + /* Table: 'phpbb_moderator_cache' */ diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index 8aab949103..d645c3384d 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -397,6 +397,18 @@ CREATE TABLE phpbb_login_attempts ( ); +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varbinary(255) DEFAULT '' NOT NULL, + migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_state blob NOT NULL, + migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + UNIQUE migration_name (migration_name) +); + + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index 04aef2844a..d10f2dc55a 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -397,6 +397,18 @@ CREATE TABLE phpbb_login_attempts ( ) CHARACTER SET `utf8` COLLATE `utf8_bin`; +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) DEFAULT '' NOT NULL, + migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_state text NOT NULL, + migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + UNIQUE migration_name (migration_name) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 91f906bc8b..9993caeb7a 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -780,6 +780,21 @@ CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id) / +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE phpbb_migrations ( + migration_name varchar2(255) DEFAULT '' , + migration_schema_done number(1) DEFAULT '0' NOT NULL, + migration_data_done number(1) DEFAULT '0' NOT NULL, + migration_data_state clob DEFAULT '' , + migration_start_time number(11) DEFAULT '0' NOT NULL, + migration_end_time number(11) DEFAULT '0' NOT NULL, + CONSTRAINT u_phpbb_migration_name UNIQUE (migration_name) +) +/ + + /* Table: 'phpbb_moderator_cache' */ diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index 619985e0d6..ef138dac0f 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -557,6 +557,20 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwa CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) DEFAULT '' NOT NULL, + migration_schema_done INT2 DEFAULT '0' NOT NULL CHECK (migration_schema_done >= 0), + migration_data_done INT2 DEFAULT '0' NOT NULL CHECK (migration_data_done >= 0), + migration_data_state varchar(8000) DEFAULT '' NOT NULL, + migration_start_time INT4 DEFAULT '0' NOT NULL CHECK (migration_start_time >= 0), + migration_end_time INT4 DEFAULT '0' NOT NULL CHECK (migration_end_time >= 0) +); + +CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations (migration_name); + /* Table: 'phpbb_moderator_cache' */ diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 1690a7dcab..309297779e 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -385,6 +385,18 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwa CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) NOT NULL DEFAULT '', + migration_schema_done INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_data_done INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_data_state text(65535) NOT NULL DEFAULT '', + migration_start_time INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_end_time INTEGER UNSIGNED NOT NULL DEFAULT '0' +); + +CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations (migration_name); + # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', -- cgit v1.2.1 From b1f9ca2f6541924c75a30c68dd8a4bc8db62205d Mon Sep 17 00:00:00 2001 From: Nils Adermann Date: Fri, 9 Nov 2012 17:10:48 +0100 Subject: [feature/migrations] Moved database_update info to individual migration classes --- phpBB/install/database_update.php | 1457 ------------------------------------- 1 file changed, 1457 deletions(-) (limited to 'phpBB/install') diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 8950d677ae..1f89035b43 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -881,277 +881,6 @@ function _add_permission(auth_admin $auth_admin, phpbb_db_driver $db, $permissio function database_update_info() { return array( - // Changes from 3.0.0 to the next version - '3.0.0' => array( - // Add the following columns - 'add_columns' => array( - FORUMS_TABLE => array( - 'display_subforum_list' => array('BOOL', 1), - ), - SESSIONS_TABLE => array( - 'session_forum_id' => array('UINT', 0), - ), - ), - 'drop_keys' => array( - GROUPS_TABLE => array('group_legend'), - ), - 'add_index' => array( - SESSIONS_TABLE => array( - 'session_forum_id' => array('session_forum_id'), - ), - GROUPS_TABLE => array( - 'group_legend_name' => array('group_legend', 'group_name'), - ), - ), - ), - // No changes from 3.0.1-RC1 to 3.0.1 - '3.0.1-RC1' => array(), - // No changes from 3.0.1 to 3.0.2-RC1 - '3.0.1' => array(), - // Changes from 3.0.2-RC1 to 3.0.2-RC2 - '3.0.2-RC1' => array( - 'change_columns' => array( - DRAFTS_TABLE => array( - 'draft_subject' => array('STEXT_UNI', ''), - ), - FORUMS_TABLE => array( - 'forum_last_post_subject' => array('STEXT_UNI', ''), - ), - POSTS_TABLE => array( - 'post_subject' => array('STEXT_UNI', '', 'true_sort'), - ), - PRIVMSGS_TABLE => array( - 'message_subject' => array('STEXT_UNI', ''), - ), - TOPICS_TABLE => array( - 'topic_title' => array('STEXT_UNI', '', 'true_sort'), - 'topic_last_post_subject' => array('STEXT_UNI', ''), - ), - ), - 'drop_keys' => array( - SESSIONS_TABLE => array('session_forum_id'), - ), - 'add_index' => array( - SESSIONS_TABLE => array( - 'session_fid' => array('session_forum_id'), - ), - ), - ), - // No changes from 3.0.2-RC2 to 3.0.2 - '3.0.2-RC2' => array(), - - // Changes from 3.0.2 to 3.0.3-RC1 - '3.0.2' => array( - // Add the following columns - 'add_columns' => array( - STYLES_TEMPLATE_TABLE => array( - 'template_inherits_id' => array('UINT:4', 0), - 'template_inherit_path' => array('VCHAR', ''), - ), - GROUPS_TABLE => array( - 'group_max_recipients' => array('UINT', 0), - ), - ), - ), - - // No changes from 3.0.3-RC1 to 3.0.3 - '3.0.3-RC1' => array(), - - // Changes from 3.0.3 to 3.0.4-RC1 - '3.0.3' => array( - 'add_columns' => array( - PROFILE_FIELDS_TABLE => array( - 'field_show_profile' => array('BOOL', 0), - ), - ), - 'change_columns' => array( - STYLES_TABLE => array( - 'style_id' => array('UINT', NULL, 'auto_increment'), - 'template_id' => array('UINT', 0), - 'theme_id' => array('UINT', 0), - 'imageset_id' => array('UINT', 0), - ), - STYLES_IMAGESET_TABLE => array( - 'imageset_id' => array('UINT', NULL, 'auto_increment'), - ), - STYLES_IMAGESET_DATA_TABLE => array( - 'image_id' => array('UINT', NULL, 'auto_increment'), - 'imageset_id' => array('UINT', 0), - ), - STYLES_THEME_TABLE => array( - 'theme_id' => array('UINT', NULL, 'auto_increment'), - ), - STYLES_TEMPLATE_TABLE => array( - 'template_id' => array('UINT', NULL, 'auto_increment'), - ), - STYLES_TEMPLATE_DATA_TABLE => array( - 'template_id' => array('UINT', 0), - ), - FORUMS_TABLE => array( - 'forum_style' => array('UINT', 0), - ), - USERS_TABLE => array( - 'user_style' => array('UINT', 0), - ), - ), - ), - - // Changes from 3.0.4-RC1 to 3.0.4 - '3.0.4-RC1' => array(), - - // Changes from 3.0.4 to 3.0.5-RC1 - '3.0.4' => array( - 'change_columns' => array( - FORUMS_TABLE => array( - 'forum_style' => array('UINT', 0), - ), - ), - ), - - // No changes from 3.0.5-RC1 to 3.0.5 - '3.0.5-RC1' => array(), - - // Changes from 3.0.5 to 3.0.6-RC1 - '3.0.5' => array( - 'add_columns' => array( - CONFIRM_TABLE => array( - 'attempts' => array('UINT', 0), - ), - USERS_TABLE => array( - 'user_new' => array('BOOL', 1), - 'user_reminded' => array('TINT:4', 0), - 'user_reminded_time'=> array('TIMESTAMP', 0), - ), - GROUPS_TABLE => array( - 'group_skip_auth' => array('BOOL', 0, 'after' => 'group_founder_manage'), - ), - PRIVMSGS_TABLE => array( - 'message_reported' => array('BOOL', 0), - ), - REPORTS_TABLE => array( - 'pm_id' => array('UINT', 0), - ), - PROFILE_FIELDS_TABLE => array( - 'field_show_on_vt' => array('BOOL', 0), - ), - FORUMS_TABLE => array( - 'forum_options' => array('UINT:20', 0), - ), - ), - 'change_columns' => array( - USERS_TABLE => array( - 'user_options' => array('UINT:11', 230271), - ), - ), - 'add_index' => array( - REPORTS_TABLE => array( - 'post_id' => array('post_id'), - 'pm_id' => array('pm_id'), - ), - POSTS_TABLE => array( - 'post_username' => array('post_username:255'), - ), - ), - ), - - // No changes from 3.0.6-RC1 to 3.0.6-RC2 - '3.0.6-RC1' => array(), - // No changes from 3.0.6-RC2 to 3.0.6-RC3 - '3.0.6-RC2' => array(), - // No changes from 3.0.6-RC3 to 3.0.6-RC4 - '3.0.6-RC3' => array(), - // No changes from 3.0.6-RC4 to 3.0.6 - '3.0.6-RC4' => array(), - - // Changes from 3.0.6 to 3.0.7-RC1 - '3.0.6' => array( - 'drop_keys' => array( - LOG_TABLE => array('log_time'), - ), - 'add_index' => array( - TOPICS_TRACK_TABLE => array( - 'topic_id' => array('topic_id'), - ), - ), - ), - - // No changes from 3.0.7-RC1 to 3.0.7-RC2 - '3.0.7-RC1' => array(), - // No changes from 3.0.7-RC2 to 3.0.7 - '3.0.7-RC2' => array(), - // No changes from 3.0.7 to 3.0.7-PL1 - '3.0.7' => array(), - // No changes from 3.0.7-PL1 to 3.0.8-RC1 - '3.0.7-PL1' => array(), - // No changes from 3.0.8-RC1 to 3.0.8 - '3.0.8-RC1' => array(), - // Changes from 3.0.8 to 3.0.9-RC1 - '3.0.8' => array( - 'add_tables' => array( - LOGIN_ATTEMPT_TABLE => array( - 'COLUMNS' => array( - // this column was removed from the database updater - // after 3.0.9-RC3 was released. It might still exist - // in 3.0.9-RCX installations and has to be dropped in - // 3.0.12 after the db_tools class is capable of properly - // removing a primary key. - // 'attempt_id' => array('UINT', NULL, 'auto_increment'), - 'attempt_ip' => array('VCHAR:40', ''), - 'attempt_browser' => array('VCHAR:150', ''), - 'attempt_forwarded_for' => array('VCHAR:255', ''), - 'attempt_time' => array('TIMESTAMP', 0), - 'user_id' => array('UINT', 0), - 'username' => array('VCHAR_UNI:255', 0), - 'username_clean' => array('VCHAR_CI', 0), - ), - //'PRIMARY_KEY' => 'attempt_id', - 'KEYS' => array( - 'att_ip' => array('INDEX', array('attempt_ip', 'attempt_time')), - 'att_for' => array('INDEX', array('attempt_forwarded_for', 'attempt_time')), - 'att_time' => array('INDEX', array('attempt_time')), - 'user_id' => array('INDEX', 'user_id'), - ), - ), - ), - 'change_columns' => array( - BBCODES_TABLE => array( - 'bbcode_id' => array('USINT', 0), - ), - ), - ), - // No changes from 3.0.9-RC1 to 3.0.9-RC2 - '3.0.9-RC1' => array(), - // No changes from 3.0.9-RC2 to 3.0.9-RC3 - '3.0.9-RC2' => array(), - // No changes from 3.0.9-RC3 to 3.0.9-RC4 - '3.0.9-RC3' => array(), - // No changes from 3.0.9-RC4 to 3.0.9 - '3.0.9-RC4' => array(), - // No changes from 3.0.9 to 3.0.10-RC1 - '3.0.9' => array(), - // No changes from 3.0.10-RC1 to 3.0.10-RC2 - '3.0.10-RC1' => array(), - // No changes from 3.0.10-RC2 to 3.0.10-RC3 - '3.0.10-RC2' => array(), - // No changes from 3.0.10-RC3 to 3.0.10 - '3.0.10-RC3' => array(), - // No changes from 3.0.10 to 3.0.11-RC1 - '3.0.10' => array(), - // Changes from 3.0.11-RC1 to 3.0.11-RC2 - '3.0.11-RC1' => array( - 'add_columns' => array( - PROFILE_FIELDS_TABLE => array( - 'field_show_novalue' => array('BOOL', 0), - ), - ), - ), - // No changes from 3.0.11-RC2 to 3.0.11 - '3.0.11-RC2' => array(), - // No changes from 3.0.11 to 3.0.12-RC1 - '3.0.11' => array(), - - /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.12-RC1 */ - // Changes from 3.1.0-dev to 3.1.0-A1 '3.1.0-dev' => array( 'add_tables' => array( @@ -1210,1192 +939,6 @@ function change_database_data(&$no_updates, $version) switch ($version) { - case '3.0.0': - - $sql = 'UPDATE ' . TOPICS_TABLE . " - SET topic_last_view_time = topic_last_post_time - WHERE topic_last_view_time = 0"; - _sql($sql, $errored, $error_ary); - - // Update smiley sizes - $smileys = array('icon_e_surprised.gif', 'icon_eek.gif', 'icon_cool.gif', 'icon_lol.gif', 'icon_mad.gif', 'icon_razz.gif', 'icon_redface.gif', 'icon_cry.gif', 'icon_evil.gif', 'icon_twisted.gif', 'icon_rolleyes.gif', 'icon_exclaim.gif', 'icon_question.gif', 'icon_idea.gif', 'icon_arrow.gif', 'icon_neutral.gif', 'icon_mrgreen.gif', 'icon_e_ugeek.gif'); - - foreach ($smileys as $smiley) - { - if (file_exists($phpbb_root_path . 'images/smilies/' . $smiley)) - { - list($width, $height) = getimagesize($phpbb_root_path . 'images/smilies/' . $smiley); - - $sql = 'UPDATE ' . SMILIES_TABLE . ' - SET smiley_width = ' . $width . ', smiley_height = ' . $height . " - WHERE smiley_url = '" . $db->sql_escape($smiley) . "'"; - - _sql($sql, $errored, $error_ary); - } - } - - $no_updates = false; - break; - - // No changes from 3.0.1-RC1 to 3.0.1 - case '3.0.1-RC1': - break; - - // changes from 3.0.1 to 3.0.2-RC1 - case '3.0.1': - - set_config('referer_validation', '1'); - set_config('check_attachment_content', '1'); - set_config('mime_triggers', 'body|head|html|img|plaintext|a href|pre|script|table|title'); - - $no_updates = false; - break; - - // No changes from 3.0.2-RC1 to 3.0.2-RC2 - case '3.0.2-RC1': - break; - - // No changes from 3.0.2-RC2 to 3.0.2 - case '3.0.2-RC2': - break; - - // Changes from 3.0.2 to 3.0.3-RC1 - case '3.0.2': - set_config('enable_queue_trigger', '0'); - set_config('queue_trigger_posts', '3'); - - set_config('pm_max_recipients', '0'); - - // Set maximum number of recipients for the registered users, bots, guests group - $sql = 'UPDATE ' . GROUPS_TABLE . ' SET group_max_recipients = 5 - WHERE ' . $db->sql_in_set('group_name', array('GUESTS', 'REGISTERED', 'REGISTERED_COPPA', 'BOTS')); - _sql($sql, $errored, $error_ary); - - // Not prefilling yet - set_config('dbms_version', ''); - - // Add new permission u_masspm_group and duplicate settings from u_masspm - include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); - $auth_admin = new auth_admin(); - - // Only add the new permission if it does not already exist - if (empty($auth_admin->acl_options['id']['u_masspm_group'])) - { - $auth_admin->acl_add_option(array('global' => array('u_masspm_group'))); - - // Now the tricky part, filling the permission - $old_id = $auth_admin->acl_options['id']['u_masspm']; - $new_id = $auth_admin->acl_options['id']['u_masspm_group']; - - $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE); - - foreach ($tables as $table) - { - $sql = 'SELECT * - FROM ' . $table . ' - WHERE auth_option_id = ' . $old_id; - $result = _sql($sql, $errored, $error_ary); - - $sql_ary = array(); - while ($row = $db->sql_fetchrow($result)) - { - $row['auth_option_id'] = $new_id; - $sql_ary[] = $row; - } - $db->sql_freeresult($result); - - if (sizeof($sql_ary)) - { - $db->sql_multi_insert($table, $sql_ary); - } - } - - // Remove any old permission entries - $auth_admin->acl_clear_prefetch(); - } - - /** - * Do not resync post counts here. An admin may do this later from the ACP - $start = 0; - $step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000; - - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0'; - _sql($sql, $errored, $error_ary); - - do - { - $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id - FROM ' . POSTS_TABLE . ' - WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . ' - AND post_postcount = 1 AND post_approved = 1 - GROUP BY poster_id'; - $result = _sql($sql, $errored, $error_ary); - - if ($row = $db->sql_fetchrow($result)) - { - do - { - $sql = 'UPDATE ' . USERS_TABLE . " SET user_posts = user_posts + {$row['num_posts']} WHERE user_id = {$row['poster_id']}"; - _sql($sql, $errored, $error_ary); - } - while ($row = $db->sql_fetchrow($result)); - - $start += $step; - } - else - { - $start = 0; - } - $db->sql_freeresult($result); - } - while ($start); - */ - - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET module_auth = \'acl_a_email && cfg_email_enable\' - WHERE module_class = \'acp\' - AND module_basename = \'email\''; - _sql($sql, $errored, $error_ary); - - $no_updates = false; - break; - - // Changes from 3.0.3-RC1 to 3.0.3 - case '3.0.3-RC1': - if ($db->sql_layer == 'oracle') - { - // log_operation is CLOB - but we can change this later - $sql = 'UPDATE ' . LOG_TABLE . " - SET log_operation = 'LOG_DELETE_TOPIC' - WHERE log_operation LIKE 'LOG_TOPIC_DELETED'"; - _sql($sql, $errored, $error_ary); - } - else - { - $sql = 'UPDATE ' . LOG_TABLE . " - SET log_operation = 'LOG_DELETE_TOPIC' - WHERE log_operation = 'LOG_TOPIC_DELETED'"; - _sql($sql, $errored, $error_ary); - } - - $no_updates = false; - break; - - // Changes from 3.0.3 to 3.0.4-RC1 - case '3.0.3': - // Update the Custom Profile Fields based on previous settings to the new format - $sql = 'SELECT field_id, field_required, field_show_on_reg, field_hide - FROM ' . PROFILE_FIELDS_TABLE; - $result = _sql($sql, $errored, $error_ary); - - while ($row = $db->sql_fetchrow($result)) - { - $sql_ary = array( - 'field_required' => 0, - 'field_show_on_reg' => 0, - 'field_hide' => 0, - 'field_show_profile'=> 0, - ); - - if ($row['field_required']) - { - $sql_ary['field_required'] = $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; - } - else if ($row['field_show_on_reg']) - { - $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; - } - else if ($row['field_hide']) - { - // Only administrators and moderators can see this CPF, if the view is enabled, they can see it, otherwise just admins in the acp_users module - $sql_ary['field_hide'] = 1; - } - else - { - // equivelant to "none", which is the "Display in user control panel" option - $sql_ary['field_show_profile'] = 1; - } - - _sql('UPDATE ' . PROFILE_FIELDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary); - } - $no_updates = false; - - break; - - // Changes from 3.0.4-RC1 to 3.0.4 - case '3.0.4-RC1': - break; - - // Changes from 3.0.4 to 3.0.5-RC1 - case '3.0.4': - - // Captcha config variables - set_config('captcha_gd_wave', 0); - set_config('captcha_gd_3d_noise', 1); - set_config('captcha_gd_fonts', 1); - set_config('confirm_refresh', 1); - - // Maximum number of keywords - set_config('max_num_search_keywords', 10); - - // Remove static config var and put it back as dynamic variable - $sql = 'UPDATE ' . CONFIG_TABLE . " - SET is_dynamic = 1 - WHERE config_name = 'search_indexing_state'"; - _sql($sql, $errored, $error_ary); - - // Hash old MD5 passwords - $sql = 'SELECT user_id, user_password - FROM ' . USERS_TABLE . ' - WHERE user_pass_convert = 1'; - $result = _sql($sql, $errored, $error_ary); - - while ($row = $db->sql_fetchrow($result)) - { - if (strlen($row['user_password']) == 32) - { - $sql_ary = array( - 'user_password' => phpbb_hash($row['user_password']), - ); - - _sql('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id'], $errored, $error_ary); - } - } - $db->sql_freeresult($result); - - // Adjust bot entry - $sql = 'UPDATE ' . BOTS_TABLE . " - SET bot_agent = 'ichiro/' - WHERE bot_agent = 'ichiro/2'"; - _sql($sql, $errored, $error_ary); - - - // Before we are able to add a unique key to auth_option, we need to remove duplicate entries - - // We get duplicate entries first - $sql = 'SELECT auth_option - FROM ' . ACL_OPTIONS_TABLE . ' - GROUP BY auth_option - HAVING COUNT(*) >= 2'; - $result = $db->sql_query($sql); - - $auth_options = array(); - while ($row = $db->sql_fetchrow($result)) - { - $auth_options[] = $row['auth_option']; - } - $db->sql_freeresult($result); - - // Remove specific auth options - if (!empty($auth_options)) - { - foreach ($auth_options as $option) - { - // Select auth_option_ids... the largest id will be preserved - $sql = 'SELECT auth_option_id - FROM ' . ACL_OPTIONS_TABLE . " - WHERE auth_option = '" . $db->sql_escape($option) . "' - ORDER BY auth_option_id DESC"; - // sql_query_limit not possible here, due to bug in postgresql layer - $result = $db->sql_query($sql); - - // Skip first row, this is our original auth option we want to preserve - $row = $db->sql_fetchrow($result); - - while ($row = $db->sql_fetchrow($result)) - { - // Ok, remove this auth option... - _sql('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - _sql('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - _sql('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - _sql('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); - } - $db->sql_freeresult($result); - } - } - - // Now make auth_option UNIQUE, by dropping the old index and adding a UNIQUE one. - $changes = array( - 'drop_keys' => array( - ACL_OPTIONS_TABLE => array('auth_option'), - ), - ); - - $statements = $db_tools->perform_schema_changes($changes); - - foreach ($statements as $sql) - { - _sql($sql, $errored, $error_ary); - } - - $changes = array( - 'add_unique_index' => array( - ACL_OPTIONS_TABLE => array( - 'auth_option' => array('auth_option'), - ), - ), - ); - - $statements = $db_tools->perform_schema_changes($changes); - - foreach ($statements as $sql) - { - _sql($sql, $errored, $error_ary); - } - - $no_updates = false; - - break; - - // No changes from 3.0.5-RC1 to 3.0.5 - case '3.0.5-RC1': - break; - - // Changes from 3.0.5 to 3.0.6-RC1 - case '3.0.5': - // Let's see if the GD Captcha can be enabled... we simply look for what *is* enabled... - if (!empty($config['captcha_gd']) && !isset($config['captcha_plugin'])) - { - set_config('captcha_plugin', 'phpbb_captcha_gd'); - } - else if (!isset($config['captcha_plugin'])) - { - set_config('captcha_plugin', 'phpbb_captcha_nogd'); - } - - // Entries for the Feed Feature - set_config('feed_enable', '0'); - set_config('feed_limit', '10'); - - set_config('feed_overall_forums', '1'); - set_config('feed_overall_forums_limit', '15'); - - set_config('feed_overall_topics', '0'); - set_config('feed_overall_topics_limit', '15'); - - set_config('feed_forum', '1'); - set_config('feed_topic', '1'); - set_config('feed_item_statistics', '1'); - - // Entries for smiley pagination - set_config('smilies_per_page', '50'); - - // Entry for reporting PMs - set_config('allow_pm_report', '1'); - - // Install modules - $modules_to_install = array( - 'feed' => array( - 'base' => 'board', - 'class' => 'acp', - 'title' => 'ACP_FEED_SETTINGS', - 'auth' => 'acl_a_board', - 'cat' => 'ACP_BOARD_CONFIGURATION', - 'after' => array('signature', 'ACP_SIGNATURE_SETTINGS') - ), - 'warnings' => array( - 'base' => 'users', - 'class' => 'acp', - 'title' => 'ACP_USER_WARNINGS', - 'auth' => 'acl_a_user', - 'display' => 0, - 'cat' => 'ACP_CAT_USERS', - 'after' => array('feedback', 'ACP_USER_FEEDBACK') - ), - 'send_statistics' => array( - 'base' => 'send_statistics', - 'class' => 'acp', - 'title' => 'ACP_SEND_STATISTICS', - 'auth' => 'acl_a_server', - 'cat' => 'ACP_SERVER_CONFIGURATION' - ), - 'setting_forum_copy' => array( - 'base' => 'permissions', - 'class' => 'acp', - 'title' => 'ACP_FORUM_PERMISSIONS_COPY', - 'auth' => 'acl_a_fauth && acl_a_authusers && acl_a_authgroups && acl_a_mauth', - 'cat' => 'ACP_FORUM_BASED_PERMISSIONS', - 'after' => array('setting_forum_local', 'ACP_FORUM_PERMISSIONS') - ), - 'pm_reports' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORTS_OPEN', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' - ), - 'pm_reports_closed' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORTS_CLOSED', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' - ), - 'pm_report_details' => array( - 'base' => 'pm_reports', - 'class' => 'mcp', - 'title' => 'MCP_PM_REPORT_DETAILS', - 'auth' => 'aclf_m_report', - 'cat' => 'MCP_REPORTS' - ), - ); - - _add_modules($modules_to_install); - - // Add newly_registered group... but check if it already exists (we always supported running the updater on any schema) - $sql = 'SELECT group_id - FROM ' . GROUPS_TABLE . " - WHERE group_name = 'NEWLY_REGISTERED'"; - $result = $db->sql_query($sql); - $group_id = (int) $db->sql_fetchfield('group_id'); - $db->sql_freeresult($result); - - if (!$group_id) - { - $sql = 'INSERT INTO ' . GROUPS_TABLE . " (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('NEWLY_REGISTERED', 3, 0, '', 0, '', '', '', 5)"; - _sql($sql, $errored, $error_ary); - - $group_id = $db->sql_nextid(); - } - - // Insert new user role... at the end of the chain - $sql = 'SELECT role_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_name = 'ROLE_USER_NEW_MEMBER' - AND role_type = 'u_'"; - $result = $db->sql_query($sql); - $u_role = (int) $db->sql_fetchfield('role_id'); - $db->sql_freeresult($result); - - if (!$u_role) - { - $sql = 'SELECT MAX(role_order) as max_order_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_type = 'u_'"; - $result = $db->sql_query($sql); - $next_order_id = (int) $db->sql_fetchfield('max_order_id'); - $db->sql_freeresult($result); - - $next_order_id++; - - $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NEW_MEMBER', 'ROLE_DESCRIPTION_USER_NEW_MEMBER', 'u_', $next_order_id)"; - _sql($sql, $errored, $error_ary); - $u_role = $db->sql_nextid(); - - if (!$errored) - { - // Now add the correct data to the roles... - // The standard role says that new users are not able to send a PM, Mass PM, are not able to PM groups - $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $u_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group')"; - _sql($sql, $errored, $error_ary); - - // Add user role to group - $sql = 'INSERT INTO ' . ACL_GROUPS_TABLE . " (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES ($group_id, 0, 0, $u_role, 0)"; - _sql($sql, $errored, $error_ary); - } - } - - // Insert new forum role - $sql = 'SELECT role_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_name = 'ROLE_FORUM_NEW_MEMBER' - AND role_type = 'f_'"; - $result = $db->sql_query($sql); - $f_role = (int) $db->sql_fetchfield('role_id'); - $db->sql_freeresult($result); - - if (!$f_role) - { - $sql = 'SELECT MAX(role_order) as max_order_id - FROM ' . ACL_ROLES_TABLE . " - WHERE role_type = 'f_'"; - $result = $db->sql_query($sql); - $next_order_id = (int) $db->sql_fetchfield('max_order_id'); - $db->sql_freeresult($result); - - $next_order_id++; - - $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NEW_MEMBER', 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER', 'f_', $next_order_id)"; - _sql($sql, $errored, $error_ary); - $f_role = $db->sql_nextid(); - - if (!$errored) - { - $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $f_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove')"; - _sql($sql, $errored, $error_ary); - } - } - - // Set every members user_new column to 0 (old users) only if there is no one yet (this makes sure we do not execute this more than once) - $sql = 'SELECT 1 - FROM ' . USERS_TABLE . ' - WHERE user_new = 0'; - $result = $db->sql_query_limit($sql, 1); - $row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - if (!$row) - { - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new = 0'; - _sql($sql, $errored, $error_ary); - } - - // Newly registered users limit - if (!isset($config['new_member_post_limit'])) - { - set_config('new_member_post_limit', (!empty($config['enable_queue_trigger'])) ? $config['queue_trigger_posts'] : 0); - } - - if (!isset($config['new_member_group_default'])) - { - set_config('new_member_group_default', 0); - } - - // To mimick the old "feature" we will assign the forum role to every forum, regardless of the setting (this makes sure there are no "this does not work!!!! YUO!!!" posts... - // Check if the role is already assigned... - $sql = 'SELECT forum_id - FROM ' . ACL_GROUPS_TABLE . ' - WHERE group_id = ' . $group_id . ' - AND auth_role_id = ' . $f_role; - $result = $db->sql_query($sql); - $is_options = (int) $db->sql_fetchfield('forum_id'); - $db->sql_freeresult($result); - - // Not assigned at all... :/ - if (!$is_options) - { - // Get postable forums - $sql = 'SELECT forum_id - FROM ' . FORUMS_TABLE . ' - WHERE forum_type != ' . FORUM_LINK; - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - _sql('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (' . $group_id . ', ' . (int) $row['forum_id'] . ', 0, ' . $f_role . ', 0)', $errored, $error_ary); - } - $db->sql_freeresult($result); - } - - // Clear permissions... - include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); - $auth_admin = new auth_admin(); - $auth_admin->acl_clear_prefetch(); - - if (!isset($config['allow_avatar'])) - { - if ($config['allow_avatar_upload'] || $config['allow_avatar_local'] || $config['allow_avatar_remote']) - { - set_config('allow_avatar', '1'); - } - else - { - set_config('allow_avatar', '0'); - } - } - - if (!isset($config['allow_avatar_remote_upload'])) - { - if ($config['allow_avatar_remote'] && $config['allow_avatar_upload']) - { - set_config('allow_avatar_remote_upload', '1'); - } - else - { - set_config('allow_avatar_remote_upload', '0'); - } - } - - // Minimum number of characters - if (!isset($config['min_post_chars'])) - { - set_config('min_post_chars', '1'); - } - - if (!isset($config['allow_quick_reply'])) - { - set_config('allow_quick_reply', '1'); - } - - // Set every members user_options column to enable - // bbcode, smilies and URLs for signatures by default - $sql = 'SELECT user_options - FROM ' . USERS_TABLE . ' - WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; - $result = $db->sql_query_limit($sql, 1); - $user_option = (int) $db->sql_fetchfield('user_options'); - $db->sql_freeresult($result); - - // Check if we already updated the database by checking bit 15 which we used to store the sig_bbcode option - if (!($user_option & 1 << 15)) - { - // 229376 is the added value to enable all three signature options - $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = user_options + 229376'; - _sql($sql, $errored, $error_ary); - } - - if (!isset($config['delete_time'])) - { - set_config('delete_time', $config['edit_time']); - } - - $no_updates = false; - break; - - // No changes from 3.0.6-RC1 to 3.0.6-RC2 - case '3.0.6-RC1': - break; - - // Changes from 3.0.6-RC2 to 3.0.6-RC3 - case '3.0.6-RC2': - - // Update the Custom Profile Fields based on previous settings to the new format - $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . ' - SET field_show_on_vt = 1 - WHERE field_hide = 0 - AND (field_required = 1 OR field_show_on_reg = 1 OR field_show_profile = 1)'; - _sql($sql, $errored, $error_ary); - $no_updates = false; - - break; - - // No changes from 3.0.6-RC3 to 3.0.6-RC4 - case '3.0.6-RC3': - break; - - // No changes from 3.0.6-RC4 to 3.0.6 - case '3.0.6-RC4': - break; - - // Changes from 3.0.6 to 3.0.7-RC1 - case '3.0.6': - - // ATOM Feeds - set_config('feed_overall', '1'); - set_config('feed_http_auth', '0'); - set_config('feed_limit_post', (string) (isset($config['feed_limit']) ? (int) $config['feed_limit'] : 15)); - set_config('feed_limit_topic', (string) (isset($config['feed_overall_topics_limit']) ? (int) $config['feed_overall_topics_limit'] : 10)); - set_config('feed_topics_new', (!empty($config['feed_overall_topics']) ? '1' : '0')); - set_config('feed_topics_active', (!empty($config['feed_overall_topics']) ? '1' : '0')); - - // Delete all text-templates from the template_data - $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' - WHERE template_filename ' . $db->sql_like_expression($db->any_char . '.txt'); - _sql($sql, $errored, $error_ary); - - $no_updates = false; - break; - - // Changes from 3.0.7-RC1 to 3.0.7-RC2 - case '3.0.7-RC1': - - $sql = 'SELECT user_id, user_email, user_email_hash - FROM ' . USERS_TABLE . ' - WHERE user_type <> ' . USER_IGNORE . " - AND user_email <> ''"; - $result = $db->sql_query($sql); - - $i = 0; - while ($row = $db->sql_fetchrow($result)) - { - // Snapshot of the phpbb_email_hash() function - // We cannot call it directly because the auto updater updates the DB first. :/ - $user_email_hash = sprintf('%u', crc32(strtolower($row['user_email']))) . strlen($row['user_email']); - - if ($user_email_hash != $row['user_email_hash']) - { - $sql_ary = array( - 'user_email_hash' => $user_email_hash, - ); - - $sql = 'UPDATE ' . USERS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE user_id = ' . (int) $row['user_id']; - _sql($sql, $errored, $error_ary, ($i % 100 == 0)); - - ++$i; - } - } - $db->sql_freeresult($result); - - $no_updates = false; - - break; - - // No changes from 3.0.7-RC2 to 3.0.7 - case '3.0.7-RC2': - break; - - // No changes from 3.0.7 to 3.0.7-PL1 - case '3.0.7': - break; - - // Changes from 3.0.7-PL1 to 3.0.8-RC1 - case '3.0.7-PL1': - // Update file extension group names to use language strings. - $sql = 'SELECT lang_dir - FROM ' . LANG_TABLE; - $result = $db->sql_query($sql); - - $extension_groups_updated = array(); - while ($lang_dir = $db->sql_fetchfield('lang_dir')) - { - $lang_dir = basename($lang_dir); - - // The language strings we need are either in language/.../acp/attachments.php - // in the update package if we're updating to 3.0.8-RC1 or later, - // or they are in language/.../install.php when we're updating from 3.0.7-PL1 or earlier. - // On an already updated board, they can also already be in language/.../acp/attachments.php - // in the board root. - $lang_files = array( - "{$phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.$phpEx", - "{$phpbb_root_path}language/$lang_dir/install.$phpEx", - "{$phpbb_root_path}language/$lang_dir/acp/attachments.$phpEx", - ); - - foreach ($lang_files as $lang_file) - { - if (!file_exists($lang_file)) - { - continue; - } - - $lang = array(); - include($lang_file); - - foreach($lang as $lang_key => $lang_val) - { - if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0) - { - continue; - } - - $sql_ary = array( - 'group_name' => substr($lang_key, 10), // Strip off 'EXT_GROUP_' - ); - - $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " - WHERE group_name = '" . $db->sql_escape($lang_val) . "'"; - _sql($sql, $errored, $error_ary); - - $extension_groups_updated[$lang_key] = true; - } - } - } - $db->sql_freeresult($result); - - // Install modules - $modules_to_install = array( - 'post' => array( - 'base' => 'board', - 'class' => 'acp', - 'title' => 'ACP_POST_SETTINGS', - 'auth' => 'acl_a_board', - 'cat' => 'ACP_MESSAGES', - 'after' => array('message', 'ACP_MESSAGE_SETTINGS') - ), - ); - - _add_modules($modules_to_install); - - // update - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET module_auth = \'cfg_allow_avatar && (cfg_allow_avatar_local || cfg_allow_avatar_remote || cfg_allow_avatar_upload || cfg_allow_avatar_remote_upload)\' - WHERE module_class = \'ucp\' - AND module_basename = \'profile\' - AND module_mode = \'avatar\''; - _sql($sql, $errored, $error_ary); - - // add Bing Bot - $bot_name = 'Bing [Bot]'; - $bot_name_clean = utf8_clean_string($bot_name); - - $sql = 'SELECT user_id - FROM ' . USERS_TABLE . " - WHERE username_clean = '" . $db->sql_escape($bot_name_clean) . "'"; - $result = $db->sql_query($sql); - $bing_already_added = (bool) $db->sql_fetchfield('user_id'); - $db->sql_freeresult($result); - - if (!$bing_already_added) - { - $bot_agent = 'bingbot/'; - $bot_ip = ''; - $sql = 'SELECT group_id, group_colour - FROM ' . GROUPS_TABLE . " - WHERE group_name = 'BOTS'"; - $result = $db->sql_query($sql); - $group_row = $db->sql_fetchrow($result); - $db->sql_freeresult($result); - - if (!$group_row) - { - // default fallback, should never get here - $group_row['group_id'] = 6; - $group_row['group_colour'] = '9E8DA7'; - } - - if (!function_exists('user_add')) - { - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); - } - - $user_row = array( - 'user_type' => USER_IGNORE, - 'group_id' => $group_row['group_id'], - 'username' => $bot_name, - 'user_regdate' => time(), - 'user_password' => '', - 'user_colour' => $group_row['group_colour'], - 'user_email' => '', - 'user_lang' => $config['default_lang'], - 'user_style' => $config['default_style'], - 'user_timezone' => 'UTC', - 'user_dateformat' => $config['default_dateformat'], - 'user_allow_massemail' => 0, - ); - - $user_id = user_add($user_row); - - $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( - 'bot_active' => 1, - 'bot_name' => (string) $bot_name, - 'user_id' => (int) $user_id, - 'bot_agent' => (string) $bot_agent, - 'bot_ip' => (string) $bot_ip, - )); - - _sql($sql, $errored, $error_ary); - } - // end Bing Bot addition - - // Delete shadow topics pointing to not existing topics - $batch_size = 500; - - // Set of affected forums we have to resync - $sync_forum_ids = array(); - - do - { - $sql_array = array( - 'SELECT' => 't1.topic_id, t1.forum_id', - 'FROM' => array( - TOPICS_TABLE => 't1', - ), - 'LEFT_JOIN' => array( - array( - 'FROM' => array(TOPICS_TABLE => 't2'), - 'ON' => 't1.topic_moved_id = t2.topic_id', - ), - ), - 'WHERE' => 't1.topic_moved_id <> 0 - AND t2.topic_id IS NULL', - ); - $sql = $db->sql_build_query('SELECT', $sql_array); - $result = $db->sql_query_limit($sql, $batch_size); - - $topic_ids = array(); - while ($row = $db->sql_fetchrow($result)) - { - $topic_ids[] = (int) $row['topic_id']; - - $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; - } - $db->sql_freeresult($result); - - if (!empty($topic_ids)) - { - $sql = 'DELETE FROM ' . TOPICS_TABLE . ' - WHERE ' . $db->sql_in_set('topic_id', $topic_ids); - $db->sql_query($sql); - } - } - while (sizeof($topic_ids) == $batch_size); - - // Sync the forums we have deleted shadow topics from. - sync('forum', 'forum_id', $sync_forum_ids, true, true); - - // Unread posts search load switch - set_config('load_unreads_search', '1'); - - // Reduce queue interval to 60 seconds, email package size to 20 - if ($config['queue_interval'] == 600) - { - set_config('queue_interval', '60'); - } - - if ($config['email_package_size'] == 50) - { - set_config('email_package_size', '20'); - } - - $no_updates = false; - break; - - // No changes from 3.0.8-RC1 to 3.0.8 - case '3.0.8-RC1': - break; - - // Changes from 3.0.8 to 3.0.9-RC1 - case '3.0.8': - set_config('ip_login_limit_max', '50'); - set_config('ip_login_limit_time', '21600'); - set_config('ip_login_limit_use_forwarded', '0'); - - // Update file extension group names to use language strings, again. - $sql = 'SELECT group_id, group_name - FROM ' . EXTENSION_GROUPS_TABLE . ' - WHERE group_name ' . $db->sql_like_expression('EXT_GROUP_' . $db->any_char); - $result = $db->sql_query($sql); - - while ($row = $db->sql_fetchrow($result)) - { - $sql_ary = array( - 'group_name' => substr($row['group_name'], 10), // Strip off 'EXT_GROUP_' - ); - - $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' - SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' - WHERE group_id = ' . $row['group_id']; - _sql($sql, $errored, $error_ary); - } - $db->sql_freeresult($result); - - /* - * Due to a bug, vanilla phpbb could not create captcha tables - * in 3.0.8 on firebird. It was possible for board administrators - * to adjust the code to work. If code was manually adjusted by - * board administrators, index names would not be the same as - * what 3.0.9 and newer expect. This code fragment drops captcha - * tables, destroying all entered Q&A captcha configuration, such - * that when Q&A is configured next the respective tables will be - * created with correct index names. - * - * If you wish to preserve your Q&A captcha configuration, you can - * manually rename indexes to the currently expected name: - * phpbb_captcha_questions_lang_iso => phpbb_captcha_questions_lang - * phpbb_captcha_answers_question_id => phpbb_captcha_answers_qid - * - * Again, this needs to be done only if a board was manually modified - * to fix broken captcha code. - * - if ($db_tools->sql_layer == 'firebird') - { - $changes = array( - 'drop_tables' => array( - $table_prefix . 'captcha_questions', - $table_prefix . 'captcha_answers', - $table_prefix . 'qa_confirm', - ), - ); - $statements = $db_tools->perform_schema_changes($changes); - - foreach ($statements as $sql) - { - _sql($sql, $errored, $error_ary); - } - } - */ - - $no_updates = false; - break; - - // No changes from 3.0.9-RC1 to 3.0.9-RC2 - case '3.0.9-RC1': - break; - - // No changes from 3.0.9-RC2 to 3.0.9-RC3 - case '3.0.9-RC2': - break; - - // No changes from 3.0.9-RC3 to 3.0.9-RC4 - case '3.0.9-RC3': - break; - - // No changes from 3.0.9-RC4 to 3.0.9 - case '3.0.9-RC4': - break; - - // Changes from 3.0.9 to 3.0.10-RC1 - case '3.0.9': - if (!isset($config['email_max_chunk_size'])) - { - set_config('email_max_chunk_size', '50'); - } - - $no_updates = false; - break; - - // No changes from 3.0.10-RC1 to 3.0.10-RC2 - case '3.0.10-RC1': - break; - - // No changes from 3.0.10-RC2 to 3.0.10-RC3 - case '3.0.10-RC2': - break; - - // No changes from 3.0.10-RC3 to 3.0.10 - case '3.0.10-RC3': - break; - - // Changes from 3.0.10 to 3.0.11-RC1 - case '3.0.10': - // Updates users having current style a deactivated one - $sql = 'SELECT style_id - FROM ' . STYLES_TABLE . ' - WHERE style_active = 0'; - $result = $db->sql_query($sql); - - $deactivated_style_ids = array(); - while ($style_id = $db->sql_fetchfield('style_id', false, $result)) - { - $deactivated_style_ids[] = (int) $style_id; - } - $db->sql_freeresult($result); - - if (!empty($deactivated_style_ids)) - { - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_style = ' . (int) $config['default_style'] .' - WHERE ' . $db->sql_in_set('user_style', $deactivated_style_ids); - _sql($sql, $errored, $error_ary); - } - - // Delete orphan private messages - $batch_size = 500; - - $sql_array = array( - 'SELECT' => 'p.msg_id', - 'FROM' => array( - PRIVMSGS_TABLE => 'p', - ), - 'LEFT_JOIN' => array( - array( - 'FROM' => array(PRIVMSGS_TO_TABLE => 't'), - 'ON' => 'p.msg_id = t.msg_id', - ), - ), - 'WHERE' => 't.user_id IS NULL', - ); - $sql = $db->sql_build_query('SELECT', $sql_array); - - do - { - $result = $db->sql_query_limit($sql, $batch_size); - - $delete_pms = array(); - while ($row = $db->sql_fetchrow($result)) - { - $delete_pms[] = (int) $row['msg_id']; - } - $db->sql_freeresult($result); - - if (!empty($delete_pms)) - { - $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' - WHERE ' . $db->sql_in_set('msg_id', $delete_pms); - _sql($sql, $errored, $error_ary); - } - } - while (sizeof($delete_pms) == $batch_size); - - $no_updates = false; - break; - - // No changes from 3.0.11-RC1 to 3.0.11-RC2 - case '3.0.11-RC1': - break; - - // No changes from 3.0.11-RC2 to 3.0.11 - case '3.0.11-RC2': - break; - - // Changes from 3.0.11 to 3.0.12-RC1 - case '3.0.11': - $sql = 'UPDATE ' . MODULES_TABLE . ' - SET module_auth = \'acl_u_sig\' - WHERE module_class = \'ucp\' - AND module_basename = \'profile\' - AND module_mode = \'signature\''; - _sql($sql, $errored, $error_ary); - - // Update bots - if (!function_exists('user_delete')) - { - include($phpbb_root_path . 'includes/functions_user.' . $phpEx); - } - - $bots_updates = array( - // Bot Deletions - 'NG-Search [Bot]' => false, - 'Nutch/CVS [Bot]' => false, - 'OmniExplorer [Bot]' => false, - 'Seekport [Bot]' => false, - 'Synoo [Bot]' => false, - 'WiseNut [Bot]' => false, - - // Bot Updates - // Bot name to bot user agent map - 'Baidu [Spider]' => 'Baiduspider', - 'Exabot [Bot]' => 'Exabot', - 'Voyager [Bot]' => 'voyager/', - 'W3C [Validator]' => 'W3C_Validator', - ); - - foreach ($bots_updates as $bot_name => $bot_agent) - { - $sql = 'SELECT user_id - FROM ' . USERS_TABLE . ' - WHERE user_type = ' . USER_IGNORE . " - AND username_clean = '" . $db->sql_escape(utf8_clean_string($bot_name)) . "'"; - $result = $db->sql_query($sql); - $bot_user_id = (int) $db->sql_fetchfield('user_id'); - $db->sql_freeresult($result); - - if ($bot_user_id) - { - if ($bot_agent === false) - { - $sql = 'DELETE FROM ' . BOTS_TABLE . " - WHERE user_id = $bot_user_id"; - _sql($sql, $errored, $error_ary); - - user_delete('remove', $bot_user_id); - } - else - { - $sql = 'UPDATE ' . BOTS_TABLE . " - SET bot_agent = '" . $db->sql_escape($bot_agent) . "' - WHERE user_id = $bot_user_id"; - _sql($sql, $errored, $error_ary); - } - } - } - - // Disable receiving pms for bots - $sql = 'SELECT user_id - FROM ' . BOTS_TABLE; - $result = $db->sql_query($sql); - - $bot_user_ids = array(); - while ($row = $db->sql_fetchrow($result)) - { - $bot_user_ids[] = (int) $row['user_id']; - } - $db->sql_freeresult($result); - - if (!empty($bot_user_ids)) - { - $sql = 'UPDATE ' . USERS_TABLE . ' - SET user_allow_pm = 0 - WHERE ' . $db->sql_in_set('user_id', $bot_user_ids); - _sql($sql, $errored, $error_ary); - } - - $no_updates = false; - break; - // Changes from 3.1.0-dev to 3.1.0-A1 case '3.1.0-dev': -- cgit v1.2.1 From 6c44dadecbf50d6550f98dd1e1694519f39be680 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 8 Jan 2013 22:07:26 -0600 Subject: [feature/migrations] Move migrator to service container Version numbers 3.1 updates Restore database_update.php file to what it was in develop Get first forum to place global announcements in PHPBB3-9737 --- phpBB/install/database_update.php | 1424 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1424 insertions(+) (limited to 'phpBB/install') diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 1f89035b43..207ad716de 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -881,6 +881,277 @@ function _add_permission(auth_admin $auth_admin, phpbb_db_driver $db, $permissio function database_update_info() { return array( + // Changes from 3.0.0 to the next version + '3.0.0' => array( + // Add the following columns + 'add_columns' => array( + FORUMS_TABLE => array( + 'display_subforum_list' => array('BOOL', 1), + ), + SESSIONS_TABLE => array( + 'session_forum_id' => array('UINT', 0), + ), + ), + 'drop_keys' => array( + GROUPS_TABLE => array('group_legend'), + ), + 'add_index' => array( + SESSIONS_TABLE => array( + 'session_forum_id' => array('session_forum_id'), + ), + GROUPS_TABLE => array( + 'group_legend_name' => array('group_legend', 'group_name'), + ), + ), + ), + // No changes from 3.0.1-RC1 to 3.0.1 + '3.0.1-RC1' => array(), + // No changes from 3.0.1 to 3.0.2-RC1 + '3.0.1' => array(), + // Changes from 3.0.2-RC1 to 3.0.2-RC2 + '3.0.2-RC1' => array( + 'change_columns' => array( + DRAFTS_TABLE => array( + 'draft_subject' => array('STEXT_UNI', ''), + ), + FORUMS_TABLE => array( + 'forum_last_post_subject' => array('STEXT_UNI', ''), + ), + POSTS_TABLE => array( + 'post_subject' => array('STEXT_UNI', '', 'true_sort'), + ), + PRIVMSGS_TABLE => array( + 'message_subject' => array('STEXT_UNI', ''), + ), + TOPICS_TABLE => array( + 'topic_title' => array('STEXT_UNI', '', 'true_sort'), + 'topic_last_post_subject' => array('STEXT_UNI', ''), + ), + ), + 'drop_keys' => array( + SESSIONS_TABLE => array('session_forum_id'), + ), + 'add_index' => array( + SESSIONS_TABLE => array( + 'session_fid' => array('session_forum_id'), + ), + ), + ), + // No changes from 3.0.2-RC2 to 3.0.2 + '3.0.2-RC2' => array(), + + // Changes from 3.0.2 to 3.0.3-RC1 + '3.0.2' => array( + // Add the following columns + 'add_columns' => array( + STYLES_TEMPLATE_TABLE => array( + 'template_inherits_id' => array('UINT:4', 0), + 'template_inherit_path' => array('VCHAR', ''), + ), + GROUPS_TABLE => array( + 'group_max_recipients' => array('UINT', 0), + ), + ), + ), + + // No changes from 3.0.3-RC1 to 3.0.3 + '3.0.3-RC1' => array(), + + // Changes from 3.0.3 to 3.0.4-RC1 + '3.0.3' => array( + 'add_columns' => array( + PROFILE_FIELDS_TABLE => array( + 'field_show_profile' => array('BOOL', 0), + ), + ), + 'change_columns' => array( + STYLES_TABLE => array( + 'style_id' => array('UINT', NULL, 'auto_increment'), + 'template_id' => array('UINT', 0), + 'theme_id' => array('UINT', 0), + 'imageset_id' => array('UINT', 0), + ), + STYLES_IMAGESET_TABLE => array( + 'imageset_id' => array('UINT', NULL, 'auto_increment'), + ), + STYLES_IMAGESET_DATA_TABLE => array( + 'image_id' => array('UINT', NULL, 'auto_increment'), + 'imageset_id' => array('UINT', 0), + ), + STYLES_THEME_TABLE => array( + 'theme_id' => array('UINT', NULL, 'auto_increment'), + ), + STYLES_TEMPLATE_TABLE => array( + 'template_id' => array('UINT', NULL, 'auto_increment'), + ), + STYLES_TEMPLATE_DATA_TABLE => array( + 'template_id' => array('UINT', 0), + ), + FORUMS_TABLE => array( + 'forum_style' => array('UINT', 0), + ), + USERS_TABLE => array( + 'user_style' => array('UINT', 0), + ), + ), + ), + + // Changes from 3.0.4-RC1 to 3.0.4 + '3.0.4-RC1' => array(), + + // Changes from 3.0.4 to 3.0.5-RC1 + '3.0.4' => array( + 'change_columns' => array( + FORUMS_TABLE => array( + 'forum_style' => array('UINT', 0), + ), + ), + ), + + // No changes from 3.0.5-RC1 to 3.0.5 + '3.0.5-RC1' => array(), + + // Changes from 3.0.5 to 3.0.6-RC1 + '3.0.5' => array( + 'add_columns' => array( + CONFIRM_TABLE => array( + 'attempts' => array('UINT', 0), + ), + USERS_TABLE => array( + 'user_new' => array('BOOL', 1), + 'user_reminded' => array('TINT:4', 0), + 'user_reminded_time'=> array('TIMESTAMP', 0), + ), + GROUPS_TABLE => array( + 'group_skip_auth' => array('BOOL', 0, 'after' => 'group_founder_manage'), + ), + PRIVMSGS_TABLE => array( + 'message_reported' => array('BOOL', 0), + ), + REPORTS_TABLE => array( + 'pm_id' => array('UINT', 0), + ), + PROFILE_FIELDS_TABLE => array( + 'field_show_on_vt' => array('BOOL', 0), + ), + FORUMS_TABLE => array( + 'forum_options' => array('UINT:20', 0), + ), + ), + 'change_columns' => array( + USERS_TABLE => array( + 'user_options' => array('UINT:11', 230271), + ), + ), + 'add_index' => array( + REPORTS_TABLE => array( + 'post_id' => array('post_id'), + 'pm_id' => array('pm_id'), + ), + POSTS_TABLE => array( + 'post_username' => array('post_username:255'), + ), + ), + ), + + // No changes from 3.0.6-RC1 to 3.0.6-RC2 + '3.0.6-RC1' => array(), + // No changes from 3.0.6-RC2 to 3.0.6-RC3 + '3.0.6-RC2' => array(), + // No changes from 3.0.6-RC3 to 3.0.6-RC4 + '3.0.6-RC3' => array(), + // No changes from 3.0.6-RC4 to 3.0.6 + '3.0.6-RC4' => array(), + + // Changes from 3.0.6 to 3.0.7-RC1 + '3.0.6' => array( + 'drop_keys' => array( + LOG_TABLE => array('log_time'), + ), + 'add_index' => array( + TOPICS_TRACK_TABLE => array( + 'topic_id' => array('topic_id'), + ), + ), + ), + + // No changes from 3.0.7-RC1 to 3.0.7-RC2 + '3.0.7-RC1' => array(), + // No changes from 3.0.7-RC2 to 3.0.7 + '3.0.7-RC2' => array(), + // No changes from 3.0.7 to 3.0.7-PL1 + '3.0.7' => array(), + // No changes from 3.0.7-PL1 to 3.0.8-RC1 + '3.0.7-PL1' => array(), + // No changes from 3.0.8-RC1 to 3.0.8 + '3.0.8-RC1' => array(), + // Changes from 3.0.8 to 3.0.9-RC1 + '3.0.8' => array( + 'add_tables' => array( + LOGIN_ATTEMPT_TABLE => array( + 'COLUMNS' => array( + // this column was removed from the database updater + // after 3.0.9-RC3 was released. It might still exist + // in 3.0.9-RCX installations and has to be dropped in + // 3.0.12 after the db_tools class is capable of properly + // removing a primary key. + // 'attempt_id' => array('UINT', NULL, 'auto_increment'), + 'attempt_ip' => array('VCHAR:40', ''), + 'attempt_browser' => array('VCHAR:150', ''), + 'attempt_forwarded_for' => array('VCHAR:255', ''), + 'attempt_time' => array('TIMESTAMP', 0), + 'user_id' => array('UINT', 0), + 'username' => array('VCHAR_UNI:255', 0), + 'username_clean' => array('VCHAR_CI', 0), + ), + //'PRIMARY_KEY' => 'attempt_id', + 'KEYS' => array( + 'att_ip' => array('INDEX', array('attempt_ip', 'attempt_time')), + 'att_for' => array('INDEX', array('attempt_forwarded_for', 'attempt_time')), + 'att_time' => array('INDEX', array('attempt_time')), + 'user_id' => array('INDEX', 'user_id'), + ), + ), + ), + 'change_columns' => array( + BBCODES_TABLE => array( + 'bbcode_id' => array('USINT', 0), + ), + ), + ), + // No changes from 3.0.9-RC1 to 3.0.9-RC2 + '3.0.9-RC1' => array(), + // No changes from 3.0.9-RC2 to 3.0.9-RC3 + '3.0.9-RC2' => array(), + // No changes from 3.0.9-RC3 to 3.0.9-RC4 + '3.0.9-RC3' => array(), + // No changes from 3.0.9-RC4 to 3.0.9 + '3.0.9-RC4' => array(), + // No changes from 3.0.9 to 3.0.10-RC1 + '3.0.9' => array(), + // No changes from 3.0.10-RC1 to 3.0.10-RC2 + '3.0.10-RC1' => array(), + // No changes from 3.0.10-RC2 to 3.0.10-RC3 + '3.0.10-RC2' => array(), + // No changes from 3.0.10-RC3 to 3.0.10 + '3.0.10-RC3' => array(), + // No changes from 3.0.10 to 3.0.11-RC1 + '3.0.10' => array(), + // Changes from 3.0.11-RC1 to 3.0.11-RC2 + '3.0.11-RC1' => array( + 'add_columns' => array( + PROFILE_FIELDS_TABLE => array( + 'field_show_novalue' => array('BOOL', 0), + ), + ), + ), + // No changes from 3.0.11-RC2 to 3.0.11 + '3.0.11-RC2' => array(), + // No changes from 3.0.11 to 3.0.12-RC1 + '3.0.11' => array(), + + /** @todo DROP LOGIN_ATTEMPT_TABLE.attempt_id in 3.0.12-RC1 */ + // Changes from 3.1.0-dev to 3.1.0-A1 '3.1.0-dev' => array( 'add_tables' => array( @@ -939,6 +1210,1159 @@ function change_database_data(&$no_updates, $version) switch ($version) { + case '3.0.0': + + $sql = 'UPDATE ' . TOPICS_TABLE . " + SET topic_last_view_time = topic_last_post_time + WHERE topic_last_view_time = 0"; + _sql($sql, $errored, $error_ary); + + // Update smiley sizes + $smileys = array('icon_e_surprised.gif', 'icon_eek.gif', 'icon_cool.gif', 'icon_lol.gif', 'icon_mad.gif', 'icon_razz.gif', 'icon_redface.gif', 'icon_cry.gif', 'icon_evil.gif', 'icon_twisted.gif', 'icon_rolleyes.gif', 'icon_exclaim.gif', 'icon_question.gif', 'icon_idea.gif', 'icon_arrow.gif', 'icon_neutral.gif', 'icon_mrgreen.gif', 'icon_e_ugeek.gif'); + + foreach ($smileys as $smiley) + { + if (file_exists($phpbb_root_path . 'images/smilies/' . $smiley)) + { + list($width, $height) = getimagesize($phpbb_root_path . 'images/smilies/' . $smiley); + + $sql = 'UPDATE ' . SMILIES_TABLE . ' + SET smiley_width = ' . $width . ', smiley_height = ' . $height . " + WHERE smiley_url = '" . $db->sql_escape($smiley) . "'"; + + _sql($sql, $errored, $error_ary); + } + } + + $no_updates = false; + break; + + // No changes from 3.0.1-RC1 to 3.0.1 + case '3.0.1-RC1': + break; + + // changes from 3.0.1 to 3.0.2-RC1 + case '3.0.1': + + set_config('referer_validation', '1'); + set_config('check_attachment_content', '1'); + set_config('mime_triggers', 'body|head|html|img|plaintext|a href|pre|script|table|title'); + + $no_updates = false; + break; + + // No changes from 3.0.2-RC1 to 3.0.2-RC2 + case '3.0.2-RC1': + break; + + // No changes from 3.0.2-RC2 to 3.0.2 + case '3.0.2-RC2': + break; + + // Changes from 3.0.2 to 3.0.3-RC1 + case '3.0.2': + set_config('enable_queue_trigger', '0'); + set_config('queue_trigger_posts', '3'); + + set_config('pm_max_recipients', '0'); + + // Set maximum number of recipients for the registered users, bots, guests group + $sql = 'UPDATE ' . GROUPS_TABLE . ' SET group_max_recipients = 5 + WHERE ' . $db->sql_in_set('group_name', array('GUESTS', 'REGISTERED', 'REGISTERED_COPPA', 'BOTS')); + _sql($sql, $errored, $error_ary); + + // Not prefilling yet + set_config('dbms_version', ''); + + // Add new permission u_masspm_group and duplicate settings from u_masspm + include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + $auth_admin = new auth_admin(); + + // Only add the new permission if it does not already exist + if (empty($auth_admin->acl_options['id']['u_masspm_group'])) + { + $auth_admin->acl_add_option(array('global' => array('u_masspm_group'))); + + // Now the tricky part, filling the permission + $old_id = $auth_admin->acl_options['id']['u_masspm']; + $new_id = $auth_admin->acl_options['id']['u_masspm_group']; + + $tables = array(ACL_GROUPS_TABLE, ACL_ROLES_DATA_TABLE, ACL_USERS_TABLE); + + foreach ($tables as $table) + { + $sql = 'SELECT * + FROM ' . $table . ' + WHERE auth_option_id = ' . $old_id; + $result = _sql($sql, $errored, $error_ary); + + $sql_ary = array(); + while ($row = $db->sql_fetchrow($result)) + { + $row['auth_option_id'] = $new_id; + $sql_ary[] = $row; + } + $db->sql_freeresult($result); + + if (sizeof($sql_ary)) + { + $db->sql_multi_insert($table, $sql_ary); + } + } + + // Remove any old permission entries + $auth_admin->acl_clear_prefetch(); + } + + /** + * Do not resync post counts here. An admin may do this later from the ACP + $start = 0; + $step = ($config['num_posts']) ? (max((int) ($config['num_posts'] / 5), 20000)) : 20000; + + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_posts = 0'; + _sql($sql, $errored, $error_ary); + + do + { + $sql = 'SELECT COUNT(post_id) AS num_posts, poster_id + FROM ' . POSTS_TABLE . ' + WHERE post_id BETWEEN ' . ($start + 1) . ' AND ' . ($start + $step) . ' + AND post_postcount = 1 AND post_approved = 1 + GROUP BY poster_id'; + $result = _sql($sql, $errored, $error_ary); + + if ($row = $db->sql_fetchrow($result)) + { + do + { + $sql = 'UPDATE ' . USERS_TABLE . " SET user_posts = user_posts + {$row['num_posts']} WHERE user_id = {$row['poster_id']}"; + _sql($sql, $errored, $error_ary); + } + while ($row = $db->sql_fetchrow($result)); + + $start += $step; + } + else + { + $start = 0; + } + $db->sql_freeresult($result); + } + while ($start); + */ + + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET module_auth = \'acl_a_email && cfg_email_enable\' + WHERE module_class = \'acp\' + AND module_basename = \'email\''; + _sql($sql, $errored, $error_ary); + + $no_updates = false; + break; + + // Changes from 3.0.3-RC1 to 3.0.3 + case '3.0.3-RC1': + if ($db->sql_layer == 'oracle') + { + // log_operation is CLOB - but we can change this later + $sql = 'UPDATE ' . LOG_TABLE . " + SET log_operation = 'LOG_DELETE_TOPIC' + WHERE log_operation LIKE 'LOG_TOPIC_DELETED'"; + _sql($sql, $errored, $error_ary); + } + else + { + $sql = 'UPDATE ' . LOG_TABLE . " + SET log_operation = 'LOG_DELETE_TOPIC' + WHERE log_operation = 'LOG_TOPIC_DELETED'"; + _sql($sql, $errored, $error_ary); + } + + $no_updates = false; + break; + + // Changes from 3.0.3 to 3.0.4-RC1 + case '3.0.3': + // Update the Custom Profile Fields based on previous settings to the new format + $sql = 'SELECT field_id, field_required, field_show_on_reg, field_hide + FROM ' . PROFILE_FIELDS_TABLE; + $result = _sql($sql, $errored, $error_ary); + + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary = array( + 'field_required' => 0, + 'field_show_on_reg' => 0, + 'field_hide' => 0, + 'field_show_profile'=> 0, + ); + + if ($row['field_required']) + { + $sql_ary['field_required'] = $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; + } + else if ($row['field_show_on_reg']) + { + $sql_ary['field_show_on_reg'] = $sql_ary['field_show_profile'] = 1; + } + else if ($row['field_hide']) + { + // Only administrators and moderators can see this CPF, if the view is enabled, they can see it, otherwise just admins in the acp_users module + $sql_ary['field_hide'] = 1; + } + else + { + // equivelant to "none", which is the "Display in user control panel" option + $sql_ary['field_show_profile'] = 1; + } + + _sql('UPDATE ' . PROFILE_FIELDS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE field_id = ' . $row['field_id'], $errored, $error_ary); + } + $no_updates = false; + + break; + + // Changes from 3.0.4-RC1 to 3.0.4 + case '3.0.4-RC1': + break; + + // Changes from 3.0.4 to 3.0.5-RC1 + case '3.0.4': + + // Captcha config variables + set_config('captcha_gd_wave', 0); + set_config('captcha_gd_3d_noise', 1); + set_config('captcha_gd_fonts', 1); + set_config('confirm_refresh', 1); + + // Maximum number of keywords + set_config('max_num_search_keywords', 10); + + // Remove static config var and put it back as dynamic variable + $sql = 'UPDATE ' . CONFIG_TABLE . " + SET is_dynamic = 1 + WHERE config_name = 'search_indexing_state'"; + _sql($sql, $errored, $error_ary); + + // Hash old MD5 passwords + $sql = 'SELECT user_id, user_password + FROM ' . USERS_TABLE . ' + WHERE user_pass_convert = 1'; + $result = _sql($sql, $errored, $error_ary); + + while ($row = $db->sql_fetchrow($result)) + { + if (strlen($row['user_password']) == 32) + { + $sql_ary = array( + 'user_password' => phpbb_hash($row['user_password']), + ); + + _sql('UPDATE ' . USERS_TABLE . ' SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' WHERE user_id = ' . $row['user_id'], $errored, $error_ary); + } + } + $db->sql_freeresult($result); + + // Adjust bot entry + $sql = 'UPDATE ' . BOTS_TABLE . " + SET bot_agent = 'ichiro/' + WHERE bot_agent = 'ichiro/2'"; + _sql($sql, $errored, $error_ary); + + + // Before we are able to add a unique key to auth_option, we need to remove duplicate entries + + // We get duplicate entries first + $sql = 'SELECT auth_option + FROM ' . ACL_OPTIONS_TABLE . ' + GROUP BY auth_option + HAVING COUNT(*) >= 2'; + $result = $db->sql_query($sql); + + $auth_options = array(); + while ($row = $db->sql_fetchrow($result)) + { + $auth_options[] = $row['auth_option']; + } + $db->sql_freeresult($result); + + // Remove specific auth options + if (!empty($auth_options)) + { + foreach ($auth_options as $option) + { + // Select auth_option_ids... the largest id will be preserved + $sql = 'SELECT auth_option_id + FROM ' . ACL_OPTIONS_TABLE . " + WHERE auth_option = '" . $db->sql_escape($option) . "' + ORDER BY auth_option_id DESC"; + // sql_query_limit not possible here, due to bug in postgresql layer + $result = $db->sql_query($sql); + + // Skip first row, this is our original auth option we want to preserve + $row = $db->sql_fetchrow($result); + + while ($row = $db->sql_fetchrow($result)) + { + // Ok, remove this auth option... + _sql('DELETE FROM ' . ACL_OPTIONS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + _sql('DELETE FROM ' . ACL_ROLES_DATA_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + _sql('DELETE FROM ' . ACL_GROUPS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + _sql('DELETE FROM ' . ACL_USERS_TABLE . ' WHERE auth_option_id = ' . $row['auth_option_id'], $errored, $error_ary); + } + $db->sql_freeresult($result); + } + } + + // Now make auth_option UNIQUE, by dropping the old index and adding a UNIQUE one. + $changes = array( + 'drop_keys' => array( + ACL_OPTIONS_TABLE => array('auth_option'), + ), + ); + + global $db_tools; + + $statements = $db_tools->perform_schema_changes($changes); + + foreach ($statements as $sql) + { + _sql($sql, $errored, $error_ary); + } + + $changes = array( + 'add_unique_index' => array( + ACL_OPTIONS_TABLE => array( + 'auth_option' => array('auth_option'), + ), + ), + ); + + $statements = $db_tools->perform_schema_changes($changes); + + foreach ($statements as $sql) + { + _sql($sql, $errored, $error_ary); + } + + $no_updates = false; + + break; + + // No changes from 3.0.5-RC1 to 3.0.5 + case '3.0.5-RC1': + break; + + // Changes from 3.0.5 to 3.0.6-RC1 + case '3.0.5': + // Let's see if the GD Captcha can be enabled... we simply look for what *is* enabled... + if (!empty($config['captcha_gd']) && !isset($config['captcha_plugin'])) + { + set_config('captcha_plugin', 'phpbb_captcha_gd'); + } + else if (!isset($config['captcha_plugin'])) + { + set_config('captcha_plugin', 'phpbb_captcha_nogd'); + } + + // Entries for the Feed Feature + set_config('feed_enable', '0'); + set_config('feed_limit', '10'); + + set_config('feed_overall_forums', '1'); + set_config('feed_overall_forums_limit', '15'); + + set_config('feed_overall_topics', '0'); + set_config('feed_overall_topics_limit', '15'); + + set_config('feed_forum', '1'); + set_config('feed_topic', '1'); + set_config('feed_item_statistics', '1'); + + // Entries for smiley pagination + set_config('smilies_per_page', '50'); + + // Entry for reporting PMs + set_config('allow_pm_report', '1'); + + // Install modules + $modules_to_install = array( + 'feed' => array( + 'base' => 'board', + 'class' => 'acp', + 'title' => 'ACP_FEED_SETTINGS', + 'auth' => 'acl_a_board', + 'cat' => 'ACP_BOARD_CONFIGURATION', + 'after' => array('signature', 'ACP_SIGNATURE_SETTINGS') + ), + 'warnings' => array( + 'base' => 'users', + 'class' => 'acp', + 'title' => 'ACP_USER_WARNINGS', + 'auth' => 'acl_a_user', + 'display' => 0, + 'cat' => 'ACP_CAT_USERS', + 'after' => array('feedback', 'ACP_USER_FEEDBACK') + ), + 'send_statistics' => array( + 'base' => 'send_statistics', + 'class' => 'acp', + 'title' => 'ACP_SEND_STATISTICS', + 'auth' => 'acl_a_server', + 'cat' => 'ACP_SERVER_CONFIGURATION' + ), + 'setting_forum_copy' => array( + 'base' => 'permissions', + 'class' => 'acp', + 'title' => 'ACP_FORUM_PERMISSIONS_COPY', + 'auth' => 'acl_a_fauth && acl_a_authusers && acl_a_authgroups && acl_a_mauth', + 'cat' => 'ACP_FORUM_BASED_PERMISSIONS', + 'after' => array('setting_forum_local', 'ACP_FORUM_PERMISSIONS') + ), + 'pm_reports' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORTS_OPEN', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + 'pm_reports_closed' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORTS_CLOSED', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + 'pm_report_details' => array( + 'base' => 'pm_reports', + 'class' => 'mcp', + 'title' => 'MCP_PM_REPORT_DETAILS', + 'auth' => 'aclf_m_report', + 'cat' => 'MCP_REPORTS' + ), + ); + + _add_modules($modules_to_install); + + // Add newly_registered group... but check if it already exists (we always supported running the updater on any schema) + $sql = 'SELECT group_id + FROM ' . GROUPS_TABLE . " + WHERE group_name = 'NEWLY_REGISTERED'"; + $result = $db->sql_query($sql); + $group_id = (int) $db->sql_fetchfield('group_id'); + $db->sql_freeresult($result); + + if (!$group_id) + { + $sql = 'INSERT INTO ' . GROUPS_TABLE . " (group_name, group_type, group_founder_manage, group_colour, group_legend, group_avatar, group_desc, group_desc_uid, group_max_recipients) VALUES ('NEWLY_REGISTERED', 3, 0, '', 0, '', '', '', 5)"; + _sql($sql, $errored, $error_ary); + + $group_id = $db->sql_nextid(); + } + + // Insert new user role... at the end of the chain + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = 'ROLE_USER_NEW_MEMBER' + AND role_type = 'u_'"; + $result = $db->sql_query($sql); + $u_role = (int) $db->sql_fetchfield('role_id'); + $db->sql_freeresult($result); + + if (!$u_role) + { + $sql = 'SELECT MAX(role_order) as max_order_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_type = 'u_'"; + $result = $db->sql_query($sql); + $next_order_id = (int) $db->sql_fetchfield('max_order_id'); + $db->sql_freeresult($result); + + $next_order_id++; + + $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_USER_NEW_MEMBER', 'ROLE_DESCRIPTION_USER_NEW_MEMBER', 'u_', $next_order_id)"; + _sql($sql, $errored, $error_ary); + $u_role = $db->sql_nextid(); + + if (!$errored) + { + // Now add the correct data to the roles... + // The standard role says that new users are not able to send a PM, Mass PM, are not able to PM groups + $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $u_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'u_%' AND auth_option IN ('u_sendpm', 'u_masspm', 'u_masspm_group')"; + _sql($sql, $errored, $error_ary); + + // Add user role to group + $sql = 'INSERT INTO ' . ACL_GROUPS_TABLE . " (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES ($group_id, 0, 0, $u_role, 0)"; + _sql($sql, $errored, $error_ary); + } + } + + // Insert new forum role + $sql = 'SELECT role_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_name = 'ROLE_FORUM_NEW_MEMBER' + AND role_type = 'f_'"; + $result = $db->sql_query($sql); + $f_role = (int) $db->sql_fetchfield('role_id'); + $db->sql_freeresult($result); + + if (!$f_role) + { + $sql = 'SELECT MAX(role_order) as max_order_id + FROM ' . ACL_ROLES_TABLE . " + WHERE role_type = 'f_'"; + $result = $db->sql_query($sql); + $next_order_id = (int) $db->sql_fetchfield('max_order_id'); + $db->sql_freeresult($result); + + $next_order_id++; + + $sql = 'INSERT INTO ' . ACL_ROLES_TABLE . " (role_name, role_description, role_type, role_order) VALUES ('ROLE_FORUM_NEW_MEMBER', 'ROLE_DESCRIPTION_FORUM_NEW_MEMBER', 'f_', $next_order_id)"; + _sql($sql, $errored, $error_ary); + $f_role = $db->sql_nextid(); + + if (!$errored) + { + $sql = 'INSERT INTO ' . ACL_ROLES_DATA_TABLE . " (role_id, auth_option_id, auth_setting) SELECT $f_role, auth_option_id, 0 FROM " . ACL_OPTIONS_TABLE . " WHERE auth_option LIKE 'f_%' AND auth_option IN ('f_noapprove')"; + _sql($sql, $errored, $error_ary); + } + } + + // Set every members user_new column to 0 (old users) only if there is no one yet (this makes sure we do not execute this more than once) + $sql = 'SELECT 1 + FROM ' . USERS_TABLE . ' + WHERE user_new = 0'; + $result = $db->sql_query_limit($sql, 1); + $row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$row) + { + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_new = 0'; + _sql($sql, $errored, $error_ary); + } + + // Newly registered users limit + if (!isset($config['new_member_post_limit'])) + { + set_config('new_member_post_limit', (!empty($config['enable_queue_trigger'])) ? $config['queue_trigger_posts'] : 0); + } + + if (!isset($config['new_member_group_default'])) + { + set_config('new_member_group_default', 0); + } + + // To mimick the old "feature" we will assign the forum role to every forum, regardless of the setting (this makes sure there are no "this does not work!!!! YUO!!!" posts... + // Check if the role is already assigned... + $sql = 'SELECT forum_id + FROM ' . ACL_GROUPS_TABLE . ' + WHERE group_id = ' . $group_id . ' + AND auth_role_id = ' . $f_role; + $result = $db->sql_query($sql); + $is_options = (int) $db->sql_fetchfield('forum_id'); + $db->sql_freeresult($result); + + // Not assigned at all... :/ + if (!$is_options) + { + // Get postable forums + $sql = 'SELECT forum_id + FROM ' . FORUMS_TABLE . ' + WHERE forum_type != ' . FORUM_LINK; + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + _sql('INSERT INTO ' . ACL_GROUPS_TABLE . ' (group_id, forum_id, auth_option_id, auth_role_id, auth_setting) VALUES (' . $group_id . ', ' . (int) $row['forum_id'] . ', 0, ' . $f_role . ', 0)', $errored, $error_ary); + } + $db->sql_freeresult($result); + } + + // Clear permissions... + include_once($phpbb_root_path . 'includes/acp/auth.' . $phpEx); + $auth_admin = new auth_admin(); + $auth_admin->acl_clear_prefetch(); + + if (!isset($config['allow_avatar'])) + { + if ($config['allow_avatar_upload'] || $config['allow_avatar_local'] || $config['allow_avatar_remote']) + { + set_config('allow_avatar', '1'); + } + else + { + set_config('allow_avatar', '0'); + } + } + + if (!isset($config['allow_avatar_remote_upload'])) + { + if ($config['allow_avatar_remote'] && $config['allow_avatar_upload']) + { + set_config('allow_avatar_remote_upload', '1'); + } + else + { + set_config('allow_avatar_remote_upload', '0'); + } + } + + // Minimum number of characters + if (!isset($config['min_post_chars'])) + { + set_config('min_post_chars', '1'); + } + + if (!isset($config['allow_quick_reply'])) + { + set_config('allow_quick_reply', '1'); + } + + // Set every members user_options column to enable + // bbcode, smilies and URLs for signatures by default + $sql = 'SELECT user_options + FROM ' . USERS_TABLE . ' + WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')'; + $result = $db->sql_query_limit($sql, 1); + $user_option = (int) $db->sql_fetchfield('user_options'); + $db->sql_freeresult($result); + + // Check if we already updated the database by checking bit 15 which we used to store the sig_bbcode option + if (!($user_option & 1 << 15)) + { + // 229376 is the added value to enable all three signature options + $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = user_options + 229376'; + _sql($sql, $errored, $error_ary); + } + + if (!isset($config['delete_time'])) + { + set_config('delete_time', $config['edit_time']); + } + + $no_updates = false; + break; + + // No changes from 3.0.6-RC1 to 3.0.6-RC2 + case '3.0.6-RC1': + break; + + // Changes from 3.0.6-RC2 to 3.0.6-RC3 + case '3.0.6-RC2': + + // Update the Custom Profile Fields based on previous settings to the new format + $sql = 'UPDATE ' . PROFILE_FIELDS_TABLE . ' + SET field_show_on_vt = 1 + WHERE field_hide = 0 + AND (field_required = 1 OR field_show_on_reg = 1 OR field_show_profile = 1)'; + _sql($sql, $errored, $error_ary); + $no_updates = false; + + break; + + // No changes from 3.0.6-RC3 to 3.0.6-RC4 + case '3.0.6-RC3': + break; + + // No changes from 3.0.6-RC4 to 3.0.6 + case '3.0.6-RC4': + break; + + // Changes from 3.0.6 to 3.0.7-RC1 + case '3.0.6': + + // ATOM Feeds + set_config('feed_overall', '1'); + set_config('feed_http_auth', '0'); + set_config('feed_limit_post', (string) (isset($config['feed_limit']) ? (int) $config['feed_limit'] : 15)); + set_config('feed_limit_topic', (string) (isset($config['feed_overall_topics_limit']) ? (int) $config['feed_overall_topics_limit'] : 10)); + set_config('feed_topics_new', (!empty($config['feed_overall_topics']) ? '1' : '0')); + set_config('feed_topics_active', (!empty($config['feed_overall_topics']) ? '1' : '0')); + + // Delete all text-templates from the template_data + $sql = 'DELETE FROM ' . STYLES_TEMPLATE_DATA_TABLE . ' + WHERE template_filename ' . $db->sql_like_expression($db->any_char . '.txt'); + _sql($sql, $errored, $error_ary); + + $no_updates = false; + break; + + // Changes from 3.0.7-RC1 to 3.0.7-RC2 + case '3.0.7-RC1': + + $sql = 'SELECT user_id, user_email, user_email_hash + FROM ' . USERS_TABLE . ' + WHERE user_type <> ' . USER_IGNORE . " + AND user_email <> ''"; + $result = $db->sql_query($sql); + + $i = 0; + while ($row = $db->sql_fetchrow($result)) + { + // Snapshot of the phpbb_email_hash() function + // We cannot call it directly because the auto updater updates the DB first. :/ + $user_email_hash = sprintf('%u', crc32(strtolower($row['user_email']))) . strlen($row['user_email']); + + if ($user_email_hash != $row['user_email_hash']) + { + $sql_ary = array( + 'user_email_hash' => $user_email_hash, + ); + + $sql = 'UPDATE ' . USERS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE user_id = ' . (int) $row['user_id']; + _sql($sql, $errored, $error_ary, ($i % 100 == 0)); + + ++$i; + } + } + $db->sql_freeresult($result); + + $no_updates = false; + + break; + + // No changes from 3.0.7-RC2 to 3.0.7 + case '3.0.7-RC2': + break; + + // No changes from 3.0.7 to 3.0.7-PL1 + case '3.0.7': + break; + + // Changes from 3.0.7-PL1 to 3.0.8-RC1 + case '3.0.7-PL1': + // Update file extension group names to use language strings. + $sql = 'SELECT lang_dir + FROM ' . LANG_TABLE; + $result = $db->sql_query($sql); + + $extension_groups_updated = array(); + while ($lang_dir = $db->sql_fetchfield('lang_dir')) + { + $lang_dir = basename($lang_dir); + + // The language strings we need are either in language/.../acp/attachments.php + // in the update package if we're updating to 3.0.8-RC1 or later, + // or they are in language/.../install.php when we're updating from 3.0.7-PL1 or earlier. + // On an already updated board, they can also already be in language/.../acp/attachments.php + // in the board root. + $lang_files = array( + "{$phpbb_root_path}install/update/new/language/$lang_dir/acp/attachments.$phpEx", + "{$phpbb_root_path}language/$lang_dir/install.$phpEx", + "{$phpbb_root_path}language/$lang_dir/acp/attachments.$phpEx", + ); + + foreach ($lang_files as $lang_file) + { + if (!file_exists($lang_file)) + { + continue; + } + + $lang = array(); + include($lang_file); + + foreach($lang as $lang_key => $lang_val) + { + if (isset($extension_groups_updated[$lang_key]) || strpos($lang_key, 'EXT_GROUP_') !== 0) + { + continue; + } + + $sql_ary = array( + 'group_name' => substr($lang_key, 10), // Strip off 'EXT_GROUP_' + ); + + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . " + WHERE group_name = '" . $db->sql_escape($lang_val) . "'"; + _sql($sql, $errored, $error_ary); + + $extension_groups_updated[$lang_key] = true; + } + } + } + $db->sql_freeresult($result); + + // Install modules + $modules_to_install = array( + 'post' => array( + 'base' => 'board', + 'class' => 'acp', + 'title' => 'ACP_POST_SETTINGS', + 'auth' => 'acl_a_board', + 'cat' => 'ACP_MESSAGES', + 'after' => array('message', 'ACP_MESSAGE_SETTINGS') + ), + ); + + _add_modules($modules_to_install); + + // update + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET module_auth = \'cfg_allow_avatar && (cfg_allow_avatar_local || cfg_allow_avatar_remote || cfg_allow_avatar_upload || cfg_allow_avatar_remote_upload)\' + WHERE module_class = \'ucp\' + AND module_basename = \'profile\' + AND module_mode = \'avatar\''; + _sql($sql, $errored, $error_ary); + + // add Bing Bot + $bot_name = 'Bing [Bot]'; + $bot_name_clean = utf8_clean_string($bot_name); + + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . " + WHERE username_clean = '" . $db->sql_escape($bot_name_clean) . "'"; + $result = $db->sql_query($sql); + $bing_already_added = (bool) $db->sql_fetchfield('user_id'); + $db->sql_freeresult($result); + + if (!$bing_already_added) + { + $bot_agent = 'bingbot/'; + $bot_ip = ''; + $sql = 'SELECT group_id, group_colour + FROM ' . GROUPS_TABLE . " + WHERE group_name = 'BOTS'"; + $result = $db->sql_query($sql); + $group_row = $db->sql_fetchrow($result); + $db->sql_freeresult($result); + + if (!$group_row) + { + // default fallback, should never get here + $group_row['group_id'] = 6; + $group_row['group_colour'] = '9E8DA7'; + } + + if (!function_exists('user_add')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } + + $user_row = array( + 'user_type' => USER_IGNORE, + 'group_id' => $group_row['group_id'], + 'username' => $bot_name, + 'user_regdate' => time(), + 'user_password' => '', + 'user_colour' => $group_row['group_colour'], + 'user_email' => '', + 'user_lang' => $config['default_lang'], + 'user_style' => $config['default_style'], + 'user_timezone' => 'UTC', + 'user_dateformat' => $config['default_dateformat'], + 'user_allow_massemail' => 0, + ); + + $user_id = user_add($user_row); + + $sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $db->sql_build_array('INSERT', array( + 'bot_active' => 1, + 'bot_name' => (string) $bot_name, + 'user_id' => (int) $user_id, + 'bot_agent' => (string) $bot_agent, + 'bot_ip' => (string) $bot_ip, + )); + + _sql($sql, $errored, $error_ary); + } + // end Bing Bot addition + + // Delete shadow topics pointing to not existing topics + $batch_size = 500; + + // Set of affected forums we have to resync + $sync_forum_ids = array(); + + do + { + $sql_array = array( + 'SELECT' => 't1.topic_id, t1.forum_id', + 'FROM' => array( + TOPICS_TABLE => 't1', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(TOPICS_TABLE => 't2'), + 'ON' => 't1.topic_moved_id = t2.topic_id', + ), + ), + 'WHERE' => 't1.topic_moved_id <> 0 + AND t2.topic_id IS NULL', + ); + $sql = $db->sql_build_query('SELECT', $sql_array); + $result = $db->sql_query_limit($sql, $batch_size); + + $topic_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $topic_ids[] = (int) $row['topic_id']; + + $sync_forum_ids[(int) $row['forum_id']] = (int) $row['forum_id']; + } + $db->sql_freeresult($result); + + if (!empty($topic_ids)) + { + $sql = 'DELETE FROM ' . TOPICS_TABLE . ' + WHERE ' . $db->sql_in_set('topic_id', $topic_ids); + $db->sql_query($sql); + } + } + while (sizeof($topic_ids) == $batch_size); + + // Sync the forums we have deleted shadow topics from. + sync('forum', 'forum_id', $sync_forum_ids, true, true); + + // Unread posts search load switch + set_config('load_unreads_search', '1'); + + // Reduce queue interval to 60 seconds, email package size to 20 + if ($config['queue_interval'] == 600) + { + set_config('queue_interval', '60'); + } + + if ($config['email_package_size'] == 50) + { + set_config('email_package_size', '20'); + } + + $no_updates = false; + break; + + // No changes from 3.0.8-RC1 to 3.0.8 + case '3.0.8-RC1': + break; + + // Changes from 3.0.8 to 3.0.9-RC1 + case '3.0.8': + set_config('ip_login_limit_max', '50'); + set_config('ip_login_limit_time', '21600'); + set_config('ip_login_limit_use_forwarded', '0'); + + // Update file extension group names to use language strings, again. + $sql = 'SELECT group_id, group_name + FROM ' . EXTENSION_GROUPS_TABLE . ' + WHERE group_name ' . $db->sql_like_expression('EXT_GROUP_' . $db->any_char); + $result = $db->sql_query($sql); + + while ($row = $db->sql_fetchrow($result)) + { + $sql_ary = array( + 'group_name' => substr($row['group_name'], 10), // Strip off 'EXT_GROUP_' + ); + + $sql = 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' + SET ' . $db->sql_build_array('UPDATE', $sql_ary) . ' + WHERE group_id = ' . $row['group_id']; + _sql($sql, $errored, $error_ary); + } + $db->sql_freeresult($result); + + global $db_tools, $table_prefix; + + // Recover from potentially broken Q&A CAPTCHA table on firebird + // Q&A CAPTCHA was uninstallable, so it's safe to remove these + // without data loss + if ($db_tools->sql_layer == 'firebird') + { + $tables = array( + $table_prefix . 'captcha_questions', + $table_prefix . 'captcha_answers', + $table_prefix . 'qa_confirm', + ); + foreach ($tables as $table) + { + if ($db_tools->sql_table_exists($table)) + { + $db_tools->sql_table_drop($table); + } + } + } + + $no_updates = false; + break; + + // No changes from 3.0.9-RC1 to 3.0.9-RC2 + case '3.0.9-RC1': + break; + + // No changes from 3.0.9-RC2 to 3.0.9-RC3 + case '3.0.9-RC2': + break; + + // No changes from 3.0.9-RC3 to 3.0.9-RC4 + case '3.0.9-RC3': + break; + + // No changes from 3.0.9-RC4 to 3.0.9 + case '3.0.9-RC4': + break; + + // Changes from 3.0.9 to 3.0.10-RC1 + case '3.0.9': + if (!isset($config['email_max_chunk_size'])) + { + set_config('email_max_chunk_size', '50'); + } + + $no_updates = false; + break; + + // No changes from 3.0.10-RC1 to 3.0.10-RC2 + case '3.0.10-RC1': + break; + + // No changes from 3.0.10-RC2 to 3.0.10-RC3 + case '3.0.10-RC2': + break; + + // No changes from 3.0.10-RC3 to 3.0.10 + case '3.0.10-RC3': + break; + + // Changes from 3.0.10 to 3.0.11-RC1 + case '3.0.10': + // Updates users having current style a deactivated one + $sql = 'SELECT style_id + FROM ' . STYLES_TABLE . ' + WHERE style_active = 0'; + $result = $db->sql_query($sql); + + $deactivated_style_ids = array(); + while ($style_id = $db->sql_fetchfield('style_id', false, $result)) + { + $deactivated_style_ids[] = (int) $style_id; + } + $db->sql_freeresult($result); + + if (!empty($deactivated_style_ids)) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_style = ' . (int) $config['default_style'] .' + WHERE ' . $db->sql_in_set('user_style', $deactivated_style_ids); + _sql($sql, $errored, $error_ary); + } + + // Delete orphan private messages + $batch_size = 500; + + $sql_array = array( + 'SELECT' => 'p.msg_id', + 'FROM' => array( + PRIVMSGS_TABLE => 'p', + ), + 'LEFT_JOIN' => array( + array( + 'FROM' => array(PRIVMSGS_TO_TABLE => 't'), + 'ON' => 'p.msg_id = t.msg_id', + ), + ), + 'WHERE' => 't.user_id IS NULL', + ); + $sql = $db->sql_build_query('SELECT', $sql_array); + + do + { + $result = $db->sql_query_limit($sql, $batch_size); + + $delete_pms = array(); + while ($row = $db->sql_fetchrow($result)) + { + $delete_pms[] = (int) $row['msg_id']; + } + $db->sql_freeresult($result); + + if (!empty($delete_pms)) + { + $sql = 'DELETE FROM ' . PRIVMSGS_TABLE . ' + WHERE ' . $db->sql_in_set('msg_id', $delete_pms); + _sql($sql, $errored, $error_ary); + } + } + while (sizeof($delete_pms) == $batch_size); + + $no_updates = false; + break; + + // No changes from 3.0.11-RC1 to 3.0.11-RC2 + case '3.0.11-RC1': + break; + + // No changes from 3.0.11-RC2 to 3.0.11 + case '3.0.11-RC2': + break; + + // Changes from 3.0.11 to 3.0.12-RC1 + case '3.0.11': + $sql = 'UPDATE ' . MODULES_TABLE . ' + SET module_auth = \'acl_u_sig\' + WHERE module_class = \'ucp\' + AND module_basename = \'profile\' + AND module_mode = \'signature\''; + _sql($sql, $errored, $error_ary); + + // Update bots + if (!function_exists('user_delete')) + { + include($phpbb_root_path . 'includes/functions_user.' . $phpEx); + } + + $bots_updates = array( + // Bot Deletions + 'NG-Search [Bot]' => false, + 'Nutch/CVS [Bot]' => false, + 'OmniExplorer [Bot]' => false, + 'Seekport [Bot]' => false, + 'Synoo [Bot]' => false, + 'WiseNut [Bot]' => false, + + // Bot Updates + // Bot name to bot user agent map + 'Baidu [Spider]' => 'Baiduspider', + 'Exabot [Bot]' => 'Exabot', + 'Voyager [Bot]' => 'voyager/', + 'W3C [Validator]' => 'W3C_Validator', + ); + + foreach ($bots_updates as $bot_name => $bot_agent) + { + $sql = 'SELECT user_id + FROM ' . USERS_TABLE . ' + WHERE user_type = ' . USER_IGNORE . " + AND username_clean = '" . $db->sql_escape(utf8_clean_string($bot_name)) . "'"; + $result = $db->sql_query($sql); + $bot_user_id = (int) $db->sql_fetchfield('user_id'); + $db->sql_freeresult($result); + + if ($bot_user_id) + { + if ($bot_agent === false) + { + $sql = 'DELETE FROM ' . BOTS_TABLE . " + WHERE user_id = $bot_user_id"; + _sql($sql, $errored, $error_ary); + + user_delete('remove', $bot_user_id); + } + else + { + $sql = 'UPDATE ' . BOTS_TABLE . " + SET bot_agent = '" . $db->sql_escape($bot_agent) . "' + WHERE user_id = $bot_user_id"; + _sql($sql, $errored, $error_ary); + } + } + } + + $no_updates = false; + break; + // Changes from 3.1.0-dev to 3.1.0-A1 case '3.1.0-dev': -- cgit v1.2.1 From 5c91e2569cb3a400acd20bf06cc0e609dd63a778 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Tue, 8 Jan 2013 22:09:14 -0600 Subject: [feature/migrations] Migrations now somewhat works PHPBB3-9737 --- phpBB/install/database_update.php | 65 +++++++++++++++++++++++-------- phpBB/install/schemas/firebird_schema.sql | 29 +++++++------- phpBB/install/schemas/mssql_schema.sql | 42 +++++++++++--------- phpBB/install/schemas/mysql_40_schema.sql | 26 ++++++------- phpBB/install/schemas/mysql_41_schema.sql | 26 ++++++------- phpBB/install/schemas/oracle_schema.sql | 32 +++++++-------- phpBB/install/schemas/postgres_schema.sql | 30 +++++++------- phpBB/install/schemas/sqlite_schema.sql | 28 ++++++------- 8 files changed, 158 insertions(+), 120 deletions(-) (limited to 'phpBB/install') diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php index 207ad716de..8950d677ae 100644 --- a/phpBB/install/database_update.php +++ b/phpBB/install/database_update.php @@ -1521,8 +1521,6 @@ function change_database_data(&$no_updates, $version) ), ); - global $db_tools; - $statements = $db_tools->perform_schema_changes($changes); foreach ($statements as $sql) @@ -2164,26 +2162,41 @@ function change_database_data(&$no_updates, $version) } $db->sql_freeresult($result); - global $db_tools, $table_prefix; - - // Recover from potentially broken Q&A CAPTCHA table on firebird - // Q&A CAPTCHA was uninstallable, so it's safe to remove these - // without data loss + /* + * Due to a bug, vanilla phpbb could not create captcha tables + * in 3.0.8 on firebird. It was possible for board administrators + * to adjust the code to work. If code was manually adjusted by + * board administrators, index names would not be the same as + * what 3.0.9 and newer expect. This code fragment drops captcha + * tables, destroying all entered Q&A captcha configuration, such + * that when Q&A is configured next the respective tables will be + * created with correct index names. + * + * If you wish to preserve your Q&A captcha configuration, you can + * manually rename indexes to the currently expected name: + * phpbb_captcha_questions_lang_iso => phpbb_captcha_questions_lang + * phpbb_captcha_answers_question_id => phpbb_captcha_answers_qid + * + * Again, this needs to be done only if a board was manually modified + * to fix broken captcha code. + * if ($db_tools->sql_layer == 'firebird') { - $tables = array( - $table_prefix . 'captcha_questions', - $table_prefix . 'captcha_answers', - $table_prefix . 'qa_confirm', + $changes = array( + 'drop_tables' => array( + $table_prefix . 'captcha_questions', + $table_prefix . 'captcha_answers', + $table_prefix . 'qa_confirm', + ), ); - foreach ($tables as $table) + $statements = $db_tools->perform_schema_changes($changes); + + foreach ($statements as $sql) { - if ($db_tools->sql_table_exists($table)) - { - $db_tools->sql_table_drop($table); - } + _sql($sql, $errored, $error_ary); } } + */ $no_updates = false; break; @@ -2360,6 +2373,26 @@ function change_database_data(&$no_updates, $version) } } + // Disable receiving pms for bots + $sql = 'SELECT user_id + FROM ' . BOTS_TABLE; + $result = $db->sql_query($sql); + + $bot_user_ids = array(); + while ($row = $db->sql_fetchrow($result)) + { + $bot_user_ids[] = (int) $row['user_id']; + } + $db->sql_freeresult($result); + + if (!empty($bot_user_ids)) + { + $sql = 'UPDATE ' . USERS_TABLE . ' + SET user_allow_pm = 0 + WHERE ' . $db->sql_in_set('user_id', $bot_user_ids); + _sql($sql, $errored, $error_ary); + } + $no_updates = false; break; diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 43099fc33b..535cbb0df4 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -573,18 +573,6 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts(attempt_forwar CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts(attempt_time);; CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts(user_id);; -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - migration_schema_done INTEGER DEFAULT 0 NOT NULL, - migration_data_done INTEGER DEFAULT 0 NOT NULL, - migration_data_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, - migration_start_time INTEGER DEFAULT 0 NOT NULL, - migration_end_time INTEGER DEFAULT 0 NOT NULL -);; - -CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations(migration_name);; - # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER DEFAULT 0 NOT NULL, @@ -598,6 +586,19 @@ CREATE TABLE phpbb_moderator_cache ( CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache(display_on_index);; CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache(forum_id);; +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_schema_done INTEGER DEFAULT 0 NOT NULL, + migration_data_done INTEGER DEFAULT 0 NOT NULL, + migration_data_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_start_time INTEGER DEFAULT 0 NOT NULL, + migration_end_time INTEGER DEFAULT 0 NOT NULL +);; + +ALTER TABLE phpbb_migrations ADD PRIMARY KEY (migration_name);; + + # Table: 'phpbb_modules' CREATE TABLE phpbb_modules ( module_id INTEGER NOT NULL, @@ -924,8 +925,8 @@ CREATE TABLE phpbb_reports ( report_time INTEGER DEFAULT 0 NOT NULL, report_text BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, reported_post_text BLOB SUB_TYPE TEXT CHARACTER SET UTF8 DEFAULT '' NOT NULL, - reported_post_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, - reported_post_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL + reported_post_uid VARCHAR(8) CHARACTER SET NONE DEFAULT '' NOT NULL, + reported_post_bitfield VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL );; ALTER TABLE phpbb_reports ADD PRIMARY KEY (report_id);; diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 1174cdfa3d..43b8f3e556 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -696,23 +696,6 @@ CREATE INDEX [user_id] ON [phpbb_login_attempts]([user_id]) ON [PRIMARY] GO -/* - Table: 'phpbb_migrations' -*/ -CREATE TABLE [phpbb_migrations] ( - [migration_name] [varchar] (255) DEFAULT ('') NOT NULL , - [migration_schema_done] [int] DEFAULT (0) NOT NULL , - [migration_data_done] [int] DEFAULT (0) NOT NULL , - [migration_data_state] [varchar] (8000) DEFAULT ('') NOT NULL , - [migration_start_time] [int] DEFAULT (0) NOT NULL , - [migration_end_time] [int] DEFAULT (0) NOT NULL -) ON [PRIMARY] -GO - -CREATE UNIQUE INDEX [migration_name] ON [phpbb_migrations]([migration_name]) ON [PRIMARY] -GO - - /* Table: 'phpbb_moderator_cache' */ @@ -733,6 +716,27 @@ CREATE INDEX [forum_id] ON [phpbb_moderator_cache]([forum_id]) ON [PRIMARY] GO +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE [phpbb_migrations] ( + [migration_name] [varchar] (255) DEFAULT ('') NOT NULL , + [migration_schema_done] [int] DEFAULT (0) NOT NULL , + [migration_data_done] [int] DEFAULT (0) NOT NULL , + [migration_data_state] [varchar] (8000) DEFAULT ('') NOT NULL , + [migration_start_time] [int] DEFAULT (0) NOT NULL , + [migration_end_time] [int] DEFAULT (0) NOT NULL +) ON [PRIMARY] +GO + +ALTER TABLE [phpbb_migrations] WITH NOCHECK ADD + CONSTRAINT [PK_phpbb_migrations] PRIMARY KEY CLUSTERED + ( + [migration_name] + ) ON [PRIMARY] +GO + + /* Table: 'phpbb_modules' */ @@ -1128,8 +1132,8 @@ CREATE TABLE [phpbb_reports] ( [report_time] [int] DEFAULT (0) NOT NULL , [report_text] [text] DEFAULT ('') NOT NULL , [reported_post_text] [text] DEFAULT ('') NOT NULL , - [reported_post_bitfield] [varchar] (255) DEFAULT ('') NOT NULL , - [reported_post_uid] [varchar] (8) DEFAULT ('') NOT NULL + [reported_post_uid] [varchar] (8) DEFAULT ('') NOT NULL , + [reported_post_bitfield] [varchar] (255) DEFAULT ('') NOT NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index d645c3384d..c46230744a 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -397,18 +397,6 @@ CREATE TABLE phpbb_login_attempts ( ); -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name varbinary(255) DEFAULT '' NOT NULL, - migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_state blob NOT NULL, - migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - UNIQUE migration_name (migration_name) -); - - # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -422,6 +410,18 @@ CREATE TABLE phpbb_moderator_cache ( ); +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varbinary(255) DEFAULT '' NOT NULL, + migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_state blob NOT NULL, + migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + PRIMARY KEY (migration_name) +); + + # Table: 'phpbb_modules' CREATE TABLE phpbb_modules ( module_id mediumint(8) UNSIGNED NOT NULL auto_increment, @@ -661,8 +661,8 @@ CREATE TABLE phpbb_reports ( report_time int(11) UNSIGNED DEFAULT '0' NOT NULL, report_text mediumblob NOT NULL, reported_post_text mediumblob NOT NULL, - reported_post_bitfield varbinary(255) DEFAULT '' NOT NULL, reported_post_uid varbinary(8) DEFAULT '' NOT NULL, + reported_post_bitfield varbinary(255) DEFAULT '' NOT NULL, PRIMARY KEY (report_id), KEY post_id (post_id), KEY pm_id (pm_id) diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index d10f2dc55a..fa94598e9c 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -397,18 +397,6 @@ CREATE TABLE phpbb_login_attempts ( ) CHARACTER SET `utf8` COLLATE `utf8_bin`; -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name varchar(255) DEFAULT '' NOT NULL, - migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, - migration_data_state text NOT NULL, - migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, - UNIQUE migration_name (migration_name) -) CHARACTER SET `utf8` COLLATE `utf8_bin`; - - # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id mediumint(8) UNSIGNED DEFAULT '0' NOT NULL, @@ -422,6 +410,18 @@ CREATE TABLE phpbb_moderator_cache ( ) CHARACTER SET `utf8` COLLATE `utf8_bin`; +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) DEFAULT '' NOT NULL, + migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, + migration_data_state text NOT NULL, + migration_start_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + migration_end_time int(11) UNSIGNED DEFAULT '0' NOT NULL, + PRIMARY KEY (migration_name) +) CHARACTER SET `utf8` COLLATE `utf8_bin`; + + # Table: 'phpbb_modules' CREATE TABLE phpbb_modules ( module_id mediumint(8) UNSIGNED NOT NULL auto_increment, @@ -661,8 +661,8 @@ CREATE TABLE phpbb_reports ( report_time int(11) UNSIGNED DEFAULT '0' NOT NULL, report_text mediumtext NOT NULL, reported_post_text mediumtext NOT NULL, - reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, reported_post_uid varchar(8) DEFAULT '' NOT NULL, + reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, PRIMARY KEY (report_id), KEY post_id (post_id), KEY pm_id (pm_id) diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index 9993caeb7a..f8a9d5e1a6 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -780,21 +780,6 @@ CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id) / -/* - Table: 'phpbb_migrations' -*/ -CREATE TABLE phpbb_migrations ( - migration_name varchar2(255) DEFAULT '' , - migration_schema_done number(1) DEFAULT '0' NOT NULL, - migration_data_done number(1) DEFAULT '0' NOT NULL, - migration_data_state clob DEFAULT '' , - migration_start_time number(11) DEFAULT '0' NOT NULL, - migration_end_time number(11) DEFAULT '0' NOT NULL, - CONSTRAINT u_phpbb_migration_name UNIQUE (migration_name) -) -/ - - /* Table: 'phpbb_moderator_cache' */ @@ -813,6 +798,21 @@ CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache (display_on CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id) / +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE phpbb_migrations ( + migration_name varchar2(255) DEFAULT '' , + migration_schema_done number(1) DEFAULT '0' NOT NULL, + migration_data_done number(1) DEFAULT '0' NOT NULL, + migration_data_state clob DEFAULT '' , + migration_start_time number(11) DEFAULT '0' NOT NULL, + migration_end_time number(11) DEFAULT '0' NOT NULL, + CONSTRAINT pk_phpbb_migrations PRIMARY KEY (migration_name) +) +/ + + /* Table: 'phpbb_modules' */ @@ -1231,8 +1231,8 @@ CREATE TABLE phpbb_reports ( report_time number(11) DEFAULT '0' NOT NULL, report_text clob DEFAULT '' , reported_post_text clob DEFAULT '' , - reported_post_bitfield varchar2(255) DEFAULT '' , reported_post_uid varchar2(8) DEFAULT '' , + reported_post_bitfield varchar2(255) DEFAULT '' , CONSTRAINT pk_phpbb_reports PRIMARY KEY (report_id) ) / diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index ef138dac0f..c976659f05 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -557,20 +557,6 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwa CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); -/* - Table: 'phpbb_migrations' -*/ -CREATE TABLE phpbb_migrations ( - migration_name varchar(255) DEFAULT '' NOT NULL, - migration_schema_done INT2 DEFAULT '0' NOT NULL CHECK (migration_schema_done >= 0), - migration_data_done INT2 DEFAULT '0' NOT NULL CHECK (migration_data_done >= 0), - migration_data_state varchar(8000) DEFAULT '' NOT NULL, - migration_start_time INT4 DEFAULT '0' NOT NULL CHECK (migration_start_time >= 0), - migration_end_time INT4 DEFAULT '0' NOT NULL CHECK (migration_end_time >= 0) -); - -CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations (migration_name); - /* Table: 'phpbb_moderator_cache' */ @@ -586,6 +572,20 @@ CREATE TABLE phpbb_moderator_cache ( CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache (display_on_index); CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); +/* + Table: 'phpbb_migrations' +*/ +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) DEFAULT '' NOT NULL, + migration_schema_done INT2 DEFAULT '0' NOT NULL CHECK (migration_schema_done >= 0), + migration_data_done INT2 DEFAULT '0' NOT NULL CHECK (migration_data_done >= 0), + migration_data_state varchar(8000) DEFAULT '' NOT NULL, + migration_start_time INT4 DEFAULT '0' NOT NULL CHECK (migration_start_time >= 0), + migration_end_time INT4 DEFAULT '0' NOT NULL CHECK (migration_end_time >= 0), + PRIMARY KEY (migration_name) +); + + /* Table: 'phpbb_modules' */ @@ -869,8 +869,8 @@ CREATE TABLE phpbb_reports ( report_time INT4 DEFAULT '0' NOT NULL CHECK (report_time >= 0), report_text TEXT DEFAULT '' NOT NULL, reported_post_text TEXT DEFAULT '' NOT NULL, - reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, reported_post_uid varchar(8) DEFAULT '' NOT NULL, + reported_post_bitfield varchar(255) DEFAULT '' NOT NULL, PRIMARY KEY (report_id) ); diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 309297779e..31a6f715a0 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -385,18 +385,6 @@ CREATE INDEX phpbb_login_attempts_att_for ON phpbb_login_attempts (attempt_forwa CREATE INDEX phpbb_login_attempts_att_time ON phpbb_login_attempts (attempt_time); CREATE INDEX phpbb_login_attempts_user_id ON phpbb_login_attempts (user_id); -# Table: 'phpbb_migrations' -CREATE TABLE phpbb_migrations ( - migration_name varchar(255) NOT NULL DEFAULT '', - migration_schema_done INTEGER UNSIGNED NOT NULL DEFAULT '0', - migration_data_done INTEGER UNSIGNED NOT NULL DEFAULT '0', - migration_data_state text(65535) NOT NULL DEFAULT '', - migration_start_time INTEGER UNSIGNED NOT NULL DEFAULT '0', - migration_end_time INTEGER UNSIGNED NOT NULL DEFAULT '0' -); - -CREATE UNIQUE INDEX phpbb_migrations_migration_name ON phpbb_migrations (migration_name); - # Table: 'phpbb_moderator_cache' CREATE TABLE phpbb_moderator_cache ( forum_id INTEGER UNSIGNED NOT NULL DEFAULT '0', @@ -410,6 +398,18 @@ CREATE TABLE phpbb_moderator_cache ( CREATE INDEX phpbb_moderator_cache_disp_idx ON phpbb_moderator_cache (display_on_index); CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); +# Table: 'phpbb_migrations' +CREATE TABLE phpbb_migrations ( + migration_name varchar(255) NOT NULL DEFAULT '', + migration_schema_done INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_data_done INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_data_state text(65535) NOT NULL DEFAULT '', + migration_start_time INTEGER UNSIGNED NOT NULL DEFAULT '0', + migration_end_time INTEGER UNSIGNED NOT NULL DEFAULT '0', + PRIMARY KEY (migration_name) +); + + # Table: 'phpbb_modules' CREATE TABLE phpbb_modules ( module_id INTEGER PRIMARY KEY NOT NULL , @@ -642,8 +642,8 @@ CREATE TABLE phpbb_reports ( report_time INTEGER UNSIGNED NOT NULL DEFAULT '0', report_text mediumtext(16777215) NOT NULL DEFAULT '', reported_post_text mediumtext(16777215) NOT NULL DEFAULT '', - reported_post_bitfield varchar(255) NOT NULL DEFAULT '', - reported_post_uid varchar(8) NOT NULL DEFAULT '' + reported_post_uid varchar(8) NOT NULL DEFAULT '', + reported_post_bitfield varchar(255) NOT NULL DEFAULT '' ); CREATE INDEX phpbb_reports_post_id ON phpbb_reports (post_id); -- cgit v1.2.1 From d50500860fe44a78c8f29e0f2382b96da17c0b62 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 15:09:51 -0600 Subject: [feature/migrations] Store depends on in the database (serialized) This is required so that when migrations are reverted we can check through all installed migrations and make sure that all dependencies are handled properly and so that we are only required to load the migrations files that could be dependent on the ones installed. I believe in normal proper use the old way might have worked, but in case something happens and an unrelated migration file is installed, but cannot be loaded, this makes sure we do not stop everything unless we absolutely must (one of those files is dependent on something we want to revert). PHPBB3-9737 --- phpBB/install/schemas/firebird_schema.sql | 1 + phpBB/install/schemas/mssql_schema.sql | 1 + phpBB/install/schemas/mysql_40_schema.sql | 1 + phpBB/install/schemas/mysql_41_schema.sql | 1 + phpBB/install/schemas/oracle_schema.sql | 1 + phpBB/install/schemas/postgres_schema.sql | 1 + phpBB/install/schemas/sqlite_schema.sql | 1 + 7 files changed, 7 insertions(+) (limited to 'phpBB/install') diff --git a/phpBB/install/schemas/firebird_schema.sql b/phpBB/install/schemas/firebird_schema.sql index 535cbb0df4..45024c4049 100644 --- a/phpBB/install/schemas/firebird_schema.sql +++ b/phpBB/install/schemas/firebird_schema.sql @@ -589,6 +589,7 @@ CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache(forum_id);; # Table: 'phpbb_migrations' CREATE TABLE phpbb_migrations ( migration_name VARCHAR(255) CHARACTER SET NONE DEFAULT '' NOT NULL, + migration_depends_on BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, migration_schema_done INTEGER DEFAULT 0 NOT NULL, migration_data_done INTEGER DEFAULT 0 NOT NULL, migration_data_state BLOB SUB_TYPE TEXT CHARACTER SET NONE DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/mssql_schema.sql b/phpBB/install/schemas/mssql_schema.sql index 43b8f3e556..e261e73d73 100644 --- a/phpBB/install/schemas/mssql_schema.sql +++ b/phpBB/install/schemas/mssql_schema.sql @@ -721,6 +721,7 @@ GO */ CREATE TABLE [phpbb_migrations] ( [migration_name] [varchar] (255) DEFAULT ('') NOT NULL , + [migration_depends_on] [varchar] (8000) DEFAULT ('') NOT NULL , [migration_schema_done] [int] DEFAULT (0) NOT NULL , [migration_data_done] [int] DEFAULT (0) NOT NULL , [migration_data_state] [varchar] (8000) DEFAULT ('') NOT NULL , diff --git a/phpBB/install/schemas/mysql_40_schema.sql b/phpBB/install/schemas/mysql_40_schema.sql index c46230744a..0f184d4d05 100644 --- a/phpBB/install/schemas/mysql_40_schema.sql +++ b/phpBB/install/schemas/mysql_40_schema.sql @@ -413,6 +413,7 @@ CREATE TABLE phpbb_moderator_cache ( # Table: 'phpbb_migrations' CREATE TABLE phpbb_migrations ( migration_name varbinary(255) DEFAULT '' NOT NULL, + migration_depends_on blob NOT NULL, migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, migration_data_state blob NOT NULL, diff --git a/phpBB/install/schemas/mysql_41_schema.sql b/phpBB/install/schemas/mysql_41_schema.sql index fa94598e9c..b7564ceb7c 100644 --- a/phpBB/install/schemas/mysql_41_schema.sql +++ b/phpBB/install/schemas/mysql_41_schema.sql @@ -413,6 +413,7 @@ CREATE TABLE phpbb_moderator_cache ( # Table: 'phpbb_migrations' CREATE TABLE phpbb_migrations ( migration_name varchar(255) DEFAULT '' NOT NULL, + migration_depends_on text NOT NULL, migration_schema_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, migration_data_done tinyint(1) UNSIGNED DEFAULT '0' NOT NULL, migration_data_state text NOT NULL, diff --git a/phpBB/install/schemas/oracle_schema.sql b/phpBB/install/schemas/oracle_schema.sql index f8a9d5e1a6..7796c3a729 100644 --- a/phpBB/install/schemas/oracle_schema.sql +++ b/phpBB/install/schemas/oracle_schema.sql @@ -803,6 +803,7 @@ CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id) */ CREATE TABLE phpbb_migrations ( migration_name varchar2(255) DEFAULT '' , + migration_depends_on clob DEFAULT '' , migration_schema_done number(1) DEFAULT '0' NOT NULL, migration_data_done number(1) DEFAULT '0' NOT NULL, migration_data_state clob DEFAULT '' , diff --git a/phpBB/install/schemas/postgres_schema.sql b/phpBB/install/schemas/postgres_schema.sql index c976659f05..9fd81ec06a 100644 --- a/phpBB/install/schemas/postgres_schema.sql +++ b/phpBB/install/schemas/postgres_schema.sql @@ -577,6 +577,7 @@ CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); */ CREATE TABLE phpbb_migrations ( migration_name varchar(255) DEFAULT '' NOT NULL, + migration_depends_on varchar(8000) DEFAULT '' NOT NULL, migration_schema_done INT2 DEFAULT '0' NOT NULL CHECK (migration_schema_done >= 0), migration_data_done INT2 DEFAULT '0' NOT NULL CHECK (migration_data_done >= 0), migration_data_state varchar(8000) DEFAULT '' NOT NULL, diff --git a/phpBB/install/schemas/sqlite_schema.sql b/phpBB/install/schemas/sqlite_schema.sql index 31a6f715a0..9d6d648c00 100644 --- a/phpBB/install/schemas/sqlite_schema.sql +++ b/phpBB/install/schemas/sqlite_schema.sql @@ -401,6 +401,7 @@ CREATE INDEX phpbb_moderator_cache_forum_id ON phpbb_moderator_cache (forum_id); # Table: 'phpbb_migrations' CREATE TABLE phpbb_migrations ( migration_name varchar(255) NOT NULL DEFAULT '', + migration_depends_on text(65535) NOT NULL DEFAULT '', migration_schema_done INTEGER UNSIGNED NOT NULL DEFAULT '0', migration_data_done INTEGER UNSIGNED NOT NULL DEFAULT '0', migration_data_state text(65535) NOT NULL DEFAULT '', -- cgit v1.2.1 From 63780bda8d6e6e968b934b200853de2776e53596 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 15:14:16 -0600 Subject: [feature/migrations] Move test.php -> install/database_update_migrations.php This should be used as a basis for the database updater using migrations. PHPBB3-9737 --- phpBB/install/database_update_migrations.php | 139 +++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 phpBB/install/database_update_migrations.php (limited to 'phpBB/install') diff --git a/phpBB/install/database_update_migrations.php b/phpBB/install/database_update_migrations.php new file mode 100644 index 0000000000..52682dc489 --- /dev/null +++ b/phpBB/install/database_update_migrations.php @@ -0,0 +1,139 @@ +register(); + +// Set up container +$container_extensions = array( + new phpbb_di_extension_config($phpbb_root_path . 'config.' . $phpEx), + new phpbb_di_extension_core($phpbb_root_path), +); +$container_passes = array( + new phpbb_di_pass_collection_pass(), + //new phpbb_di_pass_kernel_pass(), +); +$phpbb_container = phpbb_create_container($container_extensions, $phpbb_root_path, $phpEx); + +// Compile the container +foreach ($container_passes as $pass) +{ + $phpbb_container->addCompilerPass($pass); +} +$phpbb_container->compile(); + +// set up caching +$cache = $phpbb_container->get('cache'); + +// Instantiate some basic classes +$phpbb_dispatcher = $phpbb_container->get('dispatcher'); +$request = $phpbb_container->get('request'); +$user = $phpbb_container->get('user'); +$auth = $phpbb_container->get('auth'); +$db = $phpbb_container->get('dbal.conn'); + +// make sure request_var uses this request instance +request_var('', 0, false, false, $request); // "dependency injection" for a function + +// Grab global variables, re-cache if necessary +$config = $phpbb_container->get('config'); +set_config(null, null, null, $config); +set_config_count(null, null, null, $config); + +// End startup code + +$db_tools = $phpbb_container->get('dbal.tools'); +if (!$db_tools->sql_table_exists(MIGRATIONS_TABLE)) +{ + $db_tools->sql_create_table(MIGRATIONS_TABLE, array( + 'COLUMNS' => array( + 'migration_name' => array('VCHAR', ''), + 'migration_depends_on' => array('TEXT', ''), + 'migration_schema_done' => array('BOOL', 0), + 'migration_data_done' => array('BOOL', 0), + 'migration_data_state' => array('TEXT', ''), + 'migration_start_time' => array('TIMESTAMP', 0), + 'migration_end_time' => array('TIMESTAMP', 0), + ), + 'PRIMARY_KEY' => 'migration_name', + )); +} + +$migrator = $phpbb_container->get('migrator'); +$migrator->load_migrations($phpbb_root_path . 'includes/db/migration/data/'); + +// What is a safe limit of execution time? Half the max execution time should be safe. +$safe_time_limit = (ini_get('max_execution_time') / 2); + +while (!$migrator->finished()) +{ + try + { + $migrator->update(); + } + catch (phpbb_db_migration_exception $e) + { + echo $e; + + garbage_collection(); + exit_handler(); + } + + echo $migrator->last_run_migration['name'] . '
'; + + // Are we approaching the time limit? If so we want to pause the update and continue after refreshing + if ((time() - $update_start_time) >= $safe_time_limit) + { + //echo ''; + echo 'Update not yet completed.
'; + echo 'Continue'; + + garbage_collection(); + exit_handler(); + } +} + +echo 'Finished'; + +garbage_collection(); +exit_handler(); -- cgit v1.2.1 From ebfa42455a19376a7996980301a81ad5665a1414 Mon Sep 17 00:00:00 2001 From: Nathan Guse Date: Thu, 10 Jan 2013 15:17:36 -0600 Subject: [feature/migrations] install/database_update_migrations.php Actually, this does not belong in the main PR, moving to the data PR. PHPBB3-9737 --- phpBB/install/database_update_migrations.php | 139 --------------------------- 1 file changed, 139 deletions(-) delete mode 100644 phpBB/install/database_update_migrations.php (limited to 'phpBB/install') diff --git a/phpBB/install/database_update_migrations.php b/phpBB/install/database_update_migrations.php deleted file mode 100644 index 52682dc489..0000000000 --- a/phpBB/install/database_update_migrations.php +++ /dev/null @@ -1,139 +0,0 @@ -register(); - -// Set up container -$container_extensions = array( - new phpbb_di_extension_config($phpbb_root_path . 'config.' . $phpEx), - new phpbb_di_extension_core($phpbb_root_path), -); -$container_passes = array( - new phpbb_di_pass_collection_pass(), - //new phpbb_di_pass_kernel_pass(), -); -$phpbb_container = phpbb_create_container($container_extensions, $phpbb_root_path, $phpEx); - -// Compile the container -foreach ($container_passes as $pass) -{ - $phpbb_container->addCompilerPass($pass); -} -$phpbb_container->compile(); - -// set up caching -$cache = $phpbb_container->get('cache'); - -// Instantiate some basic classes -$phpbb_dispatcher = $phpbb_container->get('dispatcher'); -$request = $phpbb_container->get('request'); -$user = $phpbb_container->get('user'); -$auth = $phpbb_container->get('auth'); -$db = $phpbb_container->get('dbal.conn'); - -// make sure request_var uses this request instance -request_var('', 0, false, false, $request); // "dependency injection" for a function - -// Grab global variables, re-cache if necessary -$config = $phpbb_container->get('config'); -set_config(null, null, null, $config); -set_config_count(null, null, null, $config); - -// End startup code - -$db_tools = $phpbb_container->get('dbal.tools'); -if (!$db_tools->sql_table_exists(MIGRATIONS_TABLE)) -{ - $db_tools->sql_create_table(MIGRATIONS_TABLE, array( - 'COLUMNS' => array( - 'migration_name' => array('VCHAR', ''), - 'migration_depends_on' => array('TEXT', ''), - 'migration_schema_done' => array('BOOL', 0), - 'migration_data_done' => array('BOOL', 0), - 'migration_data_state' => array('TEXT', ''), - 'migration_start_time' => array('TIMESTAMP', 0), - 'migration_end_time' => array('TIMESTAMP', 0), - ), - 'PRIMARY_KEY' => 'migration_name', - )); -} - -$migrator = $phpbb_container->get('migrator'); -$migrator->load_migrations($phpbb_root_path . 'includes/db/migration/data/'); - -// What is a safe limit of execution time? Half the max execution time should be safe. -$safe_time_limit = (ini_get('max_execution_time') / 2); - -while (!$migrator->finished()) -{ - try - { - $migrator->update(); - } - catch (phpbb_db_migration_exception $e) - { - echo $e; - - garbage_collection(); - exit_handler(); - } - - echo $migrator->last_run_migration['name'] . '
'; - - // Are we approaching the time limit? If so we want to pause the update and continue after refreshing - if ((time() - $update_start_time) >= $safe_time_limit) - { - //echo ''; - echo 'Update not yet completed.
'; - echo 'Continue'; - - garbage_collection(); - exit_handler(); - } -} - -echo 'Finished'; - -garbage_collection(); -exit_handler(); -- cgit v1.2.1