6 * @copyright (c) 2006 phpBB Group
7 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
11 $updates_to_version = '3.0.RC6';
13 // Return if we "just include it" to find out for which version the database update is responsuble for
14 if (defined('IN_PHPBB') && defined('IN_INSTALL'))
21 define('IN_PHPBB', true);
22 define('IN_INSTALL', true);
24 $phpbb_root_path = (defined('PHPBB_ROOT_PATH')) ? PHPBB_ROOT_PATH
: './../';
25 $phpEx = substr(strrchr(__FILE__
, '.'), 1);
27 // Report all errors, except notices
28 //error_reporting(E_ALL ^ E_NOTICE);
29 error_reporting(E_ALL
);
33 // Include essential scripts
34 include($phpbb_root_path . 'config.' . $phpEx);
38 die("Please read: <a href='../docs/INSTALL.html'>INSTALL.html</a> before attempting to update.");
42 if (!empty($load_extensions))
44 $load_extensions = explode(',', $load_extensions);
46 foreach ($load_extensions as $extension)
48 @dl
(trim($extension));
53 require($phpbb_root_path . 'includes/acm/acm_' . $acm_type . '.' . $phpEx);
54 require($phpbb_root_path . 'includes/cache.' . $phpEx);
55 require($phpbb_root_path . 'includes/template.' . $phpEx);
56 require($phpbb_root_path . 'includes/session.' . $phpEx);
57 require($phpbb_root_path . 'includes/auth.' . $phpEx);
59 require($phpbb_root_path . 'includes/functions.' . $phpEx);
61 if (file_exists($phpbb_root_path . 'includes/functions_content.' . $phpEx))
63 require($phpbb_root_path . 'includes/functions_content.' . $phpEx);
66 require($phpbb_root_path . 'includes/functions_admin.' . $phpEx);
67 require($phpbb_root_path . 'includes/constants.' . $phpEx);
68 require($phpbb_root_path . 'includes/db/' . $dbms . '.' . $phpEx);
69 require($phpbb_root_path . 'includes/utf/utf_tools.' . $phpEx);
71 // If we are on PHP >= 6.0.0 we do not need some code
72 if (version_compare(PHP_VERSION
, '6.0.0-dev', '>='))
77 define('STRIP', false);
81 set_magic_quotes_runtime(0);
82 define('STRIP', (get_magic_quotes_gpc()) ?
true : false);
89 // Add own hook handler, if present. :o
90 if (file_exists($phpbb_root_path . 'includes/hooks/index.' . $phpEx))
92 require($phpbb_root_path . 'includes/hooks/index.' . $phpEx);
93 $phpbb_hook = new phpbb_hook(array('exit_handler', 'phpbb_user_session_handler', 'append_sid', array('template', 'display')));
95 foreach ($cache->obtain_hooks() as $hook)
97 @include
($phpbb_root_path . 'includes/hooks/' . $hook . '.' . $phpEx);
106 $db->sql_connect($dbhost, $dbuser, $dbpasswd, $dbname, $dbport, false, false);
108 // We do not need this any longer, unset for safety purposes
111 $user->ip
= (!empty($_SERVER['REMOTE_ADDR'])) ?
htmlspecialchars($_SERVER['REMOTE_ADDR']) : '';
113 $sql = "SELECT config_value
114 FROM " . CONFIG_TABLE
. "
115 WHERE config_name = 'default_lang'";
116 $result = $db->sql_query($sql);
117 $row = $db->sql_fetchrow($result);
118 $db->sql_freeresult($result);
120 $language = basename(request_var('language', ''));
124 $language = $row['config_value'];
127 if (!file_exists($phpbb_root_path . 'language/' . $language))
129 die('No language found!');
132 // And finally, load the relevant language files
133 include($phpbb_root_path . 'language/' . $language . '/common.' . $phpEx);
134 include($phpbb_root_path . 'language/' . $language . '/acp/common.' . $phpEx);
135 include($phpbb_root_path . 'language/' . $language . '/install.' . $phpEx);
137 // Set PHP error handler to ours
138 //set_error_handler('msg_handler');
140 // Define some variables for the database update
141 $inline_update = (request_var('type', 0)) ?
true : false;
143 // Database column types mapping
144 $dbms_type_map = array(
147 'BINT' => 'bigint(20)',
148 'UINT' => 'mediumint(8) UNSIGNED',
149 'UINT:' => 'int(%d) UNSIGNED',
150 'TINT:' => 'tinyint(%d)',
151 'USINT' => 'smallint(4) UNSIGNED',
152 'BOOL' => 'tinyint(1) UNSIGNED',
153 'VCHAR' => 'varchar(255)',
154 'VCHAR:' => 'varchar(%d)',
155 'CHAR:' => 'char(%d)',
157 'XSTEXT_UNI'=> 'varchar(100)',
159 'STEXT_UNI' => 'varchar(255)',
161 'TEXT_UNI' => 'text',
162 'MTEXT' => 'mediumtext',
163 'MTEXT_UNI' => 'mediumtext',
164 'TIMESTAMP' => 'int(11) UNSIGNED',
165 'DECIMAL' => 'decimal(5,2)',
166 'VCHAR_UNI' => 'varchar(255)',
167 'VCHAR_UNI:'=> 'varchar(%d)',
168 'VCHAR_CI' => 'varchar(255)',
169 'VARBINARY' => 'varbinary(255)',
174 'BINT' => 'bigint(20)',
175 'UINT' => 'mediumint(8) UNSIGNED',
176 'UINT:' => 'int(%d) UNSIGNED',
177 'TINT:' => 'tinyint(%d)',
178 'USINT' => 'smallint(4) UNSIGNED',
179 'BOOL' => 'tinyint(1) UNSIGNED',
180 'VCHAR' => 'varbinary(255)',
181 'VCHAR:' => 'varbinary(%d)',
182 'CHAR:' => 'binary(%d)',
184 'XSTEXT_UNI'=> 'blob',
186 'STEXT_UNI' => 'blob',
188 'TEXT_UNI' => 'blob',
189 'MTEXT' => 'mediumblob',
190 'MTEXT_UNI' => 'mediumblob',
191 'TIMESTAMP' => 'int(11) UNSIGNED',
192 'DECIMAL' => 'decimal(5,2)',
193 'VCHAR_UNI' => 'blob',
194 'VCHAR_UNI:'=> array('varbinary(%d)', 'limit' => array('mult', 3, 255, 'blob')),
195 'VCHAR_CI' => 'blob',
196 'VARBINARY' => 'varbinary(255)',
201 'BINT' => 'DOUBLE PRECISION',
203 'UINT:' => 'INTEGER',
204 'TINT:' => 'INTEGER',
205 'USINT' => 'INTEGER',
207 'VCHAR' => 'VARCHAR(255) CHARACTER SET NONE',
208 'VCHAR:' => 'VARCHAR(%d) CHARACTER SET NONE',
209 'CHAR:' => 'CHAR(%d) CHARACTER SET NONE',
210 'XSTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
211 'STEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
212 'TEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
213 'MTEXT' => 'BLOB SUB_TYPE TEXT CHARACTER SET NONE',
214 'XSTEXT_UNI'=> 'VARCHAR(100) CHARACTER SET UTF8',
215 'STEXT_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
216 'TEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
217 'MTEXT_UNI' => 'BLOB SUB_TYPE TEXT CHARACTER SET UTF8',
218 'TIMESTAMP' => 'INTEGER',
219 'DECIMAL' => 'DOUBLE PRECISION',
220 'VCHAR_UNI' => 'VARCHAR(255) CHARACTER SET UTF8',
221 'VCHAR_UNI:'=> 'VARCHAR(%d) CHARACTER SET UTF8',
222 'VCHAR_CI' => 'VARCHAR(255) CHARACTER SET UTF8',
223 'VARBINARY' => 'CHAR(255) CHARACTER SET NONE',
234 'VCHAR' => '[varchar] (255)',
235 'VCHAR:' => '[varchar] (%d)',
236 'CHAR:' => '[char] (%d)',
237 'XSTEXT' => '[varchar] (1000)',
238 'STEXT' => '[varchar] (3000)',
239 'TEXT' => '[varchar] (8000)',
241 'XSTEXT_UNI'=> '[varchar] (100)',
242 'STEXT_UNI' => '[varchar] (255)',
243 'TEXT_UNI' => '[varchar] (4000)',
244 'MTEXT_UNI' => '[text]',
245 'TIMESTAMP' => '[int]',
246 'DECIMAL' => '[float]',
247 'VCHAR_UNI' => '[varchar] (255)',
248 'VCHAR_UNI:'=> '[varchar] (%d)',
249 'VCHAR_CI' => '[varchar] (255)',
250 'VARBINARY' => '[varchar] (255)',
254 'INT:' => 'number(%d)',
255 'BINT' => 'number(20)',
256 'UINT' => 'number(8)',
257 'UINT:' => 'number(%d)',
258 'TINT:' => 'number(%d)',
259 'USINT' => 'number(4)',
260 'BOOL' => 'number(1)',
261 'VCHAR' => 'varchar2(255)',
262 'VCHAR:' => 'varchar2(%d)',
263 'CHAR:' => 'char(%d)',
264 'XSTEXT' => 'varchar2(1000)',
265 'STEXT' => 'varchar2(3000)',
268 'XSTEXT_UNI'=> 'varchar2(300)',
269 'STEXT_UNI' => 'varchar2(765)',
270 'TEXT_UNI' => 'clob',
271 'MTEXT_UNI' => 'clob',
272 'TIMESTAMP' => 'number(11)',
273 'DECIMAL' => 'number(5, 2)',
274 'VCHAR_UNI' => 'varchar2(765)',
275 'VCHAR_UNI:'=> array('varchar2(%d)', 'limit' => array('mult', 3, 765, 'clob')),
276 'VCHAR_CI' => 'varchar2(255)',
277 'VARBINARY' => 'raw(255)',
282 'BINT' => 'bigint(20)',
283 'UINT' => 'INTEGER UNSIGNED', //'mediumint(8) UNSIGNED',
284 'UINT:' => 'INTEGER UNSIGNED', // 'int(%d) UNSIGNED',
285 'TINT:' => 'tinyint(%d)',
286 'USINT' => 'INTEGER UNSIGNED', //'mediumint(4) UNSIGNED',
287 'BOOL' => 'INTEGER UNSIGNED', //'tinyint(1) UNSIGNED',
288 'VCHAR' => 'varchar(255)',
289 'VCHAR:' => 'varchar(%d)',
290 'CHAR:' => 'char(%d)',
291 'XSTEXT' => 'text(65535)',
292 'STEXT' => 'text(65535)',
293 'TEXT' => 'text(65535)',
294 'MTEXT' => 'mediumtext(16777215)',
295 'XSTEXT_UNI'=> 'text(65535)',
296 'STEXT_UNI' => 'text(65535)',
297 'TEXT_UNI' => 'text(65535)',
298 'MTEXT_UNI' => 'mediumtext(16777215)',
299 'TIMESTAMP' => 'INTEGER UNSIGNED', //'int(11) UNSIGNED',
300 'DECIMAL' => 'decimal(5,2)',
301 'VCHAR_UNI' => 'varchar(255)',
302 'VCHAR_UNI:'=> 'varchar(%d)',
303 'VCHAR_CI' => 'varchar(255)',
304 'VARBINARY' => 'blob',
310 'UINT' => 'INT4', // unsigned
311 'UINT:' => 'INT4', // unsigned
312 'USINT' => 'INT2', // unsigned
313 'BOOL' => 'INT2', // unsigned
315 'VCHAR' => 'varchar(255)',
316 'VCHAR:' => 'varchar(%d)',
317 'CHAR:' => 'char(%d)',
318 'XSTEXT' => 'varchar(1000)',
319 'STEXT' => 'varchar(3000)',
320 'TEXT' => 'varchar(8000)',
322 'XSTEXT_UNI'=> 'varchar(100)',
323 'STEXT_UNI' => 'varchar(255)',
324 'TEXT_UNI' => 'varchar(4000)',
325 'MTEXT_UNI' => 'TEXT',
326 'TIMESTAMP' => 'INT4', // unsigned
327 'DECIMAL' => 'decimal(5,2)',
328 'VCHAR_UNI' => 'varchar(255)',
329 'VCHAR_UNI:'=> 'varchar(%d)',
330 'VCHAR_CI' => 'varchar_ci',
331 'VARBINARY' => 'bytea',
335 // A list of types being unsigned for better reference in some db's
336 $unsigned_types = array('UINT', 'UINT:', 'USINT', 'BOOL', 'TIMESTAMP');
338 // Only an example, but also commented out
339 $database_update_info = array(
340 // Changes from 3.0.RC2 to the next version
342 // Change the following columns
343 'change_columns' => array(
344 BANLIST_TABLE
=> array(
345 'ban_reason' => array('VCHAR_UNI', ''),
346 'ban_give_reason' => array('VCHAR_UNI', ''),
350 // Changes from 3.0.RC3 to the next version
352 // Change the following columns
353 'change_columns' => array(
354 BANLIST_TABLE
=> array(
355 'ban_reason' => array('VCHAR_UNI', ''),
356 'ban_give_reason' => array('VCHAR_UNI', ''),
358 STYLES_TABLE
=> array(
359 'style_id' => array('USINT', 0),
360 'template_id' => array('USINT', 0),
361 'theme_id' => array('USINT', 0),
362 'imageset_id' => array('USINT', 0),
364 STYLES_TEMPLATE_TABLE
=> array(
365 'template_id' => array('USINT', 0),
367 STYLES_TEMPLATE_DATA_TABLE
=> array(
368 'template_id' => array('USINT', 0),
370 STYLES_THEME_TABLE
=> array(
371 'theme_id' => array('USINT', 0),
373 STYLES_IMAGESET_TABLE
=> array(
374 'imageset_id' => array('USINT', 0),
376 STYLES_IMAGESET_DATA_TABLE
=> array(
377 'imageset_id' => array('USINT', 0),
379 USERS_TABLE
=> array(
380 'user_style' => array('USINT', 0),
382 FORUMS_TABLE
=> array(
383 'forum_style' => array('USINT', 0),
385 GROUPS_TABLE
=> array(
386 'group_avatar_type' => array('TINT:2', 0),
387 'group_avatar_width' => array('USINT', 0),
388 'group_avatar_height' => array('USINT', 0),
392 // Changes from 3.0.RC4 to the next version
394 // Change the following columns
395 'change_columns' => array(
396 STYLES_TABLE
=> array(
397 'style_id' => array('USINT', NULL, 'auto_increment'),
398 'template_id' => array('USINT', 0),
399 'theme_id' => array('USINT', 0),
400 'imageset_id' => array('USINT', 0),
402 STYLES_TEMPLATE_TABLE
=> array(
403 'template_id' => array('USINT', NULL, 'auto_increment'),
405 STYLES_TEMPLATE_DATA_TABLE
=> array(
406 'template_id' => array('USINT', 0),
408 STYLES_THEME_TABLE
=> array(
409 'theme_id' => array('USINT', NULL, 'auto_increment'),
411 STYLES_IMAGESET_TABLE
=> array(
412 'imageset_id' => array('USINT', NULL, 'auto_increment'),
414 STYLES_IMAGESET_DATA_TABLE
=> array(
415 'imageset_id' => array('USINT', 0),
417 USERS_TABLE
=> array(
418 'user_style' => array('USINT', 0),
420 FORUMS_TABLE
=> array(
421 'forum_style' => array('USINT', 0),
423 GROUPS_TABLE
=> array(
424 'group_avatar_width' => array('USINT', 0),
425 'group_avatar_height' => array('USINT', 0),
429 // Changes from 3.0.RC5 to the next version
431 // Add the following columns
432 'add_columns' => array(
433 USERS_TABLE
=> array(
434 'user_form_salt' => array('VCHAR_UNI:32', ''),
437 // Change the following columns
438 'change_columns' => array(
439 POSTS_TABLE
=> array(
440 'bbcode_uid' => array('VCHAR:8', ''),
442 PRIVMSGS_TABLE
=> array(
443 'bbcode_uid' => array('VCHAR:8', ''),
445 USERS_TABLE
=> array(
446 'user_sig_bbcode_uid' => array('VCHAR:8', ''),
452 // Determine mapping database type
453 switch ($db->sql_layer
)
456 $map_dbms = 'mysql_40';
460 if (version_compare($db->mysql_version
, '4.1.3', '>='))
462 $map_dbms = 'mysql_41';
466 $map_dbms = 'mysql_40';
471 $map_dbms = 'mysql_41';
480 $map_dbms = $db->sql_layer
;
484 $error_ary = array();
487 header('Content-type: text/html; charset=UTF-8');
490 <!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
491 <html xmlns
="http://www.w3.org/1999/xhtml" dir
="<?php echo $lang['DIRECTION']; ?>" lang
="<?php echo $lang['USER_LANG']; ?>" xml
:lang
="<?php echo $lang['USER_LANG']; ?>">
494 <meta http
-equiv
="content-type" content
="text/html; charset=UTF-8" />
495 <meta http
-equiv
="content-language" content
="<?php echo $lang['USER_LANG']; ?>" />
496 <meta http
-equiv
="content-style-type" content
="text/css" />
497 <meta http
-equiv
="imagetoolbar" content
="no" />
499 <title
><?php
echo $lang['UPDATING_TO_LATEST_STABLE']; ?
></title
>
501 <link href
="../adm/style/admin.css" rel
="stylesheet" type
="text/css" media
="screen" />
507 <div id
="page-header"> 
;</div
>
512 <span
class="corners-top"><span
></span
></span
>
516 <h1
><?php
echo $lang['UPDATING_TO_LATEST_STABLE']; ?
></h1
>
520 <p
><?php
echo $lang['DATABASE_TYPE']; ?
> :: <strong
><?php
echo $db->sql_layer
; ?
></strong
><br
/>
523 // To let set_config() calls succeed, we need to make the config array available globally
526 FROM ' . CONFIG_TABLE
;
527 $result = $db->sql_query($sql);
529 while ($row = $db->sql_fetchrow($result))
531 $config[$row['config_name']] = $row['config_value'];
533 $db->sql_freeresult($result);
535 echo $lang['PREVIOUS_VERSION'] . ' :: <strong>' . $config['version'] . '</strong><br />';
536 echo $lang['UPDATED_VERSION'] . ' :: <strong>' . $updates_to_version . '</strong></p>';
538 $current_version = str_replace('rc', 'RC', strtolower($config['version']));
539 $latest_version = str_replace('rc', 'RC', strtolower($updates_to_version));
540 $orig_version = $config['version'];
542 // If the latest version and the current version are 'unequal', we will update the version_update_from, else we do not update anything.
545 if ($current_version !== $latest_version)
547 set_config('version_update_from', $orig_version);
552 // If not called from the update script, we will actually remove the traces
553 $db->sql_query('DELETE FROM ' . CONFIG_TABLE
. " WHERE config_name = 'version_update_from'");
556 // Checks/Operations that have to be completed prior to starting the update itself
558 if (version_compare($current_version, '3.0.RC4', '<='))
560 // Define missing language entries...
561 if (!isset($lang['CLEANING_USERNAMES']))
563 $lang = array_merge($lang, array(
564 'CLEANING_USERNAMES' => 'Cleaning usernames',
565 'LONG_SCRIPT_EXECUTION' => 'Please note that this can take a while... Please do not stop the script.',
566 '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.',
567 'USER_ACTIVE' => 'Active user',
568 'USER_INACTIVE' => 'Inactive user',
569 'BOT' => 'Spider/Robot',
570 'UPDATE_REQUIRES_FILE' => 'The updater requires that the following file is present: %s',
572 'DELETE_USER_REMOVE' => 'Delete user and remove posts',
573 'DELETE_USER_RETAIN' => 'Delete user but keep posts',
574 'EDIT_USERNAME' => 'Edit username',
575 'KEEP_OLD_NAME' => 'Keep username',
576 'NEW_USERNAME' => 'New username',
582 <h1
><?php
echo $lang['CLEANING_USERNAMES']; ?
></h1
>
589 $submit = (isset($_POST['resolve_conflicts'])) ?
true : false;
590 $modify_users = request_var('modify_users', array(0 => ''));
591 $new_usernames = request_var('new_usernames', array(0 => ''), true);
593 if (!class_exists('utf_new_normalizer'))
595 if (!file_exists($phpbb_root_path . 'install/data/new_normalizer.' . $phpEx))
598 trigger_error(sprintf($lang['UPDATE_REQUIRES_FILE'], $phpbb_root_path . 'install/data/new_normalizer.' . $phpEx), E_USER_ERROR
);
600 include($phpbb_root_path . 'install/data/new_normalizer.' . $phpEx);
603 // the admin decided to change some usernames
604 if (sizeof($modify_users) && $submit)
606 $sql = 'SELECT user_id, username, user_type
607 FROM ' . USERS_TABLE
. '
608 WHERE ' . $db->sql_in_set('user_id', array_keys($modify_users));
609 $result = $db->sql_query($sql);
612 while ($row = $db->sql_fetchrow($result))
615 $user_id = (int) $row['user_id'];
617 if (isset($modify_users[$user_id]))
619 $row['action'] = $modify_users[$user_id];
620 $modify_users[$user_id] = $row;
623 $db->sql_freeresult($result);
625 // only if all ids really existed
626 if (sizeof($modify_users) == $users)
628 $user->data
['user_id'] = ANONYMOUS
;
629 include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
630 foreach ($modify_users as $user_id => $row)
632 switch ($row['action'])
635 if (isset($new_usernames[$user_id]))
637 $data = array('username' => utf8_new_normalize_nfc($new_usernames[$user_id]));
638 // Need to update config, forum, topic, posting, messages, etc.
639 if ($data['username'] != $row['username'])
641 $check_ary = array('username' => array(
642 array('string', false, $config['min_name_chars'], $config['max_name_chars']),
645 // need a little trick for this to work properly
646 $user->data
['username_clean'] = utf8_clean_string($data['username']) . 'a';
647 $errors = validate_data($data, $check_ary);
651 include($phpbb_root_path . 'language/' . $language . '/ucp.' . $phpEx);
652 echo '<div class="errorbox">';
653 foreach ($errors as $error)
655 echo '<p>' . $lang[$error] . '</p>';
662 $sql = 'UPDATE ' . USERS_TABLE
. '
663 SET ' . $db->sql_build_array('UPDATE', array(
664 'username' => $data['username'],
665 'username_clean' => utf8_clean_string($data['username'])
667 WHERE user_id = ' . $user_id;
668 $db->sql_query($sql);
670 add_log('user', $user_id, 'LOG_USER_UPDATE_NAME', $row['username'], $data['username']);
671 user_update_name($row['username'], $data['username']);
677 case 'delete_retain':
678 case 'delete_remove':
679 if ($user_id != ANONYMOUS
&& $row['user_type'] != USER_FOUNDER
)
681 user_delete(substr($row['action'], 7), $user_id, $row['username']);
682 add_log('admin', 'LOG_USER_DELETED', $row['username']);
691 <p
><?php
echo $lang['LONG_SCRIPT_EXECUTION']; ?
></p
>
692 <p
><?php
echo $lang['PROGRESS']; ?
> :: <strong
>
697 // after RC3 a different utf8_clean_string function is used, this requires that
698 // the unique column username_clean is recalculated, during this recalculation
699 // duplicates might be created. Since the column has to be unique such usernames
700 // must not exist. We need identify them and let the admin decide what to do
702 $sql = 'SELECT user_id, username, username_clean
703 FROM ' . USERS_TABLE
. '
704 ORDER BY user_id ASC';
705 $result = $db->sql_query($sql);
707 $colliding_users = $found_names = array();
710 while ($row = $db->sql_fetchrow($result))
712 // Calculate the new clean name. If it differs from the old one we need
713 // to make sure there is no collision
714 $clean_name = utf8_new_clean_string($row['username']);
716 if ($clean_name != $row['username_clean'])
718 // Check if there would be a collission, if not put it up for changing
719 $user_id = (int) $row['user_id'];
721 // If this clean name was not the result of another user already ...
722 if (!isset($found_names[$clean_name]))
724 // then we need to figure out whether there are any other users
725 // who already had this clean name with the old version
726 $sql = 'SELECT user_id, username
727 FROM ' . USERS_TABLE
. '
728 WHERE username_clean = \'' . $db->sql_escape($clean_name) . '\'';
729 $result2 = $db->sql_query($sql);
731 $user_ids = array($user_id);
732 while ($row = $db->sql_fetchrow($result2))
734 // For not trimmed entries this could happen, yes. ;)
735 if ($row['user_id'] == $user_id)
740 // Make sure this clean name will still be the same with the
741 // new function. If it is, then we have to add it to the list
742 // of user ids for this clean name
743 if (utf8_new_clean_string($row['username']) == $clean_name)
745 $user_ids[] = (int) $row['user_id'];
748 $db->sql_freeresult($result2);
750 // if we already found a collision save it
751 if (sizeof($user_ids) > 1)
753 $colliding_users[$clean_name] = $user_ids;
754 $found_names[$clean_name] = true;
758 // otherwise just mark this name as found
759 $found_names[$clean_name] = $user_id;
762 // Else, if we already found the username
765 // If the value in the found_names lookup table is only true ...
766 if ($found_names[$clean_name] === true)
768 // then the actual data was already added to $colliding_users
769 // and we only need to append the user_id
770 $colliding_users[$clean_name][] = $user_id;
774 // otherwise it still keeps the first user_id for this name
775 // and we need to move the data to $colliding_users, and set
776 // the value in the found_names lookup table to true, so
777 // following users will directly be appended to $colliding_users
778 $colliding_users[$clean_name] = array($found_names[$clean_name], $user_id);
779 $found_names[$clean_name] = true;
784 if (($echos %
1000) == 0)
791 $db->sql_freeresult($result);
793 _write_result(false, $errored, $error_ary);
795 // now retrieve all information about the users and let the admin decide what to do
796 if (sizeof($colliding_users))
799 include($phpbb_root_path . 'includes/functions_display.' . $phpEx);
800 include($phpbb_root_path . 'language/' . $language . '/memberlist.' . $phpEx);
801 include($phpbb_root_path . 'language/' . $language . '/acp/users.' . $phpEx);
803 // link a few things to the correct place so we don't get any problems
804 $user->lang
= &$lang;
805 $user->data
['user_id'] = ANONYMOUS
;
806 $user->date_format
= $config['default_dateformat'];
808 // a little trick to get all user_ids
809 $user_ids = call_user_func_array('array_merge', array_values($colliding_users));
811 $sql = 'SELECT session_user_id, MAX(session_time) AS session_time
812 FROM ' . SESSIONS_TABLE
. '
813 WHERE session_time >= ' . (time() - $config['session_length']) . '
814 AND ' . $db->sql_in_set('session_user_id', $user_ids) . '
815 GROUP BY session_user_id';
816 $result = $db->sql_query($sql);
818 $session_times = array();
819 while ($row = $db->sql_fetchrow($result))
821 $session_times[$row['session_user_id']] = $row['session_time'];
823 $db->sql_freeresult($result);
826 FROM ' . USERS_TABLE
. '
827 WHERE ' . $db->sql_in_set('user_id', $user_ids);
828 $result = $db->sql_query($sql);
831 while ($row = $db->sql_fetchrow($result))
833 if (isset($session_times[$row['user_id']]))
835 $row['session_time'] = $session_times[$row['user_id']];
839 $row['session_time'] = 0;
841 $users[(int) $row['user_id']] = $row;
843 $db->sql_freeresult($result);
844 unset($session_times);
846 // now display a table with all users, some information about them and options
847 // for the admin: keep name, change name (with text input) or delete user
848 $u_action = "database_update.$phpEx?language=$language&type=$inline_update";
852 <p
><?php
echo $lang['CHANGE_CLEAN_NAMES']; ?
></p
>
853 <form id
="change_clean_names" method
="post" action
="<?php echo $u_action; ?>">
857 foreach ($colliding_users as $clean_name => $user_ids)
860 <fieldset
class="tabulated">
862 <caption
><?php
echo sprintf($lang['COLLIDING_CLEAN_USERNAME'], $clean_name); ?
></caption
>
865 <th
><?php
echo $lang['RANK']; ?
> <?php
echo $lang['USERNAME']; ?
></th
>
866 <th
><?php
echo $lang['POSTS']; ?
></th
>
867 <th
><?php
echo $lang['INFORMATION']; ?
></th
>
868 <th
><?php
echo $lang['JOINED']; ?
></th
>
869 <th
><?php
echo $lang['LAST_ACTIVE']; ?
></th
>
870 <th
><?php
echo $lang['ACTION']; ?
></th
>
871 <th
><?php
echo $lang['NEW_USERNAME']; ?
></th
>
876 foreach ($user_ids as $i => $user_id)
878 $row = $users[$user_id];
880 $rank_title = $rank_img = '';
881 get_user_rank($row['user_rank'], $row['user_posts'], $rank_title, $rank_img, $rank_img_src);
883 $last_visit = (!empty($row['session_time'])) ?
$row['session_time'] : $row['user_lastvisit'];
886 switch ($row['user_type'])
889 $info .= $lang['USER_INACTIVE'];
893 $info .= $lang['BOT'];
897 $info .= $lang['FOUNDER'];
901 $info .= $lang['USER_ACTIVE'];
904 if ($user_id == ANONYMOUS
)
906 $info = $lang['GUEST'];
909 <tr
class="bg<?php echo ($i % 2) + 1; ?>">
911 <span
class="rank-img"><?php
echo ($rank_img) ?
$rank_img : $rank_title; ?
></span
><br
/>
912 <?php
echo get_username_string('full', $row['user_id'], $row['username'], $row['user_colour']); ?
>
914 <td
class="posts"><?php
echo $row['user_posts']; ?
></td
>
915 <td
class="info"><?php
echo $info; ?
></td
>
916 <td
><?php
echo $user->format_date($row['user_regdate']) ?
></td
>
917 <td
><?php
echo (empty($last_visit)) ?
' - ' : $user->format_date($last_visit); ?
> 
;</td
>
919 <label
><input type
="radio" class="radio" id
="keep_user_<?php echo $user_id; ?>" name
="modify_users[<?php echo $user_id; ?>]" value
="keep" checked
="checked" /> <?php
echo $lang['KEEP_OLD_NAME']; ?
></label
><br
/>
920 <label
><input type
="radio" class="radio" id
="edit_user_<?php echo $user_id; ?>" name
="modify_users[<?php echo $user_id; ?>]" value
="edit" /> <?php
echo $lang['EDIT_USERNAME']; ?
></label
><br
/>
922 // some users must not be deleted
923 if ($user_id != ANONYMOUS
&& $row['user_type'] != USER_FOUNDER
)
926 <label
><input type
="radio" class="radio" id
="delete_user_retain_<?php echo $user_id; ?>" name
="modify_users[<?php echo $user_id; ?>]" value
="delete_retain" /> <?php
echo $lang['DELETE_USER_RETAIN']; ?
></label
><br
/>
927 <label
><input type
="radio" class="radio" id
="delete_user_remove_<?php echo $user_id; ?>" name
="modify_users[<?php echo $user_id; ?>]" value
="delete_remove" /> <?php
echo $lang['DELETE_USER_REMOVE']; ?
></label
>
933 <input id
="new_username_<?php echo $user_id; ?>" type
="text" name
="new_usernames[<?php echo $user_id; ?>]" value
="<?php echo $row['username']; ?>" />
946 <input
class="button2" id
="resolve_conflicts" type
="submit" name
="resolve_conflicts" value
="<?php echo $lang['SUBMIT']; ?>" />
951 else if (sizeof($found_names))
953 $sql = 'SELECT user_id, username, username_clean
954 FROM ' . USERS_TABLE
. '
955 WHERE ' . $db->sql_in_set('user_id', array_values($found_names));
956 $result = $db->sql_query($sql);
958 $found_names = array();
959 while ($row = $db->sql_fetchrow($result))
961 $clean_name = utf8_new_clean_string($row['username']);
963 if ($clean_name != $row['username_clean'])
965 $user_id = (int) $row['user_id'];
966 $found_names[$user_id] = $clean_name;
968 // impossible unique clean name
969 $sql = 'UPDATE ' . USERS_TABLE
. "
970 SET username_clean = ' {$user_id}'
971 WHERE user_id = {$user_id}";
972 $db->sql_query($sql);
975 $db->sql_freeresult($result);
977 foreach ($found_names as $user_id => $clean_name)
979 $sql = 'UPDATE ' . USERS_TABLE
. '
980 SET username_clean = \'' . $db->sql_escape($clean_name) . '\'
981 WHERE user_id = ' . $user_id;
982 $db->sql_query($sql);
986 unset($colliding_users);
995 <span
class="corners-bottom"><span
></span
></span
>
1000 <div id
="page-footer">
1001 Powered by phpBB
©
; 2000, 2002, 2005, 2007 <a href
="http://www.phpbb.com/">phpBB Group
</a
>
1016 <h1
><?php
echo $lang['UPDATE_DATABASE_SCHEMA']; ?
></h1
>
1019 <p
><?php
echo $lang['PROGRESS']; ?
> :: <strong
>
1025 // We go through the schema changes from the lowest to the highest version
1026 // We skip those versions older than the current version
1028 foreach ($database_update_info as $version => $schema_changes)
1030 if (version_compare($version, $current_version, '<'))
1035 if (!sizeof($schema_changes))
1040 $no_updates = false;
1043 if (!empty($schema_changes['change_columns']))
1045 foreach ($schema_changes['change_columns'] as $table => $columns)
1047 foreach ($columns as $column_name => $column_data)
1049 sql_column_change($map_dbms, $table, $column_name, $column_data);
1055 if (!empty($schema_changes['add_columns']))
1057 foreach ($schema_changes['add_columns'] as $table => $columns)
1059 foreach ($columns as $column_name => $column_data)
1061 // Only add the column if it does not exist yet
1062 if (!column_exists($map_dbms, $table, $column_name))
1064 sql_column_add($map_dbms, $table, $column_name, $column_data);
1071 if (!empty($schema_changes['drop_keys']))
1073 foreach ($schema_changes['drop_keys'] as $table => $indexes)
1075 foreach ($indexes as $index_name)
1077 sql_index_drop($map_dbms, $index_name, $table);
1083 if (!empty($schema_changes['drop_columns']))
1085 foreach ($schema_changes['drop_columns'] as $table => $columns)
1087 foreach ($columns as $column)
1089 sql_column_remove($map_dbms, $table, $column);
1094 // Add primary keys?
1095 if (!empty($schema_changes['add_primary_keys']))
1097 foreach ($schema_changes['add_primary_keys'] as $table => $columns)
1099 sql_create_primary_key($map_dbms, $table, $columns);
1103 // Add unqiue indexes?
1104 if (!empty($schema_changes['add_unique_index']))
1106 foreach ($schema_changes['add_unique_index'] as $table => $index_array)
1108 foreach ($index_array as $index_name => $column)
1110 sql_create_unique_index($map_dbms, $index_name, $table, $column);
1116 if (!empty($schema_changes['add_index']))
1118 foreach ($schema_changes['add_index'] as $table => $index_array)
1120 foreach ($index_array as $index_name => $column)
1122 sql_create_index($map_dbms, $index_name, $table, $column);
1128 _write_result($no_updates, $errored, $error_ary);
1131 $error_ary = array();
1132 $errored = $no_updates = false;
1137 <h1
><?php
echo $lang['UPDATING_DATA']; ?
></h1
>
1139 <p
><?php
echo $lang['PROGRESS']; ?
> :: <strong
>
1148 if (version_compare($current_version, '3.0.RC2', '<='))
1151 $sql = 'SELECT smiley_id, code
1152 FROM ' . SMILIES_TABLE
;
1154 $result = $db->sql_query($sql);
1156 while ($row = $db->sql_fetchrow($result))
1158 $smileys[$row['smiley_id']] = $row['code'];
1160 $db->sql_freeresult($result);
1162 foreach($smileys as $id => $code)
1164 // 2.0 only entitized lt and gt; We need to do something about double quotes.
1165 if (strchr($code, '"') === false)
1170 $new_code = str_replace('&', '&', $code);
1171 $new_code = str_replace('<', '<', $new_code);
1172 $new_code = str_replace('>', '>', $new_code);
1173 $new_code = utf8_htmlspecialchars($new_code);
1175 $sql = 'UPDATE ' . SMILIES_TABLE
. '
1176 SET code = \'' . $db->sql_escape($new_code) . '\'
1177 WHERE smiley_id = ' . (int) $id;
1178 $db->sql_query($sql);
1181 $index_list = sql_list_index($map_dbms, ACL_ROLES_DATA_TABLE
);
1183 if (in_array('ath_opt_id', $index_list))
1185 sql_index_drop($map_dbms, 'ath_opt_id', ACL_ROLES_DATA_TABLE
);
1186 sql_create_index($map_dbms, 'ath_op_id', ACL_ROLES_DATA_TABLE
, array('auth_option_id'));
1189 $no_updates = false;
1192 if (version_compare($current_version, '3.0.RC3', '<='))
1194 if ($map_dbms === 'postgres')
1196 $sql = "SELECT SETVAL('" . FORUMS_TABLE
. "_seq',(select case when max(forum_id)>0 then max(forum_id)+1 else 1 end from " . FORUMS_TABLE
. '));';
1197 _sql($sql, $errored, $error_ary);
1203 // ACL_ROLES_DATA_TABLE_ath_opt_id
1204 // we want ACL_ROLES_DATA_TABLE_ath_op_id
1206 $table_index_fix = array(
1207 ACL_ROLES_DATA_TABLE
=> array(
1208 'ath_opt_id' => 'ath_op_id',
1209 'ath_op_id' => 'ath_op_id',
1210 ACL_ROLES_DATA_TABLE
. '_ath_opt_id' => 'ath_op_id'
1212 STYLES_IMAGESET_DATA_TABLE
=> array(
1215 STYLES_IMAGESET_DATA_TABLE
. '_i_id' => 'i_d'
1219 // we need to create some indicies...
1220 $needed_creation = array();
1222 foreach ($table_index_fix as $table_name => $index_info)
1224 $index_list = sql_list_fake($map_dbms, $table_name);
1225 foreach ($index_info as $bad_index => $good_index)
1227 if (in_array($bad_index, $index_list))
1229 // mysql is actually OK, it won't get a hand in this crud
1232 // last version, mssql had issues with index removal
1234 $sql = 'DROP INDEX ' . $table_name . '.' . $bad_index;
1235 _sql($sql, $errored, $error_ary);
1238 // last version, firebird, oracle, postgresql and sqlite all got bad index names
1239 // we got kinda lucky, tho: they all support the same syntax
1244 $sql = 'DROP INDEX ' . $bad_index;
1245 _sql($sql, $errored, $error_ary);
1249 // If the good index already exist we do not need to create it again...
1250 if (($map_dbms == 'mysql_40' ||
$map_dbms == 'mysql_41') && $bad_index == $good_index)
1255 $needed_creation[$table_name][$good_index] = 1;
1261 $new_index_defs = array('ath_op_id' => array('auth_option_id'), 'i_d' => array('imageset_id'));
1263 foreach ($needed_creation as $bad_table => $index_repair_list)
1265 foreach ($index_repair_list as $new_index => $garbage)
1267 sql_create_index($map_dbms, $new_index, $bad_table, $new_index_defs[$new_index]);
1268 $no_updates = false;
1272 // Make sure empty smiley codes do not exist
1273 $sql = 'DELETE FROM ' . SMILIES_TABLE
. "
1275 _sql($sql, $errored, $error_ary);
1277 set_config('allow_birthdays', '1');
1278 set_config('cron_lock', '0', true);
1280 $no_updates = false;
1283 if (version_compare($current_version, '3.0.RC4', '<='))
1285 $update_auto_increment = array(
1286 STYLES_TABLE
=> 'style_id',
1287 STYLES_TEMPLATE_TABLE
=> 'template_id',
1288 STYLES_THEME_TABLE
=> 'theme_id',
1289 STYLES_IMAGESET_TABLE
=> 'imageset_id'
1293 FROM ' . STYLES_TABLE
. '
1294 WHERE style_id = 0';
1295 $result = _sql($sql, $errored, $error_ary);
1296 $bad_style_row = $db->sql_fetchrow($result);
1297 $db->sql_freeresult($result);
1301 $sql = 'SELECT MAX(style_id) as max_id
1302 FROM ' . STYLES_TABLE
;
1303 $result = _sql($sql, $errored, $error_ary);
1304 $row = $db->sql_fetchrow($result);
1305 $db->sql_freeresult($result);
1307 $proper_id = $row['max_id'] +
1;
1309 _sql('UPDATE ' . STYLES_TABLE
. " SET style_id = $proper_id WHERE style_id = 0", $errored, $error_ary);
1310 _sql('UPDATE ' . FORUMS_TABLE
. " SET forum_style = $proper_id WHERE forum_style = 0", $errored, $error_ary);
1311 _sql('UPDATE ' . USERS_TABLE
. " SET user_style = $proper_id WHERE user_style = 0", $errored, $error_ary);
1313 $sql = 'SELECT config_value
1314 FROM ' . CONFIG_TABLE
. "
1315 WHERE config_name = 'default_style'";
1316 $result = _sql($sql, $errored, $error_ary);
1317 $style_config = $db->sql_fetchrow($result);
1318 $db->sql_freeresult($result);
1320 if ($style_config['config_value'] === '0')
1322 set_config('default_style', (string) $proper_id);
1327 FROM ' . STYLES_TEMPLATE_TABLE
. '
1328 WHERE template_id = 0';
1329 $result = _sql($sql, $errored, $error_ary);
1330 $bad_style_row = $db->sql_fetchrow($result);
1331 $db->sql_freeresult($result);
1335 $sql = 'SELECT MAX(template_id) as max_id
1336 FROM ' . STYLES_TEMPLATE_TABLE
;
1337 $result = _sql($sql, $errored, $error_ary);
1338 $row = $db->sql_fetchrow($result);
1339 $db->sql_freeresult($result);
1341 $proper_id = $row['max_id'] +
1;
1343 _sql('UPDATE ' . STYLES_TABLE
. " SET template_id = $proper_id WHERE template_id = 0", $errored, $error_ary);
1347 FROM ' . STYLES_THEME_TABLE
. '
1348 WHERE theme_id = 0';
1349 $result = _sql($sql, $errored, $error_ary);
1350 $bad_style_row = $db->sql_fetchrow($result);
1351 $db->sql_freeresult($result);
1355 $sql = 'SELECT MAX(theme_id) as max_id
1356 FROM ' . STYLES_THEME_TABLE
;
1357 $result = _sql($sql, $errored, $error_ary);
1358 $row = $db->sql_fetchrow($result);
1359 $db->sql_freeresult($result);
1361 $proper_id = $row['max_id'] +
1;
1363 _sql('UPDATE ' . STYLES_TABLE
. " SET theme_id = $proper_id WHERE theme_id = 0", $errored, $error_ary);
1367 FROM ' . STYLES_IMAGESET_TABLE
. '
1368 WHERE imageset_id = 0';
1369 $result = _sql($sql, $errored, $error_ary);
1370 $bad_style_row = $db->sql_fetchrow($result);
1371 $db->sql_freeresult($result);
1375 $sql = 'SELECT MAX(imageset_id) as max_id
1376 FROM ' . STYLES_IMAGESET_TABLE
;
1377 $result = _sql($sql, $errored, $error_ary);
1378 $row = $db->sql_fetchrow($result);
1379 $db->sql_freeresult($result);
1381 $proper_id = $row['max_id'] +
1;
1383 _sql('UPDATE ' . STYLES_TABLE
. " SET imageset_id = $proper_id WHERE imageset_id = 0", $errored, $error_ary);
1384 _sql('UPDATE ' . STYLES_IMAGESET_DATA_TABLE
. " SET imageset_id = $proper_id WHERE imageset_id = 0", $errored, $error_ary);
1387 if ($map_dbms == 'mysql_40' ||
$map_dbms == 'mysql_41')
1389 foreach ($update_auto_increment as $auto_table_name => $auto_column_name)
1391 $sql = "SELECT MAX({$auto_column_name}) as max_id
1392 FROM {$auto_table_name}";
1393 $result = _sql($sql, $errored, $error_ary);
1394 $row = $db->sql_fetchrow($result);
1395 $db->sql_freeresult($result);
1397 $max_id = ((int) $row['max_id']) +
1;
1398 _sql("ALTER TABLE {$auto_table_name} AUTO_INCREMENT = {$max_id}", $errored, $error_ary);
1401 $no_updates = false;
1403 else if ($map_dbms == 'postgres')
1405 foreach ($update_auto_increment as $auto_table_name => $auto_column_name)
1407 $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 . '));';
1408 _sql($sql, $errored, $error_ary);
1411 $sql = 'DROP SEQUENCE ' . STYLES_TEMPLATE_DATA_TABLE
. '_seq';
1412 _sql($sql, $errored, $error_ary);
1414 else if ($map_dbms == 'firebird')
1416 $sql = 'DROP TRIGGER t_' . STYLES_TEMPLATE_DATA_TABLE
;
1417 _sql($sql, $errored, $error_ary);
1419 $sql = 'DROP GENERATOR ' . STYLES_TEMPLATE_DATA_TABLE
. '_gen';
1420 _sql($sql, $errored, $error_ary);
1422 else if ($map_dbms == 'oracle')
1424 $sql = 'DROP TRIGGER t_' . STYLES_TEMPLATE_DATA_TABLE
;
1425 _sql($sql, $errored, $error_ary);
1427 $sql = 'DROP SEQUENCE ' . STYLES_TEMPLATE_DATA_TABLE
. '_seq';
1428 _sql($sql, $errored, $error_ary);
1430 else if ($map_dbms == 'mssql')
1432 // we use transactions because we need to have a working DB at the end of all of this
1433 $db->sql_transaction('begin');
1436 FROM ' . STYLES_TEMPLATE_DATA_TABLE
;
1437 $result = _sql($sql, $errored, $error_ary);
1438 $old_style_rows = array();
1439 while ($row = $db->sql_fetchrow($result))
1441 $old_style_rows[] = $row;
1443 $db->sql_freeresult($result);
1445 // death to the table, it is evil!
1446 $sql = 'DROP TABLE ' . STYLES_TEMPLATE_DATA_TABLE
;
1447 _sql($sql, $errored, $error_ary);
1449 // the table of awesomeness, praise be to it (or something)
1450 $sql = 'CREATE TABLE [' . STYLES_TEMPLATE_DATA_TABLE
. "] (
1451 [template_id] [int] DEFAULT (0) NOT NULL ,
1452 [template_filename] [varchar] (100) DEFAULT ('') NOT NULL ,
1453 [template_included] [varchar] (8000) DEFAULT ('') NOT NULL ,
1454 [template_mtime] [int] DEFAULT (0) NOT NULL ,
1455 [template_data] [text] DEFAULT ('') NOT NULL
1456 ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]";
1457 _sql($sql, $errored, $error_ary);
1460 $sql = 'CREATE INDEX [tid] ON [' . STYLES_TEMPLATE_DATA_TABLE
. ']([template_id]) ON [PRIMARY]';
1461 _sql($sql, $errored, $error_ary);
1463 // yet another index
1464 $sql = 'CREATE INDEX [tfn] ON [' . STYLES_TEMPLATE_DATA_TABLE
. ']([template_filename]) ON [PRIMARY]';
1465 _sql($sql, $errored, $error_ary);
1467 foreach ($old_style_rows as $return_row)
1469 _sql('INSERT INTO ' . STYLES_TEMPLATE_DATA_TABLE
. ' ' . $db->sql_build_array('INSERT', $return_row), $errored, $error_ary);
1472 $db->sql_transaction('commit');
1475 // Setting this here again because new installations may not have it...
1476 set_config('cron_lock', '0', true);
1477 set_config('ldap_port', '');
1478 set_config('ldap_user_filter', '');
1480 $no_updates = false;
1483 if (version_compare($current_version, '3.0.RC5', '<='))
1485 // In case the user is having the bot mediapartner google "as is", adjust it.
1486 $sql = 'UPDATE ' . BOTS_TABLE
. "
1487 SET bot_agent = '" . $db->sql_escape('Mediapartners-Google') . "'
1488 WHERE bot_agent = '" . $db->sql_escape('Mediapartners-Google/') . "'";
1489 _sql($sql, $errored, $error_ary);
1491 set_config('form_token_lifetime', '7200');
1492 set_config('form_token_mintime', '0');
1494 $db->sql_transaction('begin');
1496 $sql = 'SELECT forum_id, forum_password
1497 FROM ' . FORUMS_TABLE
;
1498 $result = _sql($sql, $errored, $error_ary);
1500 while ($row = $db->sql_fetchrow($result))
1502 if (!empty($row['forum_password']))
1504 _sql('UPDATE ' . FORUMS_TABLE
. " SET forum_password = '" . md5($row['forum_password']) . "' WHERE forum_id = {$row['forum_id']}", $errored, $error_ary);
1507 $db->sql_freeresult($result);
1509 $db->sql_transaction('commit');
1511 $no_updates = false;
1514 _write_result($no_updates, $errored, $error_ary);
1516 $error_ary = array();
1517 $errored = $no_updates = false;
1522 <h1
><?php
echo $lang['UPDATE_VERSION_OPTIMIZE']; ?
></h1
>
1524 <p
><?php
echo $lang['PROGRESS']; ?
> :: <strong
>
1530 // update the version
1531 $sql = "UPDATE " . CONFIG_TABLE
. "
1532 SET config_value = '$updates_to_version'
1533 WHERE config_name = 'version'";
1534 _sql($sql, $errored, $error_ary);
1536 // Reset permissions
1537 $sql = 'UPDATE ' . USERS_TABLE
. "
1538 SET user_permissions = ''";
1539 _sql($sql, $errored, $error_ary);
1541 /* Optimize/vacuum analyze the tables where appropriate
1542 // this should be done for each version in future along with
1543 // the version number update
1544 switch ($db->sql_layer)
1549 $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';
1550 _sql($sql, $errored, $error_ary);
1554 _sql("VACUUM ANALYZE", $errored, $error_ary);
1559 _write_result($no_updates, $errored, $error_ary);
1564 <h1
><?php
echo $lang['UPDATE_COMPLETED']; ?
></h1
>
1570 if (!$inline_update)
1574 <p style
="color:red"><?php
echo $lang['UPDATE_FILES_NOTICE']; ?
></p
>
1576 <p
><?php
echo $lang['COMPLETE_LOGIN_TO_BOARD']; ?
></p
>
1584 <p
><?php
echo ((isset($lang['INLINE_UPDATE_SUCCESSFUL'])) ?
$lang['INLINE_UPDATE_SUCCESSFUL'] : 'The database update was successful. Now you need to continue the update process.'); ?
></p
>
1586 <p
><a href
="<?php echo append_sid("{$phpbb_root_path}install
/index
.{$phpEx}", "mode
=update
&
;sub
=file_check
&
;lang
=$language"); ?>" class="button1"><?php
echo (isset($lang['CONTINUE_UPDATE_NOW'])) ?
$lang['CONTINUE_UPDATE_NOW'] : 'Continue the update process now'; ?
></a
></p
>
1591 // Add database update to log
1592 add_log('admin', 'LOG_UPDATE_DATABASE', $orig_version, $updates_to_version);
1594 // Now we purge the session table as well as all cache files
1601 <span
class="corners-bottom"><span
></span
></span
>
1606 <div id
="page-footer">
1607 Powered by phpBB
©
; 2000, 2002, 2005, 2007 <a href
="http://www.phpbb.com/">phpBB Group
</a
>
1620 * Function for triggering an sql statement
1622 function _sql($sql, &$errored, &$error_ary, $echo_dot = true)
1626 if (defined('DEBUG_EXTRA'))
1628 echo "<br />\n{$sql}\n<br />";
1631 $db->sql_return_on_error(true);
1633 $result = $db->sql_query($sql);
1634 if ($db->sql_error_triggered
)
1637 $error_ary['sql'][] = $db->sql_error_sql
;
1638 $error_ary['error_code'][] = $db->_sql_error();
1641 $db->sql_return_on_error(false);
1652 function _write_result($no_updates, $errored, $error_ary)
1658 echo ' ' . $lang['NO_UPDATES_REQUIRED'] . '</strong></p>';
1662 echo ' <span class="success">' . $lang['DONE'] . '</span></strong><br />' . $lang['RESULT'] . ' :: ';
1666 echo ' <strong>' . $lang['SOME_QUERIES_FAILED'] . '</strong> <ul>';
1668 for ($i = 0; $i < sizeof($error_ary['sql']); $i++
)
1670 echo '<li>' . $lang['ERROR'] . ' :: <strong>' . htmlspecialchars($error_ary['error_code'][$i]['message']) . '</strong><br />';
1671 echo $lang['SQL'] . ' :: <strong>' . htmlspecialchars($error_ary['sql'][$i]) . '</strong><br /><br /></li>';
1674 echo '</ul> <br /><br />' . $lang['SQL_FAILURE_EXPLAIN'] . '</p>';
1678 echo '<strong>' . $lang['NO_ERRORS'] . '</strong></p>';
1684 * Check if a specified column exist
1686 function column_exists($dbms, $table, $column_name)
1694 $sql = "SHOW COLUMNS
1696 $result = $db->sql_query($sql);
1697 while ($row = $db->sql_fetchrow($result))
1699 // lower case just in case
1700 if (strtolower($row['Field']) == $column_name)
1702 $db->sql_freeresult($result);
1706 $db->sql_freeresult($result);
1710 // PostgreSQL has a way of doing this in a much simpler way but would
1711 // not allow us to support all versions of PostgreSQL
1713 $sql = "SELECT a.attname
1714 FROM pg_class c, pg_attribute a
1715 WHERE c.relname = '{$table}'
1717 AND a.attrelid = c.oid";
1718 $result = $db->sql_query($sql);
1719 while ($row = $db->sql_fetchrow($result))
1721 // lower case just in case
1722 if (strtolower($row['attname']) == $column_name)
1724 $db->sql_freeresult($result);
1728 $db->sql_freeresult($result);
1732 // same deal with PostgreSQL, we must perform more complex operations than
1733 // we technically could
1735 $sql = "SELECT c.name
1737 LEFT JOIN sysobjects o (ON c.id = o.id)
1738 WHERE o.name = '{$table}'";
1739 $result = $db->sql_query($sql);
1740 while ($row = $db->sql_fetchrow($result))
1742 // lower case just in case
1743 if (strtolower($row['name']) == $column_name)
1745 $db->sql_freeresult($result);
1749 $db->sql_freeresult($result);
1754 $sql = "SELECT column_name
1755 FROM user_tab_columns
1756 WHERE table_name = '{$table}'";
1757 $result = $db->sql_query($sql);
1758 while ($row = $db->sql_fetchrow($result))
1760 // lower case just in case
1761 if (strtolower($row['column_name']) == $column_name)
1763 $db->sql_freeresult($result);
1767 $db->sql_freeresult($result);
1772 $sql = "SELECT RDB\$FIELD_NAME as FNAME
1773 FROM RDB\$RELATION_FIELDS
1774 WHERE RDB\$RELATION_NAME = '{$table}'";
1775 $result = $db->sql_query($sql);
1776 while ($row = $db->sql_fetchrow($result))
1778 // lower case just in case
1779 if (strtolower($row['fname']) == $column_name)
1781 $db->sql_freeresult($result);
1785 $db->sql_freeresult($result);
1793 WHERE type = 'table'
1794 AND name = '{$table}'";
1795 $result = $db->sql_query($sql);
1802 $row = $db->sql_fetchrow($result);
1803 $db->sql_freeresult($result);
1805 preg_match('#\((.*)\)#s', $row['sql'], $matches);
1807 $cols = trim($matches[1]);
1808 $col_array = preg_split('/,(?![\s\w]+\))/m', $cols);
1810 foreach ($col_array as $declaration)
1812 $entities = preg_split('#\s+#', trim($declaration));
1813 if ($entities[0] == 'PRIMARY')
1818 if (strtolower($entities[0]) == $column_name)
1829 * Function to prepare some column information for better usage
1831 function prepare_column_data($dbms, $column_data, $table_name, $column_name)
1833 global $dbms_type_map, $unsigned_types;
1836 if (strpos($column_data[0], ':') !== false)
1838 list($orig_column_type, $column_length) = explode(':', $column_data[0]);
1840 if (!is_array($dbms_type_map[$dbms][$orig_column_type . ':']))
1842 $column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'], $column_length);
1846 if (isset($dbms_type_map[$dbms][$orig_column_type . ':']['rule']))
1848 switch ($dbms_type_map[$dbms][$orig_column_type . ':']['rule'][0])
1851 $column_length /= $dbms_type_map[$dbms][$orig_column_type . ':']['rule'][1];
1852 $column_length = ceil($column_length);
1853 $column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length);
1858 if (isset($dbms_type_map[$dbms][$orig_column_type . ':']['limit']))
1860 switch ($dbms_type_map[$dbms][$orig_column_type . ':']['limit'][0])
1863 $column_length *= $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][1];
1864 if ($column_length > $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][2])
1866 $column_type = $dbms_type_map[$dbms][$orig_column_type . ':']['limit'][3];
1870 $column_type = sprintf($dbms_type_map[$dbms][$orig_column_type . ':'][0], $column_length);
1876 $orig_column_type .= ':';
1880 $orig_column_type = $column_data[0];
1881 $column_type = $dbms_type_map[$dbms][$column_data[0]];
1884 // Adjust default value if db-dependant specified
1885 if (is_array($column_data[1]))
1887 $column_data[1] = (isset($column_data[1][$dbms])) ?
$column_data[1][$dbms] : $column_data[1]['default'];
1892 $return_array = array();
1897 $sql .= " {$column_type} ";
1899 if (!is_null($column_data[1]))
1901 $sql .= 'DEFAULT ' . ((is_numeric($column_data[1])) ?
$column_data[1] : "'{$column_data[1]}'") . ' ';
1906 // This is a UNICODE column and thus should be given it's fair share
1907 if (preg_match('/^X?STEXT_UNI|VCHAR_(CI|UNI:?)/', $column_data[0]))
1909 $sql .= ' COLLATE UNICODE';
1915 $sql .= " {$column_type} ";
1917 // we do not support MSSQL DEFAULTs for the near future
1918 /*if (!is_null($column_data[1]))
1920 // For hexadecimal values do not use single quotes
1921 if (strpos($column_data[1], '0x') === 0)
1923 $sql .= 'DEFAULT (' . $column_data[1] . ') ';
1927 $sql .= 'DEFAULT (' . ((is_numeric($column_data[1])) ? $column_data[1] : "'{$column_data[1]}'") . ') ';
1936 $sql .= " {$column_type} ";
1938 // For hexadecimal values do not use single quotes
1939 if (!is_null($column_data[1]) && substr($column_type, -4) !== 'text' && substr($column_type, -4) !== 'blob')
1941 $sql .= (strpos($column_data[1], '0x') === 0) ?
"DEFAULT {$column_data[1]} " : "DEFAULT '{$column_data[1]}' ";
1945 if (isset($column_data[2]))
1947 if ($column_data[2] == 'auto_increment')
1949 $sql .= ' auto_increment';
1951 else if ($dbms === 'mysql_41' && $column_data[2] == 'true_sort')
1953 $sql .= ' COLLATE utf8_unicode_ci';
1960 $sql .= " {$column_type} ";
1961 $sql .= (!is_null($column_data[1])) ?
"DEFAULT '{$column_data[1]}' " : '';
1963 // In Oracle empty strings ('') are treated as NULL.
1964 // Therefore in oracle we allow NULL's for all DEFAULT '' entries
1965 // Oracle does not like setting NOT NULL on a column that is already NOT NULL (this happens only on number fields)
1966 if (preg_match('/number/i', $column_type))
1968 $sql .= ($column_data[1] === '') ?
'' : 'NOT NULL';
1973 $return_array['column_type'] = $column_type;
1975 $sql .= " {$column_type} ";
1977 if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
1979 $default_val = "nextval('{$table_name}_seq')";
1981 else if (!is_null($column_data[1]))
1983 $default_val = "'" . $column_data[1] . "'";
1984 $return_array['null'] = 'NOT NULL';
1985 $sql .= 'NOT NULL ';
1988 $return_array['default'] = $default_val;
1990 $sql .= "DEFAULT {$default_val}";
1992 // Unsigned? Then add a CHECK contraint
1993 if (in_array($orig_column_type, $unsigned_types))
1995 $return_array['constraint'] = "CHECK ({$column_name} >= 0)";
1996 $sql .= " CHECK ({$column_name} >= 0)";
2001 if (isset($column_data[2]) && $column_data[2] == 'auto_increment')
2003 $sql .= ' INTEGER PRIMARY KEY';
2007 $sql .= ' ' . $column_type;
2010 $sql .= ' NOT NULL ';
2011 $sql .= (!is_null($column_data[1])) ?
"DEFAULT '{$column_data[1]}'" : '';
2015 $return_array['column_type_sql'] = $sql;
2017 return $return_array;
2023 function sql_column_add($dbms, $table_name, $column_name, $column_data)
2025 global $errored, $error_ary;
2027 $column_data = prepare_column_data($dbms, $column_data, $table_name, $column_name);
2032 $sql = 'ALTER TABLE "' . $table_name . '" ADD "' . $column_name . '" ' . $column_data['column_type_sql'];
2033 _sql($sql, $errored, $error_ary);
2037 $sql = 'ALTER TABLE [' . $table_name . '] ADD [' . $column_name . '] ' . $column_data['column_type_sql'];
2038 _sql($sql, $errored, $error_ary);
2043 $sql = 'ALTER TABLE `' . $table_name . '` ADD COLUMN `' . $column_name . '` ' . $column_data['column_type_sql'];
2044 _sql($sql, $errored, $error_ary);
2048 $sql = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' ' . $column_data['column_type_sql'];
2049 _sql($sql, $errored, $error_ary);
2053 $sql = 'ALTER TABLE ' . $table_name . ' ADD COLUMN "' . $column_name . '" ' . $column_data['column_type_sql'];
2054 _sql($sql, $errored, $error_ary);
2058 if (version_compare(sqlite_libversion(), '3.0') == -1)
2063 WHERE type = 'table'
2064 AND name = '{$table_name}'
2065 ORDER BY type DESC, name;";
2066 $result = $db->sql_query($sql);
2073 $row = $db->sql_fetchrow($result);
2074 $db->sql_freeresult($result);
2076 $db->sql_transaction('begin');
2078 // Create a backup table and populate it, destroy the existing one
2079 $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
2080 $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
2081 $db->sql_query('DROP TABLE ' . $table_name);
2083 preg_match('#\((.*)\)#s', $row['sql'], $matches);
2085 $new_table_cols = trim($matches[1]);
2086 $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
2087 $column_list = array();
2089 foreach ($old_table_cols as $declaration)
2091 $entities = preg_split('#\s+#', trim($declaration));
2092 if ($entities[0] == 'PRIMARY')
2096 $column_list[] = $entities[0];
2099 $columns = implode(',', $column_list);
2101 $new_table_cols = $column_name . ' ' . $column_data['column_type_sql'] . ',' . $new_table_cols;
2103 // create a new table and fill it up. destroy the temp one
2104 $db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');');
2105 $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
2106 $db->sql_query('DROP TABLE ' . $table_name . '_temp');
2108 $db->sql_transaction('commit');
2112 $sql = 'ALTER TABLE ' . $table_name . ' ADD ' . $column_name . ' [' . $column_data['column_type_sql'] . ']';
2113 _sql($sql, $errored, $error_ary);
2122 function sql_column_remove($dbms, $table_name, $column_name)
2124 global $errored, $error_ary;
2129 $sql = 'ALTER TABLE "' . $table_name . '" DROP "' . $column_name . '"';
2130 _sql($sql, $errored, $error_ary);
2134 $sql = 'ALTER TABLE [' . $table_name . '] DROP COLUMN [' . $column_name . ']';
2135 _sql($sql, $errored, $error_ary);
2140 $sql = 'ALTER TABLE `' . $table_name . '` DROP COLUMN `' . $column_name . '`';
2141 _sql($sql, $errored, $error_ary);
2145 $sql = 'ALTER TABLE ' . $table_name . ' DROP ' . $column_name;
2146 _sql($sql, $errored, $error_ary);
2150 $sql = 'ALTER TABLE ' . $table_name . ' DROP COLUMN "' . $column_name . '"';
2151 _sql($sql, $errored, $error_ary);
2155 if (version_compare(sqlite_libversion(), '3.0') == -1)
2160 WHERE type = 'table'
2161 AND name = '{$table_name}'
2162 ORDER BY type DESC, name;";
2163 $result = $db->sql_query($sql);
2170 $row = $db->sql_fetchrow($result);
2171 $db->sql_freeresult($result);
2173 $db->sql_transaction('begin');
2175 // Create a backup table and populate it, destroy the existing one
2176 $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
2177 $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
2178 $db->sql_query('DROP TABLE ' . $table_name);
2180 preg_match('#\((.*)\)#s', $row['sql'], $matches);
2182 $new_table_cols = trim($matches[1]);
2183 $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
2184 $column_list = array();
2186 foreach ($old_table_cols as $declaration)
2188 $entities = preg_split('#\s+#', trim($declaration));
2189 if ($entities[0] == 'PRIMARY' ||
$entities[0] === $column_name)
2193 $column_list[] = $entities[0];
2196 $columns = implode(',', $column_list);
2198 $new_table_cols = $new_table_cols = preg_replace('/' . $column_name . '[^,]+(?:,|$)/m', '', $new_table_cols);
2200 // create a new table and fill it up. destroy the temp one
2201 $db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ');');
2202 $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
2203 $db->sql_query('DROP TABLE ' . $table_name . '_temp');
2205 $db->sql_transaction('commit');
2209 $sql = 'ALTER TABLE ' . $table_name . ' DROP COLUMN ' . $column_name;
2210 _sql($sql, $errored, $error_ary);
2216 function sql_index_drop($dbms, $index_name, $table_name)
2218 global $dbms_type_map, $db;
2219 global $errored, $error_ary;
2224 $sql = 'DROP INDEX ' . $table_name . '.' . $index_name;
2225 _sql($sql, $errored, $error_ary);
2230 $sql = 'DROP INDEX ' . $index_name . ' ON ' . $table_name;
2231 _sql($sql, $errored, $error_ary);
2238 $sql = 'DROP INDEX ' . $table_name . '_' . $index_name;
2239 _sql($sql, $errored, $error_ary);
2244 function sql_create_primary_key($dbms, $table_name, $column)
2246 global $dbms_type_map, $db;
2247 global $errored, $error_ary;
2253 $sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
2254 _sql($sql, $errored, $error_ary);
2258 $sql = "ALTER TABLE [{$table_name}] WITH NOCHECK ADD ";
2259 $sql .= "CONSTRAINT [PK_{$table_name}] PRIMARY KEY CLUSTERED (";
2260 $sql .= '[' . implode("],\n\t\t[", $column) . ']';
2261 $sql .= ') ON [PRIMARY]';
2262 _sql($sql, $errored, $error_ary);
2267 $sql = 'ALTER TABLE ' . $table_name . ' ADD PRIMARY KEY (' . implode(', ', $column) . ')';
2268 _sql($sql, $errored, $error_ary);
2272 $sql = 'ALTER TABLE ' . $table_name . 'add CONSTRAINT pk_' . $table_name . ' PRIMARY KEY (' . implode(', ', $column) . ')';
2273 _sql($sql, $errored, $error_ary);
2279 WHERE type = 'table'
2280 AND name = '{$table_name}'
2281 ORDER BY type DESC, name;";
2282 $result = _sql($sql, $errored, $error_ary);
2289 $row = $db->sql_fetchrow($result);
2290 $db->sql_freeresult($result);
2292 $db->sql_transaction('begin');
2294 // Create a backup table and populate it, destroy the existing one
2295 $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
2296 $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
2297 $db->sql_query('DROP TABLE ' . $table_name);
2299 preg_match('#\((.*)\)#s', $row['sql'], $matches);
2301 $new_table_cols = trim($matches[1]);
2302 $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
2303 $column_list = array();
2305 foreach ($old_table_cols as $declaration)
2307 $entities = preg_split('#\s+#', trim($declaration));
2308 if ($entities[0] == 'PRIMARY')
2312 $column_list[] = $entities[0];
2315 $columns = implode(',', $column_list);
2317 // create a new table and fill it up. destroy the temp one
2318 $db->sql_query('CREATE TABLE ' . $table_name . ' (' . $new_table_cols . ', PRIMARY KEY (' . implode(', ', $column) . '));');
2319 $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
2320 $db->sql_query('DROP TABLE ' . $table_name . '_temp');
2322 $db->sql_transaction('commit');
2327 function sql_create_unique_index($dbms, $index_name, $table_name, $column)
2329 global $dbms_type_map, $db;
2330 global $errored, $error_ary;
2338 $sql = 'CREATE UNIQUE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
2339 _sql($sql, $errored, $error_ary);
2344 $sql = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
2345 _sql($sql, $errored, $error_ary);
2349 $sql = 'CREATE UNIQUE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
2350 _sql($sql, $errored, $error_ary);
2355 function sql_create_index($dbms, $index_name, $table_name, $column)
2357 global $dbms_type_map, $db;
2358 global $errored, $error_ary;
2366 $sql = 'CREATE INDEX ' . $table_name . '_' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
2367 _sql($sql, $errored, $error_ary);
2372 $sql = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ')';
2373 _sql($sql, $errored, $error_ary);
2377 $sql = 'CREATE INDEX ' . $index_name . ' ON ' . $table_name . '(' . implode(', ', $column) . ') ON [PRIMARY]';
2378 _sql($sql, $errored, $error_ary);
2383 // List all of the indices that belong to a table,
2387 function sql_list_index($dbms, $table_name)
2389 global $dbms_type_map, $db;
2390 global $errored, $error_ary;
2392 $index_array = array();
2394 if ($dbms == 'mssql')
2396 $sql = "EXEC sp_statistics '$table_name'";
2397 $result = $db->sql_query($sql);
2398 while ($row = $db->sql_fetchrow($result))
2400 if ($row['TYPE'] == 3)
2402 $index_array[] = $row['INDEX_NAME'];
2405 $db->sql_freeresult($result);
2412 $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
2414 WHERE RDB\$RELATION_NAME = " . strtoupper($table_name) . "
2415 AND RDB\$UNIQUE_FLAG IS NULL
2416 AND RDB\$FOREIGN_KEY IS NULL";
2417 $col = 'index_name';
2421 $sql = "SELECT ic.relname as index_name
2422 FROM pg_class bc, pg_class ic, pg_index i
2423 WHERE (bc.oid = i.indrelid)
2424 AND (ic.oid = i.indexrelid)
2425 AND (bc.relname = '" . $table_name . "')
2426 AND (i.indisunique != 't')
2427 AND (i.indisprimary != 't')";
2428 $col = 'index_name';
2434 FROM ' . $table_name;
2439 $sql = "SELECT index_name
2441 WHERE table_name = '" . $table_name . "'
2442 AND generated = 'N'";
2446 $sql = "PRAGMA index_info('" . $table_name . "');";
2451 $result = $db->sql_query($sql);
2452 while ($row = $db->sql_fetchrow($result))
2454 if (($dbms == 'mysql_40' ||
$dbms == 'mysql_41') && !$row['Non_unique'])
2465 $row[$col] = substr($row[$col], strlen($table_name) +
1);
2469 $index_array[] = $row[$col];
2471 $db->sql_freeresult($result);
2474 return array_map('strtolower', $index_array);
2477 // This is totally fake, never use it
2478 // it exists only to mend bad update functions introduced
2481 function sql_list_fake($dbms, $table_name)
2483 global $dbms_type_map, $db;
2484 global $errored, $error_ary;
2486 $index_array = array();
2488 if ($dbms == 'mssql')
2490 $sql = "EXEC sp_statistics '$table_name'";
2491 $result = $db->sql_query($sql);
2492 while ($row = $db->sql_fetchrow($result))
2494 if ($row['TYPE'] == 3)
2496 $index_array[] = $row['INDEX_NAME'];
2499 $db->sql_freeresult($result);
2506 $sql = "SELECT LOWER(RDB\$INDEX_NAME) as index_name
2508 WHERE RDB\$RELATION_NAME = " . strtoupper($table_name) . "
2509 AND RDB\$UNIQUE_FLAG IS NULL
2510 AND RDB\$FOREIGN_KEY IS NULL";
2511 $col = 'index_name';
2515 $sql = "SELECT ic.relname as index_name
2516 FROM pg_class bc, pg_class ic, pg_index i
2517 WHERE (bc.oid = i.indrelid)
2518 AND (ic.oid = i.indexrelid)
2519 AND (bc.relname = '" . $table_name . "')
2520 AND (i.indisunique != 't')
2521 AND (i.indisprimary != 't')";
2522 $col = 'index_name';
2528 FROM ' . $table_name;
2533 $sql = "SELECT index_name
2535 WHERE table_name = '" . $table_name . "'
2536 AND generated = 'N'";
2540 $sql = "PRAGMA index_info('" . $table_name . "');";
2545 $result = $db->sql_query($sql);
2546 while ($row = $db->sql_fetchrow($result))
2548 if (($dbms == 'mysql_40' ||
$dbms == 'mysql_41') && !$row['Non_unique'])
2553 $index_array[] = $row[$col];
2555 $db->sql_freeresult($result);
2558 return array_map('strtolower', $index_array);
2562 * Change column type (not name!)
2564 function sql_column_change($dbms, $table_name, $column_name, $column_data)
2566 global $dbms_type_map, $db;
2567 global $errored, $error_ary;
2569 $column_data = prepare_column_data($dbms, $column_data, $table_name, $column_name);
2575 $sql = 'ALTER TABLE "' . $table_name . '" ALTER COLUMN "' . $column_name . '" TYPE ' . ' ' . $column_data['column_type_sql'];
2576 _sql($sql, $errored, $error_ary);
2580 $sql = 'ALTER TABLE [' . $table_name . '] ALTER COLUMN [' . $column_name . '] ' . $column_data['column_type_sql'];
2581 _sql($sql, $errored, $error_ary);
2586 $sql = 'ALTER TABLE `' . $table_name . '` CHANGE `' . $column_name . '` `' . $column_name . '` ' . $column_data['column_type_sql'];
2587 _sql($sql, $errored, $error_ary);
2591 $sql = 'ALTER TABLE ' . $table_name . ' MODIFY ' . $column_name . ' ' . $column_data['column_type_sql'];
2592 _sql($sql, $errored, $error_ary);
2596 $sql = 'ALTER TABLE ' . $table_name . ' ';
2598 $sql_array = array();
2599 $sql_array[] = 'ALTER COLUMN ' . $column_name . ' TYPE ' . $column_data['column_type'];
2601 if (isset($column_data['null']))
2603 if ($column_data['null'] == 'NOT NULL')
2605 $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET NOT NULL';
2607 else if ($column_data['null'] == 'NULL')
2609 $sql_array[] = 'ALTER COLUMN ' . $column_name . ' DROP NOT NULL';
2613 if (isset($column_data['default']))
2615 $sql_array[] = 'ALTER COLUMN ' . $column_name . ' SET DEFAULT ' . $column_data['default'];
2618 // we don't want to double up on constraints if we change different number data types
2619 if (isset($column_data['constraint']))
2621 $constraint_sql = "SELECT consrc as constraint_data
2622 FROM pg_constraint, pg_class bc
2623 WHERE conrelid = bc.oid
2624 AND bc.relname = '{$table_name}'
2627 FROM pg_constraint as c, pg_inherits as i
2628 WHERE i.inhrelid = pg_constraint.conrelid
2629 AND c.conname = pg_constraint.conname
2630 AND c.consrc = pg_constraint.consrc
2631 AND c.conrelid = i.inhparent
2634 $constraint_exists = false;
2636 $result = $db->sql_query($constraint_sql);
2637 while ($row = $db->sql_fetchrow($result))
2639 if (trim($row['constraint_data']) == trim($column_data['constraint']))
2641 $constraint_exists = true;
2645 $db->sql_freeresult($result);
2647 if (!$constraint_exists)
2649 $sql_array[] = 'ADD ' . $column_data['constraint'];
2653 $sql .= implode(', ', $sql_array);
2655 _sql($sql, $errored, $error_ary);
2662 WHERE type = 'table'
2663 AND name = '{$table_name}'
2664 ORDER BY type DESC, name;";
2665 $result = _sql($sql, $errored, $error_ary);
2672 $row = $db->sql_fetchrow($result);
2673 $db->sql_freeresult($result);
2675 $db->sql_transaction('begin');
2677 // Create a temp table and populate it, destroy the existing one
2678 $db->sql_query(preg_replace('#CREATE\s+TABLE\s+"?' . $table_name . '"?#i', 'CREATE TEMPORARY TABLE ' . $table_name . '_temp', $row['sql']));
2679 $db->sql_query('INSERT INTO ' . $table_name . '_temp SELECT * FROM ' . $table_name);
2680 $db->sql_query('DROP TABLE ' . $table_name);
2682 preg_match('#\((.*)\)#s', $row['sql'], $matches);
2684 $new_table_cols = trim($matches[1]);
2685 $old_table_cols = preg_split('/,(?![\s\w]+\))/m', $new_table_cols);
2686 $column_list = array();
2688 foreach ($old_table_cols as $key => $declaration)
2690 $entities = preg_split('#\s+#', trim($declaration));
2691 $column_list[] = $entities[0];
2692 if ($entities[0] == $column_name)
2694 $old_table_cols[$key] = $column_name . ' ' . $column_data['column_type_sql'];
2698 $columns = implode(',', $column_list);
2700 // create a new table and fill it up. destroy the temp one
2701 $db->sql_query('CREATE TABLE ' . $table_name . ' (' . implode(',', $old_table_cols) . ');');
2702 $db->sql_query('INSERT INTO ' . $table_name . ' (' . $columns . ') SELECT ' . $columns . ' FROM ' . $table_name . '_temp;');
2703 $db->sql_query('DROP TABLE ' . $table_name . '_temp');
2705 $db->sql_transaction('commit');
2711 function utf8_new_clean_string($text)
2713 static $homographs = array();
2714 static $utf8_case_fold_nfkc = '';
2715 if (empty($homographs))
2717 global $phpbb_root_path, $phpEx;
2718 if (!function_exists('utf8_case_fold_nfkc') ||
!file_exists($phpbb_root_path . 'includes/utf/data/confusables.' . $phpEx))
2720 if (!file_exists($phpbb_root_path . 'install/data/confusables.' . $phpEx))
2723 trigger_error(sprintf($lang['UPDATE_REQUIRES_FILE'], $phpbb_root_path . 'install/data/confusables.' . $phpEx), E_USER_ERROR
);
2725 $homographs = include($phpbb_root_path . 'install/data/confusables.' . $phpEx);
2726 $utf8_case_fold_nfkc = 'utf8_new_case_fold_nfkc';
2730 $homographs = include($phpbb_root_path . 'includes/utf/data/confusables.' . $phpEx);
2731 $utf8_case_fold_nfkc = 'utf8_case_fold_nfkc';
2735 $text = $utf8_case_fold_nfkc($text);
2736 $text = strtr($text, $homographs);
2737 // Other control characters
2738 $text = preg_replace('#(?:[\x00-\x1F\x7F]+|(?:\xC2[\x80-\x9F])+)#', '', $text);
2740 // we can use trim here as all the other space characters should have been turned
2741 // into normal ASCII spaces by now