home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 April (DVD) / PCWorld_2008-04_DVD.iso / temadvd / phpbb / phpBB-2.0.22.exe / phpBB2 / install / upgrade.php < prev   
Encoding:
PHP Script  |  2006-12-19  |  56.1 KB  |  1,942 lines

  1. <?php
  2. /***************************************************************************
  3. *                                  upgrade.php
  4. *                              -------------------
  5. *     begin                : Wed Sep 05 2001
  6. *     copyright            : (C) 2001 The phpBB Group
  7. *     email                : support@phpbb.com
  8. *
  9. *     $Id: upgrade.php,v 1.1.2.10 2003/03/18 23:24:01 acydburn Exp $
  10. *
  11. ****************************************************************************/
  12.  
  13. /***************************************************************************
  14.  *
  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.
  19.  *
  20.  ***************************************************************************/
  21.  
  22. define('IN_PHPBB', true);
  23.  
  24. $phpbb_root_path = './../';
  25.  
  26. if ( !defined('INSTALLING') )
  27. {
  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
  30.  
  31.     //
  32.     // If we are being called from the install script then we don't need these
  33.     // as they are already included.
  34.     //
  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);
  39.  
  40.     if( defined("PHPBB_INSTALLED") )
  41.     {
  42.         redirect("../index.$phpEx");
  43.     }
  44. }
  45.  
  46. //
  47. // Force the DB type to be MySQL
  48. //
  49. $dbms = 'mysql';
  50.  
  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);
  54.  
  55. set_time_limit(0); // Unlimited execution time
  56.  
  57. $months = array(
  58.     'Jan' => 1,
  59.     'Feb' => 2,
  60.     'Mar' => 3,
  61.     'Apr' => 4,
  62.     'May' => 5,
  63.     'Jun' => 6,
  64.     'Jul' => 7,
  65.     'Aug' => 8,
  66.     'Sep' => 9,
  67.     'Sept' => 9,
  68.     'Oct' => 10,
  69.     'Nov' => 11,
  70.     'Dec' => 12
  71. );
  72.  
  73. // ---------------
  74. // Begin functions
  75. //
  76. function common_header()
  77. {
  78. ?>
  79. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  80. <html>
  81. <head>
  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">
  85. <!--
  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!
  90. */
  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') }
  95.  
  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;}
  100.  
  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;}
  102.  
  103. .ok {color:green}
  104.  
  105. /* Import the fancy styles for IE only (NS4.x doesn't use the @import function) */
  106. @import url("../templates/subSilver/formIE.css"); 
  107. -->
  108. </style>
  109. </head>
  110. <body bgcolor="#FFFFFF" text="#000000" link="#006699" vlink="#5584AA">
  111.  
  112. <table width="100%" border="0" cellspacing="0" cellpadding="10" align="center"> 
  113.     <tr>
  114.         <td><table width="100%" border="0" cellspacing="0" cellpadding="0">
  115.             <tr>
  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>
  118.             </tr>
  119.         </table></td>
  120.     </tr>
  121. </table>
  122.  
  123. <br clear="all" />
  124.  
  125. <?
  126.     return;
  127. }
  128.  
  129. function common_footer()
  130. {
  131. ?>
  132.  
  133. <br clear="all" />
  134.  
  135. </body>
  136. </html>
  137. <?
  138.     return;
  139. }
  140.  
  141. function query($sql, $errormsg)
  142. {
  143.     global $db;
  144.  
  145.     if ( !($result = $db->sql_query($sql)) )
  146.     {
  147.         print "<br><font color=\"red\">\n";
  148.         print "$errormsg<br>";
  149.  
  150.         $sql_error = $db->sql_error();
  151.         print $sql_error['code'] .": ". $sql_error['message']. "<br>\n";
  152.  
  153.         print "<pre>$sql</pre>";
  154.         print "</font>\n";
  155.  
  156.         return FALSE;
  157.     }
  158.     else
  159.     {
  160.         return $result;
  161.     }
  162. }
  163.  
  164. function smiley_replace($text = '')
  165. {
  166.     global $db;
  167.  
  168.     static $search, $replace;
  169.  
  170.     // Did we get the smiley info in a previous call?
  171.     if ( !is_array($search) )
  172.     {
  173.         $sql = "SELECT code, smile_url
  174.             FROM smiles";
  175.         $result = query($sql, "Unable to get list of smilies from the DB");
  176.  
  177.         $smilies = $db->sql_fetchrowset($result);
  178.         @usort($smilies, 'smiley_sort');
  179.  
  180.         $search = array();
  181.         $replace = array();
  182.         for($i = 0; $i < count($smilies); $i++)
  183.         {
  184.             $search[] = '/<IMG SRC=".*?\/' . phpbb_preg_quote($smilies[$i]['smile_url'], '/') .'">/i';
  185.             $replace[] = $smilies[$i]['code'];
  186.         }
  187.     }
  188.  
  189.     return ( $text != '' ) ? preg_replace($search, $replace, $text) : '';
  190.     
  191. }
  192.  
  193. function get_schema()
  194. {
  195.     global $table_prefix;
  196.  
  197.     $schemafile = file('schemas/mysql_schema.sql');
  198.     $tabledata = 0;
  199.  
  200.     for($i=0; $i < count($schemafile); $i++)
  201.     {
  202.         $line = $schemafile[$i];
  203.  
  204.         if ( preg_match('/^CREATE TABLE (\w+)/i', $line, $matches) )
  205.         {
  206.             // Start of a new table definition, set some variables and go to the next line.
  207.             $tabledata = 1;
  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";
  211.             continue;
  212.         }
  213.  
  214.         if ( preg_match('/^\);/', $line) )
  215.         {
  216.             // End of the table definition
  217.             // After this we will skip everything until the next 'CREATE' line
  218.             $tabledata = 0;
  219.             $table_def[$table] .= ')'; // We don't need the closing semicolon
  220.         }
  221.  
  222.         if ( $tabledata == 1 )
  223.         {
  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) )
  228.             {
  229.                 // This is a column definition
  230.                 $field = $matches[1];
  231.                 $type = $matches[2];
  232.                 $size = $matches[3];
  233.  
  234.                 preg_match('/DEFAULT (NULL|\'.*?\')[,\s](.*)$/i', $matches[4], $match);
  235.                 $default = $match[1];
  236.  
  237.                 $notnull = ( preg_match('/NOT NULL/i', $matches[4]) ) ? 1 : 0;
  238.                 $auto_increment = ( preg_match('/auto_increment/i', $matches[4]) ) ? 1 : 0;
  239.  
  240.                 $field_def[$table][$field] = array(
  241.                     'type' => $type,
  242.                     'size' => $size,
  243.                     'default' => $default,
  244.                     'notnull' => $notnull,
  245.                     'auto_increment' => $auto_increment
  246.                 );
  247.             }
  248.             
  249.             if ( preg_match('/\s*PRIMARY\s+KEY\s*\((.*)\).*/', $line, $matches) )
  250.             {
  251.                 // Primary key
  252.                 $key_def[$table]['PRIMARY'] = $matches[1];
  253.             }
  254.             else if ( preg_match('/\s*KEY\s+(\w+)\s*\((.*)\)/', $line, $matches) )
  255.             {
  256.                 // Normal key
  257.                 $key_def[$table][$matches[1]] = $matches[2];
  258.             }
  259.             else if ( preg_match('/^\s*(\w+)\s*(.*?),?\s*$/', $line, $matches) )
  260.             {
  261.                 // Column definition
  262.                 $create_def[$table][$matches[1]] = $matches[2];
  263.             }
  264.             else
  265.             {
  266.                 // It's a bird! It's a plane! It's something we didn't expect ;(
  267.             }
  268.         }
  269.     }
  270.  
  271.     $schema['field_def'] = $field_def;
  272.     $schema['table_def'] = $table_def;
  273.     $schema['create_def'] = $create_def;
  274.     $schema['key_def'] = $key_def;
  275.  
  276.     return $schema;
  277. }
  278.  
  279. function get_inserts()
  280. {
  281.     global $table_prefix;
  282.  
  283.     $insertfile = file('schemas/mysql_basic.sql');
  284.  
  285.     for($i = 0; $i < count($insertfile); $i++)
  286.     {
  287.         if ( preg_match('/(INSERT INTO (\w+)\s.*);/i', str_replace('phpbb_', $table_prefix, $insertfile[$i]), $matches) )
  288.         {
  289.             $returnvalue[$matches[2]][] = $matches[1];
  290.         }
  291.     }
  292.  
  293.     return $returnvalue;
  294. }
  295.  
  296. function lock_tables($state, $tables= '')
  297. {
  298.     if ( $state == 1 )
  299.     {
  300.         if ( is_array($tables) )
  301.         {
  302.             $tables = join(' WRITE, ', $tables);
  303.         }
  304.  
  305.         query("LOCK TABLES $tables WRITE", "Couldn't do: $sql");
  306.     }
  307.     else
  308.     {
  309.         query("UNLOCK TABLES", "Couldn't unlock all tables");
  310.     }
  311. }
  312.  
  313. function output_table_content($content)
  314. {
  315.     echo $content . "\n";
  316.  
  317.     return;
  318. }
  319.  
  320. //
  321. // Nathan's bbcode2 conversion routines
  322. //
  323. function bbdecode($message)
  324. {
  325.     // Undo [code]
  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);
  330.  
  331.     // Undo [quote]
  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);
  336.  
  337.     // Undo [b] and [i]
  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);
  340.  
  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);
  343.  
  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);
  346.  
  347.     // Undo [email]
  348.     $message = preg_replace("#<!-- BBCode Start --><A HREF=\"mailto:(.*?)\">(.*?)</A><!-- BBCode End -->#s", "[email]\\1[/email]", $message);
  349.  
  350.     // Undo [img]
  351.     $message = preg_replace("#<!-- BBCode Start --><IMG SRC=\"(.*?)\" BORDER=\"0\"><!-- BBCode End -->#s", "[img]\\1[/img]", $message);
  352.  
  353.     // Undo lists (unordered/ordered)
  354.  
  355.     // <li> tags:
  356.     $message = str_replace('<!-- BBCode --><LI>', '[*]', $message);
  357.  
  358.     // [list] tags:
  359.     $message = str_replace('<!-- BBCode ulist Start --><UL>', '[list]', $message);
  360.  
  361.     // [list=x] tags:
  362.     $message = preg_replace('#<!-- BBCode olist Start --><OL TYPE=([A1])>#si', "[list=\\1]", $message);
  363.  
  364.     // [/list] tags:
  365.     $message = str_replace('</UL><!-- BBCode ulist End -->', '[/list]', $message);
  366.     $message = str_replace('</OL><!-- BBCode olist End -->', '[/list]', $message);
  367.  
  368.     return $message;
  369. }
  370.  
  371. //
  372. // Alternative for in_array() which is only available in PHP4
  373. //
  374. function inarray($needle, $haystack)
  375.     for( $i = 0 ; $i < sizeof($haystack) ; $i++ )
  376.     { 
  377.         if ( $haystack[$i] == $needle )
  378.         { 
  379.             return true; 
  380.         } 
  381.     } 
  382.  
  383.     return false; 
  384. }
  385.  
  386. function end_step($next)
  387. {
  388.     print "<hr /><a href=\"$PHP_SELF?next=$next\">Next step: <b>$next</b></a><br /><br />\n";
  389.     exit;
  390. }
  391. //
  392. // End functions
  393. // -------------
  394.  
  395.  
  396. //
  397. // Start at the beginning if the user hasn't specified a specific starting point.
  398. //
  399. $next = ( isset($HTTP_GET_VARS['next']) ) ? $HTTP_GET_VARS['next'] : 'start';
  400.  
  401. // If debug is set we'll do all steps in one go.
  402. $debug = 1;
  403.  
  404. // Parse the MySQL schema file into some arrays.
  405. $schema = get_schema();
  406.  
  407. $table_def = $schema['table_def'];
  408. $field_def = $schema['field_def'];
  409. $key_def = $schema['key_def'];
  410. $create_def = $schema['create_def'];
  411.  
  412. //
  413. // Get mysql_basic data
  414. //
  415. $inserts = get_inserts();
  416.  
  417. //
  418. // Get smiley data
  419. //
  420. smiley_replace();
  421.  
  422. common_header();
  423.  
  424. if ( !empty($next) )
  425. {
  426.     switch($next)
  427.     {
  428.         case 'start':
  429.             end_step('initial_drops');
  430.  
  431.         case 'initial_drops':
  432.             print " * Dropping sessions and themes tables :: ";
  433.             flush();
  434.  
  435.             query("DROP TABLE sessions", "Couldn't drop table 'sessions'");
  436.             query("DROP TABLE themes", "Couldn't drop table 'themes'");   
  437.  
  438.             print "<span class=\"ok\"><b>OK</b></span><br />\n";
  439.  
  440.             end_step('mod_old_tables');
  441.  
  442.         case 'mod_old_tables':
  443.             $modtables = array(
  444.                 "banlist" => "banlist",
  445.                 "catagories" => "categories",
  446.                 "config" => "old_config",
  447.                 "forums" => "forums",
  448.                 "disallow" => "disallow",
  449.                 "posts" => "posts",
  450.                 "posts_text" => "posts_text",
  451.                 "priv_msgs" => "privmsgs",
  452.                 "ranks" => "ranks",
  453.                 "smiles" => "smilies",
  454.                 "topics" => "topics",
  455.                 "users" => "users",
  456.                 "words" => "words"
  457.             );
  458.  
  459.             while( list($old, $new) = each($modtables) )
  460.             {
  461.                 $result = query("SHOW INDEX FROM $old", "Couldn't get list of indices for table $old");
  462.  
  463.                 while( $row = $db->sql_fetchrow($result) )
  464.                 {
  465.                     $index = $row['Key_name'];
  466.                     if ( $index != 'PRIMARY' )
  467.                     {
  468.                         query("ALTER TABLE $old DROP INDEX $index", "Couldn't DROP INDEX $old.$index");
  469.                     }
  470.                 }
  471.  
  472.                 // Rename table
  473.                 $new = $table_prefix . $new;
  474.  
  475.                 print " * Renaming '$old' to '$new' :: ";
  476.                 flush();
  477.                 query("ALTER TABLE $old RENAME $new", "Failed to rename $old to $new");
  478.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  479.                 
  480.             }
  481.             end_step('create_tables');
  482.             
  483.         case 'create_tables':
  484.             // Create array with tables in 'old' database
  485.             $result = query('SHOW TABLES', "Couldn't get list of current tables");
  486.  
  487.             while( $table = $db->sql_fetchrow($result) )
  488.             {
  489.                 $currenttables[] = $table[0];
  490.             }
  491.             
  492.             // Check what tables we need to CREATE
  493.             while( list($table, $definition) = each($table_def) )
  494.             {
  495.                 if ( !inarray($table, $currenttables) )
  496.                 {
  497.                     print " * Creating $table :: ";
  498.  
  499.                     query($definition, "Couldn't create table $table");
  500.  
  501.                     print "<span class=\"ok\"><b>OK</b></span><br />\n";
  502.                 }
  503.             }
  504.             
  505.             end_step('create_config');
  506.             
  507.         case 'create_config':
  508.             print " * Inserting new values into new layout config table :: ";
  509.  
  510.             @reset($inserts);
  511.             while( list($table, $inserts_table) = each($inserts) )
  512.             {
  513.                 if ( $table == CONFIG_TABLE )
  514.                 {
  515.                     $per_pct = ceil( count($inserts_table) / 40 );
  516.                     $inc = 0;
  517.  
  518.                     while( list($nr, $insert) = each($inserts_table) )
  519.                     {
  520.                         query($insert, "Couldn't insert value into config table");
  521.  
  522.                         $inc++;
  523.                         if ( $inc == $per_pct )
  524.                         {
  525.                             print ".";
  526.                             flush();
  527.                             $inc = 0;
  528.                         }
  529.                     }
  530.                 }
  531.             }
  532.  
  533.             print " <span class=\"ok\"><b>OK</b></span><br />\n";
  534.  
  535.             end_step('convert_config');
  536.             
  537.         case 'convert_config':
  538.             print " * Converting configuration table :: ";
  539.  
  540.             $sql = "SELECT * 
  541.                 FROM $table_prefix" . "old_config";
  542.             $result = query($sql, "Couldn't get info from old config table");
  543.  
  544.             $oldconfig = $db->sql_fetchrow($result);
  545.  
  546.             //
  547.             // We don't need several original config types and two others
  548.             // have changed name ... so take account of this.
  549.             //
  550.             $ignore_configs = array("selected", "admin_passwd", "override_themes", "allow_sig");
  551.             $rename_configs = array(
  552.                 "email_from" => "board_email",
  553.                 "email_sig" => "board_email_sig"
  554.             );
  555.  
  556.             while( list($name, $value) = each($oldconfig) )
  557.             {
  558.                 if ( is_int($name) )
  559.                 {
  560.                     continue;
  561.                 }
  562.  
  563.                 if ( !inarray($name, $ignore_configs) )
  564.                 {
  565.                     $name = ( !empty($rename_configs[$name]) ) ? $rename_configs[$name] : $name;
  566.                     
  567.                     // phpBB 1.x has some problems with escaping strings in the database. Try to correct for
  568.                     // this by removing all slashes and then escaping once.
  569.                     $sql = "REPLACE INTO " . CONFIG_TABLE . " (config_name, config_value) 
  570.                         VALUES ('$name', '".addslashes(stripslashes(stripslashes($value)))."')";
  571.                     query($sql, "Couldn't update config table with values from old config table");
  572.                 }
  573.             }
  574.             
  575.             $sql = "UPDATE " . CONFIG_TABLE . " 
  576.                 SET config_value = 'dutch' 
  577.                 WHERE config_name = 'default_lang' && config_value = 'nederlands'";
  578.             query($sql, "Couldn't rename 'nederlands' to 'dutch' in config table");
  579.             
  580.             print "<span class=\"ok\"><b>OK</b></span><br />\n";
  581.             end_step('convert_ips');
  582.  
  583.         case 'convert_ips':
  584.             $names = array( 
  585.                 POSTS_TABLE => array(
  586.                     'id' => 'post_id',
  587.                     'field' => 'poster_ip'
  588.                 ), 
  589.                 PRIVMSGS_TABLE => array( 
  590.                     'id' => 'msg_id', 
  591.                     'field' => 'poster_ip'
  592.                 ), 
  593.                 BANLIST_TABLE => array( 
  594.                     'id' => 'ban_id', 
  595.                     'field' => 'ban_ip'
  596.                 )
  597.             );
  598.  
  599.             lock_tables(1, array(POSTS_TABLE, PRIVMSGS_TABLE, BANLIST_TABLE));
  600.  
  601.             $batchsize = 2000;
  602.             while( list($table, $data_array) = each($names) )
  603.             {
  604.                 $sql = "SELECT MAX(" . $data_array['id'] . ") AS max_id 
  605.                     FROM $table";
  606.                 $result = query($sql, "Couldn't obtain ip data from $table (" . $fields . ")");
  607.  
  608.                 $row = $db->sql_fetchrow($result);
  609.  
  610.                 $maxid = $row['max_id'];
  611.  
  612.                 for($i = 0; $i <= $maxid; $i += $batchsize)
  613.                 {
  614.                     $batchstart = $i;
  615.                     $batchend = $i + $batchsize;
  616.  
  617.                     $field_id = $data_array['id'];
  618.                     $field = $data_array['field'];
  619.  
  620.                     print " * Converting IP format '" . $field . "' / '$table' ( $batchstart to $batchend ) :: ";
  621.                     flush();
  622.  
  623.                     $sql = "SELECT $field_id, $field 
  624.                         FROM $table 
  625.                         WHERE $field_id 
  626.                             BETWEEN $batchstart 
  627.                                 AND $batchend";
  628.                     $result = query($sql, "Couldn't obtain ip data from $table (" . $fields . ")");
  629.  
  630.                     $per_pct = ceil( $db->sql_numrows($result) / 40 );
  631.                     $inc = 0;
  632.  
  633.                     while( $row = $db->sql_fetchrow($result) )
  634.                     {
  635.                         $sql = "UPDATE $table 
  636.                             SET $field = '" . encode_ip($row[$field]) . "' 
  637.                             WHERE $field_id = " . $row[$field_id];
  638.                         query($sql, "Couldn't convert IP format of $field in $table with $field_id of " . $rowset[$field_id]);
  639.  
  640.                         $inc++;
  641.                         if ( $inc == $per_pct )
  642.                         {
  643.                             print ".";
  644.                             flush();
  645.                             $inc = 0;
  646.                         }
  647.                     }
  648.  
  649.                     print " <span class=\"ok\"><b>OK</b></span><br />\n";
  650.                 }
  651.             }
  652.  
  653.             lock_tables(0);
  654.             end_step('convert_dates');
  655.  
  656.         case 'convert_dates':
  657.             $names = array(
  658.                 POSTS_TABLE => array('post_time'),
  659.                 TOPICS_TABLE => array('topic_time'), 
  660.                 PRIVMSGS_TABLE => array('msg_time')
  661.             );
  662.  
  663.             lock_tables(1, array(POSTS_TABLE, TOPICS_TABLE, PRIVMSGS_TABLE));
  664.  
  665.             while( list($table, $fields) = each($names) )
  666.             {
  667.                 print " * Converting date format of $fields[$i] in $table :: ";
  668.                 flush();
  669.  
  670.                 for($i = 0; $i < count($fields); $i++)
  671.                 {
  672.                     $sql = "UPDATE $table 
  673.                         SET " . $fields[$i] . " = UNIX_TIMESTAMP(" . $fields[$i] . ")";
  674.                     query($sql, "Couldn't convert date format of $table(" . $fields[$i] . ")");
  675.                 }
  676.  
  677.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  678.             }
  679.  
  680.             lock_tables(0);
  681.             end_step('fix_addslashes');
  682.  
  683.         case 'fix_addslashes':
  684.             $slashfields[TOPICS_TABLE] = array('topic_title');
  685.             $slashfields[FORUMS_TABLE] = array('forum_desc', 'forum_name');
  686.             $slashfields[CATEGORIES_TABLE] = array('cat_title');
  687.             $slashfields[WORDS_TABLE] = array('word', 'replacement');
  688.             $slashfields[RANKS_TABLE] = array('rank_title');
  689.             $slashfields[DISALLOW_TABLE] = array('disallow_username');
  690.  
  691.             //convert smilies?
  692.             $slashes = array(
  693.                 "\\'" => "'",
  694.                 "\\\"" => "\"",
  695.                 "\\\\" => "\\");
  696.             $slashes = array(
  697.                 "\\'" => "'",
  698.                 "\\\"" => "\"",
  699.                 "\\\\" => "\\");
  700.  
  701.             lock_tables(1, array(TOPICS_TABLE, FORUMS_TABLE, CATEGORIES_TABLE, WORDS_TABLE, RANKS_TABLE, DISALLOW_TABLE, SMILIES_TABLE));
  702.  
  703.             while( list($table, $fields) = each($slashfields) )
  704.             {
  705.                 print " * Removing slashes from $table table :: ";
  706.                 flush();
  707.  
  708.                 while( list($nr, $field) = each($fields) )
  709.                 {
  710.                     @reset($slashes);
  711.                     while( list($search, $replace) = each($slashes) )
  712.                     {
  713.                         $sql = "UPDATE $table 
  714.                             SET $field = REPLACE($field, '" . addslashes($search) . "', '" . addslashes($replace) . "')";
  715.                         query($sql, "Couldn't remove extraneous slashes from the old data.");
  716.                     }
  717.                 }
  718.  
  719.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  720.             }
  721.  
  722.             lock_tables(0);
  723.             end_step('remove_topics');
  724.  
  725.         case 'remove_topics':
  726.             print " * Removing posts with no corresponding topics :: ";
  727.             flush();
  728.  
  729.             $sql = "SELECT p.post_id 
  730.                 FROM " . POSTS_TABLE . " p 
  731.                 LEFT JOIN " . TOPICS_TABLE . " t ON p.topic_id = t.topic_id  
  732.                 WHERE t.topic_id IS NULL";
  733.             $result = query($sql, "Couldn't obtain list of deleted topics");
  734.             
  735.             $post_total = $db->sql_numrows($result);
  736.  
  737.             if ( $post_total )
  738.             {
  739.                 $post_id_ary = array();
  740.                 while( $row = $db->sql_fetchrow($result) )
  741.                 {
  742.                     $post_id_ary[] = $row['post_id'];
  743.                 }
  744.  
  745.                 $sql = "DELETE FROM " . POSTS_TABLE . "  
  746.                     WHERE post_id IN (" . implode(", ", $post_id_ary) . ")";
  747.                 query($sql, "Couldn't update posts to remove deleted user poster_id values");
  748.  
  749.                 $sql = "DELETE FROM " . POSTS_TEXT_TABLE . "
  750.                     WHERE post_id IN (" . implode(", ", $post_id_ary) . ")";
  751.                 query($sql, "Couldn't update posts to remove deleted user poster_id values");
  752.             }
  753.  
  754.             echo "<span class=\"ok\"><b>OK</b></span> ( Removed $post_total posts )<br />\n";
  755.             end_step('convert_users');
  756.  
  757.         case 'convert_users':
  758.             //
  759.             // Completely remove old soft-deleted users
  760.             //
  761.             $sql = "DELETE FROM " . USERS_TABLE . " 
  762.                 WHERE user_level = -1";
  763.             query($sql, "Couldn't delete old soft-deleted users");
  764.  
  765.             $sql = "SELECT COUNT(*) AS total, MAX(user_id) AS maxid 
  766.                 FROM " . USERS_TABLE;
  767.             $result = query($sql, "Couldn't get max user_id.");
  768.  
  769.             $row = $db->sql_fetchrow($result);
  770.  
  771.             $totalposts = $row['total'];
  772.             $maxid = $row['maxid'];
  773.  
  774.             $sql = "ALTER TABLE " . USERS_TABLE . " 
  775.                 ADD user_sig_bbcode_uid CHAR(10),
  776.                 MODIFY user_sig text";
  777.             query($sql, "Couldn't add user_sig_bbcode_uid field to users table");
  778.  
  779.             $super_mods = array();
  780.             $first_admin = -2;
  781.  
  782.             $batchsize = 1000;
  783.             for($i = -1; $i <= $maxid; $i += $batchsize)
  784.             {
  785.                 $batchstart = $i;
  786.                 $batchend = $i + $batchsize;
  787.                 
  788.                 print " * Converting Users ( $batchstart to $batchend ) :: ";
  789.                 flush();
  790.  
  791.                 $sql = "SELECT * 
  792.                     FROM " . USERS_TABLE . " 
  793.                     WHERE user_id 
  794.                         BETWEEN $batchstart 
  795.                             AND $batchend";
  796.                 $result = query($sql, "Couldn't get ". USERS_TABLE .".user_id $batchstart to $batchend");
  797.  
  798.                 // Array with user fields that we want to check for invalid data (to few characters)
  799.                 $checklength = array(
  800.                     'user_occ',
  801.                     'user_website',
  802.                     'user_email',
  803.                     'user_from',
  804.                     'user_intrest',
  805.                     'user_aim',
  806.                     'user_yim',
  807.                     'user_msnm');
  808.  
  809.                 lock_tables(1, array(USERS_TABLE, GROUPS_TABLE, USER_GROUP_TABLE, POSTS_TABLE));
  810.  
  811.                 $per_pct = ceil( $db->sql_numrows($result) / 40 );
  812.                 $inc = 0;
  813.  
  814.                 while( $row = $db->sql_fetchrow($result) )
  815.                 {
  816.                     $sql = "INSERT INTO " . GROUPS_TABLE . " (group_name, group_description, group_single_user) 
  817.                         VALUES ('" . addslashes($row['username']) . "', 'Personal User', 1)";
  818.                     query($sql, "Wasn't able to insert user ".$row['user_id']." into table ".GROUPS_TABLE);
  819.  
  820.                     $group_id = $db->sql_nextid();
  821.  
  822.                     $sql = "INSERT INTO " . USER_GROUP_TABLE . " (group_id, user_id, user_pending)    
  823.                         VALUES ($group_id, " . $row['user_id'] . ", 0)";
  824.                     query($sql, "Wasn't able to insert user ".$row['user_id']." into table ".USER_GROUP_TABLE);
  825.  
  826.                     if ( is_int($row['user_regdate']) )
  827.                     {
  828.                         // We already converted this post to the new style BBcode, skip this post.
  829.                         continue;
  830.                     }
  831.  
  832.                     //
  833.                     // Nathan's bbcode2 conversion
  834.                     //
  835.  
  836.                     // undo 1.2.x encoding..
  837.                     $row['user_sig'] = bbdecode(stripslashes($row['user_sig']));
  838.                     $row['user_sig'] = undo_make_clickable($row['user_sig']);
  839.                     $row['user_sig'] = str_replace("<BR>", "\n", $row['user_sig']);
  840.  
  841.                     // make a uid
  842.                     $uid = make_bbcode_uid();
  843.  
  844.                     // do 2.x first-pass encoding..
  845.                     $row['user_sig'] = bbencode_first_pass($row['user_sig'], $uid);
  846.                     $row['user_sig'] = addslashes($row['user_sig']);
  847.  
  848.                     // Check for invalid info like '-' and '?' for a lot of fields
  849.                     @reset($checklength);
  850.                     while($field = each($checklength))
  851.                     {
  852.                         $row[$field[1]] = strlen($row[$field[1]]) < 3 ? '' : $row[$field[1]];
  853.                     }
  854.  
  855.                     preg_match('/(.*?) (\d{1,2}), (\d{4})/', $row['user_regdate'], $parts);
  856.                     $row['user_regdate'] = gmmktime(0, 0, 0, $months[$parts[1]], $parts[2], $parts[3]);
  857.  
  858.                     $website = $row['user_website'];
  859.                     if ( substr(strtolower($website), 0, 7) != "http://" )
  860.                     {
  861.                         $website = "http://" . $website;
  862.                     }
  863.                     if( strtolower($website) == 'http://' )
  864.                     {
  865.                         $website = '';
  866.                     }
  867.                     $row['user_website'] = addslashes($website);
  868.                     
  869.                     $row['user_icq'] = (ereg("^[0-9]+$", $row['user_icq'])) ? $row['user_icq'] : '';
  870.                     @reset($checklength);
  871.  
  872.                     while($field = each($checklength))
  873.                     {
  874.                         if ( strlen($row[$field[1]]) < 3 )
  875.                         {
  876.                             $row[$field[1]] = '';
  877.                         }
  878.                         $row[$field[1]] = addslashes($row[$field[1]]);
  879.                     }
  880.                     
  881.                     //
  882.                     // Is user a super moderator?
  883.                     //
  884.                     if( $row['user_level'] == 3 )
  885.                     {
  886.                         $super_mods[] = $row['user_id'];
  887.                     }
  888.  
  889.                     $row['user_level'] = ( $row['user_level'] == 4 ) ? ADMIN : USER;
  890.  
  891.                     //
  892.                     // Used to define a 'practical' group moderator user_id
  893.                     // for super mods a little latter.
  894.                     //
  895.                     if( $first_admin == -2 && $row['user_level'] == ADMIN )
  896.                     {
  897.                         $first_admin = $row['user_id'];
  898.                     }
  899.  
  900.                     //
  901.                     // Dutch language files have been renamed from 'nederlands' to 'dutch'
  902.                     //
  903.                     if( $row['user_lang'] == 'nederlands' )
  904.                     {
  905.                         $row['user_lang'] = 'dutch';
  906.                     }
  907.  
  908.                     $sql = "UPDATE " . USERS_TABLE . " 
  909.                         SET 
  910.                             user_sig = '" . $row['user_sig'] . "',
  911.                             user_sig_bbcode_uid = '$uid', 
  912.                             user_regdate = '" . $row['user_regdate'] . "',
  913.                             user_website = '" . $row['user_website'] . "',
  914.                             user_occ = '" . $row['user_occ'] . "',
  915.                             user_email = '" . $row['user_email'] . "',
  916.                             user_from = '" . $row['user_from'] . "',
  917.                             user_intrest = '" . $row['user_intrest'] . "', 
  918.                             user_aim = '" . $row['user_aim'] . "',
  919.                             user_yim = '" . $row['user_yim'] . "',
  920.                             user_msnm = '" . $row['user_msnm'] . "',
  921.                             user_level = '" . $row['user_level'] . "', 
  922.                             user_desmile = NOT(user_desmile), 
  923.                             user_bbcode = 1, 
  924.                             user_theme = 1 
  925.                         WHERE user_id = " . $row['user_id'];
  926.                     query($sql, "Couldn't update ".USERS_TABLE." table with new BBcode and regdate for user_id ".$row['user_id']);
  927.  
  928.                     $inc++;
  929.                     if ( $inc == $per_pct )
  930.                     {
  931.                         print ".";
  932.                         flush();
  933.                         $inc = 0;
  934.                     }
  935.                 }
  936.  
  937.                 // Set any non-standard (like) email addresses to nothing
  938.                 // could do this above as a preg_ but this one query may
  939.                 // be faster
  940.                 $sql = "UPDATE " . USERS_TABLE . " 
  941.                     SET user_email = '' 
  942.                     WHERE user_email NOT REGEXP '^[a-zA-Z0-9_\+\.\-]+@.*[a-zA-Z0-9\-_]+\.[a-zA-Z]{2,}$'";
  943.                 query($sql, "Couldn't update ".USERS_TABLE." table non-standard user_email entries");
  944.  
  945.                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
  946.  
  947.                 lock_tables(0);
  948.             }
  949.  
  950.             //
  951.             // Handle super-mods, create hidden group for them
  952.             //
  953.             // Iterate trough access table
  954.             if( count($super_mods) && $first_admin != -2 )
  955.             {
  956.                 print "\n<br />\n * Creating new group for super moderators :: ";
  957.                 flush();
  958.  
  959.                 $sql = "INSERT INTO " . GROUPS_TABLE . " (group_type, group_name, group_description, group_moderator, group_single_user)
  960.                     VALUES (" . GROUP_HIDDEN . ", 'Super Moderators', 'Converted super moderators', $first_admin, 0)";
  961.                 $result = query($sql, "Couldn't create group for ".$row['forum_name']);
  962.  
  963.                 $group_id = $db->sql_nextid();
  964.  
  965.                 if ( $group_id <= 0 )
  966.                 {
  967.                     print "<font color=\"red\">Group creation failed. Aborting creation of groups...<br></font>\n";
  968.                     continue 2;
  969.                 }
  970.  
  971.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  972.  
  973.                 print " * Updating auth_access for super moderator group :: ";
  974.                 flush();
  975.  
  976.                 $sql = "SELECT forum_id 
  977.                     FROM " . FORUMS_TABLE;
  978.                 $result = query($sql, "Couldn't obtain forum_id list");
  979.  
  980.                 while( $row = $db->sql_fetchrow($result) )
  981.                 {
  982.                     $sql = "INSERT INTO " . AUTH_ACCESS_TABLE . " (group_id, forum_id, auth_mod)
  983.                         VALUES ($group_id, " . $row['forum_id'] . ", 1)";
  984.                     $result_insert = query($sql, "Unable to set group auth access for super mods.");
  985.                 }
  986.  
  987.                 for($i = 0; $i < count($super_mods); $i++)
  988.                 {
  989.                     $sql = "INSERT INTO " . USER_GROUP_TABLE . " (group_id, user_id, user_pending)
  990.                         VALUES ($group_id, " . $super_mods[$i] . ", 0)";
  991.                     query($sql, "Unable to add user_id $user_id to group_id $group_id (super mods)<br>\n");
  992.                 }
  993.             
  994.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  995.             }
  996.  
  997.             end_step('convert_posts');
  998.  
  999.         case 'convert_posts':
  1000.             print " * Adding enable_sig field to " . POSTS_TABLE . " :: ";
  1001.             flush();
  1002.             $sql = "ALTER TABLE " . POSTS_TABLE . " 
  1003.                 ADD enable_sig tinyint(1) DEFAULT '1' NOT NULL";
  1004.             $result = query($sql, "Couldn't add enable_sig field to " . POSTS_TABLE . ".");
  1005.             print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1006.             
  1007.             print " * Adding enable_bbcode field to " . POSTS_TEXT_TABLE . " :: ";
  1008.             flush();
  1009.             $sql = "ALTER TABLE " . POSTS_TEXT_TABLE . "  
  1010.                 ADD enable_bbcode tinyint(1) DEFAULT '1' NOT NULL";
  1011.             $result = query($sql, "Couldn't add enable_bbcode field to " . POSTS_TABLE . ".");
  1012.             print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1013.  
  1014.             print " * Adding bbcode_uid field to " . POSTS_TEXT_TABLE . " :: ";
  1015.             flush();
  1016.             $sql = "ALTER TABLE " . POSTS_TEXT_TABLE . "  
  1017.                 ADD bbcode_uid char(10) NOT NULL";
  1018.             $result = query($sql, "Couldn't add bbcode_uid field to " . POSTS_TABLE . ".");
  1019.             print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1020.             
  1021.             print " * Adding post_edit_time field to " . POSTS_TABLE . " :: ";
  1022.             flush();
  1023.             $sql = "ALTER TABLE " . POSTS_TABLE . "  
  1024.                 ADD post_edit_time int(11)";
  1025.             $result = query($sql, "Couldn't add post_edit_time field to " . POSTS_TABLE . ".");
  1026.             print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1027.  
  1028.             print " * Adding post_edit_count field to " . POSTS_TABLE . " :: ";
  1029.             flush();
  1030.             $sql = "ALTER TABLE " . POSTS_TABLE . "  
  1031.                 ADD post_edit_count smallint(5) UNSIGNED DEFAULT '0' NOT NULL";
  1032.             $result = query($sql, "Couldn't add post_edit_count field to " . POSTS_TABLE . ".");
  1033.             print "<span class=\"ok\"><b>OK</b></span><br />\n<br />\n";
  1034.  
  1035.             $sql = "SELECT COUNT(*) as total, MAX(post_id) as maxid 
  1036.                 FROM " . POSTS_TEXT_TABLE;
  1037.             $result = query($sql, "Couldn't get max post_id.");
  1038.  
  1039.             $maxid = $db->sql_fetchrow($result);
  1040.  
  1041.             $totalposts = $maxid['total'];
  1042.             $maxid = $maxid['maxid'];
  1043.  
  1044.             $batchsize = 2000;
  1045.             for($i = 0; $i <= $maxid; $i += $batchsize)
  1046.             {
  1047.                 $batchstart = $i + 1;
  1048.                 $batchend = $i + $batchsize;
  1049.                 
  1050.                 print " * Converting BBcode ( $batchstart to $batchend ) :: ";
  1051.                 flush();
  1052.  
  1053.                 $sql = "SELECT * 
  1054.                     FROM " . POSTS_TEXT_TABLE . "
  1055.                     WHERE post_id 
  1056.                         BETWEEN $batchstart 
  1057.                             AND $batchend";
  1058.                 $result = query($sql, "Couldn't get ". POSTS_TEXT_TABLE .".post_id $batchstart to $batchend");
  1059.  
  1060.                 lock_tables(1, array(POSTS_TEXT_TABLE, POSTS_TABLE));
  1061.  
  1062.                 $per_pct = ceil( $db->sql_numrows($result) / 40 );
  1063.                 $inc = 0;
  1064.  
  1065.                 while( $row = $db->sql_fetchrow($result) )
  1066.                 {
  1067.                     if ( $row['bbcode_uid'] != '' )
  1068.                     {
  1069.                         // We already converted this post to the new style BBcode, skip this post.
  1070.                         continue;
  1071.                     }
  1072.  
  1073.                     //
  1074.                     // Nathan's bbcode2 conversion
  1075.                     //
  1076.                     // undo 1.2.x encoding..
  1077.                     $row['post_text'] = bbdecode(stripslashes($row['post_text']));
  1078.                     $row['post_text'] = undo_make_clickable($row['post_text']);
  1079.                     $row['post_text'] = str_replace('<BR>', "\n", $row['post_text']);
  1080.  
  1081.                     // make a uid
  1082.                     $uid = make_bbcode_uid();
  1083.  
  1084.                     // do 2.x first-pass encoding..
  1085.                     $row['post_text'] = smiley_replace($row['post_text']);
  1086.                     $row['post_text'] = bbencode_first_pass($row['post_text'], $uid);
  1087.                     $row['post_text'] = addslashes($row['post_text']);
  1088.  
  1089.                     $edited_sql = "";
  1090.                     if ( preg_match('/^(.*?)([\n]+<font size=\-1>\[ This message was .*?)$/s', $row['post_text'], $matches) )
  1091.                     {
  1092.                         $row['post_text'] = $matches[1];
  1093.                         $edit_info = $matches[2];
  1094.  
  1095.                         $edit_times = count(explode(' message ', $edit_info)) - 1; // Taken from example for substr_count in annotated PHP manual
  1096.  
  1097.                         if ( preg_match('/^.* by: (.*?) on (....)-(..)-(..) (..):(..) \]<\/font>/s', $edit_info, $matches) )
  1098.                         {
  1099.                             $edited_user = $matches[1];
  1100.                             $edited_time = gmmktime($matches[5], $matches[6], 0, $matches[3], $matches[4], $matches[2]);
  1101.  
  1102.                             //
  1103.                             // This isn't strictly correct since 2.0 won't include and edit
  1104.                             // statement if the edit wasn't by the user who posted ...
  1105.                             //
  1106.                             $edited_sql = ", post_edit_time = $edited_time, post_edit_count = $edit_times";
  1107.                         }
  1108.                     }
  1109.     
  1110.                     if ( preg_match("/^(.*?)\n-----------------\n.*$/is", $row['post_text'], $matches) )
  1111.                     {
  1112.                         $row['post_text'] = $matches[1];
  1113.                         $enable_sig = 1;
  1114.                     }
  1115.                     else
  1116.                     {
  1117.                         $checksig = preg_replace('/\[addsig\]$/', '', $row['post_text']);
  1118.                         $enable_sig = ( strlen($checksig) == strlen($row['post_text']) ) ? 0 : 1;
  1119.                     }
  1120.  
  1121.                     $sql = "UPDATE " . POSTS_TEXT_TABLE . " 
  1122.                         SET post_text = '$checksig', bbcode_uid = '$uid'
  1123.                         WHERE post_id = " . $row['post_id'];
  1124.                     query($sql, "Couldn't update " . POSTS_TEXT_TABLE . " table with new BBcode for post_id :: " . $row['post_id']);
  1125.  
  1126.                     $sql = "UPDATE " . POSTS_TABLE . " 
  1127.                         SET enable_sig = $enable_sig" . $edited_sql . " 
  1128.                         WHERE post_id = " . $row['post_id'];
  1129.                     query($sql, "Couldn't update " . POSTS_TABLE . " table with signature status for post with post_id :: " . $row['post_id']);
  1130.  
  1131.                     $inc++;
  1132.                     if ( $inc == $per_pct )
  1133.                     {
  1134.                         print '.';
  1135.                         flush();
  1136.                         $inc = 0;
  1137.                     }
  1138.                 }
  1139.  
  1140.                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
  1141.  
  1142.                 lock_tables(0);
  1143.             }
  1144.  
  1145.             print "<br />\n * Updating poster_id for deleted users :: ";
  1146.             flush();
  1147.  
  1148.             $sql = "SELECT DISTINCT p.post_id 
  1149.                 FROM " . POSTS_TABLE . " p 
  1150.                 LEFT JOIN " . USERS_TABLE . " u ON p.poster_id = u.user_id 
  1151.                 WHERE u.user_id IS NULL";
  1152.             $result = query($sql, "Couldn't obtain list of deleted users");
  1153.             
  1154.             $users_removed = $db->sql_numrows($result);
  1155.  
  1156.             if ( $users_removed )
  1157.             {
  1158.                 $post_id_ary = array();
  1159.                 while( $row = $db->sql_fetchrow($result) )
  1160.                 {
  1161.                     $post_id_ary[] = $row['post_id'];
  1162.                 }
  1163.  
  1164.                 $sql = "UPDATE " . POSTS_TABLE . " 
  1165.                     SET poster_id = " . ANONYMOUS . ", enable_sig = 0 
  1166.                     WHERE post_id IN (" . implode(", ", $post_id_ary) . ")";
  1167.                 query($sql, "Couldn't update posts to remove deleted user poster_id values");
  1168.             }
  1169.  
  1170.             print "<span class=\"ok\"><b>OK</b></span> ( Removed $users_removed non-existent user references )<br />\n";
  1171.  
  1172.             end_step('convert_privmsgs');
  1173.  
  1174.         case 'convert_privmsgs':
  1175.             $sql = "SELECT COUNT(*) as total, max(msg_id) as maxid 
  1176.                 FROM " . PRIVMSGS_TABLE;
  1177.             $result = query($sql, "Couldn't get max privmsgs_id.");
  1178.  
  1179.             $maxid = $db->sql_fetchrow($result);
  1180.  
  1181.             $totalposts = $maxid['total'];
  1182.             $maxid = $maxid['maxid'];
  1183.  
  1184.             $sql = "ALTER TABLE " . PRIVMSGS_TABLE . " 
  1185.                 ADD privmsgs_subject VARCHAR(255),
  1186.                 ADD privmsgs_attach_sig TINYINT(1) DEFAULT 1";
  1187.             query($sql, "Couldn't add privmsgs_subject field to " . PRIVMSGS_TABLE . " table");
  1188.  
  1189.             $batchsize = 2000;
  1190.             for($i = 0; $i <= $maxid; $i += $batchsize)
  1191.             {
  1192.                 $batchstart = $i + 1;
  1193.                 $batchend = $i + $batchsize;
  1194.                 
  1195.                 print " * Converting Private Message ( $batchstart to $batchend ) :: ";
  1196.                 flush();
  1197.  
  1198.                 $sql = "SELECT * 
  1199.                     FROM " . PRIVMSGS_TABLE . "
  1200.                     WHERE msg_id 
  1201.                         BETWEEN $batchstart 
  1202.                             AND $batchend";
  1203.                 $result = query($sql, "Couldn't get " . POSTS_TEXT_TABLE . " post_id $batchstart to $batchend");
  1204.  
  1205.                 lock_tables(1, array(PRIVMSGS_TABLE, PRIVMSGS_TEXT_TABLE));
  1206.  
  1207.                 $per_pct = ceil( $db->sql_numrows($result) / 40 );
  1208.                 $inc = 0;
  1209.  
  1210.                 while( $row = $db->sql_fetchrow($result) )
  1211.                 {
  1212.                     if ( $row['msg_text'] == NULL )
  1213.                     {
  1214.                         // We already converted this post to the new style BBcode, skip this post.
  1215.                         continue;
  1216.                     }
  1217.                     //
  1218.                     // Nathan's bbcode2 conversion
  1219.                     //
  1220.                     // undo 1.2.x encoding..
  1221.                     $row['msg_text'] = bbdecode(stripslashes($row['msg_text']));
  1222.                     $row['msg_text'] = undo_make_clickable($row['msg_text']);
  1223.                     $row['msg_text'] = str_replace("<BR>", "\n", $row['msg_text']);
  1224.  
  1225.                     // make a uid
  1226.                     $uid = make_bbcode_uid();
  1227.  
  1228.                     // do 2.x first-pass encoding..
  1229.                     $row['msg_text'] = smiley_replace($row['msg_text']);
  1230.                     $row['msg_text'] = bbencode_first_pass($row['msg_text'], $uid);
  1231.                     
  1232.                     $checksig = preg_replace('/\[addsig\]$/', '', $row['msg_text']);
  1233.                     $enable_sig = (strlen($checksig) == strlen($row['msg_text'])) ? 0 : 1;
  1234.  
  1235.                     if ( preg_match("/^(.*?)\n-----------------\n.*$/is", $checksig, $matches) )
  1236.                     {
  1237.                         $checksig = $matches[1];
  1238.                         $enable_sig = 1;
  1239.                     }
  1240.  
  1241.                     $row['msg_text'] = $checksig;
  1242.                     
  1243.                     $row['msg_status'] = ($row['msg_status'] == 1) ? PRIVMSGS_READ_MAIL : PRIVMSGS_NEW_MAIL;
  1244.  
  1245.                     // Subject contains first 60 characters of msg, remove any BBCode tags
  1246.                     $subject = addslashes(strip_tags(substr($row['msg_text'], 0, 60)));
  1247.                     $subject = preg_replace("/\[.*?\:(([a-z0-9]:)?)$uid.*?\]/si", "", $subject);
  1248.                     
  1249.                     $row['msg_text'] = addslashes($row['msg_text']);
  1250.  
  1251.                     $sql = "INSERT INTO " . PRIVMSGS_TEXT_TABLE . " (privmsgs_text_id, privmsgs_bbcode_uid, privmsgs_text)
  1252.                         VALUES ('" . $row['msg_id'] . "', '$uid', '" . $row['msg_text'] . "')";
  1253.                     query($sql, "Couldn't insert PrivMsg text into " . PRIVMSGS_TEXT_TABLE . " table msg_id " . $row['msg_id']);
  1254.  
  1255.                     $sql = "UPDATE " . PRIVMSGS_TABLE . " 
  1256.                         SET msg_text = NULL, msg_status = " . $row['msg_status'] . ", privmsgs_subject = '$subject', privmsgs_attach_sig = $enable_sig
  1257.                         WHERE msg_id = " . $row['msg_id'];
  1258.                     query($sql, "Couldn't update " . PRIVMSGS_TABLE . " table for msg_id " . $row['post_id']);
  1259.  
  1260.                     $inc++;
  1261.                     if ( $inc == $per_pct )
  1262.                     {
  1263.                         print '.';
  1264.                         flush();
  1265.                         $inc = 0;
  1266.                     }
  1267.                 }
  1268.  
  1269.                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
  1270.             }
  1271.  
  1272.             lock_tables(0);
  1273.             end_step('convert_moderators');
  1274.  
  1275.         case 'convert_moderators';
  1276.             $sql = "SELECT * 
  1277.                 FROM forum_mods";
  1278.             $result = query($sql, "Couldn't get list with all forum moderators");
  1279.  
  1280.             while( $row = $db->sql_fetchrow($result) )
  1281.             {
  1282.                 // Check if this moderator and this forum still exist
  1283.                 $sql = "SELECT user_id  
  1284.                     FROM " . USERS_TABLE . ", " . FORUMS_TABLE . " 
  1285.                     WHERE user_id = " . $row['user_id'] . " 
  1286.                         AND forum_id = " . $row['forum_id'];
  1287.                 $check_data = query($sql, "Couldn't check if user " . $row['user_id'] . " and forum " . $row['forum_id'] . " exist");
  1288.  
  1289.                 if ( !($rowtest = $db->sql_fetchrow($check_data)) )
  1290.                 {
  1291.                     // Either the moderator or the forum have been deleted, this line in forum_mods was redundant, skip it.
  1292.                     continue;
  1293.                 }
  1294.  
  1295.                 $sql = "SELECT g.group_id 
  1296.                     FROM " . GROUPS_TABLE . " g, " . USER_GROUP_TABLE . " ug 
  1297.                     WHERE g.group_id = ug.group_id 
  1298.                         AND ug.user_id = " . $row['user_id'] . "
  1299.                         AND g.group_single_user = 1";
  1300.                 $insert_group = query($sql, "Couldn't get group number for user " . $row['user_id'] . ".");
  1301.  
  1302.                 $group_id = $db->sql_fetchrow($insert_group);
  1303.                 $group_id = $group_id['group_id'];
  1304.  
  1305.                 print " * Adding moderator for forum " . $row['forum_id'] . " :: ";
  1306.                 flush();
  1307.  
  1308.                 $sql = "INSERT INTO " . AUTH_ACCESS_TABLE . " (group_id, forum_id, auth_mod) VALUES ($group_id, ".$row['forum_id'].", 1)";
  1309.                 query($sql, "Couldn't set moderator (user_id = " . $row['user_id'] . ") for forum " . $row['forum_id'] . ".");
  1310.  
  1311.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1312.             }
  1313.  
  1314.             print " * Setting correct user_level for moderators ::";
  1315.             flush();
  1316.  
  1317.             $sql = "SELECT DISTINCT u.user_id 
  1318.                 FROM " . USERS_TABLE . " u, " . USER_GROUP_TABLE . " ug, " . AUTH_ACCESS_TABLE . " aa 
  1319.                 WHERE aa.auth_mod = 1 
  1320.                     AND ug.group_id = aa.group_id 
  1321.                     AND u.user_id = ug.user_id 
  1322.                     AND u.user_level <> " . ADMIN;
  1323.             $result = query($sql, "Couldn't obtain list of moderators");
  1324.  
  1325.             if ( $row = $db->sql_fetchrow($result) )
  1326.             {
  1327.                 $ug_sql = '';
  1328.  
  1329.                 do
  1330.                 {
  1331.                     $ug_sql .= ( ( $ug_sql != '' ) ? ', ' : '' ) . $row['user_id'];
  1332.                 }
  1333.                 while ( $row = $db->sql_fetchrow($result) );
  1334.  
  1335.                 $sql = "UPDATE " . USERS_TABLE . " 
  1336.                     SET user_level = " . MOD . " 
  1337.                     WHERE user_id IN ($ug_sql)";
  1338.                 query($sql, "Couldn't set moderator status for users");
  1339.             }
  1340.  
  1341.             print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1342.             
  1343.             end_step('convert_privforums');
  1344.  
  1345.         case 'convert_privforums':
  1346.             $sql = "SELECT fa.*, f.forum_name 
  1347.                     FROM forum_access fa 
  1348.                     LEFT JOIN " . FORUMS_TABLE . " f ON fa.forum_id = f.forum_id  
  1349.                     ORDER BY fa.forum_id, fa.user_id";
  1350.             $forum_access = query($sql, "Couldn't get list with special forum access (forum_access)");
  1351.  
  1352.             $forum_id = -1;
  1353.             while( $row = $db->sql_fetchrow($forum_access) )
  1354.             {
  1355.                 // Iterate trough access table
  1356.                 if ( $row['forum_id'] != $forum_id )
  1357.                 {
  1358.                     // This is a new forum, create new group.
  1359.                     $forum_id = $row['forum_id'];
  1360.  
  1361.                     print " * Creating new group for forum $forum_id :: ";
  1362.                     flush();
  1363.  
  1364.                     $sql = "INSERT INTO " . GROUPS_TABLE . " (group_type, group_name, group_description, group_moderator, group_single_user)
  1365.                         VALUES (" . GROUP_HIDDEN . ", '" . addslashes($row['forum_name']) . " Group', 'Converted Private Forum Group', " . $row['user_id'] . ", 0)";
  1366.                     $result = query($sql, "Couldn't create group for ".$row['forum_name']);
  1367.  
  1368.                     $group_id = $db->sql_nextid();
  1369.  
  1370.                     if ( $group_id <= 0 )
  1371.                     {
  1372.                         print "<font color=\"red\">Group creation failed. Aborting creation of groups...<br></font>\n";
  1373.                         continue 2;
  1374.                     }
  1375.  
  1376.                     print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1377.  
  1378.                     print " * Creating auth_access group for forum $forum_id :: ";
  1379.                     flush();
  1380.  
  1381.                     $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)
  1382.                         VALUES ($group_id, $forum_id, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1)";
  1383.                     $result = query($sql, "Unable to set group auth access.");
  1384.  
  1385.                     if ( $db->sql_affectedrows($result) <= 0 )
  1386.                     {
  1387.                         print "<font color=\"red\">Group creation failed. Aborting creation of groups...</font><br>\n";
  1388.                         continue 2;
  1389.                     }
  1390.  
  1391.                     print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1392.                 }
  1393.  
  1394.                 // Add user to the group
  1395.                 $user_id = $row['user_id'];
  1396.  
  1397.                 $sql = "INSERT INTO " . USER_GROUP_TABLE . " (group_id, user_id, user_pending)
  1398.                     VALUES ($group_id, $user_id, 0)";
  1399.                 query($sql, "Unable to add user_id $user_id to group_id $group_id <br>\n");
  1400.             }
  1401.  
  1402.             end_step('update_schema');
  1403.  
  1404.         case 'update_schema':
  1405.             $rename = array(
  1406.                 $table_prefix . "users" => array(
  1407.                     "user_interests" => "user_intrest",
  1408.                     "user_allowsmile" => "user_desmile",
  1409.                     "user_allowhtml" => "user_html",
  1410.                     "user_allowbbcode" => "user_bbcode", 
  1411.                     "user_style" => "user_theme" 
  1412.                 ),
  1413.                 $table_prefix . "privmsgs" => array(
  1414.                      "privmsgs_id" => "msg_id",
  1415.                      "privmsgs_from_userid" => "from_userid",
  1416.                      "privmsgs_to_userid" => "to_userid",
  1417.                      "privmsgs_date" => "msg_time",
  1418.                      "privmsgs_ip" => "poster_ip",
  1419.                      "privmsgs_type" => "msg_status" 
  1420.                 ),
  1421.                 $table_prefix . "smilies" => array(
  1422.                     "smilies_id" => "id"
  1423.                 )
  1424.             );
  1425.  
  1426.             $schema = get_schema();
  1427.  
  1428.             $table_def = $schema['table_def'];
  1429.             $field_def = $schema['field_def'];
  1430.  
  1431.             // Loop tables in schema
  1432.             while (list($table, $table_def) = @each($field_def))
  1433.             {
  1434.                 // Loop fields in table
  1435.                 print " * Updating table '$table' :: ";
  1436.                 flush();
  1437.                 
  1438.                 $sql = "SHOW FIELDS 
  1439.                     FROM $table";
  1440.                 $result = query($sql, "Can't get definition of current $table table");
  1441.  
  1442.                 while( $row = $db->sql_fetchrow($result) )
  1443.                 {
  1444.                     $current_fields[] = $row['Field'];
  1445.                 }
  1446.                 
  1447.                 $alter_sql = "ALTER TABLE $table ";
  1448.                 while (list($field, $definition) = each($table_def))
  1449.                 {
  1450.                     if ( $field == '' )
  1451.                     {
  1452.                         // Skip empty fields if any (shouldn't be needed)
  1453.                         continue;
  1454.                     }
  1455.  
  1456.                     $type = $definition['type'];
  1457.                     $size = $definition['size'];
  1458.  
  1459.                     $default = isset($definition['default']) ? "DEFAULT " . $definition['default'] : '';
  1460.  
  1461.                     $notnull = $definition['notnull'] == 1 ? 'NOT NULL' : '';
  1462.  
  1463.                     $auto_increment = $definition['auto_increment'] == 1 ? 'auto_increment' : '';
  1464.  
  1465.                     $oldfield = isset($rename[$table][$field]) ? $rename[$table][$field] : $field;
  1466.  
  1467.                     if ( !inarray($field, $current_fields) && $oldfield == $field )
  1468.                     {
  1469.                         // If the current is not a key of $current_def and it is not a field that is 
  1470.                         // to be renamed then the field doesn't currently exist.
  1471.                         $changes[] = " ADD $field " . $create_def[$table][$field];
  1472.                     }
  1473.                     else
  1474.                     {
  1475.                         $changes[] = " CHANGE $oldfield $field " . $create_def[$table][$field];
  1476.                     }
  1477.                 }
  1478.                 
  1479.                 $alter_sql .= join(',', $changes);
  1480.                 unset($changes);
  1481.                 unset($current_fields);
  1482.                 
  1483.                 $sql = "SHOW INDEX 
  1484.                     FROM $table";
  1485.                 $result = query($sql, "Couldn't get list of indices for table $table");
  1486.  
  1487.                 unset($indices);
  1488.  
  1489.                 while( $row = $db->sql_fetchrow($result) )
  1490.                 {
  1491.                     $indices[] = $row['Key_name'];
  1492.                 }
  1493.                 
  1494.                 while ( list($key_name, $key_field) = each($key_def[$table]) )
  1495.                 {
  1496.                     if ( !inarray($key_name, $indices) )
  1497.                     {
  1498.                         $alter_sql .= ($key_name == 'PRIMARY') ? ", ADD PRIMARY KEY ($key_field)" : ", ADD INDEX $key_name ($key_field)";
  1499.                     }
  1500.                 }
  1501.                 query($alter_sql, "Couldn't alter table $table");
  1502.  
  1503.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1504.                 flush();
  1505.             }
  1506.  
  1507.             end_step('convert_forums');
  1508.  
  1509.         case 'convert_forums':
  1510.             $sql = "SELECT * 
  1511.                 FROM " . FORUMS_TABLE;
  1512.             $result = query($sql, "Couldn't get list with all forums");
  1513.  
  1514.             while( $row = $db->sql_fetchrow($result) )
  1515.             {
  1516.                 print " * Converting forum '" . $row['forum_name'] . "' :: ";
  1517.                 flush();
  1518.  
  1519.                 // forum_access: (only concerns posting)
  1520.                 //        1 = Registered users only
  1521.                 //        2 = Anonymous Posting
  1522.                 //        3 = Moderators/Administrators only
  1523.                 switch( $row['forum_access'] )
  1524.                 {
  1525.                     case 1:
  1526.                         // Public forum, no anonymous posting
  1527.                         $auth_view            = AUTH_ALL;
  1528.                         $auth_read            = AUTH_ALL;
  1529.                         $auth_post            = AUTH_REG;
  1530.                         $auth_reply            = AUTH_REG;
  1531.                         $auth_edit            = AUTH_REG;
  1532.                         $auth_delete        = AUTH_REG;
  1533.                         $auth_vote            = AUTH_REG;
  1534.                         $auth_pollcreate    = AUTH_REG;
  1535.                         $auth_sticky        = AUTH_MOD;
  1536.                         $auth_announce        = AUTH_MOD;
  1537.                         break;
  1538.                     case 2:
  1539.                         $auth_post            = AUTH_ALL;
  1540.                         $auth_reply            = AUTH_ALL;
  1541.                         $auth_edit            = AUTH_REG;
  1542.                         $auth_delete        = AUTH_REG;
  1543.                         $auth_vote            = AUTH_ALL;
  1544.                         $auth_pollcreate    = AUTH_ALL;
  1545.                         $auth_sticky        = AUTH_MOD;
  1546.                         $auth_announce        = AUTH_MOD;
  1547.                         break;
  1548.                     default:
  1549.                         $auth_post            = AUTH_MOD;
  1550.                         $auth_reply            = AUTH_MOD;
  1551.                         $auth_edit            = AUTH_MOD;
  1552.                         $auth_delete        = AUTH_MOD;
  1553.                         $auth_vote            = AUTH_MOD;
  1554.                         $auth_pollcreate    = AUTH_MOD;
  1555.                         $auth_sticky        = AUTH_MOD;
  1556.                         $auth_announce        = AUTH_MOD;
  1557.                         break;
  1558.                 }
  1559.                 
  1560.                 // Old auth structure:
  1561.                 // forum_type: (only concerns viewing)
  1562.                 //        0 = Public
  1563.                 //        1 = Private
  1564.                 switch( $row['forum_type'] )
  1565.                 {
  1566.                     case 0:
  1567.                         $auth_view            = AUTH_ALL;
  1568.                         $auth_read            = AUTH_ALL;
  1569.                         break;
  1570.                     default:
  1571.                         //
  1572.                         // Make it really private ... 
  1573.                         //
  1574.                         $auth_view            = AUTH_ACL;
  1575.                         $auth_read            = AUTH_ACL;
  1576.                         $auth_post            = AUTH_ACL;
  1577.                         $auth_reply            = AUTH_ACL;
  1578.                         $auth_edit            = AUTH_ACL;
  1579.                         $auth_delete        = AUTH_ACL;
  1580.                         $auth_vote            = AUTH_ACL;
  1581.                         $auth_pollcreate    = AUTH_ACL;
  1582.                         $auth_sticky        = AUTH_ACL;
  1583.                         $auth_announce        = AUTH_MOD;
  1584.                         break;
  1585.                 }
  1586.  
  1587.                 $sql = "UPDATE " . FORUMS_TABLE . " SET
  1588.                     auth_view = $auth_view,
  1589.                     auth_read = $auth_read,
  1590.                     auth_post = $auth_post,
  1591.                     auth_reply = $auth_reply,
  1592.                     auth_edit = $auth_edit,
  1593.                     auth_delete = $auth_delete,
  1594.                     auth_vote = $auth_vote,
  1595.                     auth_pollcreate = $auth_pollcreate,
  1596.                     auth_sticky = $auth_sticky,
  1597.                     auth_announce = $auth_announce
  1598.                     WHERE forum_id = ". $row['forum_id'];
  1599.                 query($sql, "Was unable to update forum permissions!");
  1600.  
  1601.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1602.             }
  1603.  
  1604.             end_step('insert_themes');
  1605.  
  1606.         case 'insert_themes':
  1607.             print " * Inserting new values into themes table :: ";
  1608.  
  1609.             @reset($inserts);
  1610.             while( list($table, $inserts_table) = each($inserts) )
  1611.             {
  1612.                 if ( $table == THEMES_TABLE )
  1613.                 {
  1614.                     $per_pct = ceil( count($inserts_table) / 40 );
  1615.                     $inc = 0;
  1616.  
  1617.                     while( list($nr, $insert) = each($inserts_table) )
  1618.                     {
  1619.                         query($insert, "Couldn't insert value into " . THEMES_TABLE);
  1620.  
  1621.                         $inc++;
  1622.                         if ( $inc == $per_pct )
  1623.                         {
  1624.                             print ".";
  1625.                             flush();
  1626.                             $inc = 0;
  1627.                         }
  1628.                     }
  1629.                 }
  1630.             }
  1631.  
  1632.             print " <span class=\"ok\"><b>OK</b></span><br />\n";
  1633.             end_step('update_topics');
  1634.  
  1635.         case 'update_topics':
  1636.             $sql = "SELECT MAX(topic_id) AS max_topic 
  1637.                 FROM " . TOPICS_TABLE;
  1638.             $result = query($sql, "Couldn't get max topic id");
  1639.  
  1640.             $row = $db->sql_fetchrow($result);
  1641.  
  1642.             $maxid = $row['max_topic'];
  1643.  
  1644.             lock_tables(1, array(TOPICS_TABLE, POSTS_TABLE));
  1645.  
  1646.             $batchsize = 1000;
  1647.             for($i = 0; $i <= $maxid; $i += $batchsize)
  1648.             {
  1649.                 $batchstart = $i + 1;
  1650.                 $batchend = $i + $batchsize;
  1651.                 
  1652.                 print " * Setting topic first post_id ( $batchstart to $batchend ) :: ";
  1653.                 flush();
  1654.  
  1655.                 $sql = "SELECT MIN(post_id) AS first_post_id, topic_id
  1656.                     FROM " . POSTS_TABLE . "
  1657.                     WHERE topic_id 
  1658.                         BETWEEN $batchstart 
  1659.                             AND $batchend 
  1660.                     GROUP BY topic_id 
  1661.                     ORDER BY topic_id ASC";
  1662.                 $result = query($sql, "Couldn't get post id data");
  1663.  
  1664.                 $per_pct = ceil( $db->sql_numrows($result) / 40 );
  1665.                 $inc = 0;
  1666.  
  1667.                 if ( $row = $db->sql_fetchrow($result) )
  1668.                 {
  1669.                     do
  1670.                     {
  1671.                         $sql = "UPDATE " . TOPICS_TABLE . " 
  1672.                             SET topic_first_post_id = " . $row['first_post_id'] . " 
  1673.                             WHERE topic_id = " . $row['topic_id'];
  1674.                         query($sql, "Couldn't update topic first post id in topic :: $topic_id");
  1675.  
  1676.                         $inc++;
  1677.                         if ( $inc == $per_pct )
  1678.                         {
  1679.                             print ".";
  1680.                             flush();
  1681.                             $inc = 0;
  1682.                         }
  1683.                     }
  1684.                     while ( $row = $db->sql_fetchrow($result) );
  1685.                 }
  1686.  
  1687.                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
  1688.             }
  1689.  
  1690.             lock_tables(0);
  1691.             end_step('final_configuration');
  1692.  
  1693.         case 'final_configuration':
  1694.             //
  1695.             // Update forum last post information
  1696.             //
  1697.             $sql = "SELECT forum_id, forum_name 
  1698.                 FROM " . FORUMS_TABLE;
  1699.             $f_result = query($sql, "Couldn't obtain forum_ids");
  1700.  
  1701.             while( $forum_row = $db->sql_fetchrow($f_result) )
  1702.             {
  1703.                 print " * Updating '" . $forum_row['forum_name'] . "' post info :: ";
  1704.                 flush();
  1705.  
  1706.                 $id = $forum_row['forum_id'];
  1707.  
  1708.                 $sql = "SELECT MIN(p.post_id) AS first_post, MAX(p.post_id) AS last_post
  1709.                     FROM " . POSTS_TABLE . " p, " . TOPICS_TABLE . " t
  1710.                     WHERE p.forum_id = $id
  1711.                         AND p.topic_id = t.topic_id";
  1712.                 $result = query($sql, "Could not get post ID forum post information :: $id");
  1713.  
  1714.                 if ( $row = $db->sql_fetchrow($result) )
  1715.                 {
  1716.                     $first_post = ( $row['first_post'] ) ? $row['first_post'] : 0;
  1717.                     $last_post = ($row['last_post']) ? $row['last_post'] : 0;
  1718.                 }
  1719.                 else
  1720.                 {
  1721.                     $first_post = 0;
  1722.                     $last_post = 0;
  1723.                 }
  1724.  
  1725.                 $sql = "SELECT COUNT(post_id) AS total
  1726.                     FROM " . POSTS_TABLE . "
  1727.                     WHERE forum_id = $id";
  1728.                 $result = query($sql, "Could not get post count forum post information :: $id");
  1729.  
  1730.                 if ( $row = $db->sql_fetchrow($result) )
  1731.                 {
  1732.                     $total_posts = ($row['total']) ? $row['total'] : 0;
  1733.                 }
  1734.                 else
  1735.                 {
  1736.                     $total_posts = 0;
  1737.                 }
  1738.  
  1739.                 $sql = "SELECT COUNT(topic_id) AS total
  1740.                     FROM " . TOPICS_TABLE . "
  1741.                     WHERE forum_id = $id 
  1742.                         AND topic_status <> " . TOPIC_MOVED;
  1743.                 $result = query($sql, "Could not get topic count forum post information :: $id");
  1744.  
  1745.                 if ( $row = $db->sql_fetchrow($result) )
  1746.                 {
  1747.                     $total_topics = ($row['total']) ? $row['total'] : 0;
  1748.                 }
  1749.                 else
  1750.                 {
  1751.                     $total_topics = 0;
  1752.                 }
  1753.  
  1754.                 $sql = "UPDATE " . FORUMS_TABLE . "
  1755.                     SET forum_last_post_id = $last_post, forum_posts = $total_posts, forum_topics = $total_topics
  1756.                     WHERE forum_id = $id";
  1757.                 query($sql, "Could not update forum post information :: $id");
  1758.  
  1759.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1760.             }
  1761.  
  1762.             print "<br />\n * Update default user and finalise configuration :: ";
  1763.             flush();
  1764.  
  1765.             //
  1766.             // Update the default admin user with their information.
  1767.             //
  1768.             $sql = "SELECT MIN(user_regdate) AS oldest_time 
  1769.                 FROM " . USERS_TABLE . " 
  1770.                 WHERE user_regdate > 0 AND user_id > 0";
  1771.             $result = query($sql, "Couldn't obtain oldest post time");
  1772.  
  1773.             $row = $db->sql_fetchrow($result);
  1774.  
  1775.             $sql = "INSERT INTO " . $table_prefix . "config (config_name, config_value) 
  1776.                 VALUES ('board_startdate', " . $row['oldest_time']  . ")";
  1777.             query($sql, "Couldn't insert board_startdate");
  1778.  
  1779.             $sql = "UPDATE " . $table_prefix . "config 
  1780.                 SET config_value = '" . $server_name . "' 
  1781.                 WHERE config_name = 'server_name' 
  1782.                     OR config_name = 'cookie_domain'";
  1783.             query($sql, "Couldn't insert Board Server domain");
  1784.  
  1785.             $sql = "UPDATE " . $table_prefix . "config 
  1786.                 SET config_value = '" . $server_port . "'
  1787.                 WHERE config_name = 'server_port'";
  1788.             query($sql, "Couldn't insert Board server port");
  1789.             
  1790.             $sql = "UPDATE " . $table_prefix . "config 
  1791.                 SET config_value = '" . $board_email . "'
  1792.                 WHERE config_name = 'board_email'";
  1793.             query($sql, "Couldn't insert Board admin email");
  1794.             
  1795.             $sql = "UPDATE " . $table_prefix . "config 
  1796.                 SET config_value = '" . $script_path . "'
  1797.                 WHERE config_name = 'script_path'";
  1798.             query($sql, "Couldn't insert Board script path");
  1799.             
  1800.             //
  1801.             // Change session table to HEAP if MySQL version matches
  1802.             //
  1803.             $sql = "SELECT VERSION() AS mysql_version";
  1804.             $result = query($sql, "Couldn't obtain MySQL Version");
  1805.  
  1806.             $row = $db->sql_fetchrow($result);
  1807.  
  1808.             $version = $row['mysql_version'];
  1809.  
  1810.             if ( preg_match("/^(3\.23)|(4\.)/", $version) )
  1811.             {
  1812.                 $sql = "ALTER TABLE " . $table_prefix . "sessions 
  1813.                     TYPE=HEAP MAX_ROWS=500";
  1814.                 $db->sql_query($sql);
  1815.             }
  1816.  
  1817.             echo "<span class=\"ok\"><b>OK</b></span><br />\n";
  1818.             end_step('drop_fields');
  1819.  
  1820.         case 'drop_fields':
  1821.             $fields = array(
  1822.                 BANLIST_TABLE => array("ban_start", "ban_end", "ban_time_type"),
  1823.                 FORUMS_TABLE => array("forum_access", "forum_moderator", "forum_type"), 
  1824.                 PRIVMSGS_TABLE => array("msg_text"), 
  1825.                 RANKS_TABLE => array("rank_max"), 
  1826.                 SMILIES_TABLE => array("emotion"),
  1827.                 TOPICS_TABLE => array("topic_notify")
  1828.             );
  1829.  
  1830.             while( list($table, $field_data) = each($fields) )
  1831.             {
  1832.                 for($i = 0; $i < count($field_data); $i++)
  1833.                 {
  1834.                     print " * Drop field '" . $field_data[$i] . "' in '$table' :: ";
  1835.                     flush();
  1836.  
  1837.                     $sql = "ALTER TABLE $table 
  1838.                         DROP COLUMN " . $field_data[$i];
  1839.                     query($sql, "Couldn't drop field :: " . $field_data[$i] . " from table :: $table");
  1840.  
  1841.                     print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1842.  
  1843.                 }
  1844.             }
  1845.  
  1846.             end_step('drop_tables');
  1847.  
  1848.         case 'drop_tables':
  1849.             $drop_tables = array('access', 'forum_access', 'forum_mods', 'headermetafooter', 'whosonline', $table_prefix . 'old_config');
  1850.  
  1851.             for($i = 0; $i < count($drop_tables); $i++)
  1852.             {
  1853.                 print " * Dropping table '" . $drop_tables[$i] . "' :: ";
  1854.                 flush();
  1855.  
  1856.                 $sql = "DROP TABLE " . $drop_tables[$i];
  1857.                 query($sql, "Couldn't drop table :: " . $drop_tables[$i]);
  1858.  
  1859.                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
  1860.             }
  1861.  
  1862.             end_step('fulltext_search_indexing');
  1863.  
  1864.         case 'fulltext_search_indexing':
  1865.             //
  1866.             // Generate search word list
  1867.             //
  1868.             // Fetch a batch of posts_text entries
  1869.             //
  1870.             $sql = "SELECT COUNT(*) as total, MAX(post_id) as max_post_id 
  1871.                 FROM " . POSTS_TEXT_TABLE;
  1872.             $result = query($sql, "Couldn't get post count totals");
  1873.  
  1874.             $max_post_id = $db->sql_fetchrow($result);
  1875.  
  1876.             $totalposts = $max_post_id['total'];
  1877.             $max_post_id = $max_post_id['max_post_id'];
  1878.             $per_percent = round(( $totalposts / 500 ) * 10);
  1879.  
  1880.             $postcounter = ( !isset($HTTP_GET_VARS['batchstart']) ) ? 0 : $HTTP_GET_VARS['batchstart'];
  1881.  
  1882.             $batchsize = 150; // Process this many posts per loop
  1883.             $batchcount = 0;
  1884.             $total_percent = 0;
  1885.  
  1886.             for(;$postcounter <= $max_post_id; $postcounter += $batchsize)
  1887.             {
  1888.                 $batchstart = $postcounter + 1;
  1889.                 $batchend = $postcounter + $batchsize;
  1890.                 $batchcount++;
  1891.  
  1892.                 print " * Fulltext Indexing ( $batchstart to $batchend ) :: ";
  1893.                 flush();
  1894.                 
  1895.                 $sql = "SELECT *
  1896.                     FROM " . POSTS_TEXT_TABLE ."
  1897.                     WHERE post_id 
  1898.                         BETWEEN $batchstart 
  1899.                             AND $batchend";
  1900.                 $posts_result = query($sql, "Couldn't obtain post_text");
  1901.  
  1902.                 $per_pct = ceil( $db->sql_numrows($posts_result) / 40 );
  1903.                 $inc = 0;
  1904.  
  1905.                 if ( $row = $db->sql_fetchrow($posts_result) )
  1906.                 { 
  1907.                     do
  1908.                     {
  1909.                         add_search_words('global', $row['post_id'], $row['post_text'], $row['post_subject']);
  1910.  
  1911.                         $inc++;
  1912.                         if ( $inc == $per_pct )
  1913.                         {
  1914.                             print ".";
  1915.                             flush();
  1916.                             $inc = 0;
  1917.                         }
  1918.                     }
  1919.                     while( $row = $db->sql_fetchrow($posts_result) );
  1920.                 }
  1921.  
  1922.                 $db->sql_freeresult($posts_result);
  1923.                 
  1924.                 // Remove common words after the first 2 batches and after every 4th batch after that.
  1925.                 if ( $batchcount % 4 == 3 )
  1926.                 {
  1927.                     remove_common('global', 4/10);
  1928.                 }
  1929.  
  1930.                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
  1931.             }
  1932.  
  1933.             echo "\n<br /><br />\n\n<font size=\"+3\"><b>UPGRADE COMPLETED</b></font><br />\n";
  1934.     }
  1935. }
  1936.  
  1937. print "<br />If the upgrade completed without error you may click <a href=\"./../index.$phpEx\">Here</a> to proceed to the index<br />";
  1938.  
  1939. common_footer();
  1940.  
  1941. ?>