moving geo files to new experiments subdir
[lhc/web/wiklou.git] / maintenance / importPhase2.php
1 <?php
2 # MediaWiki 'phase 2' to current format import script
3 # (import format current as of 1.2.0, March 2004)
4 #
5 # Copyright (C) 2004 Brion Vibber <brion@pobox.com>
6 # Portions by Lee Daniel Crocker, 2002
7 # http://www.mediawiki.org/
8 #
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License along
20 # with this program; if not, write to the Free Software Foundation, Inc.,
21 # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 # http://www.gnu.org/copyleft/gpl.html
23
24 /**
25 * @todo document
26 * @deprecated
27 * @package MediaWiki
28 * @subpackage Maintenance
29 */
30
31 /** */
32 die( "This import script is not currently maintained.
33 If you need it you'll have to modify it as necessary.\n");
34
35 if ( ! is_readable( "../LocalSettings.php" ) ) {
36 print "A copy of your installation's LocalSettings.php\n" .
37 "must exist in the source directory.\n";
38 exit();
39 }
40
41 $wgCommandLineMode = true;
42 ini_set("implicit_flush", 1);
43
44 $DP = "../includes";
45 require_once( "../LocalSettings.php" );
46 require_once( "../AdminSettings.php" );
47
48 $wgDBuser = $wgDBadminuser;
49 $wgDBpassword = $wgDBadminpassword;
50
51 $sep = ( DIRECTORY_SEPARATOR == "\\" ) ? ";" : ":";
52 ini_set( "include_path", "$IP$sep$include_path" );
53
54 require_once( "Setup.php" );
55
56 require_once( "../install-utils.inc" );
57 require_once( "InitialiseMessages.inc" );
58 require_once( "rebuildlinks.inc" );
59 require_once( "rebuildrecentchanges.inc" );
60 require_once( "rebuildtextindex.inc" );
61
62 /**
63 * @todo document
64 * @package MediaWiki
65 * @subpackage Maintenance
66 */
67 class Phase2Importer {
68 var $olddb, $titleCache;
69
70 function Phase2Importer( $database ) {
71 $this->olddb = $database;
72 $this->titleCache = new TitleCache;
73 }
74
75 function importAll() {
76 $this->importCurData();
77 $this->fixCurTitles();
78
79 $this->importOldData();
80 $this->fixOldTitles();
81
82 $this->importUserData();
83 $this->fixUserOptions();
84
85 $this->importWatchlists();
86
87 $this->importLinkData();
88
89 /*
90 # For some reason this is broken. RecentChanges will just start anew...
91 rebuildRecentChangesTablePass1();
92 rebuildRecentChangesTablePass2();
93 */
94
95 print "Rebuilding search index:\n";
96 dropTextIndex();
97 rebuildTextIndex();
98 createTextIndex();
99
100 initialiseMessages();
101 }
102
103 # Simple import functions; for the most part these are pretty straightforward.
104 # MySQL copies everything over to the new database and tweaks a few things.
105 function importCurData() {
106 print "Clearing pages from default install, if any...\n";
107 wfQuery( "DELETE FROM cur", DB_MASTER );
108
109 print "Importing current revision data...\n";
110 wfQuery( "INSERT INTO cur (cur_id,cur_namespace,cur_title,cur_text,cur_comment,
111 cur_user,cur_user_text,cur_timestamp,cur_restrictions,cur_counter,
112 cur_is_redirect,cur_minor_edit,cur_is_new,cur_random,cur_touched,inverse_timestamp)
113 SELECT cur_id,0,cur_title,cur_text,cur_comment,
114 cur_user,cur_user_text,cur_timestamp,REPLACE(cur_restrictions,'is_',''),cur_counter,
115 cur_text like '#redirect%',cur_minor_edit,0,RAND(),NOW()+0,99999999999999-cur_timestamp
116 FROM {$this->olddb}.cur", DB_MASTER );
117 $n = mysql_affected_rows();
118 print "$n rows imported.\n";
119 }
120
121 function importOldData() {
122 print "Clearing old revision data from default install, if any...\n";
123 wfQuery( "DELETE FROM old", DB_MASTER );
124
125 print "Importing old revision data...\n";
126 wfQuery( "INSERT INTO old (old_id,old_namespace,old_title,old_text,old_comment,
127 old_user,old_user_text,old_timestamp,old_minor_edit,old_flags,inverse_timestamp)
128 SELECT old_id,0,old_title,old_text,old_comment,
129 old_user,old_user_text,old_timestamp,old_minor_edit,'',99999999999999-old_timestamp
130 FROM {$this->olddb}.old", DB_MASTER );
131 $n = mysql_affected_rows();
132 print "$n rows imported.\n";
133 }
134
135 function importUserData() {
136 print "Clearing users from default install, if any...\n";
137 wfQuery( "DELETE FROM user", DB_MASTER );
138
139 print "Importing user data...\n";
140 wfQuery( "INSERT INTO $newdb.user (user_id,user_name,user_rights,
141 user_password,user_newpassword,user_email,user_options,user_touched)
142 SELECT user_id,user_name,REPLACE(user_rights,'is_',''),
143 MD5(CONCAT(user_id,'-',MD5(user_password))),'',user_email,user_options,NOW()+0
144 FROM {$this->olddb}.user", DB_MASTER );
145 $n = mysql_affected_rows();
146 print "$n rows imported.\n";
147 }
148
149 # A little less clean...
150 function importWatchlists() {
151 print "Clearing watchlists from default install, if any...\n";
152 wfQuery( "DELETE FROM watchlist", DB_MASTER );
153
154 print "Importing watchlists...";
155 $res = wfQuery( "SELECT user_id,user_watch FROM {$this->olddb}.user WHERE user_watch != ''", DB_MASTER );
156 $total = wfNumRows( $res );
157 $n = 0;
158 print " ($total total)\n";
159
160 while( $row = wfFetchObject( $res ) ) {
161 $id = IntVal( $row->user_id );
162 $list = explode( "\n", $row->user_watch );
163 foreach( $list as $page ) {
164 $title = $this->titleCache->fetch( $page );
165 if( is_null( $title ) ) {
166 print "Caught bad title '{$row->title}'\n";
167 } else {
168 $ns = $title->getNamespace();
169 $t = wfStrencode( $title->getDBkey() );
170 wfQuery( "INSERT INTO watchlist(wl_user,wl_namespace,wl_title) VALUES ($id,$ns,'$t')", DB_MASTER );
171 }
172 }
173 if( ++$n % 50 == 0 ) {
174 print "$n\n";
175 }
176 }
177 wfFreeResult( $res );
178 }
179
180 function importLinkData() {
181 # MUST BE CALLED BEFORE! fixCurTitles()
182 print "Clearing links from default install, if any...\n";
183 wfQuery( "DELETE FROM links", DB_MASTER );
184 wfQuery( "DELETE FROM brokenlinks", DB_MASTER );
185
186 print "Importing live links...";
187 wfQuery( "INSERT INTO links (l_from, l_to)
188 SELECT DISTINCT linked_from,cur_id
189 FROM {$this->olddb}.linked,{$this->olddb}.cur
190 WHERE linked_to=cur_title", DB_MASTER );
191 $n = mysql_affected_rows();
192 print "$n rows imported.\n";
193
194 print "Importing broken links...";
195 wfQuery( "INSERT INTO brokenlinks (bl_from, bl_to)
196 SELECT DISTINCT cur_id,unlinked_to
197 FROM {$this->olddb}.unlinked,{$this->olddb}.cur
198 WHERE unlinked_from=cur_title", DB_MASTER );
199 $n = mysql_affected_rows();
200 print "$n rows imported.\n";
201 }
202
203 # Fixup functions: munge data that's already been brought into tables
204 function fixCurTitles() {
205 $this->fixTitles( "cur" );
206 }
207
208 function fixOldTitles() {
209 $this->fixTitles( "old" );
210 }
211
212 function fixTitles( $table ) {
213 print "Fixing titles in $table...";
214 $res = wfQuery( "SELECT DISTINCT {$table}_title AS title FROM $table", DB_MASTER );
215 $total = wfNumRows( $res );
216 $n = 0;
217 print " ($total total)\n";
218
219 while( $row = wfFetchObject( $res ) ) {
220 $xt = wfStrencode( $row->title );
221 $title = $this->titleCache->fetch( $row->title );
222 if( is_null( $title ) ) {
223 print "Caught bad title '{$row->title}'\n";
224 } else {
225 $ns = $title->getNamespace();
226 $t = wfStrencode( $title->getDBkey() );
227 wfQuery( "UPDATE $table SET {$table}_namespace=$ns,{$table}_title='$t'
228 WHERE {$table}_namespace=0 AND {$table}_title='$xt'", DB_MASTER );
229 }
230 if( ++$n % 50 == 0 ) {
231 print "$n\n";
232 }
233 }
234 wfFreeResult( $res );
235 }
236
237 function rewriteUserOptions( $in )
238 {
239 $s = urldecode( $in );
240 $a = explode( "\n", $s );
241
242 foreach ( $a as $l ) {
243 if ( preg_match( "/^([A-Za-z0-9_]+)=(.*)/", $l, $m ) ) {
244 $ops[$m[1]] = $m[2];
245 }
246 }
247 $nops = array();
248
249 $q = strtolower( $ops["quickBar"] );
250 if ( $q == "none" ) { $q = 0; }
251 else { $q = 1; } # Default to left
252 $nops["quickbar"] = $q;
253
254 if ( $ops["markupNewTopics"] == "inverse" ) {
255 $nops["highlightbroken"] = 1;
256 }
257 $sk = substr( strtolower( $ops["skin"] ), 0, 4 );
258 if ( "star" == $sk ) { $sk = 0; }
259 else if ( "nost" == $sk ) { $sk = 1; }
260 else if ( "colo" == $sk ) { $sk = 2; }
261 else { $sk = 0; }
262 $nops["skin"] = $sk;
263
264 $u = strtolower( $ops["underlineLinks"] );
265 if ( "yes" == $u || "on" == $u ) { $nops["underline"] = 1; }
266 else { $nops["underline"] = 0; }
267
268 $t = ( (int) ($ops["hourDiff"]) );
269 if ( $t < -23 || $t > 23 ) { $t = 0; }
270 if ( 0 != $t ) { $nops["timecorrection"] = $t; }
271
272 $j = strtolower( $ops["justify"] );
273 if ( "yes" == $j || "on" == $j ) { $nops["justify"] = 1; }
274 $n = strtolower( $ops["numberHeadings"] );
275 if ( "yes" == $n || "on" == $n ) { $nops["numberheadings"] = 1; }
276 $h = strtolower( $ops["hideMinor"] );
277 if ( "yes" == $h || "on" == $h ) { $nops["hideminor"] = 1; }
278 $r = strtolower( $ops["rememberPassword"] );
279 if ( "yes" == $r || "on" == $r ) { $nops["rememberpassword"] = 1; }
280 $s = strtolower( $ops["showHover"] );
281 if ( "yes" == $s || "on" == $s ) { $nops["hover"] = 1; }
282
283 $c = $ops["cols"];
284 if ( $c < 20 || $c > 200 ) { $nops["cols"] = 80; }
285 else { $nops["cols"] = $c; }
286 $r = $ops["rows"];
287 if ( $r < 5 || $r > 100 ) { $nops["rows"] = 20; }
288 else { $nops["rows"] = $r; }
289 $r = $ops["resultsPerPage"];
290 if ( $r < 3 || $r > 500 ) { $nops["searchlimit"] = 20; }
291 else { $nops["searchlimit"] = $r; }
292 $r = $ops["viewRecentChanges"];
293 if ( $r < 10 || $r > 1000 ) { $nops["rclimit"] = 50; }
294 else { $nops["rclimit"] = $r; }
295 $nops["rcdays"] = 3;
296
297 $a = array();
298 foreach ( $nops as $oname => $oval ) {
299 array_push( $a, "$oname=$oval" );
300 }
301 $s = implode( "\n", $a );
302 return $s;
303 }
304
305 function fixUserOptions() {
306 print "Fixing user options...";
307 $res = wfQuery( "SELECT user_id,user_options FROM user", DB_MASTER );
308 $total = wfNumRows( $res );
309 $n = 0;
310 print " ($total total)\n";
311
312 while( $row = wfFetchObject( $res ) ) {
313 $id = IntVal( $row->user_id );
314 $option = wfStrencode( $this->rewriteUserOptions( $row->user_options ) );
315 wfQuery( "UPDATE user SET user_options='$option' WHERE user_id=$id LIMIT 1", DB_MASTER );
316 if( ++$n % 50 == 0 ) {
317 print "$n\n";
318 }
319 }
320 wfFreeResult( $res );
321 }
322
323 }
324
325 /**
326 * @todo document
327 * @package MediaWiki
328 * @subpackage Maintenance
329 */
330 class TitleCache {
331 var $hash = array();
332
333 function &fetch( $dbkey ) {
334 if( !isset( $hash[$dbkey] ) ) {
335 $hash[$dbkey] = Title::newFromDBkey( $dbkey );
336 }
337 return $hash[$dbkey];
338 }
339
340 }
341
342 #
343 print "You should have already run the installer to create a fresh, blank database.\n";
344 print "Data will be inserted into '$wgDBname'. THIS SHOULD BE EMPTY AND ANY DATA IN IN WILL BE ERASED!\n";
345 print "\nIf that's not what you want, ABORT NOW!\n\n";
346
347 print "Please enter the name of the old 'phase 2'-format database that will be used as a source:\n";
348 print "Old database name [enciclopedia]: ";
349 $olddb = readconsole();
350 if( empty( $olddb ) ) $olddb = "enciclopedia";
351
352 if( $olddb == $wgDBname ) {
353 die( "Can't upgrade in-place! You must create a new database and copy data into it.\n" );
354 }
355
356 print "\nSource database: '$olddb'\n";
357 print " Dest database: '$wgDBname'\n";
358 print "Is this correct? Anything in '$wgDBname' WILL BE DESTROYED. [y/N] ";
359 $response = readconsole();
360 if( strtolower( $response{0} ) != 'y' ) {
361 die( "\nAborted by user.\n" );
362 }
363
364 print "Starting import....\n";
365
366 $wgTitle = Title::newFromText( "Conversion script" );
367 $importer = new Phase2Importer( $olddb );
368 $importer->importAll();
369
370 ?>