2 /***************************************************************************
5 * begin : Wed Sep 05 2001
6 * copyright : (C) 2001 The phpBB Group
7 * email : support@phpbb.com
9 * $Id: upgrade.php,v 1.1.2.10 2003/03/18 23:24:01 acydburn Exp $
11 ****************************************************************************/
13 /***************************************************************************
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 ***************************************************************************/
22 define('IN_PHPBB', true);
24 $phpbb_root_path = './../';
26 if ( !defined('INSTALLING') )
28 error_reporting (E_ERROR | E_WARNING | E_PARSE); // This will NOT report uninitialized variables
29 set_magic_quotes_runtime(0); // Disable magic_quotes_runtime
32 // If we are being called from the install script then we don't need these
33 // as they are already included.
35 include($phpbb_root_path . 'extension.inc');
36 include($phpbb_root_path . 'config.'.$phpEx);
37 include($phpbb_root_path . 'includes/constants.'.$phpEx);
38 include($phpbb_root_path . 'includes/functions.'.$phpEx);
40 if( defined("PHPBB_INSTALLED") )
42 redirect("../index.$phpEx");
47 // Force the DB type to be MySQL
51 include($phpbb_root_path . 'includes/db.'.$phpEx);
52 include($phpbb_root_path . 'includes/bbcode.'.$phpEx);
53 include($phpbb_root_path . 'includes/functions_search.'.$phpEx);
55 set_time_limit(0); // Unlimited execution time
76 function common_header()
79 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
82 <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
83 <meta http-equiv="Content-Style-Type" content="text/css">
84 <style type="text/css">
86 /* Specifiy background images for selected styles
87 This can't be done within the external style sheet as NS4 sees image paths relative to
88 the page which called the style sheet (i.e. this page in the root phpBB directory)
89 whereas all other browsers see image paths relative to the style sheet. Stupid NS again!
91 th { background-image: url('../templates/subSilver/images/cellpic3.gif') }
92 td.cat { background-image: url('../templates/subSilver/images/cellpic1.gif') }
93 td.rowpic { background-image: url('../templates/subSilver/images/cellpic2.jpg'); background-repeat: repeat-y }
94 td.catHead,td.catSides,td.catLeft,td.catRight,td.catBottom { background-image: url('../templates/subSilver/images/cellpic1.gif') }
96 font,th,td,p,body { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11pt }
97 a:link,a:active,a:visited { font-family: Verdana, Arial, Helvetica, sans-serif; color : #006699; font-size:11pt }
98 a:hover { font-family: Verdana, Arial, Helvetica, sans-serif; text-decoration: underline; color : #DD6900; font-size:11pt }
99 hr { height: 0px; border: solid #D1D7DC 0px; border-top-width: 1px;}
101 .maintitle,h1,h2 {font-weight: bold; font-size: 22px; font-family: "Trebuchet MS",Verdana, Arial, Helvetica, sans-serif; text-decoration: none; line-height : 120%; color : #000000;}
105 /* Import the fancy styles for IE only (NS4.x doesn't use the @import function) */
106 @import url("../templates/subSilver/formIE.css");
110 <body bgcolor="#FFFFFF" text="#000000" link="#006699" vlink="#5584AA">
112 <table width="100%" border="0" cellspacing="0" cellpadding="10" align="center">
114 <td><table width="100%" border="0" cellspacing="0" cellpadding="0">
116 <td><img src="../templates/subSilver/images/logo_phpBB.gif" border="0" alt="Forum Home" vspace="1" /></td>
117 <td align="center" width="100%" valign="middle"><span class="maintitle">Upgrading to phpBB 2.0</span></td>
129 function common_footer()
141 function query($sql, $errormsg)
145 if ( !($result = $db->sql_query($sql)) )
147 print "<br><font color=\"red\">\n";
148 print "$errormsg<br>";
150 $sql_error = $db->sql_error();
151 print $sql_error['code'] .": ". $sql_error['message']. "<br>\n";
153 print "<pre>$sql</pre>";
164 function smiley_replace($text = '')
168 static $search, $replace;
170 // Did we get the smiley info in a previous call?
171 if ( !is_array($search) )
173 $sql = "SELECT code, smile_url
175 $result = query($sql, "Unable to get list of smilies from the DB");
177 $smilies = $db->sql_fetchrowset($result);
178 @usort($smilies, 'smiley_sort');
182 for($i = 0; $i < count($smilies); $i++)
184 $search[] = '/<IMG SRC=".*?\/' . phpbb_preg_quote($smilies[$i]['smile_url'], '/') .'">/i';
185 $replace[] = $smilies[$i]['code'];
189 return ( $text != '' ) ? preg_replace($search, $replace, $text) : '';
193 function get_schema()
195 global $table_prefix;
197 $schemafile = file('schemas/mysql_schema.sql');
200 for($i=0; $i < count($schemafile); $i++)
202 $line = $schemafile[$i];
204 if ( preg_match('/^CREATE TABLE (\w+)/i', $line, $matches) )
206 // Start of a new table definition, set some variables and go to the next line.
208 // Replace the 'phpbb_' prefix by the user defined prefix.
209 $table = str_replace('phpbb_', $table_prefix, $matches[1]);
210 $table_def[$table] = "CREATE TABLE $table (\n";
214 if ( preg_match('/^\);/', $line) )
216 // End of the table definition
217 // After this we will skip everything until the next 'CREATE' line
219 $table_def[$table] .= ')'; // We don't need the closing semicolon
222 if ( $tabledata == 1 )
224 // We are inside a table definition, parse this line.
225 // Add the current line to the complete table definition:
226 $table_def[$table] .= $line;
227 if ( preg_match('/^\s*(\w+)\s+(\w+)\(([\d,]+)\)(.*)$/', $line, $matches) )
229 // This is a column definition
230 $field = $matches[1];
234 preg_match('/DEFAULT (NULL|\'.*?\')[,\s](.*)$/i', $matches[4], $match);
235 $default = $match[1];
237 $notnull = ( preg_match('/NOT NULL/i', $matches[4]) ) ? 1 : 0;
238 $auto_increment = ( preg_match('/auto_increment/i', $matches[4]) ) ? 1 : 0;
240 $field_def[$table][$field] = array(
243 'default' => $default,
244 'notnull' => $notnull,
245 'auto_increment' => $auto_increment
249 if ( preg_match('/\s*PRIMARY\s+KEY\s*\((.*)\).*/', $line, $matches) )
252 $key_def[$table]['PRIMARY'] = $matches[1];
254 else if ( preg_match('/\s*KEY\s+(\w+)\s*\((.*)\)/', $line, $matches) )
257 $key_def[$table][$matches[1]] = $matches[2];
259 else if ( preg_match('/^\s*(\w+)\s*(.*?),?\s*$/', $line, $matches) )
262 $create_def[$table][$matches[1]] = $matches[2];
266 // It's a bird! It's a plane! It's something we didn't expect ;(
271 $schema['field_def'] = $field_def;
272 $schema['table_def'] = $table_def;
273 $schema['create_def'] = $create_def;
274 $schema['key_def'] = $key_def;
279 function get_inserts()
281 global $table_prefix;
283 $insertfile = file('schemas/mysql_basic.sql');
285 for($i = 0; $i < count($insertfile); $i++)
287 if ( preg_match('/(INSERT INTO (\w+)\s.*);/i', str_replace('phpbb_', $table_prefix, $insertfile[$i]), $matches) )
289 $returnvalue[$matches[2]][] = $matches[1];
296 function lock_tables($state, $tables= '')
300 if ( is_array($tables) )
302 $tables = join(' WRITE, ', $tables);
305 query("LOCK TABLES $tables WRITE", "Couldn't do: $sql");
309 query("UNLOCK TABLES", "Couldn't unlock all tables");
313 function output_table_content($content)
315 echo $content . "\n";
321 // Nathan's bbcode2 conversion routines
323 function bbdecode($message)
326 $code_start_html = '<!-- BBCode Start --><TABLE BORDER=0 ALIGN=CENTER WIDTH=85%><TR><TD><font size=-1>Code:</font><HR></TD></TR><TR><TD><FONT SIZE=-1><PRE>';
327 $code_end_html = '</PRE></FONT></TD></TR><TR><TD><HR></TD></TR></TABLE><!-- BBCode End -->';
328 $message = str_replace($code_start_html, '[code]', $message);
329 $message = str_replace($code_end_html, '[/code]', $message);
332 $quote_start_html = '<!-- BBCode Quote Start --><TABLE BORDER=0 ALIGN=CENTER WIDTH=85%><TR><TD><font size=-1>Quote:</font><HR></TD></TR><TR><TD><FONT SIZE=-1><BLOCKQUOTE>';
333 $quote_end_html = '</BLOCKQUOTE></FONT></TD></TR><TR><TD><HR></TD></TR></TABLE><!-- BBCode Quote End -->';
334 $message = str_replace($quote_start_html, '[quote]', $message);
335 $message = str_replace($quote_end_html, '[/quote]', $message);
338 $message = preg_replace("#<!-- BBCode Start --><B>(.*?)</B><!-- BBCode End -->#s", "[b]\\1[/b]", $message);
339 $message = preg_replace("#<!-- BBCode Start --><I>(.*?)</I><!-- BBCode End -->#s", "[i]\\1[/i]", $message);
341 // Undo [url] (long form)
342 $message = preg_replace("#<!-- BBCode u2 Start --><A HREF=\"([a-z]+?://)(.*?)\" TARGET=\"_blank\">(.*?)</A><!-- BBCode u2 End -->#s", "[url=\\1\\2]\\3[/url]", $message);
344 // Undo [url] (short form)
345 $message = preg_replace("#<!-- BBCode u1 Start --><A HREF=\"([a-z]+?://)(.*?)\" TARGET=\"_blank\">(.*?)</A><!-- BBCode u1 End -->#s", "[url]\\3[/url]", $message);
348 $message = preg_replace("#<!-- BBCode Start --><A HREF=\"mailto:(.*?)\">(.*?)</A><!-- BBCode End -->#s", "[email]\\1[/email]", $message);
351 $message = preg_replace("#<!-- BBCode Start --><IMG SRC=\"(.*?)\" BORDER=\"0\"><!-- BBCode End -->#s", "[img]\\1[/img]", $message);
353 // Undo lists (unordered/ordered)
356 $message = str_replace('<!-- BBCode --><LI>', '[*]', $message);
359 $message = str_replace('<!-- BBCode ulist Start --><UL>', '[list]', $message);
362 $message = preg_replace('#<!-- BBCode olist Start --><OL TYPE=([A1])>#si', "[list=\\1]", $message);
365 $message = str_replace('</UL><!-- BBCode ulist End -->', '[/list]', $message);
366 $message = str_replace('</OL><!-- BBCode olist End -->', '[/list]', $message);
372 // Alternative for in_array() which is only available in PHP4
374 function inarray($needle, $haystack)
376 for( $i = 0 ; $i < sizeof($haystack) ; $i++ )
378 if ( $haystack[$i] == $needle )
387 function end_step($next)
389 print "<hr /><a href=\"$PHP_SELF?next=$next\">Next step: <b>$next</b></a><br /><br />\n";
398 // Start at the beginning if the user hasn't specified a specific starting point.
400 $next = ( isset($HTTP_GET_VARS['next']) ) ? $HTTP_GET_VARS['next'] : 'start';
402 // If debug is set we'll do all steps in one go.
405 // Parse the MySQL schema file into some arrays.
406 $schema = get_schema();
408 $table_def = $schema['table_def'];
409 $field_def = $schema['field_def'];
410 $key_def = $schema['key_def'];
411 $create_def = $schema['create_def'];
414 // Get mysql_basic data
416 $inserts = get_inserts();
430 end_step('initial_drops');
432 case 'initial_drops':
433 print " * Dropping sessions and themes tables :: ";
436 query("DROP TABLE sessions", "Couldn't drop table 'sessions'");
437 query("DROP TABLE themes", "Couldn't drop table 'themes'");
439 print "<span class=\"ok\"><b>OK</b></span><br />\n";
441 end_step('mod_old_tables');
443 case 'mod_old_tables':
445 "banlist" => "banlist",
446 "catagories" => "categories",
447 "config" => "old_config",
448 "forums" => "forums",
449 "disallow" => "disallow",
451 "posts_text" => "posts_text",
452 "priv_msgs" => "privmsgs",
454 "smiles" => "smilies",
455 "topics" => "topics",
460 while( list($old, $new) = each($modtables) )
462 $result = query("SHOW INDEX FROM $old", "Couldn't get list of indices for table $old");
464 while( $row = $db->sql_fetchrow($result) )
466 $index = $row['Key_name'];
467 if ( $index != 'PRIMARY' )
469 query("ALTER TABLE $old DROP INDEX $index", "Couldn't DROP INDEX $old.$index");
474 $new = $table_prefix . $new;
476 print " * Renaming '$old' to '$new' :: ";
478 query("ALTER TABLE $old RENAME $new", "Failed to rename $old to $new");
479 print "<span class=\"ok\"><b>OK</b></span><br />\n";
482 end_step('create_tables');
484 case 'create_tables':
485 // Create array with tables in 'old' database
486 $result = query('SHOW TABLES', "Couldn't get list of current tables");
488 while( $table = $db->sql_fetchrow($result) )
490 $currenttables[] = $table[0];
493 // Check what tables we need to CREATE
494 while( list($table, $definition) = each($table_def) )
496 if ( !inarray($table, $currenttables) )
498 print " * Creating $table :: ";
500 query($definition, "Couldn't create table $table");
502 print "<span class=\"ok\"><b>OK</b></span><br />\n";
506 end_step('create_config');
508 case 'create_config':
509 print " * Inserting new values into new layout config table :: ";
512 while( list($table, $inserts_table) = each($inserts) )
514 if ( $table == CONFIG_TABLE )
516 $per_pct = ceil( count($inserts_table) / 40 );
519 while( list($nr, $insert) = each($inserts_table) )
521 query($insert, "Couldn't insert value into config table");
524 if ( $inc == $per_pct )
534 print " <span class=\"ok\"><b>OK</b></span><br />\n";
536 end_step('convert_config');
538 case 'convert_config':
539 print " * Converting configuration table :: ";
542 FROM $table_prefix" . "old_config";
543 $result = query($sql, "Couldn't get info from old config table");
545 $oldconfig = $db->sql_fetchrow($result);
548 // We don't need several original config types and two others
549 // have changed name ... so take account of this.
551 $ignore_configs = array("selected", "admin_passwd", "override_themes", "allow_sig");
552 $rename_configs = array(
553 "email_from" => "board_email",
554 "email_sig" => "board_email_sig"
557 while( list($name, $value) = each($oldconfig) )
564 if ( !inarray($name, $ignore_configs) )
566 $name = ( !empty($rename_configs[$name]) ) ? $rename_configs[$name] : $name;
568 // phpBB 1.x has some problems with escaping strings in the database. Try to correct for
569 // this by removing all slashes and then escaping once.
570 $sql = "REPLACE INTO " . CONFIG_TABLE . " (config_name, config_value)
571 VALUES ('$name', '".addslashes(stripslashes(stripslashes($value)))."')";
572 query($sql, "Couldn't update config table with values from old config table");
576 $sql = "UPDATE " . CONFIG_TABLE . "
577 SET config_value = 'dutch'
578 WHERE config_name = 'default_lang' && config_value = 'nederlands'";
579 query($sql, "Couldn't rename 'nederlands' to 'dutch' in config table");
581 print "<span class=\"ok\"><b>OK</b></span><br />\n";
582 end_step('convert_ips');
586 POSTS_TABLE => array(
588 'field' => 'poster_ip'
590 PRIVMSGS_TABLE => array(
592 'field' => 'poster_ip'
594 BANLIST_TABLE => array(
600 lock_tables(1, array(POSTS_TABLE, PRIVMSGS_TABLE, BANLIST_TABLE));
603 while( list($table, $data_array) = each($names) )
605 $sql = "SELECT MAX(" . $data_array['id'] . ") AS max_id
607 $result = query($sql, "Couldn't obtain ip data from $table (" . $fields . ")");
609 $row = $db->sql_fetchrow($result);
611 $maxid = $row['max_id'];
613 for($i = 0; $i <= $maxid; $i += $batchsize)
616 $batchend = $i + $batchsize;
618 $field_id = $data_array['id'];
619 $field = $data_array['field'];
621 print " * Converting IP format '" . $field . "' / '$table' ( $batchstart to $batchend ) :: ";
624 $sql = "SELECT $field_id, $field
629 $result = query($sql, "Couldn't obtain ip data from $table (" . $fields . ")");
631 $per_pct = ceil( $db->sql_numrows($result) / 40 );
634 while( $row = $db->sql_fetchrow($result) )
636 $sql = "UPDATE $table
637 SET $field = '" . encode_ip($row[$field]) . "'
638 WHERE $field_id = " . $row[$field_id];
639 query($sql, "Couldn't convert IP format of $field in $table with $field_id of " . $rowset[$field_id]);
642 if ( $inc == $per_pct )
650 print " <span class=\"ok\"><b>OK</b></span><br />\n";
655 end_step('convert_dates');
657 case 'convert_dates':
659 POSTS_TABLE => array('post_time'),
660 TOPICS_TABLE => array('topic_time'),
661 PRIVMSGS_TABLE => array('msg_time')
664 lock_tables(1, array(POSTS_TABLE, TOPICS_TABLE, PRIVMSGS_TABLE));
666 while( list($table, $fields) = each($names) )
668 print " * Converting date format of $fields[$i] in $table :: ";
671 for($i = 0; $i < count($fields); $i++)
673 $sql = "UPDATE $table
674 SET " . $fields[$i] . " = UNIX_TIMESTAMP(" . $fields[$i] . ")";
675 query($sql, "Couldn't convert date format of $table(" . $fields[$i] . ")");
678 print "<span class=\"ok\"><b>OK</b></span><br />\n";
682 end_step('fix_addslashes');
684 case 'fix_addslashes':
685 $slashfields[TOPICS_TABLE] = array('topic_title');
686 $slashfields[FORUMS_TABLE] = array('forum_desc', 'forum_name');
687 $slashfields[CATEGORIES_TABLE] = array('cat_title');
688 $slashfields[WORDS_TABLE] = array('word', 'replacement');
689 $slashfields[RANKS_TABLE] = array('rank_title');
690 $slashfields[DISALLOW_TABLE] = array('disallow_username');
702 lock_tables(1, array(TOPICS_TABLE, FORUMS_TABLE, CATEGORIES_TABLE, WORDS_TABLE, RANKS_TABLE, DISALLOW_TABLE, SMILIES_TABLE));
704 while( list($table, $fields) = each($slashfields) )
706 print " * Removing slashes from $table table :: ";
709 while( list($nr, $field) = each($fields) )
712 while( list($search, $replace) = each($slashes) )
714 $sql = "UPDATE $table
715 SET $field = REPLACE($field, '" . addslashes($search) . "', '" . addslashes($replace) . "')";
716 query($sql, "Couldn't remove extraneous slashes from the old data.");
720 print "<span class=\"ok\"><b>OK</b></span><br />\n";
724 end_step('remove_topics');
726 case 'remove_topics':
727 print " * Removing posts with no corresponding topics :: ";
730 $sql = "SELECT p.post_id
731 FROM " . POSTS_TABLE . " p
732 LEFT JOIN " . TOPICS_TABLE . " t ON p.topic_id = t.topic_id
733 WHERE t.topic_id IS NULL";
734 $result = query($sql, "Couldn't obtain list of deleted topics");
736 $post_total = $db->sql_numrows($result);
740 $post_id_ary = array();
741 while( $row = $db->sql_fetchrow($result) )
743 $post_id_ary[] = $row['post_id'];
746 $sql = "DELETE FROM " . POSTS_TABLE . "
747 WHERE post_id IN (" . implode(", ", $post_id_ary) . ")";
748 query($sql, "Couldn't update posts to remove deleted user poster_id values");
750 $sql = "DELETE FROM " . POSTS_TEXT_TABLE . "
751 WHERE post_id IN (" . implode(", ", $post_id_ary) . ")";
752 query($sql, "Couldn't update posts to remove deleted user poster_id values");
755 echo "<span class=\"ok\"><b>OK</b></span> ( Removed $post_total posts )<br />\n";
756 end_step('convert_users');
758 case 'convert_users':
760 // Completely remove old soft-deleted users
762 $sql = "DELETE FROM " . USERS_TABLE . "
763 WHERE user_level = -1";
764 query($sql, "Couldn't delete old soft-deleted users");
766 $sql = "SELECT COUNT(*) AS total, MAX(user_id) AS maxid
767 FROM " . USERS_TABLE;
768 $result = query($sql, "Couldn't get max user_id.");
770 $row = $db->sql_fetchrow($result);
772 $totalposts = $row['total'];
773 $maxid = $row['maxid'];
775 $sql = "ALTER TABLE " . USERS_TABLE . "
776 ADD user_sig_bbcode_uid CHAR(10),
777 MODIFY user_sig text";
778 query($sql, "Couldn't add user_sig_bbcode_uid field to users table");
780 $super_mods = array();
784 for($i = -1; $i <= $maxid; $i += $batchsize)
787 $batchend = $i + $batchsize;
789 print " * Converting Users ( $batchstart to $batchend ) :: ";
793 FROM " . USERS_TABLE . "
797 $result = query($sql, "Couldn't get ". USERS_TABLE .".user_id $batchstart to $batchend");
799 // Array with user fields that we want to check for invalid data (to few characters)
800 $checklength = array(
810 lock_tables(1, array(USERS_TABLE, GROUPS_TABLE, USER_GROUP_TABLE, POSTS_TABLE));
812 $per_pct = ceil( $db->sql_numrows($result) / 40 );
815 while( $row = $db->sql_fetchrow($result) )
817 $sql = "INSERT INTO " . GROUPS_TABLE . " (group_name, group_description, group_single_user)
818 VALUES ('" . addslashes($row['username']) . "', 'Personal User', 1)";
819 query($sql, "Wasn't able to insert user ".$row['user_id']." into table ".GROUPS_TABLE);
821 $group_id = $db->sql_nextid();
823 $sql = "INSERT INTO " . USER_GROUP_TABLE . " (group_id, user_id, user_pending)
824 VALUES ($group_id, " . $row['user_id'] . ", 0)";
825 query($sql, "Wasn't able to insert user ".$row['user_id']." into table ".USER_GROUP_TABLE);
827 if ( is_int($row['user_regdate']) )
829 // We already converted this post to the new style BBcode, skip this post.
834 // Nathan's bbcode2 conversion
837 // undo 1.2.x encoding..
838 $row['user_sig'] = bbdecode(stripslashes($row['user_sig']));
839 $row['user_sig'] = undo_make_clickable($row['user_sig']);
840 $row['user_sig'] = str_replace("<BR>", "\n", $row['user_sig']);
843 $uid = make_bbcode_uid();
845 // do 2.x first-pass encoding..
846 $row['user_sig'] = bbencode_first_pass($row['user_sig'], $uid);
847 $row['user_sig'] = addslashes($row['user_sig']);
849 // Check for invalid info like '-' and '?' for a lot of fields
850 @reset($checklength);
851 while($field = each($checklength))
853 $row[$field[1]] = strlen($row[$field[1]]) < 3 ? '' : $row[$field[1]];
856 preg_match('/(.*?) (\d{1,2}), (\d{4})/', $row['user_regdate'], $parts);
857 $row['user_regdate'] = gmmktime(0, 0, 0, $months[$parts[1]], $parts[2], $parts[3]);
859 $website = $row['user_website'];
860 if ( substr(strtolower($website), 0, 7) != "http://" )
862 $website = "http://" . $website;
864 if( strtolower($website) == 'http://' )
868 $row['user_website'] = addslashes($website);
870 $row['user_icq'] = (ereg("^[0-9]+$", $row['user_icq'])) ? $row['user_icq'] : '';
871 @reset($checklength);
873 while($field = each($checklength))
875 if ( strlen($row[$field[1]]) < 3 )
877 $row[$field[1]] = '';
879 $row[$field[1]] = addslashes($row[$field[1]]);
883 // Is user a super moderator?
885 if( $row['user_level'] == 3 )
887 $super_mods[] = $row['user_id'];
890 $row['user_level'] = ( $row['user_level'] == 4 ) ? ADMIN : USER;
893 // Used to define a 'practical' group moderator user_id
894 // for super mods a little latter.
896 if( $first_admin == -2 && $row['user_level'] == ADMIN )
898 $first_admin = $row['user_id'];
902 // Dutch language files have been renamed from 'nederlands' to 'dutch'
904 if( $row['user_lang'] == 'nederlands' )
906 $row['user_lang'] = 'dutch';
909 $sql = "UPDATE " . USERS_TABLE . "
911 user_sig = '" . $row['user_sig'] . "',
912 user_sig_bbcode_uid = '$uid',
913 user_regdate = '" . $row['user_regdate'] . "',
914 user_website = '" . $row['user_website'] . "',
915 user_occ = '" . $row['user_occ'] . "',
916 user_email = '" . $row['user_email'] . "',
917 user_from = '" . $row['user_from'] . "',
918 user_intrest = '" . $row['user_intrest'] . "',
919 user_aim = '" . $row['user_aim'] . "',
920 user_yim = '" . $row['user_yim'] . "',
921 user_msnm = '" . $row['user_msnm'] . "',
922 user_level = '" . $row['user_level'] . "',
923 user_desmile = NOT(user_desmile),
926 WHERE user_id = " . $row['user_id'];
927 query($sql, "Couldn't update ".USERS_TABLE." table with new BBcode and regdate for user_id ".$row['user_id']);
930 if ( $inc == $per_pct )
938 // Set any non-standard (like) email addresses to nothing
939 // could do this above as a preg_ but this one query may
941 $sql = "UPDATE " . USERS_TABLE . "
943 WHERE user_email NOT REGEXP '^[a-zA-Z0-9_\+\.\-]+@.*[a-zA-Z0-9\-_]+\.[a-zA-Z]{2,}$'";
944 query($sql, "Couldn't update ".USERS_TABLE." table non-standard user_email entries");
946 print " <span class=\"ok\"><b>OK</b></span><br />\n";
952 // Handle super-mods, create hidden group for them
954 // Iterate trough access table
955 if( count($super_mods) && $first_admin != -2 )
957 print "\n<br />\n * Creating new group for super moderators :: ";
960 $sql = "INSERT INTO " . GROUPS_TABLE . " (group_type, group_name, group_description, group_moderator, group_single_user)
961 VALUES (" . GROUP_HIDDEN . ", 'Super Moderators', 'Converted super moderators', $first_admin, 0)";
962 $result = query($sql, "Couldn't create group for ".$row['forum_name']);
964 $group_id = $db->sql_nextid();
966 if ( $group_id <= 0 )
968 print "<font color=\"red\">Group creation failed. Aborting creation of groups...<br></font>\n";
972 print "<span class=\"ok\"><b>OK</b></span><br />\n";
974 print " * Updating auth_access for super moderator group :: ";
977 $sql = "SELECT forum_id
978 FROM " . FORUMS_TABLE;
979 $result = query($sql, "Couldn't obtain forum_id list");
981 while( $row = $db->sql_fetchrow($result) )
983 $sql = "INSERT INTO " . AUTH_ACCESS_TABLE . " (group_id, forum_id, auth_mod)
984 VALUES ($group_id, " . $row['forum_id'] . ", 1)";
985 $result_insert = query($sql, "Unable to set group auth access for super mods.");
988 for($i = 0; $i < count($super_mods); $i++)
990 $sql = "INSERT INTO " . USER_GROUP_TABLE . " (group_id, user_id, user_pending)
991 VALUES ($group_id, " . $super_mods[$i] . ", 0)";
992 query($sql, "Unable to add user_id $user_id to group_id $group_id (super mods)<br>\n");
995 print "<span class=\"ok\"><b>OK</b></span><br />\n";
998 end_step('convert_posts');
1000 case 'convert_posts':
1001 print " * Adding enable_sig field to " . POSTS_TABLE . " :: ";
1003 $sql = "ALTER TABLE " . POSTS_TABLE . "
1004 ADD enable_sig tinyint(1) DEFAULT '1' NOT NULL";
1005 $result = query($sql, "Couldn't add enable_sig field to " . POSTS_TABLE . ".");
1006 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1008 print " * Adding enable_bbcode field to " . POSTS_TEXT_TABLE . " :: ";
1010 $sql = "ALTER TABLE " . POSTS_TEXT_TABLE . "
1011 ADD enable_bbcode tinyint(1) DEFAULT '1' NOT NULL";
1012 $result = query($sql, "Couldn't add enable_bbcode field to " . POSTS_TABLE . ".");
1013 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1015 print " * Adding bbcode_uid field to " . POSTS_TEXT_TABLE . " :: ";
1017 $sql = "ALTER TABLE " . POSTS_TEXT_TABLE . "
1018 ADD bbcode_uid char(10) NOT NULL";
1019 $result = query($sql, "Couldn't add bbcode_uid field to " . POSTS_TABLE . ".");
1020 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1022 print " * Adding post_edit_time field to " . POSTS_TABLE . " :: ";
1024 $sql = "ALTER TABLE " . POSTS_TABLE . "
1025 ADD post_edit_time int(11)";
1026 $result = query($sql, "Couldn't add post_edit_time field to " . POSTS_TABLE . ".");
1027 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1029 print " * Adding post_edit_count field to " . POSTS_TABLE . " :: ";
1031 $sql = "ALTER TABLE " . POSTS_TABLE . "
1032 ADD post_edit_count smallint(5) UNSIGNED DEFAULT '0' NOT NULL";
1033 $result = query($sql, "Couldn't add post_edit_count field to " . POSTS_TABLE . ".");
1034 print "<span class=\"ok\"><b>OK</b></span><br />\n<br />\n";
1036 $sql = "SELECT COUNT(*) as total, MAX(post_id) as maxid
1037 FROM " . POSTS_TEXT_TABLE;
1038 $result = query($sql, "Couldn't get max post_id.");
1040 $maxid = $db->sql_fetchrow($result);
1042 $totalposts = $maxid['total'];
1043 $maxid = $maxid['maxid'];
1046 for($i = 0; $i <= $maxid; $i += $batchsize)
1048 $batchstart = $i + 1;
1049 $batchend = $i + $batchsize;
1051 print " * Converting BBcode ( $batchstart to $batchend ) :: ";
1055 FROM " . POSTS_TEXT_TABLE . "
1059 $result = query($sql, "Couldn't get ". POSTS_TEXT_TABLE .".post_id $batchstart to $batchend");
1061 lock_tables(1, array(POSTS_TEXT_TABLE, POSTS_TABLE));
1063 $per_pct = ceil( $db->sql_numrows($result) / 40 );
1066 while( $row = $db->sql_fetchrow($result) )
1068 if ( $row['bbcode_uid'] != '' )
1070 // We already converted this post to the new style BBcode, skip this post.
1075 // Nathan's bbcode2 conversion
1077 // undo 1.2.x encoding..
1078 $row['post_text'] = bbdecode(stripslashes($row['post_text']));
1079 $row['post_text'] = undo_make_clickable($row['post_text']);
1080 $row['post_text'] = str_replace('<BR>', "\n", $row['post_text']);
1083 $uid = make_bbcode_uid();
1085 // do 2.x first-pass encoding..
1086 $row['post_text'] = smiley_replace($row['post_text']);
1087 $row['post_text'] = bbencode_first_pass($row['post_text'], $uid);
1088 $row['post_text'] = addslashes($row['post_text']);
1091 if ( preg_match('/^(.*?)([\n]+<font size=\-1>\[ This message was .*?)$/s', $row['post_text'], $matches) )
1093 $row['post_text'] = $matches[1];
1094 $edit_info = $matches[2];
1096 $edit_times = count(explode(' message ', $edit_info)) - 1; // Taken from example for substr_count in annotated PHP manual
1098 if ( preg_match('/^.* by: (.*?) on (....)-(..)-(..) (..):(..) \]<\/font>/s', $edit_info, $matches) )
1100 $edited_user = $matches[1];
1101 $edited_time = gmmktime($matches[5], $matches[6], 0, $matches[3], $matches[4], $matches[2]);
1104 // This isn't strictly correct since 2.0 won't include and edit
1105 // statement if the edit wasn't by the user who posted ...
1107 $edited_sql = ", post_edit_time = $edited_time, post_edit_count = $edit_times";
1111 if ( preg_match("/^(.*?)\n-----------------\n.*$/is", $row['post_text'], $matches) )
1113 $row['post_text'] = $matches[1];
1118 $checksig = preg_replace('/\[addsig\]$/', '', $row['post_text']);
1119 $enable_sig = ( strlen($checksig) == strlen($row['post_text']) ) ? 0 : 1;
1122 $sql = "UPDATE " . POSTS_TEXT_TABLE . "
1123 SET post_text = '$checksig', bbcode_uid = '$uid'
1124 WHERE post_id = " . $row['post_id'];
1125 query($sql, "Couldn't update " . POSTS_TEXT_TABLE . " table with new BBcode for post_id :: " . $row['post_id']);
1127 $sql = "UPDATE " . POSTS_TABLE . "
1128 SET enable_sig = $enable_sig" . $edited_sql . "
1129 WHERE post_id = " . $row['post_id'];
1130 query($sql, "Couldn't update " . POSTS_TABLE . " table with signature status for post with post_id :: " . $row['post_id']);
1133 if ( $inc == $per_pct )
1141 print " <span class=\"ok\"><b>OK</b></span><br />\n";
1146 print "<br />\n * Updating poster_id for deleted users :: ";
1149 $sql = "SELECT DISTINCT p.post_id
1150 FROM " . POSTS_TABLE . " p
1151 LEFT JOIN " . USERS_TABLE . " u ON p.poster_id = u.user_id
1152 WHERE u.user_id IS NULL";
1153 $result = query($sql, "Couldn't obtain list of deleted users");
1155 $users_removed = $db->sql_numrows($result);
1157 if ( $users_removed )
1159 $post_id_ary = array();
1160 while( $row = $db->sql_fetchrow($result) )
1162 $post_id_ary[] = $row['post_id'];
1165 $sql = "UPDATE " . POSTS_TABLE . "
1166 SET poster_id = " . ANONYMOUS . ", enable_sig = 0
1167 WHERE post_id IN (" . implode(", ", $post_id_ary) . ")";
1168 query($sql, "Couldn't update posts to remove deleted user poster_id values");
1171 print "<span class=\"ok\"><b>OK</b></span> ( Removed $users_removed non-existent user references )<br />\n";
1173 end_step('convert_privmsgs');
1175 case 'convert_privmsgs':
1176 $sql = "SELECT COUNT(*) as total, max(msg_id) as maxid
1177 FROM " . PRIVMSGS_TABLE;
1178 $result = query($sql, "Couldn't get max privmsgs_id.");
1180 $maxid = $db->sql_fetchrow($result);
1182 $totalposts = $maxid['total'];
1183 $maxid = $maxid['maxid'];
1185 $sql = "ALTER TABLE " . PRIVMSGS_TABLE . "
1186 ADD privmsgs_subject VARCHAR(255),
1187 ADD privmsgs_attach_sig TINYINT(1) DEFAULT 1";
1188 query($sql, "Couldn't add privmsgs_subject field to " . PRIVMSGS_TABLE . " table");
1191 for($i = 0; $i <= $maxid; $i += $batchsize)
1193 $batchstart = $i + 1;
1194 $batchend = $i + $batchsize;
1196 print " * Converting Private Message ( $batchstart to $batchend ) :: ";
1200 FROM " . PRIVMSGS_TABLE . "
1204 $result = query($sql, "Couldn't get " . POSTS_TEXT_TABLE . " post_id $batchstart to $batchend");
1206 lock_tables(1, array(PRIVMSGS_TABLE, PRIVMSGS_TEXT_TABLE));
1208 $per_pct = ceil( $db->sql_numrows($result) / 40 );
1211 while( $row = $db->sql_fetchrow($result) )
1213 if ( $row['msg_text'] == NULL )
1215 // We already converted this post to the new style BBcode, skip this post.
1219 // Nathan's bbcode2 conversion
1221 // undo 1.2.x encoding..
1222 $row['msg_text'] = bbdecode(stripslashes($row['msg_text']));
1223 $row['msg_text'] = undo_make_clickable($row['msg_text']);
1224 $row['msg_text'] = str_replace("<BR>", "\n", $row['msg_text']);
1227 $uid = make_bbcode_uid();
1229 // do 2.x first-pass encoding..
1230 $row['msg_text'] = smiley_replace($row['msg_text']);
1231 $row['msg_text'] = bbencode_first_pass($row['msg_text'], $uid);
1233 $checksig = preg_replace('/\[addsig\]$/', '', $row['msg_text']);
1234 $enable_sig = (strlen($checksig) == strlen($row['msg_text'])) ? 0 : 1;
1236 if ( preg_match("/^(.*?)\n-----------------\n.*$/is", $checksig, $matches) )
1238 $checksig = $matches[1];
1242 $row['msg_text'] = $checksig;
1244 $row['msg_status'] = ($row['msg_status'] == 1) ? PRIVMSGS_READ_MAIL : PRIVMSGS_NEW_MAIL;
1246 // Subject contains first 60 characters of msg, remove any BBCode tags
1247 $subject = addslashes(strip_tags(substr($row['msg_text'], 0, 60)));
1248 $subject = preg_replace("/\[.*?\:(([a-z0-9]:)?)$uid.*?\]/si", "", $subject);
1250 $row['msg_text'] = addslashes($row['msg_text']);
1252 $sql = "INSERT INTO " . PRIVMSGS_TEXT_TABLE . " (privmsgs_text_id, privmsgs_bbcode_uid, privmsgs_text)
1253 VALUES ('" . $row['msg_id'] . "', '$uid', '" . $row['msg_text'] . "')";
1254 query($sql, "Couldn't insert PrivMsg text into " . PRIVMSGS_TEXT_TABLE . " table msg_id " . $row['msg_id']);
1256 $sql = "UPDATE " . PRIVMSGS_TABLE . "
1257 SET msg_text = NULL, msg_status = " . $row['msg_status'] . ", privmsgs_subject = '$subject', privmsgs_attach_sig = $enable_sig
1258 WHERE msg_id = " . $row['msg_id'];
1259 query($sql, "Couldn't update " . PRIVMSGS_TABLE . " table for msg_id " . $row['post_id']);
1262 if ( $inc == $per_pct )
1270 print " <span class=\"ok\"><b>OK</b></span><br />\n";
1274 end_step('convert_moderators');
1276 case 'convert_moderators';
1279 $result = query($sql, "Couldn't get list with all forum moderators");
1281 while( $row = $db->sql_fetchrow($result) )
1283 // Check if this moderator and this forum still exist
1284 $sql = "SELECT user_id
1285 FROM " . USERS_TABLE . ", " . FORUMS_TABLE . "
1286 WHERE user_id = " . $row['user_id'] . "
1287 AND forum_id = " . $row['forum_id'];
1288 $check_data = query($sql, "Couldn't check if user " . $row['user_id'] . " and forum " . $row['forum_id'] . " exist");
1290 if ( !($rowtest = $db->sql_fetchrow($check_data)) )
1292 // Either the moderator or the forum have been deleted, this line in forum_mods was redundant, skip it.
1296 $sql = "SELECT g.group_id
1297 FROM " . GROUPS_TABLE . " g, " . USER_GROUP_TABLE . " ug
1298 WHERE g.group_id = ug.group_id
1299 AND ug.user_id = " . $row['user_id'] . "
1300 AND g.group_single_user = 1";
1301 $insert_group = query($sql, "Couldn't get group number for user " . $row['user_id'] . ".");
1303 $group_id = $db->sql_fetchrow($insert_group);
1304 $group_id = $group_id['group_id'];
1306 print " * Adding moderator for forum " . $row['forum_id'] . " :: ";
1309 $sql = "INSERT INTO " . AUTH_ACCESS_TABLE . " (group_id, forum_id, auth_mod) VALUES ($group_id, ".$row['forum_id'].", 1)";
1310 query($sql, "Couldn't set moderator (user_id = " . $row['user_id'] . ") for forum " . $row['forum_id'] . ".");
1312 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1315 print " * Setting correct user_level for moderators ::";
1318 $sql = "SELECT DISTINCT u.user_id
1319 FROM " . USERS_TABLE . " u, " . USER_GROUP_TABLE . " ug, " . AUTH_ACCESS_TABLE . " aa
1320 WHERE aa.auth_mod = 1
1321 AND ug.group_id = aa.group_id
1322 AND u.user_id = ug.user_id
1323 AND u.user_level <> " . ADMIN;
1324 $result = query($sql, "Couldn't obtain list of moderators");
1326 if ( $row = $db->sql_fetchrow($result) )
1332 $ug_sql .= ( ( $ug_sql != '' ) ? ', ' : '' ) . $row['user_id'];
1334 while ( $row = $db->sql_fetchrow($result) );
1336 $sql = "UPDATE " . USERS_TABLE . "
1337 SET user_level = " . MOD . "
1338 WHERE user_id IN ($ug_sql)";
1339 query($sql, "Couldn't set moderator status for users");
1342 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1344 end_step('convert_privforums');
1346 case 'convert_privforums':
1347 $sql = "SELECT fa.*, f.forum_name
1348 FROM forum_access fa
1349 LEFT JOIN " . FORUMS_TABLE . " f ON fa.forum_id = f.forum_id
1350 ORDER BY fa.forum_id, fa.user_id";
1351 $forum_access = query($sql, "Couldn't get list with special forum access (forum_access)");
1354 while( $row = $db->sql_fetchrow($forum_access) )
1356 // Iterate trough access table
1357 if ( $row['forum_id'] != $forum_id )
1359 // This is a new forum, create new group.
1360 $forum_id = $row['forum_id'];
1362 print " * Creating new group for forum $forum_id :: ";
1365 $sql = "INSERT INTO " . GROUPS_TABLE . " (group_type, group_name, group_description, group_moderator, group_single_user)
1366 VALUES (" . GROUP_HIDDEN . ", '" . addslashes($row['forum_name']) . " Group', 'Converted Private Forum Group', " . $row['user_id'] . ", 0)";
1367 $result = query($sql, "Couldn't create group for ".$row['forum_name']);
1369 $group_id = $db->sql_nextid();
1371 if ( $group_id <= 0 )
1373 print "<font color=\"red\">Group creation failed. Aborting creation of groups...<br></font>\n";
1377 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1379 print " * Creating auth_access group for forum $forum_id :: ";
1382 $sql = "INSERT INTO " . AUTH_ACCESS_TABLE . " (group_id, forum_id, auth_view, auth_read, auth_post, auth_reply, auth_edit, auth_delete, auth_sticky, auth_announce, auth_vote, auth_pollcreate)
1383 VALUES ($group_id, $forum_id, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1)";
1384 $result = query($sql, "Unable to set group auth access.");
1386 if ( $db->sql_affectedrows($result) <= 0 )
1388 print "<font color=\"red\">Group creation failed. Aborting creation of groups...</font><br>\n";
1392 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1395 // Add user to the group
1396 $user_id = $row['user_id'];
1398 $sql = "INSERT INTO " . USER_GROUP_TABLE . " (group_id, user_id, user_pending)
1399 VALUES ($group_id, $user_id, 0)";
1400 query($sql, "Unable to add user_id $user_id to group_id $group_id <br>\n");
1403 end_step('update_schema');
1405 case 'update_schema':
1407 $table_prefix . "users" => array(
1408 "user_interests" => "user_intrest",
1409 "user_allowsmile" => "user_desmile",
1410 "user_allowhtml" => "user_html",
1411 "user_allowbbcode" => "user_bbcode",
1412 "user_style" => "user_theme"
1414 $table_prefix . "privmsgs" => array(
1415 "privmsgs_id" => "msg_id",
1416 "privmsgs_from_userid" => "from_userid",
1417 "privmsgs_to_userid" => "to_userid",
1418 "privmsgs_date" => "msg_time",
1419 "privmsgs_ip" => "poster_ip",
1420 "privmsgs_type" => "msg_status"
1422 $table_prefix . "smilies" => array(
1423 "smilies_id" => "id"
1427 $schema = get_schema();
1429 $table_def = $schema['table_def'];
1430 $field_def = $schema['field_def'];
1432 // Loop tables in schema
1433 while (list($table, $table_def) = @each($field_def))
1435 // Loop fields in table
1436 print " * Updating table '$table' :: ";
1441 $result = query($sql, "Can't get definition of current $table table");
1443 while( $row = $db->sql_fetchrow($result) )
1445 $current_fields[] = $row['Field'];
1448 $alter_sql = "ALTER TABLE $table ";
1449 while (list($field, $definition) = each($table_def))
1453 // Skip empty fields if any (shouldn't be needed)
1457 $type = $definition['type'];
1458 $size = $definition['size'];
1460 $default = isset($definition['default']) ? "DEFAULT " . $definition['default'] : '';
1462 $notnull = $definition['notnull'] == 1 ? 'NOT NULL' : '';
1464 $auto_increment = $definition['auto_increment'] == 1 ? 'auto_increment' : '';
1466 $oldfield = isset($rename[$table][$field]) ? $rename[$table][$field] : $field;
1468 if ( !inarray($field, $current_fields) && $oldfield == $field )
1470 // If the current is not a key of $current_def and it is not a field that is
1471 // to be renamed then the field doesn't currently exist.
1472 $changes[] = " ADD $field " . $create_def[$table][$field];
1476 $changes[] = " CHANGE $oldfield $field " . $create_def[$table][$field];
1480 $alter_sql .= join(',', $changes);
1482 unset($current_fields);
1486 $result = query($sql, "Couldn't get list of indices for table $table");
1490 while( $row = $db->sql_fetchrow($result) )
1492 $indices[] = $row['Key_name'];
1495 while ( list($key_name, $key_field) = each($key_def[$table]) )
1497 if ( !inarray($key_name, $indices) )
1499 $alter_sql .= ($key_name == 'PRIMARY') ? ", ADD PRIMARY KEY ($key_field)" : ", ADD INDEX $key_name ($key_field)";
1502 query($alter_sql, "Couldn't alter table $table");
1504 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1508 end_step('convert_forums');
1510 case 'convert_forums':
1512 FROM " . FORUMS_TABLE;
1513 $result = query($sql, "Couldn't get list with all forums");
1515 while( $row = $db->sql_fetchrow($result) )
1517 print " * Converting forum '" . $row['forum_name'] . "' :: ";
1520 // forum_access: (only concerns posting)
1521 // 1 = Registered users only
1522 // 2 = Anonymous Posting
1523 // 3 = Moderators/Administrators only
1524 switch( $row['forum_access'] )
1527 // Public forum, no anonymous posting
1528 $auth_view = AUTH_ALL;
1529 $auth_read = AUTH_ALL;
1530 $auth_post = AUTH_REG;
1531 $auth_reply = AUTH_REG;
1532 $auth_edit = AUTH_REG;
1533 $auth_delete = AUTH_REG;
1534 $auth_vote = AUTH_REG;
1535 $auth_pollcreate = AUTH_REG;
1536 $auth_sticky = AUTH_MOD;
1537 $auth_announce = AUTH_MOD;
1540 $auth_post = AUTH_ALL;
1541 $auth_reply = AUTH_ALL;
1542 $auth_edit = AUTH_REG;
1543 $auth_delete = AUTH_REG;
1544 $auth_vote = AUTH_ALL;
1545 $auth_pollcreate = AUTH_ALL;
1546 $auth_sticky = AUTH_MOD;
1547 $auth_announce = AUTH_MOD;
1550 $auth_post = AUTH_MOD;
1551 $auth_reply = AUTH_MOD;
1552 $auth_edit = AUTH_MOD;
1553 $auth_delete = AUTH_MOD;
1554 $auth_vote = AUTH_MOD;
1555 $auth_pollcreate = AUTH_MOD;
1556 $auth_sticky = AUTH_MOD;
1557 $auth_announce = AUTH_MOD;
1561 // Old auth structure:
1562 // forum_type: (only concerns viewing)
1565 switch( $row['forum_type'] )
1568 $auth_view = AUTH_ALL;
1569 $auth_read = AUTH_ALL;
1573 // Make it really private ...
1575 $auth_view = AUTH_ACL;
1576 $auth_read = AUTH_ACL;
1577 $auth_post = AUTH_ACL;
1578 $auth_reply = AUTH_ACL;
1579 $auth_edit = AUTH_ACL;
1580 $auth_delete = AUTH_ACL;
1581 $auth_vote = AUTH_ACL;
1582 $auth_pollcreate = AUTH_ACL;
1583 $auth_sticky = AUTH_ACL;
1584 $auth_announce = AUTH_MOD;
1588 $sql = "UPDATE " . FORUMS_TABLE . " SET
1589 auth_view = $auth_view,
1590 auth_read = $auth_read,
1591 auth_post = $auth_post,
1592 auth_reply = $auth_reply,
1593 auth_edit = $auth_edit,
1594 auth_delete = $auth_delete,
1595 auth_vote = $auth_vote,
1596 auth_pollcreate = $auth_pollcreate,
1597 auth_sticky = $auth_sticky,
1598 auth_announce = $auth_announce
1599 WHERE forum_id = ". $row['forum_id'];
1600 query($sql, "Was unable to update forum permissions!");
1602 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1605 end_step('insert_themes');
1607 case 'insert_themes':
1608 print " * Inserting new values into themes table :: ";
1611 while( list($table, $inserts_table) = each($inserts) )
1613 if ( $table == THEMES_TABLE )
1615 $per_pct = ceil( count($inserts_table) / 40 );
1618 while( list($nr, $insert) = each($inserts_table) )
1620 query($insert, "Couldn't insert value into " . THEMES_TABLE);
1623 if ( $inc == $per_pct )
1633 print " <span class=\"ok\"><b>OK</b></span><br />\n";
1634 end_step('update_topics');
1636 case 'update_topics':
1637 $sql = "SELECT MAX(topic_id) AS max_topic
1638 FROM " . TOPICS_TABLE;
1639 $result = query($sql, "Couldn't get max topic id");
1641 $row = $db->sql_fetchrow($result);
1643 $maxid = $row['max_topic'];
1645 lock_tables(1, array(TOPICS_TABLE, POSTS_TABLE));
1648 for($i = 0; $i <= $maxid; $i += $batchsize)
1650 $batchstart = $i + 1;
1651 $batchend = $i + $batchsize;
1653 print " * Setting topic first post_id ( $batchstart to $batchend ) :: ";
1656 $sql = "SELECT MIN(post_id) AS first_post_id, topic_id
1657 FROM " . POSTS_TABLE . "
1662 ORDER BY topic_id ASC";
1663 $result = query($sql, "Couldn't get post id data");
1665 $per_pct = ceil( $db->sql_numrows($result) / 40 );
1668 if ( $row = $db->sql_fetchrow($result) )
1672 $sql = "UPDATE " . TOPICS_TABLE . "
1673 SET topic_first_post_id = " . $row['first_post_id'] . "
1674 WHERE topic_id = " . $row['topic_id'];
1675 query($sql, "Couldn't update topic first post id in topic :: $topic_id");
1678 if ( $inc == $per_pct )
1685 while ( $row = $db->sql_fetchrow($result) );
1688 print " <span class=\"ok\"><b>OK</b></span><br />\n";
1692 end_step('final_configuration');
1694 case 'final_configuration':
1696 // Update forum last post information
1698 $sql = "SELECT forum_id, forum_name
1699 FROM " . FORUMS_TABLE;
1700 $f_result = query($sql, "Couldn't obtain forum_ids");
1702 while( $forum_row = $db->sql_fetchrow($f_result) )
1704 print " * Updating '" . $forum_row['forum_name'] . "' post info :: ";
1707 $id = $forum_row['forum_id'];
1709 $sql = "SELECT MIN(p.post_id) AS first_post, MAX(p.post_id) AS last_post
1710 FROM " . POSTS_TABLE . " p, " . TOPICS_TABLE . " t
1711 WHERE p.forum_id = $id
1712 AND p.topic_id = t.topic_id";
1713 $result = query($sql, "Could not get post ID forum post information :: $id");
1715 if ( $row = $db->sql_fetchrow($result) )
1717 $first_post = ( $row['first_post'] ) ? $row['first_post'] : 0;
1718 $last_post = ($row['last_post']) ? $row['last_post'] : 0;
1726 $sql = "SELECT COUNT(post_id) AS total
1727 FROM " . POSTS_TABLE . "
1728 WHERE forum_id = $id";
1729 $result = query($sql, "Could not get post count forum post information :: $id");
1731 if ( $row = $db->sql_fetchrow($result) )
1733 $total_posts = ($row['total']) ? $row['total'] : 0;
1740 $sql = "SELECT COUNT(topic_id) AS total
1741 FROM " . TOPICS_TABLE . "
1742 WHERE forum_id = $id
1743 AND topic_status <> " . TOPIC_MOVED;
1744 $result = query($sql, "Could not get topic count forum post information :: $id");
1746 if ( $row = $db->sql_fetchrow($result) )
1748 $total_topics = ($row['total']) ? $row['total'] : 0;
1755 $sql = "UPDATE " . FORUMS_TABLE . "
1756 SET forum_last_post_id = $last_post, forum_posts = $total_posts, forum_topics = $total_topics
1757 WHERE forum_id = $id";
1758 query($sql, "Could not update forum post information :: $id");
1760 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1763 print "<br />\n * Update default user and finalise configuration :: ";
1767 // Update the default admin user with their information.
1769 $sql = "SELECT MIN(user_regdate) AS oldest_time
1770 FROM " . USERS_TABLE . "
1771 WHERE user_regdate > 0 AND user_id > 0";
1772 $result = query($sql, "Couldn't obtain oldest post time");
1774 $row = $db->sql_fetchrow($result);
1776 $sql = "INSERT INTO " . $table_prefix . "config (config_name, config_value)
1777 VALUES ('board_startdate', " . $row['oldest_time'] . ")";
1778 query($sql, "Couldn't insert board_startdate");
1780 $sql = "UPDATE " . $table_prefix . "config
1781 SET config_value = '" . $server_name . "'
1782 WHERE config_name = 'server_name'
1783 OR config_name = 'cookie_domain'";
1784 query($sql, "Couldn't insert Board Server domain");
1786 $sql = "UPDATE " . $table_prefix . "config
1787 SET config_value = '" . $server_port . "'
1788 WHERE config_name = 'server_port'";
1789 query($sql, "Couldn't insert Board server port");
1791 $sql = "UPDATE " . $table_prefix . "config
1792 SET config_value = '" . $board_email . "'
1793 WHERE config_name = 'board_email'";
1794 query($sql, "Couldn't insert Board admin email");
1796 $sql = "UPDATE " . $table_prefix . "config
1797 SET config_value = '" . $script_path . "'
1798 WHERE config_name = 'script_path'";
1799 query($sql, "Couldn't insert Board script path");
1802 // Change session table to HEAP if MySQL version matches
1804 $sql = "SELECT VERSION() AS mysql_version";
1805 $result = query($sql, "Couldn't obtain MySQL Version");
1807 $row = $db->sql_fetchrow($result);
1809 $version = $row['mysql_version'];
1811 if ( preg_match("/^(3\.23)|(4\.)/", $version) )
1813 $sql = "ALTER TABLE " . $table_prefix . "sessions
1814 TYPE=HEAP MAX_ROWS=500";
1815 $db->sql_query($sql);
1818 echo "<span class=\"ok\"><b>OK</b></span><br />\n";
1819 end_step('drop_fields');
1823 BANLIST_TABLE => array("ban_start", "ban_end", "ban_time_type"),
1824 FORUMS_TABLE => array("forum_access", "forum_moderator", "forum_type"),
1825 PRIVMSGS_TABLE => array("msg_text"),
1826 RANKS_TABLE => array("rank_max"),
1827 SMILIES_TABLE => array("emotion"),
1828 TOPICS_TABLE => array("topic_notify")
1831 while( list($table, $field_data) = each($fields) )
1833 for($i = 0; $i < count($field_data); $i++)
1835 print " * Drop field '" . $field_data[$i] . "' in '$table' :: ";
1838 $sql = "ALTER TABLE $table
1839 DROP COLUMN " . $field_data[$i];
1840 query($sql, "Couldn't drop field :: " . $field_data[$i] . " from table :: $table");
1842 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1847 end_step('drop_tables');
1850 $drop_tables = array('access', 'forum_access', 'forum_mods', 'headermetafooter', 'whosonline', $table_prefix . 'old_config');
1852 for($i = 0; $i < count($drop_tables); $i++)
1854 print " * Dropping table '" . $drop_tables[$i] . "' :: ";
1857 $sql = "DROP TABLE " . $drop_tables[$i];
1858 query($sql, "Couldn't drop table :: " . $drop_tables[$i]);
1860 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1863 end_step('fulltext_search_indexing');
1865 case 'fulltext_search_indexing':
1867 // Generate search word list
1869 // Fetch a batch of posts_text entries
1871 $sql = "SELECT COUNT(*) as total, MAX(post_id) as max_post_id
1872 FROM " . POSTS_TEXT_TABLE;
1873 $result = query($sql, "Couldn't get post count totals");
1875 $max_post_id = $db->sql_fetchrow($result);
1877 $totalposts = $max_post_id['total'];
1878 $max_post_id = $max_post_id['max_post_id'];
1879 $per_percent = round(( $totalposts / 500 ) * 10);
1881 $postcounter = ( !isset($HTTP_GET_VARS['batchstart']) ) ? 0 : $HTTP_GET_VARS['batchstart'];
1883 $batchsize = 150; // Process this many posts per loop
1887 for(;$postcounter <= $max_post_id; $postcounter += $batchsize)
1889 $batchstart = $postcounter + 1;
1890 $batchend = $postcounter + $batchsize;
1893 print " * Fulltext Indexing ( $batchstart to $batchend ) :: ";
1897 FROM " . POSTS_TEXT_TABLE ."
1901 $posts_result = query($sql, "Couldn't obtain post_text");
1903 $per_pct = ceil( $db->sql_numrows($posts_result) / 40 );
1906 if ( $row = $db->sql_fetchrow($posts_result) )
1910 add_search_words('global', $row['post_id'], $row['post_text'], $row['post_subject']);
1913 if ( $inc == $per_pct )
1920 while( $row = $db->sql_fetchrow($posts_result) );
1923 $db->sql_freeresult($posts_result);
1925 // Remove common words after the first 2 batches and after every 4th batch after that.
1926 if ( $batchcount % 4 == 3 )
1928 remove_common('global', 4/10);
1931 print " <span class=\"ok\"><b>OK</b></span><br />\n";
1934 echo "\n<br /><br />\n\n<font size=\"+3\"><b>UPGRADE COMPLETED</b></font><br />\n";
1938 print "<br />If the upgrade completed without error you may click <a href=\"./../index.$phpEx\">Here</a> to proceed to the index<br />";