aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/install/database_update.php
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/install/database_update.php')
-rw-r--r--phpBB/install/database_update.php361
1 files changed, 336 insertions, 25 deletions
diff --git a/phpBB/install/database_update.php b/phpBB/install/database_update.php
index 461b5807c2..666cb1aad3 100644
--- a/phpBB/install/database_update.php
+++ b/phpBB/install/database_update.php
@@ -8,7 +8,7 @@
*
*/
-$updates_to_version = '3.0.B4';
+$updates_to_version = '3.0.B5';
if (defined('IN_PHPBB') && defined('IN_INSTALL'))
{
@@ -27,7 +27,7 @@ $phpEx = substr(strrchr(__FILE__, '.'), 1);
//error_reporting(E_ALL ^ E_NOTICE);
error_reporting(E_ALL);
-@set_time_limit(120);
+@set_time_limit(0);
// Include essential scripts
include($phpbb_root_path . 'config.' . $phpEx);
@@ -60,6 +60,7 @@ require($phpbb_root_path . 'includes/constants.' . $phpEx);
require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
+$user = new user();
$cache = new cache();
$db = new $sql_db();
@@ -85,6 +86,7 @@ include($phpbb_root_path . 'language/' . $row['config_value'] . '/install.' . $p
//set_error_handler('msg_handler');
// Define some variables for the database update
+$inline_update = (request_var('type', 0)) ? true : false;
// Database column types mapping
$dbms_type_map = array(
@@ -283,7 +285,7 @@ $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP');
// Only an example, but also commented out
$database_update_info = array(
- // Changes within this version
+ // Changes from 3.0.b3 to the next version
'3.0.b3' => array(
// Change the following columns...
'change_columns' => array(
@@ -307,8 +309,48 @@ $database_update_info = array(
),
),
),
- // Latest version
- '3.0.b4' => array(),
+ // Changes from 3.0.b4 to the next version
+ '3.0.b4' => array(
+ // Add the following columns
+ 'add_columns' => array(
+ CONFIRM_TABLE => array(
+ 'seed' => array('UINT:10', 0),
+ ),
+ SESSIONS_TABLE => array(
+ 'session_forwarded_for' => array('VCHAR:255', 0),
+ ),
+ ),
+ 'change_columns' => array(
+ USERS_TABLE => array(
+ 'user_options' => array('UINT:11', 895),
+ ),
+ FORUMS_TABLE => array(
+ 'prune_days' => array('UINT', 0),
+ 'prune_viewed' => array('UINT', 0),
+ 'prune_freq' => array('UINT', 0),
+ ),
+ PRIVMSGS_RULES_TABLE => array(
+ 'rule_folder_id' => array('INT:11', 0),
+ ),
+ PRIVMSGS_TO_TABLE => array(
+ 'folder_id' => array('INT:11', 0),
+ ),
+ ),
+ // Remove the following keys
+ 'drop_keys' => array(
+ ZEBRA_TABLE => array(
+ 'user_id',
+ 'zebra_id',
+ ),
+ ),
+ // Add the following primary keys
+ 'add_primary_keys' => array(
+ ZEBRA_TABLE => array(
+ 'user_id',
+ 'zebra_id',
+ ),
+ ),
+ ),
);
// Determine mapping database type
@@ -369,18 +411,39 @@ $errored = false;
<p><?php echo $lang['DATABASE_TYPE']; ?> :: <strong><?php echo $db->sql_layer; ?></strong><br />
<?php
-$sql = "SELECT config_value
- FROM " . CONFIG_TABLE . "
- WHERE config_name = 'version'";
+// To let set_config() calls succeed, we need to make the config array available globally
+$config = array();
+$sql = 'SELECT *
+ FROM ' . CONFIG_TABLE;
$result = $db->sql_query($sql);
-$row = $db->sql_fetchrow($result);
+
+while ($row = $db->sql_fetchrow($result))
+{
+ $config[$row['config_name']] = $row['config_value'];
+}
$db->sql_freeresult($result);
-echo $lang['PREVIOUS_VERSION'] . ' :: <strong>' . $row['config_value'] . '</strong><br />';
+
+echo $lang['PREVIOUS_VERSION'] . ' :: <strong>' . $config['version'] . '</strong><br />';
echo $lang['UPDATED_VERSION'] . ' :: <strong>' . $updates_to_version . '</strong>';
-$current_version = strtolower($row['config_value']);
+$current_version = strtolower($config['version']);
$latest_version = strtolower($updates_to_version);
+$orig_version = $config['version'];
+
+// If the latest version and the current version are 'unequal', we will update the version_update_from, else we do not update anything.
+if ($inline_update)
+{
+ if ($current_version !== $latest_version)
+ {
+ set_config('version_update_from', $orig_version);
+ }
+}
+else
+{
+ // If not called from the update script, we will actually remove the traces
+ $db->sql_query('DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'version_update_from'");
+}
// Schema updates
?>
@@ -439,6 +502,27 @@ foreach ($database_update_info as $version => $schema_changes)
}
}
}
+
+ // Remove keys?
+ if (!empty($schema_changes['drop_keys']))
+ {
+ foreach ($schema_changes['drop_keys'] as $table => $indexes)
+ {
+ foreach ($indexes as $index_name)
+ {
+ sql_index_drop($map_dbms, $index_name, $table);
+ }
+ }
+ }
+
+ // Add primary keys?
+ if (!empty($schema_changes['add_primary_keys']))
+ {
+ foreach ($schema_changes['add_primary_keys'] as $table => $columns)
+ {
+ sql_create_primary_key($map_dbms, $table, $columns);
+ }
+ }
}
_write_result($no_updates, $errored, $error_ary);
@@ -461,7 +545,7 @@ flush();
$no_updates = true;
// some code magic
-if (version_compare($current_version, '3.0.b3', '<'))
+if (version_compare($current_version, '3.0.b3', '<='))
{
// Set group_founder_manage for administrators group
$sql = 'SELECT group_id
@@ -483,6 +567,92 @@ if (version_compare($current_version, '3.0.b3', '<'))
$no_updates = false;
}
+if (version_compare($current_version, '3.0.b4', '<='))
+{
+ // Add config values
+ set_config('script_path', '/');
+ set_config('forwarded_for_check', '0');
+ set_config('ldap_password', '');
+ set_config('ldap_user', '');
+ set_config('fulltext_native_common_thres', '20');
+
+ // Remove config variables
+ $sql = 'DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'send_encoding'";
+ _sql($sql, $errored, $error_ary);
+
+ $sql = 'SELECT user_colour
+ FROM ' . USERS_TABLE . '
+ WHERE user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')
+ ORDER BY user_id DESC';
+ $result = $db->sql_query_limit($sql, 1);
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ set_config('newest_user_colour', $row['user_colour'], true);
+
+ switch ($config['allow_name_chars'])
+ {
+ case '[\w]+':
+ set_config('allow_name_chars', '[a-z]+');
+ break;
+
+ case '[\w_\+\. \-\[\]]+':
+ set_config('allow_name_chars', '[-\]_+ [a-z]+');
+ break;
+ }
+
+ switch ($config['pass_complex'])
+ {
+ case '.*':
+ set_config('pass_complex', 'PASS_TYPE_ANY');
+ break;
+
+ case '[a-zA-Z]':
+ set_config('pass_complex', 'PASS_TYPE_CASE');
+ break;
+
+ case '[a-zA-Z0-9]':
+ set_config('pass_complex', 'PASS_TYPE_ALPHA');
+ break;
+
+ case '[a-zA-Z\W]':
+ set_config('pass_complex', 'PASS_TYPE_SYMBOL');
+ break;
+ }
+
+ $sql = 'UPDATE ' . USERS_TABLE . ' SET user_options = 895 WHERE user_options = 893';
+ _sql($sql, $errored, $error_ary);
+
+ $sql = 'UPDATE ' . MODULES_TABLE . " SET module_auth = 'acl_a_board'
+ WHERE module_class = 'acp' AND module_mode = 'version_check' AND module_auth = 'acl_a_'";
+ _sql($sql, $errored, $error_ary);
+
+ // Because the email hash could have been calculated wrongly as well as the clean string function changed,
+ // we will update it for every user.
+
+ // Since this is not used in a live environment there are not much... not used in a live environment, yes!
+ $sql = 'SELECT user_id, user_email, username
+ FROM ' . USERS_TABLE;
+ $result = $db->sql_query($sql);
+
+ while ($row = $db->sql_fetchrow($result))
+ {
+ $sql = 'UPDATE ' . USERS_TABLE . "
+ SET username_clean = '" . $db->sql_escape(utf8_clean_string($row['username'])) . "'";
+
+ if ($row['user_email'])
+ {
+ $sql .= ', user_email_hash = ' . (crc32($row['user_email']) . strlen($row['user_email']));
+ }
+
+ $sql .= ' WHERE user_id = ' . $row['user_id'];
+ _sql($sql, $errored, $error_ary);
+ }
+ $db->sql_freeresult($result);
+
+ $no_updates = false;
+}
+
_write_result($no_updates, $errored, $error_ary);
$error_ary = array();
@@ -533,11 +703,33 @@ _write_result($no_updates, $errored, $error_ary);
<br />
-<p style="color:red"><?php echo $lang['UPDATE_FILES_NOTICE']; ?></p>
+<?php
+
+if (!$inline_update)
+{
+?>
+
+ <p style="color:red"><?php echo $lang['UPDATE_FILES_NOTICE']; ?></p>
+
+ <p><?php echo $lang['COMPLETE_LOGIN_TO_BOARD']; ?></p>
+
+<?php
+}
+else
+{
+?>
+
+ <p><?php echo ((isset($lang['CONTINUE_INLINE_UPDATE'])) ? $lang['CONTINUE_INLINE_UPDATE'] : 'The database update was successful. Now please close this window and continue the update process as explained.'); ?></p>
-<p><?php echo $lang['COMPLETE_LOGIN_TO_BOARD']; ?></p>
+ <p><a href="#" onclick="window.close();">&raquo; <?php echo $lang['CLOSE_WINDOW']; ?></a></p>
<?php
+}
+
+// Add database update to log
+
+$user->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
+add_log('admin', 'LOG_UPDATE_DATABASE', $orig_version, $updates_to_version);
// Now we purge the session table as well as all cache files
$cache->purge();
@@ -892,6 +1084,117 @@ function sql_column_add($dbms, $table_name, $column_name, $column_data)
}
}
+function sql_index_drop($dbms, $index_name, $table_name)
+{
+ global $dbms_type_map, $db;
+ global $errored, $error_ary;
+
+ switch ($dbms)
+ {
+ case 'mssql':
+ $sql = 'DROP INDEX ' . $table_name . '\.' . $index_name . ' ON ' . $table_name;
+ _sql($sql, $errored, $error_ary);
+ break;
+
+ case 'mysql_40':
+ case 'mysql_41':
+ $sql = 'DROP INDEX ' . $index_name . ' ON ' . $table_name;
+ _sql($sql, $errored, $error_ary);
+ break;
+
+ case 'firebird':
+ case 'oracle':
+ case 'postgres':
+ case 'sqlite':
+ $sql = 'DROP INDEX ' . $table_name . '_' . $index_name;
+ _sql($sql, $errored, $error_ary);
+ break;
+ }
+}
+
+function sql_create_primary_key($dbms, $table_name, $column)
+{
+ global $dbms_type_map, $db;
+ global $errored, $error_ary;
+
+ switch ($dbms)
+ {
+ case 'firebird':
+ case 'postgres':
+ $sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
+ _sql($sql, $errored, $error_ary);
+ break;
+
+ case 'mssql':
+ $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD ";
+ $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED (";
+ $sql .= '[' . implode("],\n\t\t[", $column) . ']';
+ $sql .= ') ON [PRIMARY]';
+ _sql($sql, $errored, $error_ary);
+ break;
+
+ case 'mysql_40':
+ case 'mysql_41':
+ $sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
+ _sql($sql, $errored, $error_ary);
+ break;
+
+ case 'oracle':
+ $sql = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';
+ _sql($sql, $errored, $error_ary);
+ break;
+
+ case 'sqlite':
+ $sql = "SELECT sql
+ FROM sqlite_master
+ WHERE type = 'table'
+ AND name = '{$table_name}'
+ ORDER BY type DESC, name;";
+ $result = _sql($sql, $errored, $error_ary);
+
+ if (!$result)
+ {
+ break;
+ }
+
+ $row = $db->sql_fetchrow($result);
+ $db->sql_freeresult($result);
+
+ $db->sql_transaction('begin');
+
+ // Create a backup table and populate it, destroy the existing one
+ $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
+ $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
+ $db->sql_query('DROP TABLE ' . $table_name);
+
+ preg_match('#\((.*)\)#s', $row['sql'], $matches);
+
+ $new_table_cols = trim($matches[1]);
+ $old_table_cols = preg_split('/,(?=[\\sa-z])/im', $new_table_cols);
+ $column_list = array();
+
+ foreach ($old_table_cols as $declaration)
+ {
+ $entities = preg_split('#\s+#', trim($declaration));
+ if ($entities == 'PRIMARY')
+ {
+ continue;
+ }
+ $column_list[] = $entities[0];
+ }
+
+ $columns = implode(',', $column_list);
+
+ // create a new table and fill it up. destroy the temp one
+ $db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));');
+ $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
+ $db->sql_query('DROP TABLE ' . $table_name . '_temp');
+
+ $db->sql_transaction('commit');
+ break;
+ }
+}
+
/**
* Change column type (not name!)
*/
@@ -986,6 +1289,7 @@ function sql_column_change($dbms, $table_name, $column_name, $column_data)
/**
* Add search robots to the database
+* @ignore
*/
function add_bots()
{
@@ -1057,6 +1361,12 @@ function add_bots()
$db->sql_query($sql);
}
}
+ else
+ {
+ // If the old bots are missing we can safely assume the user tries to execute the database update twice and
+ // fiddled around...
+ return;
+ }
if (!function_exists('user_add'))
{
@@ -1121,17 +1431,18 @@ function add_bots()
foreach ($bot_list as $bot_name => $bot_ary)
{
$user_row = array(
- 'user_type' => USER_IGNORE,
- 'group_id' => $group_id,
- 'username' => $bot_name,
- 'user_regdate' => time(),
- 'user_password' => '',
- 'user_colour' => '9E8DA7',
- 'user_email' => '',
- 'user_lang' => $config['default_lang'],
- 'user_style' => 1,
- 'user_timezone' => 0,
- 'user_dateformat' => $config['default_dateformat'],
+ 'user_type' => USER_IGNORE,
+ 'group_id' => $group_id,
+ 'username' => $bot_name,
+ 'user_regdate' => time(),
+ 'user_password' => '',
+ 'user_colour' => '9E8DA7',
+ 'user_email' => '',
+ 'user_lang' => $config['default_lang'],
+ 'user_style' => 1,
+ 'user_timezone' => 0,
+ 'user_dateformat' => $config['default_dateformat'],
+ 'user_allow_massemail' => 0,
);
$user_id = user_add($user_row);