Index: branches/iwtransclusion/phase3/includes/Interwiki.php |
— | — | @@ -261,16 +261,9 @@ |
262 | 262 | |
263 | 263 | /** |
264 | 264 | * Transclude an interwiki link. |
265 | | - * TODO: separate in interwikiTranscludeFromDB & interwikiTranscludeFromAPI according to the iw type |
266 | 265 | */ |
267 | 266 | public static function interwikiTransclude( $title ) { |
268 | | - |
269 | | - global $wgEnableScaryTranscluding; |
270 | | - |
271 | | - if ( !$wgEnableScaryTranscluding ) { |
272 | | - return wfMsg('scarytranscludedisabled'); |
273 | | - } |
274 | | - |
| 267 | + |
275 | 268 | // If we have a wikiID, we will use it to get an access to the remote database |
276 | 269 | // if not, we will use the API URL to retrieve the data through a HTTP Get |
277 | 270 | |
— | — | @@ -279,25 +272,20 @@ |
280 | 273 | |
281 | 274 | if ( $wikiID !== '') { |
282 | 275 | |
283 | | - $finalText = self::fetchTemplateFromDB( $wikiID, $title->getNamespace(), $title->getDBkey()); |
284 | | - $subTemplates = self::fetchSubTemplatesListFromDB( $wikiID, $title->getNamespace(), $title->getDBkey()); |
285 | | - |
286 | | - foreach ($subTemplates as $template) { |
287 | | - $listSubTemplates.=$template['namespace'].':'.$template['title']."\n"; |
288 | | - $list2.="<h2>".$template['title']."</h2>\n<pre>".self::fetchTemplateFromDB( $wikiID, $template['namespace'], $template['title'])."</pre>"; |
289 | | - } |
| 276 | + $finalText = self::fetchTemplateFromDB( $wikiID, $title ); |
| 277 | + return $finalText; |
290 | 278 | |
291 | 279 | } else if( $transAPI !== '' ) { |
| 280 | + |
| 281 | + $fullTitle = $title->getNsText().':'.$title->getText(); |
292 | 282 | |
293 | 283 | $url1 = $transAPI."?action=query&prop=revisions&titles=$fullTitle&rvprop=content&format=json"; |
294 | 284 | |
295 | 285 | if ( strlen( $url1 ) > 255 ) { |
296 | | - return wfMsg( 'Interwiki-transclusion-url-too-long' ); |
| 286 | + return false; |
297 | 287 | } |
298 | 288 | |
299 | | - $text = self::fetchTemplateHTTPMaybeFromCache( $url1 ); |
300 | | - |
301 | | - $fullTitle = $title->getNsText().':'.$title->getText(); |
| 289 | + $finalText = self::fetchTemplateHTTPMaybeFromCache( $url1 ); |
302 | 290 | |
303 | 291 | $url2 = $transAPI."?action=parse&text={{".$fullTitle."}}&prop=templates&format=json"; |
304 | 292 | |
— | — | @@ -308,98 +296,35 @@ |
309 | 297 | $templates = $myArray['parse']['templates']; |
310 | 298 | } |
311 | 299 | |
312 | | - |
313 | | - // TODO: The templates are retrieved one by one. |
314 | | - // We should split the templates in two groups: up-to-date and out-of-date |
315 | | - // Only the second group would be retrieved through the API or DB request |
| 300 | + // TODO: The templates are retrieved one by one. We should get them all in 1 request |
| 301 | + // Here, we preload and cache the subtemplates |
316 | 302 | for ($i = 0 ; $i < count( $templates ) ; $i++) { |
317 | 303 | $newTitle = $templates[$i]['*']; |
318 | 304 | |
319 | 305 | $url = $transAPI."?action=query&prop=revisions&titles=$newTitle&rvprop=content&format=json"; |
320 | 306 | |
321 | | - $listSubTemplates.= $newTitle."\n"; |
322 | | - $list2.="<h2>".$newTitle."</h2>\n<pre>".self::fetchTemplateHTTPMaybeFromCache( $url )."</pre>"; |
| 307 | + // $newText is unused, but requesting it will put the template in the cache |
| 308 | + $newText = self::fetchTemplateHTTPMaybeFromCache( $url ); |
323 | 309 | |
324 | 310 | } |
| 311 | + return $finalText; |
325 | 312 | |
326 | | - $finalText = "$url1\n$url2\n$text"; |
327 | | - |
328 | | - } else { |
329 | | - return wfMsg( 'Interwiki-transclusion-failed' ); |
330 | 313 | } |
331 | | - |
332 | | - return "<h2>$fullTitle</h2><pre>$finalText</pre> List of templates: <pre>".$listSubTemplates.'</pre>' . $list2; |
| 314 | + return false; |
333 | 315 | } |
334 | 316 | |
335 | | - public static function fetchTemplateFromDB ( $wikiID, $namespace, $DBkey ) { |
| 317 | + public static function fetchTemplateFromDB ( $wikiID, $title ) { |
336 | 318 | |
337 | | - try { |
338 | | - $dbr = wfGetDb( DB_SLAVE, array(), $wikiID ); |
339 | | - } catch (Exception $e) { |
340 | | - return wfMsg( 'Failed-to-connect-the-distant-DB' ); |
341 | | - } |
| 319 | + $revision = Revision::loadFromTitleForeignWiki( $wikiID, $title ); |
342 | 320 | |
343 | | - $fields = array('old_text', 'page_id'); |
344 | | - $res = $dbr->select( |
345 | | - array( 'page', 'revision', 'text' ), |
346 | | - $fields, |
347 | | - array( 'rev_id=page_latest', |
348 | | - 'page_namespace' => $namespace, |
349 | | - 'page_title' => $DBkey, |
350 | | - 'page_id=rev_page', |
351 | | - 'rev_text_id=old_id'), |
352 | | - null, |
353 | | - array( 'LIMIT' => 1 ) |
354 | | - ); |
355 | | - |
356 | | - $obj = $dbr->resultObject( $res ); |
357 | | - |
358 | | - if ( $obj ) { |
359 | | - $row = $obj->fetchObject(); |
360 | | - $obj->free(); |
361 | | - |
362 | | - if( $row ) { |
363 | | - $res = new Revision( $row ); |
364 | | - $articleID = $res->mTextRow->page_id; |
365 | | - $text = $articleID."\n".$res->mTextRow->old_text; |
366 | | - } |
| 321 | + if ( $revision ) { |
| 322 | + $text = $revision->getText(); |
| 323 | + return $text; |
367 | 324 | } |
368 | 325 | |
369 | | - return $text; |
| 326 | + return false; |
370 | 327 | } |
371 | 328 | |
372 | | - public static function fetchSubTemplatesListFromDB ( $wikiID, $namespace, $DBkey ) { |
373 | | - |
374 | | - try { |
375 | | - $dbr = wfGetDb( DB_SLAVE, array(), $wikiID ); |
376 | | - } catch (Exception $e) { |
377 | | - return wfMsg( 'Failed-to-connect-the-distant-DB' ); |
378 | | - } |
379 | | - |
380 | | - $fields = array('tl_namespace', 'tl_title'); |
381 | | - $res = $dbr->select( |
382 | | - array( 'page', 'templatelinks' ), |
383 | | - $fields, |
384 | | - array( 'page_namespace' => $namespace, |
385 | | - 'page_title' => $DBkey, |
386 | | - 'tl_from=page_id' ) |
387 | | - ); |
388 | | - |
389 | | - $obj = $dbr->resultObject( $res ); |
390 | | - |
391 | | - if ( $obj ) { |
392 | | - |
393 | | - $listTemplates = array(); |
394 | | - |
395 | | - while ($row = $obj->fetchObject() ) { |
396 | | - $listTemplates[] = array( 'namespace' => $row->tl_namespace, 'title' => $row->tl_title ); |
397 | | - } |
398 | | - $obj->free(); |
399 | | - } |
400 | | - |
401 | | - return $listTemplates; |
402 | | - } |
403 | | - |
404 | 329 | public static function fetchTemplateHTTPMaybeFromCache( $url ) { |
405 | 330 | global $wgTranscludeCacheExpiry; |
406 | 331 | $dbr = wfGetDB( DB_SLAVE ); |
— | — | @@ -429,7 +354,7 @@ |
430 | 355 | $dbw = wfGetDB( DB_MASTER ); |
431 | 356 | $dbw->replace( 'transcache', array('tc_url'), array( |
432 | 357 | 'tc_url' => $url, |
433 | | - 'tc_time' => $dbw->timestamp( time() ), |
| 358 | + 'tc_time' => $dbw->timestamp( ), |
434 | 359 | 'tc_contents' => $text) |
435 | 360 | ); |
436 | 361 | |
Index: branches/iwtransclusion/phase3/includes/Revision.php |
— | — | @@ -121,6 +121,30 @@ |
122 | 122 | } |
123 | 123 | |
124 | 124 | /** |
| 125 | + * Stores the origin wiki of a revision in case it is a foreign wiki |
| 126 | + */ |
| 127 | + function setWikiID( $wikiID ) { |
| 128 | + $this->mWikiID = $wikiID; |
| 129 | + } |
| 130 | + |
| 131 | + /** |
| 132 | + * Load the current revision of a given page of a foreign wiki. |
| 133 | + * The WikiID is stored for further use, such as loadText() and getTimestampFromId() |
| 134 | + */ |
| 135 | + public static function loadFromTitleForeignWiki( $wikiID, $title ) { |
| 136 | + $dbr = wfGetDB( DB_SLAVE, array(), $wikiID ); |
| 137 | + |
| 138 | + $revision = self::loadFromTitle( $dbr, $title ); |
| 139 | + |
| 140 | + if( $revision ) { |
| 141 | + $revision->setWikiID( $wikiID ); |
| 142 | + } |
| 143 | + |
| 144 | + return $revision; |
| 145 | + |
| 146 | + } |
| 147 | + |
| 148 | + /** |
125 | 149 | * Load either the current, or a specified, revision |
126 | 150 | * that's attached to a given page. If not attached |
127 | 151 | * to that page, will return null. |
— | — | @@ -358,6 +382,7 @@ |
359 | 383 | throw new MWException( 'Revision constructor passed invalid row format.' ); |
360 | 384 | } |
361 | 385 | $this->mUnpatrolled = null; |
| 386 | + $this->mWikiID = false; |
362 | 387 | } |
363 | 388 | |
364 | 389 | /** |
— | — | @@ -405,7 +430,8 @@ |
406 | 431 | if( isset( $this->mTitle ) ) { |
407 | 432 | return $this->mTitle; |
408 | 433 | } |
409 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 434 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
| 435 | + |
410 | 436 | $row = $dbr->selectRow( |
411 | 437 | array( 'page', 'revision' ), |
412 | 438 | array( 'page_namespace', 'page_title' ), |
— | — | @@ -545,7 +571,7 @@ |
546 | 572 | if( $this->mUnpatrolled !== null ) { |
547 | 573 | return $this->mUnpatrolled; |
548 | 574 | } |
549 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 575 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
550 | 576 | $this->mUnpatrolled = $dbr->selectField( 'recentchanges', |
551 | 577 | 'rc_id', |
552 | 578 | array( // Add redundant user,timestamp condition so we can use the existing index |
— | — | @@ -899,7 +925,7 @@ |
900 | 926 | |
901 | 927 | if( !$row ) { |
902 | 928 | // Text data is immutable; check slaves first. |
903 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 929 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
904 | 930 | $row = $dbr->selectRow( 'text', |
905 | 931 | array( 'old_text', 'old_flags' ), |
906 | 932 | array( 'old_id' => $this->getTextId() ), |
— | — | @@ -908,7 +934,7 @@ |
909 | 935 | |
910 | 936 | if( !$row && wfGetLB()->getServerCount() > 1 ) { |
911 | 937 | // Possible slave lag! |
912 | | - $dbw = wfGetDB( DB_MASTER ); |
| 938 | + $dbw = wfGetDB( DB_MASTER, array(), $this->mWikiID ); |
913 | 939 | $row = $dbw->selectRow( 'text', |
914 | 940 | array( 'old_text', 'old_flags' ), |
915 | 941 | array( 'old_id' => $this->getTextId() ), |
— | — | @@ -1020,7 +1046,7 @@ |
1021 | 1047 | * @return String |
1022 | 1048 | */ |
1023 | 1049 | static function getTimestampFromId( $title, $id ) { |
1024 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 1050 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
1025 | 1051 | // Casting fix for DB2 |
1026 | 1052 | if ( $id == '' ) { |
1027 | 1053 | $id = 0; |
— | — | @@ -1030,7 +1056,7 @@ |
1031 | 1057 | $timestamp = $dbr->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ ); |
1032 | 1058 | if ( $timestamp === false && wfGetLB()->getServerCount() > 1 ) { |
1033 | 1059 | # Not in slave, try master |
1034 | | - $dbw = wfGetDB( DB_MASTER ); |
| 1060 | + $dbw = wfGetDB( DB_MASTER, array(), $this->mWikiID ); |
1035 | 1061 | $timestamp = $dbw->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ ); |
1036 | 1062 | } |
1037 | 1063 | return wfTimestamp( TS_MW, $timestamp ); |
Index: branches/iwtransclusion/phase3/includes/parser/Parser.php |
— | — | @@ -3167,12 +3167,15 @@ |
3168 | 3168 | } elseif ( $title->isTrans() ) { |
3169 | 3169 | // TODO: Work by Peter17 in progress |
3170 | 3170 | |
3171 | | - $text = Interwiki::interwikiTransclude( $title ); |
| 3171 | + $text = Interwiki::interwikiTransclude( $title ); |
| 3172 | + |
| 3173 | + if ( $text !== false ) { |
3172 | 3174 | # Preprocess it like a template |
3173 | 3175 | $text = $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION ); |
| 3176 | + $found = true; |
3174 | 3177 | $isChildObj = true; |
| 3178 | + } |
3175 | 3179 | |
3176 | | - $found = true; |
3177 | 3180 | } |
3178 | 3181 | |
3179 | 3182 | # Do infinite loop check |