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
00075
00076
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 ?>