]> scripts.mit.edu Git - autoinstalls/phpBB.git/blob - install/upgrade.php
phpBB 2.0.19
[autoinstalls/phpBB.git] / install / upgrade.php
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
376         for( $i = 0 ; $i < sizeof($haystack) ; $i++ )
377         { 
378                 if ( $haystack[$i] == $needle )
379                 { 
380                         return true; 
381                 } 
382         } 
383
384         return false; 
385 }
386
387 function end_step($next)
388 {
389         print "<hr /><a href=\"$PHP_SELF?next=$next\">Next step: <b>$next</b></a><br /><br />\n";
390         exit;
391 }
392 //
393 // End functions
394 // -------------
395
396
397 //
398 // Start at the beginning if the user hasn't specified a specific starting point.
399 //
400 $next = ( isset($HTTP_GET_VARS['next']) ) ? $HTTP_GET_VARS['next'] : 'start';
401
402 // If debug is set we'll do all steps in one go.
403 $debug = 1;
404
405 // Parse the MySQL schema file into some arrays.
406 $schema = get_schema();
407
408 $table_def = $schema['table_def'];
409 $field_def = $schema['field_def'];
410 $key_def = $schema['key_def'];
411 $create_def = $schema['create_def'];
412
413 //
414 // Get mysql_basic data
415 //
416 $inserts = get_inserts();
417
418 //
419 // Get smiley data
420 //
421 smiley_replace();
422
423 common_header();
424
425 if ( !empty($next) )
426 {
427         switch($next)
428         {
429                 case 'start':
430                         end_step('initial_drops');
431
432                 case 'initial_drops':
433                         print " * Dropping sessions and themes tables :: ";
434                         flush();
435
436                         query("DROP TABLE sessions", "Couldn't drop table 'sessions'");
437                         query("DROP TABLE themes", "Couldn't drop table 'themes'");   
438
439                         print "<span class=\"ok\"><b>OK</b></span><br />\n";
440
441                         end_step('mod_old_tables');
442
443                 case 'mod_old_tables':
444                         $modtables = array(
445                                 "banlist" => "banlist",
446                                 "catagories" => "categories",
447                                 "config" => "old_config",
448                                 "forums" => "forums",
449                                 "disallow" => "disallow",
450                                 "posts" => "posts",
451                                 "posts_text" => "posts_text",
452                                 "priv_msgs" => "privmsgs",
453                                 "ranks" => "ranks",
454                                 "smiles" => "smilies",
455                                 "topics" => "topics",
456                                 "users" => "users",
457                                 "words" => "words"
458                         );
459
460                         while( list($old, $new) = each($modtables) )
461                         {
462                                 $result = query("SHOW INDEX FROM $old", "Couldn't get list of indices for table $old");
463
464                                 while( $row = $db->sql_fetchrow($result) )
465                                 {
466                                         $index = $row['Key_name'];
467                                         if ( $index != 'PRIMARY' )
468                                         {
469                                                 query("ALTER TABLE $old DROP INDEX $index", "Couldn't DROP INDEX $old.$index");
470                                         }
471                                 }
472
473                                 // Rename table
474                                 $new = $table_prefix . $new;
475
476                                 print " * Renaming '$old' to '$new' :: ";
477                                 flush();
478                                 query("ALTER TABLE $old RENAME $new", "Failed to rename $old to $new");
479                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
480                                 
481                         }
482                         end_step('create_tables');
483                         
484                 case 'create_tables':
485                         // Create array with tables in 'old' database
486                         $result = query('SHOW TABLES', "Couldn't get list of current tables");
487
488                         while( $table = $db->sql_fetchrow($result) )
489                         {
490                                 $currenttables[] = $table[0];
491                         }
492                         
493                         // Check what tables we need to CREATE
494                         while( list($table, $definition) = each($table_def) )
495                         {
496                                 if ( !inarray($table, $currenttables) )
497                                 {
498                                         print " * Creating $table :: ";
499
500                                         query($definition, "Couldn't create table $table");
501
502                                         print "<span class=\"ok\"><b>OK</b></span><br />\n";
503                                 }
504                         }
505                         
506                         end_step('create_config');
507                         
508                 case 'create_config':
509                         print " * Inserting new values into new layout config table :: ";
510
511                         @reset($inserts);
512                         while( list($table, $inserts_table) = each($inserts) )
513                         {
514                                 if ( $table == CONFIG_TABLE )
515                                 {
516                                         $per_pct = ceil( count($inserts_table) / 40 );
517                                         $inc = 0;
518
519                                         while( list($nr, $insert) = each($inserts_table) )
520                                         {
521                                                 query($insert, "Couldn't insert value into config table");
522
523                                                 $inc++;
524                                                 if ( $inc == $per_pct )
525                                                 {
526                                                         print ".";
527                                                         flush();
528                                                         $inc = 0;
529                                                 }
530                                         }
531                                 }
532                         }
533
534                         print " <span class=\"ok\"><b>OK</b></span><br />\n";
535
536                         end_step('convert_config');
537                         
538                 case 'convert_config':
539                         print " * Converting configuration table :: ";
540
541                         $sql = "SELECT * 
542                                 FROM $table_prefix" . "old_config";
543                         $result = query($sql, "Couldn't get info from old config table");
544
545                         $oldconfig = $db->sql_fetchrow($result);
546
547                         //
548                         // We don't need several original config types and two others
549                         // have changed name ... so take account of this.
550                         //
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"
555                         );
556
557                         while( list($name, $value) = each($oldconfig) )
558                         {
559                                 if ( is_int($name) )
560                                 {
561                                         continue;
562                                 }
563
564                                 if ( !inarray($name, $ignore_configs) )
565                                 {
566                                         $name = ( !empty($rename_configs[$name]) ) ? $rename_configs[$name] : $name;
567                                         
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");
573                                 }
574                         }
575                         
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");
580                         
581                         print "<span class=\"ok\"><b>OK</b></span><br />\n";
582                         end_step('convert_ips');
583
584                 case 'convert_ips':
585                         $names = array( 
586                                 POSTS_TABLE => array(
587                                         'id' => 'post_id',
588                                         'field' => 'poster_ip'
589                                 ), 
590                                 PRIVMSGS_TABLE => array( 
591                                         'id' => 'msg_id', 
592                                         'field' => 'poster_ip'
593                                 ), 
594                                 BANLIST_TABLE => array( 
595                                         'id' => 'ban_id', 
596                                         'field' => 'ban_ip'
597                                 )
598                         );
599
600                         lock_tables(1, array(POSTS_TABLE, PRIVMSGS_TABLE, BANLIST_TABLE));
601
602                         $batchsize = 2000;
603                         while( list($table, $data_array) = each($names) )
604                         {
605                                 $sql = "SELECT MAX(" . $data_array['id'] . ") AS max_id 
606                                         FROM $table";
607                                 $result = query($sql, "Couldn't obtain ip data from $table (" . $fields . ")");
608
609                                 $row = $db->sql_fetchrow($result);
610
611                                 $maxid = $row['max_id'];
612
613                                 for($i = 0; $i <= $maxid; $i += $batchsize)
614                                 {
615                                         $batchstart = $i;
616                                         $batchend = $i + $batchsize;
617
618                                         $field_id = $data_array['id'];
619                                         $field = $data_array['field'];
620
621                                         print " * Converting IP format '" . $field . "' / '$table' ( $batchstart to $batchend ) :: ";
622                                         flush();
623
624                                         $sql = "SELECT $field_id, $field 
625                                                 FROM $table 
626                                                 WHERE $field_id 
627                                                         BETWEEN $batchstart 
628                                                                 AND $batchend";
629                                         $result = query($sql, "Couldn't obtain ip data from $table (" . $fields . ")");
630
631                                         $per_pct = ceil( $db->sql_numrows($result) / 40 );
632                                         $inc = 0;
633
634                                         while( $row = $db->sql_fetchrow($result) )
635                                         {
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]);
640
641                                                 $inc++;
642                                                 if ( $inc == $per_pct )
643                                                 {
644                                                         print ".";
645                                                         flush();
646                                                         $inc = 0;
647                                                 }
648                                         }
649
650                                         print " <span class=\"ok\"><b>OK</b></span><br />\n";
651                                 }
652                         }
653
654                         lock_tables(0);
655                         end_step('convert_dates');
656
657                 case 'convert_dates':
658                         $names = array(
659                                 POSTS_TABLE => array('post_time'),
660                                 TOPICS_TABLE => array('topic_time'), 
661                                 PRIVMSGS_TABLE => array('msg_time')
662                         );
663
664                         lock_tables(1, array(POSTS_TABLE, TOPICS_TABLE, PRIVMSGS_TABLE));
665
666                         while( list($table, $fields) = each($names) )
667                         {
668                                 print " * Converting date format of $fields[$i] in $table :: ";
669                                 flush();
670
671                                 for($i = 0; $i < count($fields); $i++)
672                                 {
673                                         $sql = "UPDATE $table 
674                                                 SET " . $fields[$i] . " = UNIX_TIMESTAMP(" . $fields[$i] . ")";
675                                         query($sql, "Couldn't convert date format of $table(" . $fields[$i] . ")");
676                                 }
677
678                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
679                         }
680
681                         lock_tables(0);
682                         end_step('fix_addslashes');
683
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');
691
692                         //convert smilies?
693                         $slashes = array(
694                                 "\\'" => "'",
695                                 "\\\"" => "\"",
696                                 "\\\\" => "\\");
697                         $slashes = array(
698                                 "\\'" => "'",
699                                 "\\\"" => "\"",
700                                 "\\\\" => "\\");
701
702                         lock_tables(1, array(TOPICS_TABLE, FORUMS_TABLE, CATEGORIES_TABLE, WORDS_TABLE, RANKS_TABLE, DISALLOW_TABLE, SMILIES_TABLE));
703
704                         while( list($table, $fields) = each($slashfields) )
705                         {
706                                 print " * Removing slashes from $table table :: ";
707                                 flush();
708
709                                 while( list($nr, $field) = each($fields) )
710                                 {
711                                         @reset($slashes);
712                                         while( list($search, $replace) = each($slashes) )
713                                         {
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.");
717                                         }
718                                 }
719
720                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
721                         }
722
723                         lock_tables(0);
724                         end_step('remove_topics');
725
726                 case 'remove_topics':
727                         print " * Removing posts with no corresponding topics :: ";
728                         flush();
729
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");
735                         
736                         $post_total = $db->sql_numrows($result);
737
738                         if ( $post_total )
739                         {
740                                 $post_id_ary = array();
741                                 while( $row = $db->sql_fetchrow($result) )
742                                 {
743                                         $post_id_ary[] = $row['post_id'];
744                                 }
745
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");
749
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");
753                         }
754
755                         echo "<span class=\"ok\"><b>OK</b></span> ( Removed $post_total posts )<br />\n";
756                         end_step('convert_users');
757
758                 case 'convert_users':
759                         //
760                         // Completely remove old soft-deleted users
761                         //
762                         $sql = "DELETE FROM " . USERS_TABLE . " 
763                                 WHERE user_level = -1";
764                         query($sql, "Couldn't delete old soft-deleted users");
765
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.");
769
770                         $row = $db->sql_fetchrow($result);
771
772                         $totalposts = $row['total'];
773                         $maxid = $row['maxid'];
774
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");
779
780                         $super_mods = array();
781                         $first_admin = -2;
782
783                         $batchsize = 1000;
784                         for($i = -1; $i <= $maxid; $i += $batchsize)
785                         {
786                                 $batchstart = $i;
787                                 $batchend = $i + $batchsize;
788                                 
789                                 print " * Converting Users ( $batchstart to $batchend ) :: ";
790                                 flush();
791
792                                 $sql = "SELECT * 
793                                         FROM " . USERS_TABLE . " 
794                                         WHERE user_id 
795                                                 BETWEEN $batchstart 
796                                                         AND $batchend";
797                                 $result = query($sql, "Couldn't get ". USERS_TABLE .".user_id $batchstart to $batchend");
798
799                                 // Array with user fields that we want to check for invalid data (to few characters)
800                                 $checklength = array(
801                                         'user_occ',
802                                         'user_website',
803                                         'user_email',
804                                         'user_from',
805                                         'user_intrest',
806                                         'user_aim',
807                                         'user_yim',
808                                         'user_msnm');
809
810                                 lock_tables(1, array(USERS_TABLE, GROUPS_TABLE, USER_GROUP_TABLE, POSTS_TABLE));
811
812                                 $per_pct = ceil( $db->sql_numrows($result) / 40 );
813                                 $inc = 0;
814
815                                 while( $row = $db->sql_fetchrow($result) )
816                                 {
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);
820
821                                         $group_id = $db->sql_nextid();
822
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);
826
827                                         if ( is_int($row['user_regdate']) )
828                                         {
829                                                 // We already converted this post to the new style BBcode, skip this post.
830                                                 continue;
831                                         }
832
833                                         //
834                                         // Nathan's bbcode2 conversion
835                                         //
836
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']);
841
842                                         // make a uid
843                                         $uid = make_bbcode_uid();
844
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']);
848
849                                         // Check for invalid info like '-' and '?' for a lot of fields
850                                         @reset($checklength);
851                                         while($field = each($checklength))
852                                         {
853                                                 $row[$field[1]] = strlen($row[$field[1]]) < 3 ? '' : $row[$field[1]];
854                                         }
855
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]);
858
859                                         $website = $row['user_website'];
860                                         if ( substr(strtolower($website), 0, 7) != "http://" )
861                                         {
862                                                 $website = "http://" . $website;
863                                         }
864                                         if( strtolower($website) == 'http://' )
865                                         {
866                                                 $website = '';
867                                         }
868                                         $row['user_website'] = addslashes($website);
869                                         
870                                         $row['user_icq'] = (ereg("^[0-9]+$", $row['user_icq'])) ? $row['user_icq'] : '';
871                                         @reset($checklength);
872
873                                         while($field = each($checklength))
874                                         {
875                                                 if ( strlen($row[$field[1]]) < 3 )
876                                                 {
877                                                         $row[$field[1]] = '';
878                                                 }
879                                                 $row[$field[1]] = addslashes($row[$field[1]]);
880                                         }
881                                         
882                                         //
883                                         // Is user a super moderator?
884                                         //
885                                         if( $row['user_level'] == 3 )
886                                         {
887                                                 $super_mods[] = $row['user_id'];
888                                         }
889
890                                         $row['user_level'] = ( $row['user_level'] == 4 ) ? ADMIN : USER;
891
892                                         //
893                                         // Used to define a 'practical' group moderator user_id
894                                         // for super mods a little latter.
895                                         //
896                                         if( $first_admin == -2 && $row['user_level'] == ADMIN )
897                                         {
898                                                 $first_admin = $row['user_id'];
899                                         }
900
901                                         //
902                                         // Dutch language files have been renamed from 'nederlands' to 'dutch'
903                                         //
904                                         if( $row['user_lang'] == 'nederlands' )
905                                         {
906                                                 $row['user_lang'] = 'dutch';
907                                         }
908
909                                         $sql = "UPDATE " . USERS_TABLE . " 
910                                                 SET 
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), 
924                                                         user_bbcode = 1, 
925                                                         user_theme = 1 
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']);
928
929                                         $inc++;
930                                         if ( $inc == $per_pct )
931                                         {
932                                                 print ".";
933                                                 flush();
934                                                 $inc = 0;
935                                         }
936                                 }
937
938                                 // Set any non-standard (like) email addresses to nothing
939                                 // could do this above as a preg_ but this one query may
940                                 // be faster
941                                 $sql = "UPDATE " . USERS_TABLE . " 
942                                         SET user_email = '' 
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");
945
946                                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
947
948                                 lock_tables(0);
949                         }
950
951                         //
952                         // Handle super-mods, create hidden group for them
953                         //
954                         // Iterate trough access table
955                         if( count($super_mods) && $first_admin != -2 )
956                         {
957                                 print "\n<br />\n * Creating new group for super moderators :: ";
958                                 flush();
959
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']);
963
964                                 $group_id = $db->sql_nextid();
965
966                                 if ( $group_id <= 0 )
967                                 {
968                                         print "<font color=\"red\">Group creation failed. Aborting creation of groups...<br></font>\n";
969                                         continue 2;
970                                 }
971
972                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
973
974                                 print " * Updating auth_access for super moderator group :: ";
975                                 flush();
976
977                                 $sql = "SELECT forum_id 
978                                         FROM " . FORUMS_TABLE;
979                                 $result = query($sql, "Couldn't obtain forum_id list");
980
981                                 while( $row = $db->sql_fetchrow($result) )
982                                 {
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.");
986                                 }
987
988                                 for($i = 0; $i < count($super_mods); $i++)
989                                 {
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");
993                                 }
994                         
995                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
996                         }
997
998                         end_step('convert_posts');
999
1000                 case 'convert_posts':
1001                         print " * Adding enable_sig field to " . POSTS_TABLE . " :: ";
1002                         flush();
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";
1007                         
1008                         print " * Adding enable_bbcode field to " . POSTS_TEXT_TABLE . " :: ";
1009                         flush();
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";
1014
1015                         print " * Adding bbcode_uid field to " . POSTS_TEXT_TABLE . " :: ";
1016                         flush();
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";
1021                         
1022                         print " * Adding post_edit_time field to " . POSTS_TABLE . " :: ";
1023                         flush();
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";
1028
1029                         print " * Adding post_edit_count field to " . POSTS_TABLE . " :: ";
1030                         flush();
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";
1035
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.");
1039
1040                         $maxid = $db->sql_fetchrow($result);
1041
1042                         $totalposts = $maxid['total'];
1043                         $maxid = $maxid['maxid'];
1044
1045                         $batchsize = 2000;
1046                         for($i = 0; $i <= $maxid; $i += $batchsize)
1047                         {
1048                                 $batchstart = $i + 1;
1049                                 $batchend = $i + $batchsize;
1050                                 
1051                                 print " * Converting BBcode ( $batchstart to $batchend ) :: ";
1052                                 flush();
1053
1054                                 $sql = "SELECT * 
1055                                         FROM " . POSTS_TEXT_TABLE . "
1056                                         WHERE post_id 
1057                                                 BETWEEN $batchstart 
1058                                                         AND $batchend";
1059                                 $result = query($sql, "Couldn't get ". POSTS_TEXT_TABLE .".post_id $batchstart to $batchend");
1060
1061                                 lock_tables(1, array(POSTS_TEXT_TABLE, POSTS_TABLE));
1062
1063                                 $per_pct = ceil( $db->sql_numrows($result) / 40 );
1064                                 $inc = 0;
1065
1066                                 while( $row = $db->sql_fetchrow($result) )
1067                                 {
1068                                         if ( $row['bbcode_uid'] != '' )
1069                                         {
1070                                                 // We already converted this post to the new style BBcode, skip this post.
1071                                                 continue;
1072                                         }
1073
1074                                         //
1075                                         // Nathan's bbcode2 conversion
1076                                         //
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']);
1081
1082                                         // make a uid
1083                                         $uid = make_bbcode_uid();
1084
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']);
1089
1090                                         $edited_sql = "";
1091                                         if ( preg_match('/^(.*?)([\n]+<font size=\-1>\[ This message was .*?)$/s', $row['post_text'], $matches) )
1092                                         {
1093                                                 $row['post_text'] = $matches[1];
1094                                                 $edit_info = $matches[2];
1095
1096                                                 $edit_times = count(explode(' message ', $edit_info)) - 1; // Taken from example for substr_count in annotated PHP manual
1097
1098                                                 if ( preg_match('/^.* by: (.*?) on (....)-(..)-(..) (..):(..) \]<\/font>/s', $edit_info, $matches) )
1099                                                 {
1100                                                         $edited_user = $matches[1];
1101                                                         $edited_time = gmmktime($matches[5], $matches[6], 0, $matches[3], $matches[4], $matches[2]);
1102
1103                                                         //
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 ...
1106                                                         //
1107                                                         $edited_sql = ", post_edit_time = $edited_time, post_edit_count = $edit_times";
1108                                                 }
1109                                         }
1110         
1111                                         if ( preg_match("/^(.*?)\n-----------------\n.*$/is", $row['post_text'], $matches) )
1112                                         {
1113                                                 $row['post_text'] = $matches[1];
1114                                                 $enable_sig = 1;
1115                                         }
1116                                         else
1117                                         {
1118                                                 $checksig = preg_replace('/\[addsig\]$/', '', $row['post_text']);
1119                                                 $enable_sig = ( strlen($checksig) == strlen($row['post_text']) ) ? 0 : 1;
1120                                         }
1121
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']);
1126
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']);
1131
1132                                         $inc++;
1133                                         if ( $inc == $per_pct )
1134                                         {
1135                                                 print '.';
1136                                                 flush();
1137                                                 $inc = 0;
1138                                         }
1139                                 }
1140
1141                                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
1142
1143                                 lock_tables(0);
1144                         }
1145
1146                         print "<br />\n * Updating poster_id for deleted users :: ";
1147                         flush();
1148
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");
1154                         
1155                         $users_removed = $db->sql_numrows($result);
1156
1157                         if ( $users_removed )
1158                         {
1159                                 $post_id_ary = array();
1160                                 while( $row = $db->sql_fetchrow($result) )
1161                                 {
1162                                         $post_id_ary[] = $row['post_id'];
1163                                 }
1164
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");
1169                         }
1170
1171                         print "<span class=\"ok\"><b>OK</b></span> ( Removed $users_removed non-existent user references )<br />\n";
1172
1173                         end_step('convert_privmsgs');
1174
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.");
1179
1180                         $maxid = $db->sql_fetchrow($result);
1181
1182                         $totalposts = $maxid['total'];
1183                         $maxid = $maxid['maxid'];
1184
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");
1189
1190                         $batchsize = 2000;
1191                         for($i = 0; $i <= $maxid; $i += $batchsize)
1192                         {
1193                                 $batchstart = $i + 1;
1194                                 $batchend = $i + $batchsize;
1195                                 
1196                                 print " * Converting Private Message ( $batchstart to $batchend ) :: ";
1197                                 flush();
1198
1199                                 $sql = "SELECT * 
1200                                         FROM " . PRIVMSGS_TABLE . "
1201                                         WHERE msg_id 
1202                                                 BETWEEN $batchstart 
1203                                                         AND $batchend";
1204                                 $result = query($sql, "Couldn't get " . POSTS_TEXT_TABLE . " post_id $batchstart to $batchend");
1205
1206                                 lock_tables(1, array(PRIVMSGS_TABLE, PRIVMSGS_TEXT_TABLE));
1207
1208                                 $per_pct = ceil( $db->sql_numrows($result) / 40 );
1209                                 $inc = 0;
1210
1211                                 while( $row = $db->sql_fetchrow($result) )
1212                                 {
1213                                         if ( $row['msg_text'] == NULL )
1214                                         {
1215                                                 // We already converted this post to the new style BBcode, skip this post.
1216                                                 continue;
1217                                         }
1218                                         //
1219                                         // Nathan's bbcode2 conversion
1220                                         //
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']);
1225
1226                                         // make a uid
1227                                         $uid = make_bbcode_uid();
1228
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);
1232                                         
1233                                         $checksig = preg_replace('/\[addsig\]$/', '', $row['msg_text']);
1234                                         $enable_sig = (strlen($checksig) == strlen($row['msg_text'])) ? 0 : 1;
1235
1236                                         if ( preg_match("/^(.*?)\n-----------------\n.*$/is", $checksig, $matches) )
1237                                         {
1238                                                 $checksig = $matches[1];
1239                                                 $enable_sig = 1;
1240                                         }
1241
1242                                         $row['msg_text'] = $checksig;
1243                                         
1244                                         $row['msg_status'] = ($row['msg_status'] == 1) ? PRIVMSGS_READ_MAIL : PRIVMSGS_NEW_MAIL;
1245
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);
1249                                         
1250                                         $row['msg_text'] = addslashes($row['msg_text']);
1251
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']);
1255
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']);
1260
1261                                         $inc++;
1262                                         if ( $inc == $per_pct )
1263                                         {
1264                                                 print '.';
1265                                                 flush();
1266                                                 $inc = 0;
1267                                         }
1268                                 }
1269
1270                                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
1271                         }
1272
1273                         lock_tables(0);
1274                         end_step('convert_moderators');
1275
1276                 case 'convert_moderators';
1277                         $sql = "SELECT * 
1278                                 FROM forum_mods";
1279                         $result = query($sql, "Couldn't get list with all forum moderators");
1280
1281                         while( $row = $db->sql_fetchrow($result) )
1282                         {
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");
1289
1290                                 if ( !($rowtest = $db->sql_fetchrow($check_data)) )
1291                                 {
1292                                         // Either the moderator or the forum have been deleted, this line in forum_mods was redundant, skip it.
1293                                         continue;
1294                                 }
1295
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'] . ".");
1302
1303                                 $group_id = $db->sql_fetchrow($insert_group);
1304                                 $group_id = $group_id['group_id'];
1305
1306                                 print " * Adding moderator for forum " . $row['forum_id'] . " :: ";
1307                                 flush();
1308
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'] . ".");
1311
1312                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1313                         }
1314
1315                         print " * Setting correct user_level for moderators ::";
1316                         flush();
1317
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");
1325
1326                         if ( $row = $db->sql_fetchrow($result) )
1327                         {
1328                                 $ug_sql = '';
1329
1330                                 do
1331                                 {
1332                                         $ug_sql .= ( ( $ug_sql != '' ) ? ', ' : '' ) . $row['user_id'];
1333                                 }
1334                                 while ( $row = $db->sql_fetchrow($result) );
1335
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");
1340                         }
1341
1342                         print "<span class=\"ok\"><b>OK</b></span><br />\n";
1343                         
1344                         end_step('convert_privforums');
1345
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)");
1352
1353                         $forum_id = -1;
1354                         while( $row = $db->sql_fetchrow($forum_access) )
1355                         {
1356                                 // Iterate trough access table
1357                                 if ( $row['forum_id'] != $forum_id )
1358                                 {
1359                                         // This is a new forum, create new group.
1360                                         $forum_id = $row['forum_id'];
1361
1362                                         print " * Creating new group for forum $forum_id :: ";
1363                                         flush();
1364
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']);
1368
1369                                         $group_id = $db->sql_nextid();
1370
1371                                         if ( $group_id <= 0 )
1372                                         {
1373                                                 print "<font color=\"red\">Group creation failed. Aborting creation of groups...<br></font>\n";
1374                                                 continue 2;
1375                                         }
1376
1377                                         print "<span class=\"ok\"><b>OK</b></span><br />\n";
1378
1379                                         print " * Creating auth_access group for forum $forum_id :: ";
1380                                         flush();
1381
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.");
1385
1386                                         if ( $db->sql_affectedrows($result) <= 0 )
1387                                         {
1388                                                 print "<font color=\"red\">Group creation failed. Aborting creation of groups...</font><br>\n";
1389                                                 continue 2;
1390                                         }
1391
1392                                         print "<span class=\"ok\"><b>OK</b></span><br />\n";
1393                                 }
1394
1395                                 // Add user to the group
1396                                 $user_id = $row['user_id'];
1397
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");
1401                         }
1402
1403                         end_step('update_schema');
1404
1405                 case 'update_schema':
1406                         $rename = array(
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" 
1413                                 ),
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" 
1421                                 ),
1422                                 $table_prefix . "smilies" => array(
1423                                         "smilies_id" => "id"
1424                                 )
1425                         );
1426
1427                         $schema = get_schema();
1428
1429                         $table_def = $schema['table_def'];
1430                         $field_def = $schema['field_def'];
1431
1432                         // Loop tables in schema
1433                         while (list($table, $table_def) = @each($field_def))
1434                         {
1435                                 // Loop fields in table
1436                                 print " * Updating table '$table' :: ";
1437                                 flush();
1438                                 
1439                                 $sql = "SHOW FIELDS 
1440                                         FROM $table";
1441                                 $result = query($sql, "Can't get definition of current $table table");
1442
1443                                 while( $row = $db->sql_fetchrow($result) )
1444                                 {
1445                                         $current_fields[] = $row['Field'];
1446                                 }
1447                                 
1448                                 $alter_sql = "ALTER TABLE $table ";
1449                                 while (list($field, $definition) = each($table_def))
1450                                 {
1451                                         if ( $field == '' )
1452                                         {
1453                                                 // Skip empty fields if any (shouldn't be needed)
1454                                                 continue;
1455                                         }
1456
1457                                         $type = $definition['type'];
1458                                         $size = $definition['size'];
1459
1460                                         $default = isset($definition['default']) ? "DEFAULT " . $definition['default'] : '';
1461
1462                                         $notnull = $definition['notnull'] == 1 ? 'NOT NULL' : '';
1463
1464                                         $auto_increment = $definition['auto_increment'] == 1 ? 'auto_increment' : '';
1465
1466                                         $oldfield = isset($rename[$table][$field]) ? $rename[$table][$field] : $field;
1467
1468                                         if ( !inarray($field, $current_fields) && $oldfield == $field )
1469                                         {
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];
1473                                         }
1474                                         else
1475                                         {
1476                                                 $changes[] = " CHANGE $oldfield $field " . $create_def[$table][$field];
1477                                         }
1478                                 }
1479                                 
1480                                 $alter_sql .= join(',', $changes);
1481                                 unset($changes);
1482                                 unset($current_fields);
1483                                 
1484                                 $sql = "SHOW INDEX 
1485                                         FROM $table";
1486                                 $result = query($sql, "Couldn't get list of indices for table $table");
1487
1488                                 unset($indices);
1489
1490                                 while( $row = $db->sql_fetchrow($result) )
1491                                 {
1492                                         $indices[] = $row['Key_name'];
1493                                 }
1494                                 
1495                                 while ( list($key_name, $key_field) = each($key_def[$table]) )
1496                                 {
1497                                         if ( !inarray($key_name, $indices) )
1498                                         {
1499                                                 $alter_sql .= ($key_name == 'PRIMARY') ? ", ADD PRIMARY KEY ($key_field)" : ", ADD INDEX $key_name ($key_field)";
1500                                         }
1501                                 }
1502                                 query($alter_sql, "Couldn't alter table $table");
1503
1504                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1505                                 flush();
1506                         }
1507
1508                         end_step('convert_forums');
1509
1510                 case 'convert_forums':
1511                         $sql = "SELECT * 
1512                                 FROM " . FORUMS_TABLE;
1513                         $result = query($sql, "Couldn't get list with all forums");
1514
1515                         while( $row = $db->sql_fetchrow($result) )
1516                         {
1517                                 print " * Converting forum '" . $row['forum_name'] . "' :: ";
1518                                 flush();
1519
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'] )
1525                                 {
1526                                         case 1:
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;
1538                                                 break;
1539                                         case 2:
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;
1548                                                 break;
1549                                         default:
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;
1558                                                 break;
1559                                 }
1560                                 
1561                                 // Old auth structure:
1562                                 // forum_type: (only concerns viewing)
1563                                 //              0 = Public
1564                                 //              1 = Private
1565                                 switch( $row['forum_type'] )
1566                                 {
1567                                         case 0:
1568                                                 $auth_view                      = AUTH_ALL;
1569                                                 $auth_read                      = AUTH_ALL;
1570                                                 break;
1571                                         default:
1572                                                 //
1573                                                 // Make it really private ... 
1574                                                 //
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;
1585                                                 break;
1586                                 }
1587
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!");
1601
1602                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1603                         }
1604
1605                         end_step('insert_themes');
1606
1607                 case 'insert_themes':
1608                         print " * Inserting new values into themes table :: ";
1609
1610                         @reset($inserts);
1611                         while( list($table, $inserts_table) = each($inserts) )
1612                         {
1613                                 if ( $table == THEMES_TABLE )
1614                                 {
1615                                         $per_pct = ceil( count($inserts_table) / 40 );
1616                                         $inc = 0;
1617
1618                                         while( list($nr, $insert) = each($inserts_table) )
1619                                         {
1620                                                 query($insert, "Couldn't insert value into " . THEMES_TABLE);
1621
1622                                                 $inc++;
1623                                                 if ( $inc == $per_pct )
1624                                                 {
1625                                                         print ".";
1626                                                         flush();
1627                                                         $inc = 0;
1628                                                 }
1629                                         }
1630                                 }
1631                         }
1632
1633                         print " <span class=\"ok\"><b>OK</b></span><br />\n";
1634                         end_step('update_topics');
1635
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");
1640
1641                         $row = $db->sql_fetchrow($result);
1642
1643                         $maxid = $row['max_topic'];
1644
1645                         lock_tables(1, array(TOPICS_TABLE, POSTS_TABLE));
1646
1647                         $batchsize = 1000;
1648                         for($i = 0; $i <= $maxid; $i += $batchsize)
1649                         {
1650                                 $batchstart = $i + 1;
1651                                 $batchend = $i + $batchsize;
1652                                 
1653                                 print " * Setting topic first post_id ( $batchstart to $batchend ) :: ";
1654                                 flush();
1655
1656                                 $sql = "SELECT MIN(post_id) AS first_post_id, topic_id
1657                                         FROM " . POSTS_TABLE . "
1658                                         WHERE topic_id 
1659                                                 BETWEEN $batchstart 
1660                                                         AND $batchend 
1661                                         GROUP BY topic_id 
1662                                         ORDER BY topic_id ASC";
1663                                 $result = query($sql, "Couldn't get post id data");
1664
1665                                 $per_pct = ceil( $db->sql_numrows($result) / 40 );
1666                                 $inc = 0;
1667
1668                                 if ( $row = $db->sql_fetchrow($result) )
1669                                 {
1670                                         do
1671                                         {
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");
1676
1677                                                 $inc++;
1678                                                 if ( $inc == $per_pct )
1679                                                 {
1680                                                         print ".";
1681                                                         flush();
1682                                                         $inc = 0;
1683                                                 }
1684                                         }
1685                                         while ( $row = $db->sql_fetchrow($result) );
1686                                 }
1687
1688                                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
1689                         }
1690
1691                         lock_tables(0);
1692                         end_step('final_configuration');
1693
1694                 case 'final_configuration':
1695                         //
1696                         // Update forum last post information
1697                         //
1698                         $sql = "SELECT forum_id, forum_name 
1699                                 FROM " . FORUMS_TABLE;
1700                         $f_result = query($sql, "Couldn't obtain forum_ids");
1701
1702                         while( $forum_row = $db->sql_fetchrow($f_result) )
1703                         {
1704                                 print " * Updating '" . $forum_row['forum_name'] . "' post info :: ";
1705                                 flush();
1706
1707                                 $id = $forum_row['forum_id'];
1708
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");
1714
1715                                 if ( $row = $db->sql_fetchrow($result) )
1716                                 {
1717                                         $first_post = ( $row['first_post'] ) ? $row['first_post'] : 0;
1718                                         $last_post = ($row['last_post']) ? $row['last_post'] : 0;
1719                                 }
1720                                 else
1721                                 {
1722                                         $first_post = 0;
1723                                         $last_post = 0;
1724                                 }
1725
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");
1730
1731                                 if ( $row = $db->sql_fetchrow($result) )
1732                                 {
1733                                         $total_posts = ($row['total']) ? $row['total'] : 0;
1734                                 }
1735                                 else
1736                                 {
1737                                         $total_posts = 0;
1738                                 }
1739
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");
1745
1746                                 if ( $row = $db->sql_fetchrow($result) )
1747                                 {
1748                                         $total_topics = ($row['total']) ? $row['total'] : 0;
1749                                 }
1750                                 else
1751                                 {
1752                                         $total_topics = 0;
1753                                 }
1754
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");
1759
1760                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1761                         }
1762
1763                         print "<br />\n * Update default user and finalise configuration :: ";
1764                         flush();
1765
1766                         //
1767                         // Update the default admin user with their information.
1768                         //
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");
1773
1774                         $row = $db->sql_fetchrow($result);
1775
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");
1779
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");
1785
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");
1790                         
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");
1795                         
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");
1800                         
1801                         //
1802                         // Change session table to HEAP if MySQL version matches
1803                         //
1804                         $sql = "SELECT VERSION() AS mysql_version";
1805                         $result = query($sql, "Couldn't obtain MySQL Version");
1806
1807                         $row = $db->sql_fetchrow($result);
1808
1809                         $version = $row['mysql_version'];
1810
1811                         if ( preg_match("/^(3\.23)|(4\.)/", $version) )
1812                         {
1813                                 $sql = "ALTER TABLE " . $table_prefix . "sessions 
1814                                         TYPE=HEAP MAX_ROWS=500";
1815                                 $db->sql_query($sql);
1816                         }
1817
1818                         echo "<span class=\"ok\"><b>OK</b></span><br />\n";
1819                         end_step('drop_fields');
1820
1821                 case 'drop_fields':
1822                         $fields = array(
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")
1829                         );
1830
1831                         while( list($table, $field_data) = each($fields) )
1832                         {
1833                                 for($i = 0; $i < count($field_data); $i++)
1834                                 {
1835                                         print " * Drop field '" . $field_data[$i] . "' in '$table' :: ";
1836                                         flush();
1837
1838                                         $sql = "ALTER TABLE $table 
1839                                                 DROP COLUMN " . $field_data[$i];
1840                                         query($sql, "Couldn't drop field :: " . $field_data[$i] . " from table :: $table");
1841
1842                                         print "<span class=\"ok\"><b>OK</b></span><br />\n";
1843
1844                                 }
1845                         }
1846
1847                         end_step('drop_tables');
1848
1849                 case 'drop_tables':
1850                         $drop_tables = array('access', 'forum_access', 'forum_mods', 'headermetafooter', 'whosonline', $table_prefix . 'old_config');
1851
1852                         for($i = 0; $i < count($drop_tables); $i++)
1853                         {
1854                                 print " * Dropping table '" . $drop_tables[$i] . "' :: ";
1855                                 flush();
1856
1857                                 $sql = "DROP TABLE " . $drop_tables[$i];
1858                                 query($sql, "Couldn't drop table :: " . $drop_tables[$i]);
1859
1860                                 print "<span class=\"ok\"><b>OK</b></span><br />\n";
1861                         }
1862
1863                         end_step('fulltext_search_indexing');
1864
1865                 case 'fulltext_search_indexing':
1866                         //
1867                         // Generate search word list
1868                         //
1869                         // Fetch a batch of posts_text entries
1870                         //
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");
1874
1875                         $max_post_id = $db->sql_fetchrow($result);
1876
1877                         $totalposts = $max_post_id['total'];
1878                         $max_post_id = $max_post_id['max_post_id'];
1879                         $per_percent = round(( $totalposts / 500 ) * 10);
1880
1881                         $postcounter = ( !isset($HTTP_GET_VARS['batchstart']) ) ? 0 : $HTTP_GET_VARS['batchstart'];
1882
1883                         $batchsize = 150; // Process this many posts per loop
1884                         $batchcount = 0;
1885                         $total_percent = 0;
1886
1887                         for(;$postcounter <= $max_post_id; $postcounter += $batchsize)
1888                         {
1889                                 $batchstart = $postcounter + 1;
1890                                 $batchend = $postcounter + $batchsize;
1891                                 $batchcount++;
1892
1893                                 print " * Fulltext Indexing ( $batchstart to $batchend ) :: ";
1894                                 flush();
1895                                 
1896                                 $sql = "SELECT *
1897                                         FROM " . POSTS_TEXT_TABLE ."
1898                                         WHERE post_id 
1899                                                 BETWEEN $batchstart 
1900                                                         AND $batchend";
1901                                 $posts_result = query($sql, "Couldn't obtain post_text");
1902
1903                                 $per_pct = ceil( $db->sql_numrows($posts_result) / 40 );
1904                                 $inc = 0;
1905
1906                                 if ( $row = $db->sql_fetchrow($posts_result) )
1907                                 { 
1908                                         do
1909                                         {
1910                                                 add_search_words('global', $row['post_id'], $row['post_text'], $row['post_subject']);
1911
1912                                                 $inc++;
1913                                                 if ( $inc == $per_pct )
1914                                                 {
1915                                                         print ".";
1916                                                         flush();
1917                                                         $inc = 0;
1918                                                 }
1919                                         }
1920                                         while( $row = $db->sql_fetchrow($posts_result) );
1921                                 }
1922
1923                                 $db->sql_freeresult($posts_result);
1924                                 
1925                                 // Remove common words after the first 2 batches and after every 4th batch after that.
1926                                 if ( $batchcount % 4 == 3 )
1927                                 {
1928                                         remove_common('global', 4/10);
1929                                 }
1930
1931                                 print " <span class=\"ok\"><b>OK</b></span><br />\n";
1932                         }
1933
1934                         echo "\n<br /><br />\n\n<font size=\"+3\"><b>UPGRADE COMPLETED</b></font><br />\n";
1935         }
1936 }
1937
1938 print "<br />If the upgrade completed without error you may click <a href=\"./../index.$phpEx\">Here</a> to proceed to the index<br />";
1939
1940 common_footer();
1941
1942 ?>