:: 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.RC3', '<='))
{
/*
Clean Usernames
Please note that this can take a while... Please do not stop the script.
*/
flush();
$submit = (isset($_POST['resolve_conflicts'])) ? true : false;
$modify_users = request_var('modify_users', array(0 => ''));
$new_usernames = request_var('new_usernames', array(0 => ''), true);
// 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_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)
{
// We use utf8_new_clean_string() here to make sure the new one is really used.
$sql = 'UPDATE ' . USERS_TABLE . '
SET ' . $db->sql_build_array('UPDATE', array(
'username' => $data['username'],
'username_clean' => utf8_new_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;
}
}
}
}
// after RC3 a different utf8_clean_string function is used, this requires that
// the unique column username_clean is recalculated, during this recalculation
// duplicates might be created. Since the column has to be unique such usernames
// must not exist. We need identify them and let the admin decide what to do
// about them.
$sql = 'SELECT user_id, username, username_clean
FROM ' . USERS_TABLE . '
ORDER BY user_id';
$result = $db->sql_query($sql);
$colliding_users = $found_names = array();
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'])
{
$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))
{
// 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;
}
}
}
}
unset($found_names);
$db->sql_freeresult($result);
// 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_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$clean_name = utf8_new_clean_string($row['username']);
if ($clean_name != $row['username_clean'])
{
$sql = 'UPDATE ' . USERS_TABLE . '
SET username_clean = \'' . $db->sql_escape($clean_name) . '\'
WHERE user_id = ' . (int) $row['user_id'];
$db->sql_query($sql);
}
}
$db->sql_freeresult($result);
}
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_escape('BOTS') . "'";
$result = $db->sql_query($sql);
$bot_group_id = (int) $db->sql_fetchfield('group_id');
$db->sql_freeresult($result);
$bots = array();
$sql = 'SELECT u.user_id
FROM ' . USERS_TABLE . ' u, ' . USER_GROUP_TABLE . ' ug
WHERE ug.group_id = ' . $bot_group_id . '
AND ug.user_id = u.user_id';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$bots[] = (int)$row['user_id'];
}
$db->sql_freeresult($result);
if (sizeof($bots))
{
$sql = 'DELETE FROM ' . USER_GROUP_TABLE . "
WHERE group_id <> $bot_group_id
AND " . $db->sql_in_set('user_id', $bots);
$db->sql_query($sql);
}
if ($map_dbms === 'mysql_41')
{
sql_column_change($map_dbms, POSTS_TABLE, 'post_subject', array('XSTEXT_UNI', '', 'true_sort'));
}
$sql = 'DELETE FROM ' . CONFIG_TABLE . " WHERE config_name = 'jab_resource'";
_sql($sql, $errored, $error_ary);
set_config('jab_use_ssl', '0');
set_config('allow_post_flash', '1');
$no_updates = false;
}
if (version_compare($current_version, '3.0.RC2', '<='))
{
$smileys = array();
$sql = 'SELECT smiley_id, code
FROM ' . SMILIES_TABLE;
$result = $db->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);
$no_updates = false;
}
// 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);
$no_updates = false;
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);
$no_updates = false;
break;
}
$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 = ''";
$db->sql_query($sql);
set_config('allow_birthdays', '1');
}
_write_result($no_updates, $errored, $error_ary);
$error_ary = array();
$errored = $no_updates = false;
?>