INSTALL.html before attempting to update.");
}
// Load Extensions
if (!empty($load_extensions))
{
$load_extensions = explode(',', $load_extensions);
foreach ($load_extensions as $extension)
{
@dl(trim($extension));
}
}
// Include files
require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx);
require($phpbb_root_path . 'includes/cache.' . $phpEx);
require($phpbb_root_path . 'includes/template.' . $phpEx);
require($phpbb_root_path . 'includes/session.' . $phpEx);
require($phpbb_root_path . 'includes/auth.' . $phpEx);
require($phpbb_root_path . 'includes/functions.' . $phpEx);
if (file_exists($phpbb_root_path . 'includes/functions_content.' . $phpEx))
{
require($phpbb_root_path . 'includes/functions_content.' . $phpEx);
}
require($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
require($phpbb_root_path . 'includes/constants.' . $phpEx);
require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
// If we are on PHP >= 6.0.0 we do not need some code
if (version_compare(PHP_VERSION, '6.0.0-dev', '>='))
{
/**
* @ignore
*/
define('STRIP', false);
}
else
{
set_magic_quotes_runtime(0);
define('STRIP', (get_magic_quotes_gpc()) ? true : false);
}
$user = new user();
$cache = new cache();
$db = new $sql_db();
// Add own hook handler, if present. :o
if (file_exists($phpbb_root_path . 'includes/hooks/index.' . $phpEx))
{
require($phpbb_root_path . 'includes/hooks/index.' . $phpEx);
$phpbb_hook = new phpbb_hook(array('exit_handler', 'phpbb_user_session_handler', 'append_sid', array('template', 'display')));
foreach ($cache->obtain_hooks() as $hook)
{
@include($phpbb_root_path . 'includes/hooks/' . $hook . '.' . $phpEx);
}
}
else
{
$phpbb_hook = false;
}
// Connect to DB
$db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false);
// We do not need this any longer, unset for safety purposes
unset($dbpasswd);
$user->ip = (!empty($_SERVER['REMOTE_ADDR'])) ? htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
$sql = "SELECT config_value
FROM " . CONFIG_TABLE . "
WHERE config_name = 'default_lang'";
$result = $db->sql_query($sql);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$language = basename(request_var('language', ''));
if (!$language)
{
$language = $row['config_value'];
}
if (!file_exists($phpbb_root_path . 'language/' . $language))
{
die('No language found!');
}
// And finally, load the relevant language files
include($phpbb_root_path . 'language/' . $language . '/common.' . $phpEx);
include($phpbb_root_path . 'language/' . $language . '/acp/common.' . $phpEx);
include($phpbb_root_path . 'language/' . $language . '/install.' . $phpEx);
// Set PHP error handler to ours
//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(
'mysql_41' => array(
'INT:' => 'int(%d)',
'BINT' => 'bigint(20)',
'UINT' => 'mediumint(8) UNSIGNED',
'UINT:' => 'int(%d) UNSIGNED',
'TINT:' => 'tinyint(%d)',
'USINT' => 'smallint(4) UNSIGNED',
'BOOL' => 'tinyint(1) UNSIGNED',
'VCHAR' => 'varchar(255)',
'VCHAR:' => 'varchar(%d)',
'CHAR:' => 'char(%d)',
'XSTEXT' => 'text',
'XSTEXT_UNI'=> 'varchar(100)',
'STEXT' => 'text',
'STEXT_UNI' => 'varchar(255)',
'TEXT' => 'text',
'TEXT_UNI' => 'text',
'MTEXT' => 'mediumtext',
'MTEXT_UNI' => 'mediumtext',
'TIMESTAMP' => 'int(11) UNSIGNED',
'DECIMAL' => 'decimal(5,2)',
'VCHAR_UNI' => 'varchar(255)',
'VCHAR_UNI:'=> 'varchar(%d)',
'VCHAR_CI' => 'varchar(255)',
'VARBINARY' => 'varbinary(255)',
),
'mysql_40' => array(
'INT:' => 'int(%d)',
'BINT' => 'bigint(20)',
'UINT' => 'mediumint(8) UNSIGNED',
'UINT:' => 'int(%d) UNSIGNED',
'TINT:' => 'tinyint(%d)',
'USINT' => 'smallint(4) UNSIGNED',
'BOOL' => 'tinyint(1) UNSIGNED',
'VCHAR' => 'varbinary(255)',
'VCHAR:' => 'varbinary(%d)',
'CHAR:' => 'binary(%d)',
'XSTEXT' => 'blob',
'XSTEXT_UNI'=> 'blob',
'STEXT' => 'blob',
'STEXT_UNI' => 'blob',
'TEXT' => 'blob',
'TEXT_UNI' => 'blob',
'MTEXT' => 'mediumblob',
'MTEXT_UNI' => 'mediumblob',
'TIMESTAMP' => 'int(11) UNSIGNED',
'DECIMAL' => 'decimal(5,2)',
'VCHAR_UNI' => 'blob',
'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')),
'VCHAR_CI' => 'blob',
'VARBINARY' => 'varbinary(255)',
),
'firebird' => array(
'INT:' => 'INTEGER',
'BINT' => 'DOUBLE PRECISION',
'UINT' => 'INTEGER',
'UINT:' => 'INTEGER',
'TINT:' => 'INTEGER',
'USINT' => 'INTEGER',
'BOOL' => 'INTEGER',
'VCHAR' => 'VARCHAR(255) CHARACTER SET NONE',
'VCHAR:' => 'VARCHAR(%d) CHARACTER SET NONE',
'CHAR:' => 'CHAR(%d) CHARACTER SET NONE',
'XSTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
'STEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
'TEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
'MTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8',
'STEXT_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
'TEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
'MTEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
'TIMESTAMP' => 'INTEGER',
'DECIMAL' => 'DOUBLE PRECISION',
'VCHAR_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8',
'VCHAR_CI' => 'VARCHAR(255) CHARACTER SET UTF8',
'VARBINARY' => 'CHAR(255) CHARACTER SET NONE',
),
'mssql' => array(
'INT:' => '[int]',
'BINT' => '[float]',
'UINT' => '[int]',
'UINT:' => '[int]',
'TINT:' => '[int]',
'USINT' => '[int]',
'BOOL' => '[int]',
'VCHAR' => '[varchar] (255)',
'VCHAR:' => '[varchar] (%d)',
'CHAR:' => '[char] (%d)',
'XSTEXT' => '[varchar] (1000)',
'STEXT' => '[varchar] (3000)',
'TEXT' => '[varchar] (8000)',
'MTEXT' => '[text]',
'XSTEXT_UNI'=> '[varchar] (100)',
'STEXT_UNI' => '[varchar] (255)',
'TEXT_UNI' => '[varchar] (4000)',
'MTEXT_UNI' => '[text]',
'TIMESTAMP' => '[int]',
'DECIMAL' => '[float]',
'VCHAR_UNI' => '[varchar] (255)',
'VCHAR_UNI:'=> '[varchar] (%d)',
'VCHAR_CI' => '[varchar] (255)',
'VARBINARY' => '[varchar] (255)',
),
'oracle' => array(
'INT:' => 'number(%d)',
'BINT' => 'number(20)',
'UINT' => 'number(8)',
'UINT:' => 'number(%d)',
'TINT:' => 'number(%d)',
'USINT' => 'number(4)',
'BOOL' => 'number(1)',
'VCHAR' => 'varchar2(255)',
'VCHAR:' => 'varchar2(%d)',
'CHAR:' => 'char(%d)',
'XSTEXT' => 'varchar2(1000)',
'STEXT' => 'varchar2(3000)',
'TEXT' => 'clob',
'MTEXT' => 'clob',
'XSTEXT_UNI'=> 'varchar2(300)',
'STEXT_UNI' => 'varchar2(765)',
'TEXT_UNI' => 'clob',
'MTEXT_UNI' => 'clob',
'TIMESTAMP' => 'number(11)',
'DECIMAL' => 'number(5, 2)',
'VCHAR_UNI' => 'varchar2(765)',
'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')),
'VCHAR_CI' => 'varchar2(255)',
'VARBINARY' => 'raw(255)',
),
'sqlite' => array(
'INT:' => 'int(%d)',
'BINT' => 'bigint(20)',
'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED',
'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED',
'TINT:' => 'tinyint(%d)',
'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED',
'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED',
'VCHAR' => 'varchar(255)',
'VCHAR:' => 'varchar(%d)',
'CHAR:' => 'char(%d)',
'XSTEXT' => 'text(65535)',
'STEXT' => 'text(65535)',
'TEXT' => 'text(65535)',
'MTEXT' => 'mediumtext(16777215)',
'XSTEXT_UNI'=> 'text(65535)',
'STEXT_UNI' => 'text(65535)',
'TEXT_UNI' => 'text(65535)',
'MTEXT_UNI' => 'mediumtext(16777215)',
'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED',
'DECIMAL' => 'decimal(5,2)',
'VCHAR_UNI' => 'varchar(255)',
'VCHAR_UNI:'=> 'varchar(%d)',
'VCHAR_CI' => 'varchar(255)',
'VARBINARY' => 'blob',
),
'postgres' => array(
'INT:' => 'INT4',
'BINT' => 'INT8',
'UINT' => 'INT4', // unsigned
'UINT:' => 'INT4', // unsigned
'USINT' => 'INT2', // unsigned
'BOOL' => 'INT2', // unsigned
'TINT:' => 'INT2',
'VCHAR' => 'varchar(255)',
'VCHAR:' => 'varchar(%d)',
'CHAR:' => 'char(%d)',
'XSTEXT' => 'varchar(1000)',
'STEXT' => 'varchar(3000)',
'TEXT' => 'varchar(8000)',
'MTEXT' => 'TEXT',
'XSTEXT_UNI'=> 'varchar(100)',
'STEXT_UNI' => 'varchar(255)',
'TEXT_UNI' => 'varchar(4000)',
'MTEXT_UNI' => 'TEXT',
'TIMESTAMP' => 'INT4', // unsigned
'DECIMAL' => 'decimal(5,2)',
'VCHAR_UNI' => 'varchar(255)',
'VCHAR_UNI:'=> 'varchar(%d)',
'VCHAR_CI' => 'varchar_ci',
'VARBINARY' => 'bytea',
),
);
// A list of types being unsigned for better reference in some db's
$unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP');
// Only an example, but also commented out
$database_update_info = array(
// Changes from 3.0.RC2 to the next version
'3.0.RC2' => array(
// Change the following columns
'change_columns' => array(
BANLIST_TABLE => array(
'ban_reason' => array('VCHAR_UNI', ''),
'ban_give_reason' => array('VCHAR_UNI', ''),
),
),
),
// Changes from 3.0.RC3 to the next version
'3.0.RC3' => array(
// Change the following columns
'change_columns' => array(
BANLIST_TABLE => array(
'ban_reason' => array('VCHAR_UNI', ''),
'ban_give_reason' => array('VCHAR_UNI', ''),
),
STYLES_TABLE => array(
'style_id' => array('USINT', 0),
'template_id' => array('USINT', 0),
'theme_id' => array('USINT', 0),
'imageset_id' => array('USINT', 0),
),
STYLES_TEMPLATE_TABLE => array(
'template_id' => array('USINT', 0),
),
STYLES_TEMPLATE_DATA_TABLE => array(
'template_id' => array('USINT', 0),
),
STYLES_THEME_TABLE => array(
'theme_id' => array('USINT', 0),
),
STYLES_IMAGESET_TABLE => array(
'imageset_id' => array('USINT', 0),
),
STYLES_IMAGESET_DATA_TABLE => array(
'imageset_id' => array('USINT', 0),
),
USERS_TABLE => array(
'user_style' => array('USINT', 0),
),
FORUMS_TABLE => array(
'forum_style' => array('USINT', 0),
),
GROUPS_TABLE => array(
'group_avatar_type' => array('TINT:2', 0),
'group_avatar_width' => array('USINT', 0),
'group_avatar_height' => array('USINT', 0),
),
),
),
// Changes from 3.0.RC4 to the next version
'3.0.RC4' => array(
// Change the following columns
'change_columns' => array(
STYLES_TABLE => array(
'style_id' => array('USINT', NULL, 'auto_increment'),
'template_id' => array('USINT', 0),
'theme_id' => array('USINT', 0),
'imageset_id' => array('USINT', 0),
),
STYLES_TEMPLATE_TABLE => array(
'template_id' => array('USINT', NULL, 'auto_increment'),
),
STYLES_TEMPLATE_DATA_TABLE => array(
'template_id' => array('USINT', 0),
),
STYLES_THEME_TABLE => array(
'theme_id' => array('USINT', NULL, 'auto_increment'),
),
STYLES_IMAGESET_TABLE => array(
'imageset_id' => array('USINT', NULL, 'auto_increment'),
),
STYLES_IMAGESET_DATA_TABLE => array(
'imageset_id' => array('USINT', 0),
),
USERS_TABLE => array(
'user_style' => array('USINT', 0),
),
FORUMS_TABLE => array(
'forum_style' => array('USINT', 0),
),
GROUPS_TABLE => array(
'group_avatar_width' => array('USINT', 0),
'group_avatar_height' => array('USINT', 0),
),
),
),
// Changes from 3.0.RC5 to the next version
'3.0.RC5' => array(
// Add the following columns
'add_columns' => array(
USERS_TABLE => array(
'user_form_salt' => array('VCHAR_UNI:32', ''),
),
),
// Change the following columns
'change_columns' => array(
POSTS_TABLE => array(
'bbcode_uid' => array('VCHAR:8', ''),
),
PRIVMSGS_TABLE => array(
'bbcode_uid' => array('VCHAR:8', ''),
),
USERS_TABLE => array(
'user_sig_bbcode_uid' => array('VCHAR:8', ''),
),
),
),
// Changes from 3.0.RC6 to the next version
'3.0.RC6' => array(
// Change the following columns
'change_columns' => array(
FORUMS_TABLE => array(
'forum_desc_uid' => array('VCHAR:8', ''),
'forum_rules_uid' => array('VCHAR:8', ''),
),
GROUPS_TABLE => array(
'group_desc_uid' => array('VCHAR:8', ''),
),
USERS_TABLE => array(
'user_newpasswd' => array('VCHAR_UNI:40', ''),
),
),
),
);
// Determine mapping database type
switch ($db->sql_layer)
{
case 'mysql':
$map_dbms = 'mysql_40';
break;
case 'mysql4':
if (version_compare($db->mysql_version, '4.1.3', '>='))
{
$map_dbms = 'mysql_41';
}
else
{
$map_dbms = 'mysql_40';
}
break;
case 'mysqli':
$map_dbms = 'mysql_41';
break;
case 'mssql':
case 'mssql_odbc':
$map_dbms = 'mssql';
break;
default:
$map_dbms = $db->sql_layer;
break;
}
$error_ary = array();
$errored = false;
header('Content-type: text/html; charset=UTF-8');
?>
:: sql_layer; ?>
sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$config[$row['config_name']] = $row['config_value'];
}
$db->sql_freeresult($result);
echo $lang['PREVIOUS_VERSION'] . ' :: ' . $config['version'] . ' ';
echo $lang['UPDATED_VERSION'] . ' :: ' . $updates_to_version . '
';
$current_version = str_replace('rc', 'RC', strtolower($config['version']));
$latest_version = str_replace('rc', 'RC', 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'");
}
// Checks/Operations that have to be completed prior to starting the update itself
$exit = false;
if (version_compare($current_version, '3.0.RC4', '<='))
{
// Define missing language entries...
if (!isset($lang['CLEANING_USERNAMES']))
{
$lang = array_merge($lang, array(
'CLEANING_USERNAMES' => 'Cleaning usernames',
'LONG_SCRIPT_EXECUTION' => 'Please note that this can take a while... Please do not stop the script.',
'CHANGE_CLEAN_NAMES' => 'The method used to make sure a username is not used by multiple users has been changed. There are some users which have the same name when compared with the new method. You have to delete or rename these users to make sure that each name is only used by one user before you can proceed.',
'USER_ACTIVE' => 'Active user',
'USER_INACTIVE' => 'Inactive user',
'BOT' => 'Spider/Robot',
'UPDATE_REQUIRES_FILE' => 'The updater requires that the following file is present: %s',
'DELETE_USER_REMOVE' => 'Delete user and remove posts',
'DELETE_USER_RETAIN' => 'Delete user but keep posts',
'EDIT_USERNAME' => 'Edit username',
'KEEP_OLD_NAME' => 'Keep username',
'NEW_USERNAME' => 'New username',
));
}
?>
''));
$new_usernames = request_var('new_usernames', array(0 => ''), true);
if (!class_exists('utf_new_normalizer'))
{
if (!file_exists($phpbb_root_path . 'install/data/new_normalizer.' . $phpEx))
{
global $lang;
trigger_error(sprintf($lang['UPDATE_REQUIRES_FILE'], $phpbb_root_path . 'install/data/new_normalizer.' . $phpEx), E_USER_ERROR);
}
include($phpbb_root_path . 'install/data/new_normalizer.' . $phpEx);
}
// the admin decided to change some usernames
if (sizeof($modify_users) && $submit)
{
$sql = 'SELECT user_id, username, user_type
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_id', array_keys($modify_users));
$result = $db->sql_query($sql);
$users = 0;
while ($row = $db->sql_fetchrow($result))
{
$users++;
$user_id = (int) $row['user_id'];
if (isset($modify_users[$user_id]))
{
$row['action'] = $modify_users[$user_id];
$modify_users[$user_id] = $row;
}
}
$db->sql_freeresult($result);
// only if all ids really existed
if (sizeof($modify_users) == $users)
{
$user->data['user_id'] = ANONYMOUS;
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
foreach ($modify_users as $user_id => $row)
{
switch ($row['action'])
{
case 'edit':
if (isset($new_usernames[$user_id]))
{
$data = array('username' => utf8_new_normalize_nfc($new_usernames[$user_id]));
// Need to update config, forum, topic, posting, messages, etc.
if ($data['username'] != $row['username'])
{
$check_ary = array('username' => array(
array('string', false, $config['min_name_chars'], $config['max_name_chars']),
array('username'),
));
// need a little trick for this to work properly
$user->data['username_clean'] = utf8_clean_string($data['username']) . 'a';
$errors = validate_data($data, $check_ary);
if ($errors)
{
include($phpbb_root_path . 'language/' . $language . '/ucp.' . $phpEx);
echo '
';
foreach ($errors as $error)
{
echo '
' . $lang[$error] . '
';
}
echo '
';
}
if (!$errors)
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', array(
'username' => $data['username'],
'username_clean' => utf8_clean_string($data['username'])
)) . '
WHERE user_id = ' . $user_id;
$db->sql_query($sql);
add_log('user', $user_id, 'LOG_USER_UPDATE_NAME', $row['username'], $data['username']);
user_update_name($row['username'], $data['username']);
}
}
}
break;
case 'delete_retain':
case 'delete_remove':
if ($user_id != ANONYMOUS && $row['user_type'] != USER_FOUNDER)
{
user_delete(substr($row['action'], 7), $user_id, $row['username']);
add_log('admin', 'LOG_USER_DELETED', $row['username']);
}
break;
}
}
}
}
?>
::
sql_query($sql);
$colliding_users = $found_names = array();
$echos = 0;
while ($row = $db->sql_fetchrow($result))
{
// Calculate the new clean name. If it differs from the old one we need
// to make sure there is no collision
$clean_name = utf8_new_clean_string($row['username']);
if ($clean_name != $row['username_clean'])
{
// Check if there would be a collission, if not put it up for changing
$user_id = (int) $row['user_id'];
// If this clean name was not the result of another user already ...
if (!isset($found_names[$clean_name]))
{
// then we need to figure out whether there are any other users
// who already had this clean name with the old version
$sql = 'SELECT user_id, username
FROM ' . USERS_TABLE . '
WHERE username_clean = \'' . $db->sql_escape($clean_name) . '\'';
$result2 = $db->sql_query($sql);
$user_ids = array($user_id);
while ($row = $db->sql_fetchrow($result2))
{
// For not trimmed entries this could happen, yes. ;)
if ($row['user_id'] == $user_id)
{
continue;
}
// Make sure this clean name will still be the same with the
// new function. If it is, then we have to add it to the list
// of user ids for this clean name
if (utf8_new_clean_string($row['username']) == $clean_name)
{
$user_ids[] = (int) $row['user_id'];
}
}
$db->sql_freeresult($result2);
// if we already found a collision save it
if (sizeof($user_ids) > 1)
{
$colliding_users[$clean_name] = $user_ids;
$found_names[$clean_name] = true;
}
else
{
// otherwise just mark this name as found
$found_names[$clean_name] = $user_id;
}
}
// Else, if we already found the username
else
{
// If the value in the found_names lookup table is only true ...
if ($found_names[$clean_name] === true)
{
// then the actual data was already added to $colliding_users
// and we only need to append the user_id
$colliding_users[$clean_name][] = $user_id;
}
else
{
// otherwise it still keeps the first user_id for this name
// and we need to move the data to $colliding_users, and set
// the value in the found_names lookup table to true, so
// following users will directly be appended to $colliding_users
$colliding_users[$clean_name] = array($found_names[$clean_name], $user_id);
$found_names[$clean_name] = true;
}
}
}
if (($echos % 1000) == 0)
{
echo '.';
flush();
}
$echos++;
}
$db->sql_freeresult($result);
_write_result(false, $errored, $error_ary);
// now retrieve all information about the users and let the admin decide what to do
if (sizeof($colliding_users))
{
$exit = true;
include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
include($phpbb_root_path . 'language/' . $language . '/memberlist.' . $phpEx);
include($phpbb_root_path . 'language/' . $language . '/acp/users.' . $phpEx);
// link a few things to the correct place so we don't get any problems
$user->lang = &$lang;
$user->data['user_id'] = ANONYMOUS;
$user->date_format = $config['default_dateformat'];
// a little trick to get all user_ids
$user_ids = call_user_func_array('array_merge', array_values($colliding_users));
$sql = 'SELECT session_user_id, MAX(session_time) AS session_time
FROM ' . SESSIONS_TABLE . '
WHERE session_time >= ' . (time() - $config['session_length']) . '
AND ' . $db->sql_in_set('session_user_id', $user_ids) . '
GROUP BY session_user_id';
$result = $db->sql_query($sql);
$session_times = array();
while ($row = $db->sql_fetchrow($result))
{
$session_times[$row['session_user_id']] = $row['session_time'];
}
$db->sql_freeresult($result);
$sql = 'SELECT *
FROM ' . USERS_TABLE . '
WHERE ' . $db->sql_in_set('user_id', $user_ids);
$result = $db->sql_query($sql);
$users = array();
while ($row = $db->sql_fetchrow($result))
{
if (isset($session_times[$row['user_id']]))
{
$row['session_time'] = $session_times[$row['user_id']];
}
else
{
$row['session_time'] = 0;
}
$users[(int) $row['user_id']] = $row;
}
$db->sql_freeresult($result);
unset($session_times);
// now display a table with all users, some information about them and options
// for the admin: keep name, change name (with text input) or delete user
$u_action = "database_update.$phpEx?language=$language&type=$inline_update";
?>
sql_in_set('user_id', array_values($found_names));
$result = $db->sql_query($sql);
$found_names = array();
while ($row = $db->sql_fetchrow($result))
{
$clean_name = utf8_new_clean_string($row['username']);
if ($clean_name != $row['username_clean'])
{
$user_id = (int) $row['user_id'];
$found_names[$user_id] = $clean_name;
// impossible unique clean name
$sql = 'UPDATE ' . USERS_TABLE . "
SET username_clean = ' {$user_id}'
WHERE user_id = {$user_id}";
$db->sql_query($sql);
}
}
$db->sql_freeresult($result);
foreach ($found_names as $user_id => $clean_name)
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET username_clean = \'' . $db->sql_escape($clean_name) . '\'
WHERE user_id = ' . $user_id;
$db->sql_query($sql);
}
}
unset($found_names);
unset($colliding_users);
}
if ($exit)
{
?>
::
$schema_changes)
{
if (version_compare($version, $current_version, '<'))
{
continue;
}
if (!sizeof($schema_changes))
{
continue;
}
$no_updates = false;
// Change columns?
if (!empty($schema_changes['change_columns']))
{
foreach ($schema_changes['change_columns'] as $table => $columns)
{
foreach ($columns as $column_name => $column_data)
{
sql_column_change($map_dbms, $table, $column_name, $column_data);
}
}
}
// Add columns?
if (!empty($schema_changes['add_columns']))
{
foreach ($schema_changes['add_columns'] as $table => $columns)
{
foreach ($columns as $column_name => $column_data)
{
// Only add the column if it does not exist yet
if (!column_exists($map_dbms, $table, $column_name))
{
sql_column_add($map_dbms, $table, $column_name, $column_data);
}
}
}
}
// 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);
}
}
}
// Drop columns?
if (!empty($schema_changes['drop_columns']))
{
foreach ($schema_changes['drop_columns'] as $table => $columns)
{
foreach ($columns as $column)
{
sql_column_remove($map_dbms, $table, $column);
}
}
}
// 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);
}
}
// Add unqiue indexes?
if (!empty($schema_changes['add_unique_index']))
{
foreach ($schema_changes['add_unique_index'] as $table => $index_array)
{
foreach ($index_array as $index_name => $column)
{
sql_create_unique_index($map_dbms, $index_name, $table, $column);
}
}
}
// Add indexes?
if (!empty($schema_changes['add_index']))
{
foreach ($schema_changes['add_index'] as $table => $index_array)
{
foreach ($index_array as $index_name => $column)
{
sql_create_index($map_dbms, $index_name, $table, $column);
}
}
}
}
_write_result($no_updates, $errored, $error_ary);
// Data updates
$error_ary = array();
$errored = $no_updates = false;
?>
::
sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$smileys[$row['smiley_id']] = $row['code'];
}
$db->sql_freeresult($result);
foreach ($smileys as $id => $code)
{
// 2.0 only entitized lt and gt; We need to do something about double quotes.
if (strchr($code, '"') === false)
{
continue;
}
$new_code = str_replace('&', '&', $code);
$new_code = str_replace('<', '<', $new_code);
$new_code = str_replace('>', '>', $new_code);
$new_code = utf8_htmlspecialchars($new_code);
$sql = 'UPDATE ' . SMILIES_TABLE . '
SET code = \'' . $db->sql_escape($new_code) . '\'
WHERE smiley_id = ' . (int) $id;
$db->sql_query($sql);
}
$index_list = sql_list_index($map_dbms, ACL_ROLES_DATA_TABLE);
if (in_array('ath_opt_id', $index_list))
{
sql_index_drop($map_dbms, 'ath_opt_id', ACL_ROLES_DATA_TABLE);
sql_create_index($map_dbms, 'ath_op_id', ACL_ROLES_DATA_TABLE, array('auth_option_id'));
}
$no_updates = false;
}
if (version_compare($current_version, '3.0.RC3', '<='))
{
if ($map_dbms === 'postgres')
{
$sql = "SELECT SETVAL('" . FORUMS_TABLE . "_seq',(select case when max(forum_id)>0 then max(forum_id)+1 else 1 end from " . FORUMS_TABLE . '));';
_sql($sql, $errored, $error_ary);
}
// we check for:
// ath_opt_id
// ath_op_id
// ACL_ROLES_DATA_TABLE_ath_opt_id
// we want ACL_ROLES_DATA_TABLE_ath_op_id
$table_index_fix = array(
ACL_ROLES_DATA_TABLE => array(
'ath_opt_id' => 'ath_op_id',
'ath_op_id' => 'ath_op_id',
ACL_ROLES_DATA_TABLE . '_ath_opt_id' => 'ath_op_id'
),
STYLES_IMAGESET_DATA_TABLE => array(
'i_id' => 'i_d',
'i_d' => 'i_d',
STYLES_IMAGESET_DATA_TABLE . '_i_id' => 'i_d'
)
);
// we need to create some indicies...
$needed_creation = array();
foreach ($table_index_fix as $table_name => $index_info)
{
$index_list = sql_list_fake($map_dbms, $table_name);
foreach ($index_info as $bad_index => $good_index)
{
if (in_array($bad_index, $index_list))
{
// mysql is actually OK, it won't get a hand in this crud
switch ($map_dbms)
{
// last version, mssql had issues with index removal
case 'mssql':
$sql = 'DROP INDEX ' . $table_name . '.' . $bad_index;
_sql($sql, $errored, $error_ary);
break;
// last version, firebird, oracle, postgresql and sqlite all got bad index names
// we got kinda lucky, tho: they all support the same syntax
case 'firebird':
case 'oracle':
case 'postgres':
case 'sqlite':
$sql = 'DROP INDEX ' . $bad_index;
_sql($sql, $errored, $error_ary);
break;
}
// If the good index already exist we do not need to create it again...
if (($map_dbms == 'mysql_40' || $map_dbms == 'mysql_41') && $bad_index == $good_index)
{
}
else
{
$needed_creation[$table_name][$good_index] = 1;
}
}
}
}
$new_index_defs = array('ath_op_id' => array('auth_option_id'), 'i_d' => array('imageset_id'));
foreach ($needed_creation as $bad_table => $index_repair_list)
{
foreach ($index_repair_list as $new_index => $garbage)
{
sql_create_index($map_dbms, $new_index, $bad_table, $new_index_defs[$new_index]);
$no_updates = false;
}
}
// Make sure empty smiley codes do not exist
$sql = 'DELETE FROM ' . SMILIES_TABLE . "
WHERE code = ''";
_sql($sql, $errored, $error_ary);
set_config('allow_birthdays', '1');
set_config('cron_lock', '0', true);
$no_updates = false;
}
if (version_compare($current_version, '3.0.RC4', '<='))
{
$update_auto_increment = array(
STYLES_TABLE => 'style_id',
STYLES_TEMPLATE_TABLE => 'template_id',
STYLES_THEME_TABLE => 'theme_id',
STYLES_IMAGESET_TABLE => 'imageset_id'
);
$sql = 'SELECT *
FROM ' . STYLES_TABLE . '
WHERE style_id = 0';
$result = _sql($sql, $errored, $error_ary);
$bad_style_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($bad_style_row)
{
$sql = 'SELECT MAX(style_id) as max_id
FROM ' . STYLES_TABLE;
$result = _sql($sql, $errored, $error_ary);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$proper_id = $row['max_id'] + 1;
_sql('UPDATE ' . STYLES_TABLE . " SET style_id = $proper_id WHERE style_id = 0", $errored, $error_ary);
_sql('UPDATE ' . FORUMS_TABLE . " SET forum_style = $proper_id WHERE forum_style = 0", $errored, $error_ary);
_sql('UPDATE ' . USERS_TABLE . " SET user_style = $proper_id WHERE user_style = 0", $errored, $error_ary);
$sql = 'SELECT config_value
FROM ' . CONFIG_TABLE . "
WHERE config_name = 'default_style'";
$result = _sql($sql, $errored, $error_ary);
$style_config = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($style_config['config_value'] === '0')
{
set_config('default_style', (string) $proper_id);
}
}
$sql = 'SELECT *
FROM ' . STYLES_TEMPLATE_TABLE . '
WHERE template_id = 0';
$result = _sql($sql, $errored, $error_ary);
$bad_style_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($bad_style_row)
{
$sql = 'SELECT MAX(template_id) as max_id
FROM ' . STYLES_TEMPLATE_TABLE;
$result = _sql($sql, $errored, $error_ary);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$proper_id = $row['max_id'] + 1;
_sql('UPDATE ' . STYLES_TABLE . " SET template_id = $proper_id WHERE template_id = 0", $errored, $error_ary);
}
$sql = 'SELECT *
FROM ' . STYLES_THEME_TABLE . '
WHERE theme_id = 0';
$result = _sql($sql, $errored, $error_ary);
$bad_style_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($bad_style_row)
{
$sql = 'SELECT MAX(theme_id) as max_id
FROM ' . STYLES_THEME_TABLE;
$result = _sql($sql, $errored, $error_ary);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$proper_id = $row['max_id'] + 1;
_sql('UPDATE ' . STYLES_TABLE . " SET theme_id = $proper_id WHERE theme_id = 0", $errored, $error_ary);
}
$sql = 'SELECT *
FROM ' . STYLES_IMAGESET_TABLE . '
WHERE imageset_id = 0';
$result = _sql($sql, $errored, $error_ary);
$bad_style_row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
if ($bad_style_row)
{
$sql = 'SELECT MAX(imageset_id) as max_id
FROM ' . STYLES_IMAGESET_TABLE;
$result = _sql($sql, $errored, $error_ary);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$proper_id = $row['max_id'] + 1;
_sql('UPDATE ' . STYLES_TABLE . " SET imageset_id = $proper_id WHERE imageset_id = 0", $errored, $error_ary);
_sql('UPDATE ' . STYLES_IMAGESET_DATA_TABLE . " SET imageset_id = $proper_id WHERE imageset_id = 0", $errored, $error_ary);
}
if ($map_dbms == 'mysql_40' || $map_dbms == 'mysql_41')
{
foreach ($update_auto_increment as $auto_table_name => $auto_column_name)
{
$sql = "SELECT MAX({$auto_column_name}) as max_id
FROM {$auto_table_name}";
$result = _sql($sql, $errored, $error_ary);
$row = $db->sql_fetchrow($result);
$db->sql_freeresult($result);
$max_id = ((int) $row['max_id']) + 1;
_sql("ALTER TABLE {$auto_table_name} AUTO_INCREMENT = {$max_id}", $errored, $error_ary);
}
$no_updates = false;
}
else if ($map_dbms == 'postgres')
{
foreach ($update_auto_increment as $auto_table_name => $auto_column_name)
{
$sql = "SELECT SETVAL('" . $auto_table_name . "_seq',(select case when max({$auto_column_name})>0 then max({$auto_column_name})+1 else 1 end from " . $auto_table_name . '));';
_sql($sql, $errored, $error_ary);
}
$sql = 'DROP SEQUENCE ' . STYLES_TEMPLATE_DATA_TABLE . '_seq';
_sql($sql, $errored, $error_ary);
}
else if ($map_dbms == 'firebird')
{
$sql = 'DROP TRIGGER t_' . STYLES_TEMPLATE_DATA_TABLE;
_sql($sql, $errored, $error_ary);
$sql = 'DROP GENERATOR ' . STYLES_TEMPLATE_DATA_TABLE . '_gen';
_sql($sql, $errored, $error_ary);
}
else if ($map_dbms == 'oracle')
{
$sql = 'DROP TRIGGER t_' . STYLES_TEMPLATE_DATA_TABLE;
_sql($sql, $errored, $error_ary);
$sql = 'DROP SEQUENCE ' . STYLES_TEMPLATE_DATA_TABLE . '_seq';
_sql($sql, $errored, $error_ary);
}
else if ($map_dbms == 'mssql')
{
// we use transactions because we need to have a working DB at the end of all of this
$db->sql_transaction('begin');
$sql = 'SELECT *
FROM ' . STYLES_TEMPLATE_DATA_TABLE;
$result = _sql($sql, $errored, $error_ary);
$old_style_rows = array();
while ($row = $db->sql_fetchrow($result))
{
$old_style_rows[] = $row;
}
$db->sql_freeresult($result);
// death to the table, it is evil!
$sql = 'DROP TABLE ' . STYLES_TEMPLATE_DATA_TABLE;
_sql($sql, $errored, $error_ary);
// the table of awesomeness, praise be to it (or something)
$sql = 'CREATE TABLE [' . STYLES_TEMPLATE_DATA_TABLE . "] (
[template_id] [int] DEFAULT (0) NOT NULL ,
[template_filename] [varchar] (100) DEFAULT ('') NOT NULL ,
[template_included] [varchar] (8000) DEFAULT ('') NOT NULL ,
[template_mtime] [int] DEFAULT (0) NOT NULL ,
[template_data] [text] DEFAULT ('') NOT NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]";
_sql($sql, $errored, $error_ary);
// index? index
$sql = 'CREATE INDEX [tid] ON [' . STYLES_TEMPLATE_DATA_TABLE . ']([template_id]) ON [PRIMARY]';
_sql($sql, $errored, $error_ary);
// yet another index
$sql = 'CREATE INDEX [tfn] ON [' . STYLES_TEMPLATE_DATA_TABLE . ']([template_filename]) ON [PRIMARY]';
_sql($sql, $errored, $error_ary);
foreach ($old_style_rows as $return_row)
{
_sql('INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE . ' ' . $db->sql_build_array('INSERT', $return_row), $errored, $error_ary);
}
$db->sql_transaction('commit');
}
// Setting this here again because new installations may not have it...
set_config('cron_lock', '0', true);
set_config('ldap_port', '');
set_config('ldap_user_filter', '');
$no_updates = false;
}
if (version_compare($current_version, '3.0.RC5', '<='))
{
// In case the user is having the bot mediapartner google "as is", adjust it.
$sql = 'UPDATE ' . BOTS_TABLE . "
SET bot_agent = '" . $db->sql_escape('Mediapartners-Google') . "'
WHERE bot_agent = '" . $db->sql_escape('Mediapartners-Google/') . "'";
_sql($sql, $errored, $error_ary);
set_config('form_token_lifetime', '7200');
set_config('form_token_mintime', '0');
set_config('min_time_reg', '5');
set_config('min_time_terms', '2');
set_config('form_token_sid_guests', '1');
$db->sql_transaction('begin');
$sql = 'SELECT forum_id, forum_password
FROM ' . FORUMS_TABLE;
$result = _sql($sql, $errored, $error_ary);
while ($row = $db->sql_fetchrow($result))
{
if (!empty($row['forum_password']))
{
_sql('UPDATE ' . FORUMS_TABLE . " SET forum_password = '" . md5($row['forum_password']) . "' WHERE forum_id = {$row['forum_id']}", $errored, $error_ary);
}
}
$db->sql_freeresult($result);
$db->sql_transaction('commit');
$no_updates = false;
}
_write_result($no_updates, $errored, $error_ary);
$error_ary = array();
$errored = $no_updates = false;
?>
::
sql_layer)
{
case 'mysql':
case 'mysqli':
case 'mysql4':
$sql = 'OPTIMIZE TABLE ' . $table_prefix . 'auth_access, ' . $table_prefix . 'banlist, ' . $table_prefix . 'categories, ' . $table_prefix . 'config, ' . $table_prefix . 'disallow, ' . $table_prefix . 'forum_prune, ' . $table_prefix . 'forums, ' . $table_prefix . 'groups, ' . $table_prefix . 'posts, ' . $table_prefix . 'posts_text, ' . $table_prefix . 'privmsgs, ' . $table_prefix . 'privmsgs_text, ' . $table_prefix . 'ranks, ' . $table_prefix . 'search_results, ' . $table_prefix . 'search_wordlist, ' . $table_prefix . 'search_wordmatch, ' . $table_prefix . 'sessions_keys' . $table_prefix . 'smilies, ' . $table_prefix . 'themes, ' . $table_prefix . 'themes_name, ' . $table_prefix . 'topics, ' . $table_prefix . 'topics_watch, ' . $table_prefix . 'user_group, ' . $table_prefix . 'users, ' . $table_prefix . 'vote_desc, ' . $table_prefix . 'vote_results, ' . $table_prefix . 'vote_voters, ' . $table_prefix . 'words';
_sql($sql, $errored, $error_ary);
break;
case 'postgresql':
_sql("VACUUM ANALYZE", $errored, $error_ary);
break;
}
*/
_write_result($no_updates, $errored, $error_ary);
?>
" class="button1">
purge();
?>