Main Page | Namespace List | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

importPhase2.php

Go to the documentation of this file.
00001 <?php 00002 # MediaWiki 'phase 2' to current format import script 00003 # (import format current as of 1.2.0, March 2004) 00004 # 00005 # Copyright (C) 2004 Brion Vibber <brion@pobox.com> 00006 # Portions by Lee Daniel Crocker, 2002 00007 # http://www.mediawiki.org/ 00008 # 00009 # This program is free software; you can redistribute it and/or modify 00010 # it under the terms of the GNU General Public License as published by 00011 # the Free Software Foundation; either version 2 of the License, or 00012 # (at your option) any later version. 00013 # 00014 # This program is distributed in the hope that it will be useful, 00015 # but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 # GNU General Public License for more details. 00018 # 00019 # You should have received a copy of the GNU General Public License along 00020 # with this program; if not, write to the Free Software Foundation, Inc., 00021 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00022 # http://www.gnu.org/copyleft/gpl.html 00023 00024 if ( ! is_readable( "../LocalSettings.php" ) ) { 00025 print "A copy of your installation's LocalSettings.php\n" . 00026 "must exist in the source directory.\n"; 00027 exit(); 00028 } 00029 00030 $wgCommandLineMode = true; 00031 ini_set("implicit_flush", 1); 00032 00033 $DP = "../includes"; 00034 require_once( "../LocalSettings.php" ); 00035 require_once( "../AdminSettings.php" ); 00036 00037 $wgDBuser = $wgDBadminuser; 00038 $wgDBpassword = $wgDBadminpassword; 00039 00040 $sep = ( DIRECTORY_SEPARATOR == "\\" ) ? ";" : ":"; 00041 ini_set( "include_path", "$IP$sep$include_path" ); 00042 00043 require_once( "Setup.php" ); 00044 00045 require_once( "../install-utils.inc" ); 00046 require_once( "InitialiseMessages.inc" ); 00047 require_once( "rebuildlinks.inc" ); 00048 require_once( "rebuildrecentchanges.inc" ); 00049 require_once( "rebuildtextindex.inc" ); 00050 00051 class Phase2Importer { 00052 var $olddb, $titleCache; 00053 00054 function Phase2Importer( $database ) { 00055 $this->olddb = $database; 00056 $this->titleCache = new TitleCache; 00057 } 00058 00059 function importAll() { 00060 $this->importCurData(); 00061 $this->fixCurTitles(); 00062 00063 $this->importOldData(); 00064 $this->fixOldTitles(); 00065 00066 $this->importUserData(); 00067 $this->fixUserOptions(); 00068 00069 $this->importWatchlists(); 00070 00071 $this->importLinkData(); 00072 00073 /* 00074 # For some reason this is broken. RecentChanges will just start anew... 00075 rebuildRecentChangesTablePass1(); 00076 rebuildRecentChangesTablePass2(); 00077 */ 00078 00079 print "Rebuilding search index:\n"; 00080 dropTextIndex(); 00081 rebuildTextIndex(); 00082 createTextIndex(); 00083 00084 initialiseMessages(); 00085 } 00086 00087 # Simple import functions; for the most part these are pretty straightforward. 00088 # MySQL copies everything over to the new database and tweaks a few things. 00089 function importCurData() { 00090 print "Clearing pages from default install, if any...\n"; 00091 wfQuery( "DELETE FROM cur", DB_WRITE ); 00092 00093 print "Importing current revision data...\n"; 00094 wfQuery( "INSERT INTO cur (cur_id,cur_namespace,cur_title,cur_text,cur_comment, 00095 cur_user,cur_user_text,cur_timestamp,cur_restrictions,cur_counter, 00096 cur_is_redirect,cur_minor_edit,cur_is_new,cur_random,cur_touched,inverse_timestamp) 00097 SELECT cur_id,0,cur_title,cur_text,cur_comment, 00098 cur_user,cur_user_text,cur_timestamp,REPLACE(cur_restrictions,'is_',''),cur_counter, 00099 cur_text like '#redirect%',cur_minor_edit,0,RAND(),NOW()+0,99999999999999-cur_timestamp 00100 FROM {$this->olddb}.cur", DB_WRITE ); 00101 $n = mysql_affected_rows(); 00102 print "$n rows imported.\n"; 00103 } 00104 00105 function importOldData() { 00106 print "Clearing old revision data from default install, if any...\n"; 00107 wfQuery( "DELETE FROM old", DB_WRITE ); 00108 00109 print "Importing old revision data...\n"; 00110 wfQuery( "INSERT INTO old (old_id,old_namespace,old_title,old_text,old_comment, 00111 old_user,old_user_text,old_timestamp,old_minor_edit,old_flags,inverse_timestamp) 00112 SELECT old_id,0,old_title,old_text,old_comment, 00113 old_user,old_user_text,old_timestamp,old_minor_edit,'',99999999999999-old_timestamp 00114 FROM {$this->olddb}.old", DB_WRITE ); 00115 $n = mysql_affected_rows(); 00116 print "$n rows imported.\n"; 00117 } 00118 00119 function importUserData() { 00120 print "Clearing users from default install, if any...\n"; 00121 wfQuery( "DELETE FROM user", DB_WRITE ); 00122 00123 print "Importing user data...\n"; 00124 wfQuery( "INSERT INTO $newdb.user (user_id,user_name,user_rights, 00125 user_password,user_newpassword,user_email,user_options,user_touched) 00126 SELECT user_id,user_name,REPLACE(user_rights,'is_',''), 00127 MD5(CONCAT(user_id,'-',MD5(user_password))),'',user_email,user_options,NOW()+0 00128 FROM {$this->olddb}.user", DB_WRITE ); 00129 $n = mysql_affected_rows(); 00130 print "$n rows imported.\n"; 00131 } 00132 00133 # A little less clean... 00134 function importWatchlists() { 00135 print "Clearing watchlists from default install, if any...\n"; 00136 wfQuery( "DELETE FROM watchlist", DB_WRITE ); 00137 00138 print "Importing watchlists..."; 00139 $res = wfQuery( "SELECT user_id,user_watch FROM {$this->olddb}.user WHERE user_watch != ''", DB_WRITE ); 00140 $total = wfNumRows( $res ); 00141 $n = 0; 00142 print " ($total total)\n"; 00143 00144 while( $row = wfFetchObject( $res ) ) { 00145 $id = IntVal( $row->user_id ); 00146 $list = explode( "\n", $row->user_watch ); 00147 foreach( $list as $page ) { 00148 $title = $this->titleCache->fetch( $page ); 00149 if( is_null( $title ) ) { 00150 print "Caught bad title '{$row->title}'\n"; 00151 } else { 00152 $ns = $title->getNamespace(); 00153 $t = wfStrencode( $title->getDBkey() ); 00154 wfQuery( "INSERT INTO watchlist(wl_user,wl_namespace,wl_title) VALUES ($id,$ns,'$t')", DB_WRITE ); 00155 } 00156 } 00157 if( ++$n % 50 == 0 ) { 00158 print "$n\n"; 00159 } 00160 } 00161 wfFreeResult( $res ); 00162 } 00163 00164 function importLinkData() { 00165 # MUST BE CALLED BEFORE! fixCurTitles() 00166 print "Clearing links from default install, if any...\n"; 00167 wfQuery( "DELETE FROM links", DB_WRITE ); 00168 wfQuery( "DELETE FROM brokenlinks", DB_WRITE ); 00169 00170 print "Importing live links..."; 00171 wfQuery( "INSERT INTO links (l_from, l_to) 00172 SELECT DISTINCT linked_from,cur_id 00173 FROM {$this->olddb}.linked,{$this->olddb}.cur 00174 WHERE linked_to=cur_title", DB_WRITE ); 00175 $n = mysql_affected_rows(); 00176 print "$n rows imported.\n"; 00177 00178 print "Importing broken links..."; 00179 wfQuery( "INSERT INTO brokenlinks (bl_from, bl_to) 00180 SELECT DISTINCT cur_id,unlinked_to 00181 FROM {$this->olddb}.unlinked,{$this->olddb}.cur 00182 WHERE unlinked_from=cur_title", DB_WRITE ); 00183 $n = mysql_affected_rows(); 00184 print "$n rows imported.\n"; 00185 } 00186 00187 # Fixup functions: munge data that's already been brought into tables 00188 function fixCurTitles() { 00189 $this->fixTitles( "cur" ); 00190 } 00191 00192 function fixOldTitles() { 00193 $this->fixTitles( "old" ); 00194 } 00195 00196 function fixTitles( $table ) { 00197 print "Fixing titles in $table..."; 00198 $res = wfQuery( "SELECT DISTINCT {$table}_title AS title FROM $table", DB_WRITE ); 00199 $total = wfNumRows( $res ); 00200 $n = 0; 00201 print " ($total total)\n"; 00202 00203 while( $row = wfFetchObject( $res ) ) { 00204 $xt = wfStrencode( $row->title ); 00205 $title = $this->titleCache->fetch( $row->title ); 00206 if( is_null( $title ) ) { 00207 print "Caught bad title '{$row->title}'\n"; 00208 } else { 00209 $ns = $title->getNamespace(); 00210 $t = wfStrencode( $title->getDBkey() ); 00211 wfQuery( "UPDATE $table SET {$table}_namespace=$ns,{$table}_title='$t' 00212 WHERE {$table}_namespace=0 AND {$table}_title='$xt'", DB_WRITE ); 00213 } 00214 if( ++$n % 50 == 0 ) { 00215 print "$n\n"; 00216 } 00217 } 00218 wfFreeResult( $res ); 00219 } 00220 00221 function rewriteUserOptions( $in ) 00222 { 00223 $s = urldecode( $in ); 00224 $a = explode( "\n", $s ); 00225 00226 foreach ( $a as $l ) { 00227 if ( preg_match( "/^([A-Za-z0-9_]+)=(.*)/", $l, $m ) ) { 00228 $ops[$m[1]] = $m[2]; 00229 } 00230 } 00231 $nops = array(); 00232 00233 $q = strtolower( $ops["quickBar"] ); 00234 if ( $q == "none" ) { $q = 0; } 00235 else { $q = 1; } # Default to left 00236 $nops["quickbar"] = $q; 00237 00238 if ( $ops["markupNewTopics"] == "inverse" ) { 00239 $nops["highlightbroken"] = 1; 00240 } 00241 $sk = substr( strtolower( $ops["skin"] ), 0, 4 ); 00242 if ( "star" == $sk ) { $sk = 0; } 00243 else if ( "nost" == $sk ) { $sk = 1; } 00244 else if ( "colo" == $sk ) { $sk = 2; } 00245 else { $sk = 0; } 00246 $nops["skin"] = $sk; 00247 00248 $u = strtolower( $ops["underlineLinks"] ); 00249 if ( "yes" == $u || "on" == $u ) { $nops["underline"] = 1; } 00250 else { $nops["underline"] = 0; } 00251 00252 $t = ( (int) ($ops["hourDiff"]) ); 00253 if ( $t < -23 || $t > 23 ) { $t = 0; } 00254 if ( 0 != $t ) { $nops["timecorrection"] = $t; } 00255 00256 $j = strtolower( $ops["justify"] ); 00257 if ( "yes" == $j || "on" == $j ) { $nops["justify"] = 1; } 00258 $n = strtolower( $ops["numberHeadings"] ); 00259 if ( "yes" == $n || "on" == $n ) { $nops["numberheadings"] = 1; } 00260 $h = strtolower( $ops["hideMinor"] ); 00261 if ( "yes" == $h || "on" == $h ) { $nops["hideminor"] = 1; } 00262 $r = strtolower( $ops["rememberPassword"] ); 00263 if ( "yes" == $r || "on" == $r ) { $nops["rememberpassword"] = 1; } 00264 $s = strtolower( $ops["showHover"] ); 00265 if ( "yes" == $s || "on" == $s ) { $nops["hover"] = 1; } 00266 00267 $c = $ops["cols"]; 00268 if ( $c < 20 || c > 200 ) { $nops["cols"] = 80; } 00269 else { $nops["cols"] = $c; } 00270 $r = $ops["rows"]; 00271 if ( $r < 5 || $r > 100 ) { $nops["rows"] = 20; } 00272 else { $nops["rows"] = $r; } 00273 $r = $ops["resultsPerPage"]; 00274 if ( $r < 3 || $r > 500 ) { $nops["searchlimit"] = 20; } 00275 else { $nops["searchlimit"] = $r; } 00276 $r = $ops["viewRecentChanges"]; 00277 if ( $r < 10 || $r > 1000 ) { $nops["rclimit"] = 50; } 00278 else { $nops["rclimit"] = $r; } 00279 $nops["rcdays"] = 3; 00280 00281 $a = array(); 00282 foreach ( $nops as $oname => $oval ) { 00283 array_push( $a, "$oname=$oval" ); 00284 } 00285 $s = implode( "\n", $a ); 00286 return $s; 00287 } 00288 00289 function fixUserOptions() { 00290 print "Fixing user options..."; 00291 $res = wfQuery( "SELECT user_id,user_options FROM user", DB_WRITE ); 00292 $total = wfNumRows( $res ); 00293 $n = 0; 00294 print " ($total total)\n"; 00295 00296 while( $row = wfFetchObject( $res ) ) { 00297 $id = IntVal( $row->user_id ); 00298 $option = wfStrencode( $this->rewriteUserOptions( $row->user_options ) ); 00299 wfQuery( "UPDATE user SET user_options='$option' WHERE user_id=$id LIMIT 1", DB_WRITE ); 00300 if( ++$n % 50 == 0 ) { 00301 print "$n\n"; 00302 } 00303 } 00304 wfFreeResult( $res ); 00305 } 00306 00307 } 00308 00309 class TitleCache { 00310 var $hash = array(); 00311 00312 function &fetch( $dbkey ) { 00313 if( !isset( $hash[$dbkey] ) ) { 00314 $hash[$dbkey] = Title::newFromDBkey( $dbkey ); 00315 } 00316 return $hash[$dbkey]; 00317 } 00318 00319 } 00320 00321 # 00322 print "You should have already run the installer to create a fresh, blank database.\n"; 00323 print "Data will be inserted into '$wgDBname'. THIS SHOULD BE EMPTY AND ANY DATA IN IN WILL BE ERASED!\n"; 00324 print "\nIf that's not what you want, ABORT NOW!\n\n"; 00325 00326 print "Please enter the name of the old 'phase 2'-format database that will be used as a source:\n"; 00327 print "Old database name [enciclopedia]: "; 00328 $olddb = readconsole(); 00329 if( empty( $olddb ) ) $olddb = "enciclopedia"; 00330 00331 if( $olddb == $wgDBname ) { 00332 die( "Can't upgrade in-place! You must create a new database and copy data into it.\n" ); 00333 } 00334 00335 print "\nSource database: '$olddb'\n"; 00336 print " Dest database: '$wgDBname'\n"; 00337 print "Is this correct? Anything in '$wgDBname' WILL BE DESTROYED. [y/N] "; 00338 $response = readconsole(); 00339 if( strtolower( $response{0} ) != 'y' ) { 00340 die( "\nAborted by user.\n" ); 00341 } 00342 00343 print "Starting import....\n"; 00344 00345 $wgTitle = Title::newFromText( "Conversion script" ); 00346 $importer = new Phase2Importer( $olddb ); 00347 $importer->importAll(); 00348 00349 ?>

Generated on Tue Jun 29 23:40:03 2004 for Mediawiki by doxygen 1.3.7