Index: branches/iwtransclusion/phase3v2/includes/parser/Parser.php |
— | — | @@ -3268,17 +3268,16 @@ |
3269 | 3269 | } |
3270 | 3270 | } elseif ( $title->isTrans() ) { |
3271 | 3271 | // TODO: Work by Peter17 in progress |
3272 | | - # Interwiki transclusion |
3273 | | - //if ( $this->ot['html'] && !$forceRawInterwiki ) { |
3274 | | - // $text = $this->interwikiTransclude( $title, 'render' ); |
3275 | | - // $isHTML = true; |
3276 | | - //} else { |
3277 | | - $text = $this->interwikiTransclude( $title ); |
| 3272 | + |
| 3273 | + $text = Interwiki::interwikiTransclude( $title ); |
| 3274 | + |
| 3275 | + if ( $text !== false ) { |
3278 | 3276 | # Preprocess it like a template |
3279 | 3277 | $text = $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION ); |
| 3278 | + $found = true; |
3280 | 3279 | $isChildObj = true; |
3281 | | - //} |
3282 | | - $found = true; |
| 3280 | + } |
| 3281 | + |
3283 | 3282 | } |
3284 | 3283 | |
3285 | 3284 | # Do infinite loop check |
— | — | @@ -3507,156 +3506,7 @@ |
3508 | 3507 | |
3509 | 3508 | |
3510 | 3509 | /** |
3511 | | - * Fetch a file and its title and register a reference to it. |
3512 | | - * @param Title $title |
3513 | | - * @param string $time MW timestamp |
3514 | | - * @param string $sha1 base 36 SHA-1 |
3515 | | - * @return mixed File or false |
3516 | | - */ |
3517 | | - function fetchFile( $title, $time = false, $sha1 = false ) { |
3518 | | - $res = $this->fetchFileAndTitle( $title, $time, $sha1 ); |
3519 | | - return $res[0]; |
3520 | | - } |
3521 | | - |
3522 | 3510 | /** |
3523 | | - * Fetch a file and its title and register a reference to it. |
3524 | | - * @param Title $title |
3525 | | - * @param string $time MW timestamp |
3526 | | - * @param string $sha1 base 36 SHA-1 |
3527 | | - * @return Array ( File or false, Title of file ) |
3528 | | - */ |
3529 | | - function fetchFileAndTitle( $title, $time = false, $sha1 = false ) { |
3530 | | - if ( $time === '0' ) { |
3531 | | - $file = false; // broken thumbnail forced by hook |
3532 | | - } elseif ( $sha1 ) { // get by (sha1,timestamp) |
3533 | | - $file = RepoGroup::singleton()->findFileFromKey( $sha1, array( 'time' => $time ) ); |
3534 | | - } else { // get by (name,timestamp) |
3535 | | - $file = wfFindFile( $title, array( 'time' => $time ) ); |
3536 | | - } |
3537 | | - $time = $file ? $file->getTimestamp() : false; |
3538 | | - $sha1 = $file ? $file->getSha1() : false; |
3539 | | - # Register the file as a dependency... |
3540 | | - $this->mOutput->addImage( $title->getDBkey(), $time, $sha1 ); |
3541 | | - if ( $file && !$title->equals( $file->getTitle() ) ) { |
3542 | | - # We fetched a rev from a different title; register it too... |
3543 | | - $this->mOutput->addImage( $file->getTitle()->getDBkey(), $time, $sha1 ); |
3544 | | - # Update fetched file title |
3545 | | - $title = $file->getTitle(); |
3546 | | - } |
3547 | | - return array( $file, $title ); |
3548 | | - } |
3549 | | - |
3550 | | - /** |
3551 | | - * Transclude an interwiki link. |
3552 | | - * TODO: separate in interwikiTranscludeFromDB & interwikiTranscludeFromAPI according to the iw type |
3553 | | - */ |
3554 | | - function interwikiTransclude( $title ) { |
3555 | | - |
3556 | | - global $wgEnableScaryTranscluding; |
3557 | | - |
3558 | | - if ( !$wgEnableScaryTranscluding ) { |
3559 | | - return wfMsgForContent('scarytranscludedisabled'); |
3560 | | - } |
3561 | | - |
3562 | | - $fullTitle = $title->getNsText().':'.$title->getText(); |
3563 | | - |
3564 | | - $url1 = $title->getTransAPI( )."?action=query&prop=revisions&titles=$fullTitle&rvprop=content&format=json"; |
3565 | | - |
3566 | | - if ( strlen( $url1 ) > 255 ) { |
3567 | | - return wfMsgForContent( 'scarytranscludetoolong' ); |
3568 | | - } |
3569 | | - |
3570 | | - $text = $this->fetchTemplateMaybeFromCache( $url1 ); |
3571 | | - |
3572 | | - $url2 = $title->getTransAPI( )."?action=parse&text={{".$fullTitle."}}&prop=templates&format=json"; |
3573 | | - |
3574 | | - $get = Http::get( $url2 ); |
3575 | | - $myArray = FormatJson::decode($get, true); |
3576 | | - |
3577 | | - if ( ! empty( $myArray['parse'] )) { |
3578 | | - $templates = $myArray['parse']['templates']; |
3579 | | - } |
3580 | | - |
3581 | | - |
3582 | | - // TODO: The templates are retrieved one by one. |
3583 | | - // We should split the templates in two groups: up-to-date and out-of-date |
3584 | | - // Only the second group would be retrieved through the API or DB request |
3585 | | - for ($i = 0 ; $i < count( $templates ) ; $i++) { |
3586 | | - $newTitle = $templates[$i]['*']; |
3587 | | - |
3588 | | - $url = $title->getTransAPI( )."?action=query&prop=revisions&titles=$newTitle&rvprop=content&format=json"; |
3589 | | - |
3590 | | - $listSubTemplates.= $newTitle."\n"; |
3591 | | - $list2.="<h2>".$newTitle."</h2>\n<pre>".$this->fetchTemplateMaybeFromCache( $url )."</pre>"; |
3592 | | - |
3593 | | - } |
3594 | | - |
3595 | | - return "<h2>$fullTitle</h2><pre>$url1\n$url2\n$text</pre> List of templates: <pre>".$listSubTemplates.'</pre>' . $list2; |
3596 | | - } |
3597 | | - |
3598 | | - |
3599 | | - function fetchTemplateMaybeFromCache( $url ) { |
3600 | | - global $wgTranscludeCacheExpiry; |
3601 | | - $dbr = wfGetDB( DB_SLAVE ); |
3602 | | - $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry ); |
3603 | | - $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ), |
3604 | | - array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) ); |
3605 | | - |
3606 | | - if ( $obj ) { |
3607 | | - return $obj->tc_contents; |
3608 | | - } |
3609 | | - |
3610 | | - $get = Http::get( $url ); |
3611 | | - |
3612 | | - $content = FormatJson::decode( $get, true ); |
3613 | | - |
3614 | | - if ( ! empty($content['query']['pages']) ) { |
3615 | | - |
3616 | | - $page = array_pop( $content['query']['pages'] ); |
3617 | | - $text = $page['revisions'][0]['*']; |
3618 | | - |
3619 | | - } else { |
3620 | | - |
3621 | | - return wfMsg( 'scarytranscludefailed', $url ); |
3622 | | - |
3623 | | - } |
3624 | | - |
3625 | | - $dbw = wfGetDB( DB_MASTER ); |
3626 | | - $dbw->replace( 'transcache', array('tc_url'), array( |
3627 | | - 'tc_url' => $url, |
3628 | | - 'tc_time' => $dbw->timestamp( time() ), |
3629 | | - 'tc_contents' => $text) |
3630 | | - ); |
3631 | | - |
3632 | | - return $text; |
3633 | | - } |
3634 | | - |
3635 | | - function fetchScaryTemplateMaybeFromCache( $url ) { |
3636 | | - global $wgTranscludeCacheExpiry; |
3637 | | - $dbr = wfGetDB( DB_SLAVE ); |
3638 | | - $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry ); |
3639 | | - $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ), |
3640 | | - array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) ); |
3641 | | - if ( $obj ) { |
3642 | | - return $obj->tc_contents; |
3643 | | - } |
3644 | | - |
3645 | | - $text = Http::get( $url ); |
3646 | | - if ( !$text ) { |
3647 | | - return wfMsgForContent( 'scarytranscludefailed', $url ); |
3648 | | - } |
3649 | | - |
3650 | | - $dbw = wfGetDB( DB_MASTER ); |
3651 | | - $dbw->replace( 'transcache', array('tc_url'), array( |
3652 | | - 'tc_url' => $url, |
3653 | | - 'tc_time' => $dbw->timestamp( time() ), |
3654 | | - 'tc_contents' => $text) |
3655 | | - ); |
3656 | | - return $text; |
3657 | | - } |
3658 | | - |
3659 | | - |
3660 | | - /** |
3661 | 3511 | * Triple brace replacement -- used for template arguments |
3662 | 3512 | * @private |
3663 | 3513 | */ |
Index: branches/iwtransclusion/phase3v2/includes/interwiki/Interwiki.php |
— | — | @@ -190,9 +190,10 @@ |
191 | 191 | $iw->mURL = $mc['iw_url']; |
192 | 192 | $iw->mLocal = isset( $mc['iw_local'] ) ? $mc['iw_local'] : 0; |
193 | 193 | $iw->mTrans = isset( $mc['iw_trans'] ) ? $mc['iw_trans'] : 0; |
| 194 | + $iw->mAPI = isset( $mc['iw_api'] ) ? $mc['iw_api'] : |
194 | 195 | $iw->mAPI = isset( $mc['iw_api'] ) ? $mc['iw_api'] : ''; |
195 | 196 | $iw->mWikiID = isset( $mc['iw_wikiid'] ) ? $mc['iw_wikiid'] : ''; |
196 | | - |
| 197 | + |
197 | 198 | return $iw; |
198 | 199 | } |
199 | 200 | return false; |
— | — | @@ -269,4 +270,112 @@ |
270 | 271 | $msg = wfMessage( 'interwiki-desc-' . $this->mPrefix )->inContentLanguage(); |
271 | 272 | return !$msg->exists() ? '' : $msg; |
272 | 273 | } |
| 274 | + |
| 275 | + |
| 276 | + |
| 277 | + /** |
| 278 | + * Transclude an interwiki link. |
| 279 | + */ |
| 280 | + public static function interwikiTransclude( $title ) { |
| 281 | + |
| 282 | + // If we have a wikiID, we will use it to get an access to the remote database |
| 283 | + // if not, we will use the API URL to retrieve the data through a HTTP Get |
| 284 | + |
| 285 | + $wikiID = $title->getTransWikiID( ); |
| 286 | + $transAPI = $title->getTransAPI( ); |
| 287 | + |
| 288 | + if ( $wikiID !== '') { |
| 289 | + |
| 290 | + $finalText = self::fetchTemplateFromDB( $wikiID, $title ); |
| 291 | + return $finalText; |
| 292 | + |
| 293 | + } else if( $transAPI !== '' ) { |
| 294 | + |
| 295 | + $fullTitle = $title->getNsText().':'.$title->getText(); |
| 296 | + |
| 297 | + $url1 = $transAPI."?action=query&prop=revisions&titles=$fullTitle&rvprop=content&format=json"; |
| 298 | + |
| 299 | + if ( strlen( $url1 ) > 255 ) { |
| 300 | + return false; |
| 301 | + } |
| 302 | + |
| 303 | + $finalText = self::fetchTemplateHTTPMaybeFromCache( $url1 ); |
| 304 | + |
| 305 | + $url2 = $transAPI."?action=parse&text={{".$fullTitle."}}&prop=templates&format=json"; |
| 306 | + |
| 307 | + $get = Http::get( $url2 ); |
| 308 | + $myArray = FormatJson::decode($get, true); |
| 309 | + |
| 310 | + if ( ! empty( $myArray['parse'] )) { |
| 311 | + $templates = $myArray['parse']['templates']; |
| 312 | + } |
| 313 | + |
| 314 | + // TODO: The templates are retrieved one by one. We should get them all in 1 request |
| 315 | + // Here, we preload and cache the subtemplates |
| 316 | + for ($i = 0 ; $i < count( $templates ) ; $i++) { |
| 317 | + $newTitle = $templates[$i]['*']; |
| 318 | + |
| 319 | + $url = $transAPI."?action=query&prop=revisions&titles=$newTitle&rvprop=content&format=json"; |
| 320 | + |
| 321 | + // $newText is unused, but requesting it will put the template in the cache |
| 322 | + $newText = self::fetchTemplateHTTPMaybeFromCache( $url ); |
| 323 | + |
| 324 | + } |
| 325 | + return $finalText; |
| 326 | + |
| 327 | + } |
| 328 | + return false; |
| 329 | + } |
| 330 | + |
| 331 | + public static function fetchTemplateFromDB ( $wikiID, $title ) { |
| 332 | + |
| 333 | + $revision = Revision::loadFromTitleForeignWiki( $wikiID, $title ); |
| 334 | + |
| 335 | + if ( $revision ) { |
| 336 | + $text = $revision->getText(); |
| 337 | + return $text; |
| 338 | + } |
| 339 | + |
| 340 | + return false; |
| 341 | + } |
| 342 | + |
| 343 | + public static function fetchTemplateHTTPMaybeFromCache( $url ) { |
| 344 | + global $wgTranscludeCacheExpiry; |
| 345 | + $dbr = wfGetDB( DB_SLAVE ); |
| 346 | + $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry ); |
| 347 | + $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ), |
| 348 | + array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) ); |
| 349 | + |
| 350 | + if ( $obj ) { |
| 351 | + return $obj->tc_contents; |
| 352 | + } |
| 353 | + |
| 354 | + $get = Http::get( $url ); |
| 355 | + |
| 356 | + $content = FormatJson::decode( $get, true ); |
| 357 | + |
| 358 | + if ( ! empty($content['query']['pages']) ) { |
| 359 | + |
| 360 | + $page = array_pop( $content['query']['pages'] ); |
| 361 | + $text = $page['revisions'][0]['*']; |
| 362 | + |
| 363 | + } else { |
| 364 | + |
| 365 | + return wfMsg( 'scarytranscludefailed', $url ); |
| 366 | + |
| 367 | + } |
| 368 | + |
| 369 | + $dbw = wfGetDB( DB_MASTER ); |
| 370 | + $dbw->replace( 'transcache', array('tc_url'), array( |
| 371 | + 'tc_url' => $url, |
| 372 | + 'tc_time' => $dbw->timestamp( ), |
| 373 | + 'tc_contents' => $text) |
| 374 | + ); |
| 375 | + |
| 376 | + return $text; |
| 377 | + } |
| 378 | + |
| 379 | + |
| 380 | + |
| 381 | + |
273 | 382 | } |
Property changes on: branches/iwtransclusion/phase3v2/includes/interwiki/Interwiki.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
274 | 383 | Merged /branches/iwtransclusion/phase3/includes/interwiki/Interwiki.php:r69541,69723,69730 |
Index: branches/iwtransclusion/phase3v2/includes/Revision.php |
— | — | @@ -124,6 +124,30 @@ |
125 | 125 | } |
126 | 126 | |
127 | 127 | /** |
| 128 | + * Stores the origin wiki of a revision in case it is a foreign wiki |
| 129 | + */ |
| 130 | + function setWikiID( $wikiID ) { |
| 131 | + $this->mWikiID = $wikiID; |
| 132 | + } |
| 133 | + |
| 134 | + /** |
| 135 | + * Load the current revision of a given page of a foreign wiki. |
| 136 | + * The WikiID is stored for further use, such as loadText() and getTimestampFromId() |
| 137 | + */ |
| 138 | + public static function loadFromTitleForeignWiki( $wikiID, $title ) { |
| 139 | + $dbr = wfGetDB( DB_SLAVE, array(), $wikiID ); |
| 140 | + |
| 141 | + $revision = self::loadFromTitle( $dbr, $title ); |
| 142 | + |
| 143 | + if( $revision ) { |
| 144 | + $revision->setWikiID( $wikiID ); |
| 145 | + } |
| 146 | + |
| 147 | + return $revision; |
| 148 | + |
| 149 | + } |
| 150 | + |
| 151 | + /** |
128 | 152 | * Load either the current, or a specified, revision |
129 | 153 | * that's attached to a given page. If not attached |
130 | 154 | * to that page, will return null. |
— | — | @@ -360,6 +384,7 @@ |
361 | 385 | throw new MWException( 'Revision constructor passed invalid row format.' ); |
362 | 386 | } |
363 | 387 | $this->mUnpatrolled = null; |
| 388 | + $this->mWikiID = false; |
364 | 389 | } |
365 | 390 | |
366 | 391 | /** |
— | — | @@ -407,7 +432,8 @@ |
408 | 433 | if( isset( $this->mTitle ) ) { |
409 | 434 | return $this->mTitle; |
410 | 435 | } |
411 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 436 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
| 437 | + |
412 | 438 | $row = $dbr->selectRow( |
413 | 439 | array( 'page', 'revision' ), |
414 | 440 | array( 'page_namespace', 'page_title' ), |
— | — | @@ -547,7 +573,7 @@ |
548 | 574 | if( $this->mUnpatrolled !== null ) { |
549 | 575 | return $this->mUnpatrolled; |
550 | 576 | } |
551 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 577 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
552 | 578 | $this->mUnpatrolled = $dbr->selectField( 'recentchanges', |
553 | 579 | 'rc_id', |
554 | 580 | array( // Add redundant user,timestamp condition so we can use the existing index |
— | — | @@ -901,7 +927,7 @@ |
902 | 928 | |
903 | 929 | if( !$row ) { |
904 | 930 | // Text data is immutable; check slaves first. |
905 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 931 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
906 | 932 | $row = $dbr->selectRow( 'text', |
907 | 933 | array( 'old_text', 'old_flags' ), |
908 | 934 | array( 'old_id' => $this->getTextId() ), |
— | — | @@ -910,7 +936,7 @@ |
911 | 937 | |
912 | 938 | if( !$row && wfGetLB()->getServerCount() > 1 ) { |
913 | 939 | // Possible slave lag! |
914 | | - $dbw = wfGetDB( DB_MASTER ); |
| 940 | + $dbw = wfGetDB( DB_MASTER, array(), $this->mWikiID ); |
915 | 941 | $row = $dbw->selectRow( 'text', |
916 | 942 | array( 'old_text', 'old_flags' ), |
917 | 943 | array( 'old_id' => $this->getTextId() ), |
— | — | @@ -1021,7 +1047,7 @@ |
1022 | 1048 | * @return String |
1023 | 1049 | */ |
1024 | 1050 | static function getTimestampFromId( $title, $id ) { |
1025 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 1051 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
1026 | 1052 | // Casting fix for DB2 |
1027 | 1053 | if ( $id == '' ) { |
1028 | 1054 | $id = 0; |
— | — | @@ -1031,7 +1057,7 @@ |
1032 | 1058 | $timestamp = $dbr->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ ); |
1033 | 1059 | if ( $timestamp === false && wfGetLB()->getServerCount() > 1 ) { |
1034 | 1060 | # Not in slave, try master |
1035 | | - $dbw = wfGetDB( DB_MASTER ); |
| 1061 | + $dbw = wfGetDB( DB_MASTER, array(), $this->mWikiID ); |
1036 | 1062 | $timestamp = $dbw->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ ); |
1037 | 1063 | } |
1038 | 1064 | return wfTimestamp( TS_MW, $timestamp ); |
Property changes on: branches/iwtransclusion/phase3v2/includes/Revision.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
1039 | 1065 | Merged /branches/iwtransclusion/phase3/includes/Revision.php:r69730 |
Property changes on: branches/iwtransclusion/phase3v2 |
___________________________________________________________________ |
Modified: svn:mergeinfo |
1040 | 1066 | Merged /branches/iwtransclusion/phase3:r69541,69723,69730 |