Index: branches/iwtransclusion/phase3v3/includes/parser/Parser.php |
— | — | @@ -3265,17 +3265,16 @@ |
3266 | 3266 | } |
3267 | 3267 | } elseif ( $title->isTrans() ) { |
3268 | 3268 | // TODO: Work by Peter17 in progress |
3269 | | - # Interwiki transclusion |
3270 | | - //if ( $this->ot['html'] && !$forceRawInterwiki ) { |
3271 | | - // $text = $this->interwikiTransclude( $title, 'render' ); |
3272 | | - // $isHTML = true; |
3273 | | - //} else { |
3274 | | - $text = $this->interwikiTransclude( $title ); |
| 3269 | + |
| 3270 | + $text = Interwiki::interwikiTransclude( $title ); |
| 3271 | + |
| 3272 | + if ( $text !== false ) { |
3275 | 3273 | # Preprocess it like a template |
3276 | 3274 | $text = $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION ); |
| 3275 | + $found = true; |
3277 | 3276 | $isChildObj = true; |
3278 | | - //} |
3279 | | - $found = true; |
| 3277 | + } |
| 3278 | + |
3280 | 3279 | } |
3281 | 3280 | |
3282 | 3281 | # Do infinite loop check |
— | — | @@ -3508,165 +3507,7 @@ |
3509 | 3508 | 'deps' => $deps ); |
3510 | 3509 | } |
3511 | 3510 | |
3512 | | - |
3513 | 3511 | /** |
3514 | | - * Fetch a file and its title and register a reference to it. |
3515 | | - * @param Title $title |
3516 | | - * @param string $time MW timestamp |
3517 | | - * @param string $sha1 base 36 SHA-1 |
3518 | | - * @return mixed File or false |
3519 | | - */ |
3520 | | - function fetchFile( $title, $time = false, $sha1 = false ) { |
3521 | | - $res = $this->fetchFileAndTitle( $title, $time, $sha1 ); |
3522 | | - return $res[0]; |
3523 | | - } |
3524 | | - |
3525 | | - /** |
3526 | | - * Fetch a file and its title and register a reference to it. |
3527 | | - * @param Title $title |
3528 | | - * @param string $time MW timestamp |
3529 | | - * @param string $sha1 base 36 SHA-1 |
3530 | | - * @return Array ( File or false, Title of file ) |
3531 | | - */ |
3532 | | - function fetchFileAndTitle( $title, $time = false, $sha1 = false ) { |
3533 | | - if ( $time === '0' ) { |
3534 | | - $file = false; // broken thumbnail forced by hook |
3535 | | - } elseif ( $sha1 ) { // get by (sha1,timestamp) |
3536 | | - $file = RepoGroup::singleton()->findFileFromKey( $sha1, array( 'time' => $time ) ); |
3537 | | - } else { // get by (name,timestamp) |
3538 | | - $file = wfFindFile( $title, array( 'time' => $time ) ); |
3539 | | - } |
3540 | | - $time = $file ? $file->getTimestamp() : false; |
3541 | | - $sha1 = $file ? $file->getSha1() : false; |
3542 | | - # Register the file as a dependency... |
3543 | | - $this->mOutput->addImage( $title->getDBkey(), $time, $sha1 ); |
3544 | | - if ( $file && !$title->equals( $file->getTitle() ) ) { |
3545 | | - # Update fetched file title |
3546 | | - $title = $file->getTitle(); |
3547 | | - if ( is_null( $file->getRedirectedTitle() ) ) { |
3548 | | - # This file was not a redirect, but the title does not match. |
3549 | | - # Register under the new name because otherwise the link will |
3550 | | - # get lost. |
3551 | | - $this->mOutput->addImage( $title->getDBkey(), $time, $sha1 ); |
3552 | | - } |
3553 | | - } |
3554 | | - return array( $file, $title ); |
3555 | | - } |
3556 | | - |
3557 | | - /** |
3558 | | - * Transclude an interwiki link. |
3559 | | - * |
3560 | | - * @param $title Title |
3561 | | - * @param $action |
3562 | | - * |
3563 | | - * @return string |
3564 | | - * TODO: separate in interwikiTranscludeFromDB & interwikiTranscludeFromAPI according to the iw type |
3565 | | - */ |
3566 | | - function interwikiTransclude( $title ) { |
3567 | | - |
3568 | | - global $wgEnableScaryTranscluding; |
3569 | | - |
3570 | | - if ( !$wgEnableScaryTranscluding ) { |
3571 | | - return wfMsgForContent('scarytranscludedisabled'); |
3572 | | - } |
3573 | | - |
3574 | | - $fullTitle = $title->getNsText().':'.$title->getText(); |
3575 | | - |
3576 | | - $url1 = $title->getTransAPI( )."?action=query&prop=revisions&titles=$fullTitle&rvprop=content&format=json"; |
3577 | | - |
3578 | | - if ( strlen( $url1 ) > 255 ) { |
3579 | | - return wfMsgForContent( 'scarytranscludetoolong' ); |
3580 | | - } |
3581 | | - |
3582 | | - $text = $this->fetchTemplateMaybeFromCache( $url1 ); |
3583 | | - |
3584 | | - $url2 = $title->getTransAPI( )."?action=parse&text={{".$fullTitle."}}&prop=templates&format=json"; |
3585 | | - |
3586 | | - $get = Http::get( $url2 ); |
3587 | | - $myArray = FormatJson::decode($get, true); |
3588 | | - |
3589 | | - if ( ! empty( $myArray['parse'] )) { |
3590 | | - $templates = $myArray['parse']['templates']; |
3591 | | - } |
3592 | | - |
3593 | | - |
3594 | | - // TODO: The templates are retrieved one by one. |
3595 | | - // We should split the templates in two groups: up-to-date and out-of-date |
3596 | | - // Only the second group would be retrieved through the API or DB request |
3597 | | - for ($i = 0 ; $i < count( $templates ) ; $i++) { |
3598 | | - $newTitle = $templates[$i]['*']; |
3599 | | - |
3600 | | - $url = $title->getTransAPI( )."?action=query&prop=revisions&titles=$newTitle&rvprop=content&format=json"; |
3601 | | - |
3602 | | - $listSubTemplates.= $newTitle."\n"; |
3603 | | - $list2.="<h2>".$newTitle."</h2>\n<pre>".$this->fetchTemplateMaybeFromCache( $url )."</pre>"; |
3604 | | - |
3605 | | - } |
3606 | | - |
3607 | | - return "<h2>$fullTitle</h2><pre>$url1\n$url2\n$text</pre> List of templates: <pre>".$listSubTemplates.'</pre>' . $list2; |
3608 | | - } |
3609 | | - |
3610 | | - function fetchTemplateMaybeFromCache( $url ) { |
3611 | | - global $wgTranscludeCacheExpiry; |
3612 | | - $dbr = wfGetDB( DB_SLAVE ); |
3613 | | - $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry ); |
3614 | | - $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ), |
3615 | | - array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) ); |
3616 | | - |
3617 | | - if ( $obj ) { |
3618 | | - return $obj->tc_contents; |
3619 | | - } |
3620 | | - |
3621 | | - $get = Http::get( $url ); |
3622 | | - |
3623 | | - $content = FormatJson::decode( $get, true ); |
3624 | | - |
3625 | | - if ( ! empty($content['query']['pages']) ) { |
3626 | | - |
3627 | | - $page = array_pop( $content['query']['pages'] ); |
3628 | | - $text = $page['revisions'][0]['*']; |
3629 | | - |
3630 | | - } else { |
3631 | | - |
3632 | | - return wfMsg( 'scarytranscludefailed', $url ); |
3633 | | - |
3634 | | - } |
3635 | | - |
3636 | | - $dbw = wfGetDB( DB_MASTER ); |
3637 | | - $dbw->replace( 'transcache', array('tc_url'), array( |
3638 | | - 'tc_url' => $url, |
3639 | | - 'tc_time' => $dbw->timestamp( time() ), |
3640 | | - 'tc_contents' => $text) |
3641 | | - ); |
3642 | | - |
3643 | | - return $text; |
3644 | | - } |
3645 | | - |
3646 | | - function fetchScaryTemplateMaybeFromCache( $url ) { |
3647 | | - global $wgTranscludeCacheExpiry; |
3648 | | - $dbr = wfGetDB( DB_SLAVE ); |
3649 | | - $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry ); |
3650 | | - $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ), |
3651 | | - array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) ); |
3652 | | - if ( $obj ) { |
3653 | | - return $obj->tc_contents; |
3654 | | - } |
3655 | | - |
3656 | | - $text = Http::get( $url ); |
3657 | | - if ( !$text ) { |
3658 | | - return wfMsgForContent( 'scarytranscludefailed', $url ); |
3659 | | - } |
3660 | | - |
3661 | | - $dbw = wfGetDB( DB_MASTER ); |
3662 | | - $dbw->replace( 'transcache', array('tc_url'), array( |
3663 | | - 'tc_url' => $url, |
3664 | | - 'tc_time' => $dbw->timestamp( time() ), |
3665 | | - 'tc_contents' => $text) |
3666 | | - ); |
3667 | | - return $text; |
3668 | | - } |
3669 | | - |
3670 | | - /** |
3671 | 3512 | * Triple brace replacement -- used for template arguments |
3672 | 3513 | * @private |
3673 | 3514 | * |
Index: branches/iwtransclusion/phase3v3/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; |
— | — | @@ -381,4 +382,112 @@ |
382 | 383 | $msg = wfMessage( 'interwiki-desc-' . $this->mPrefix )->inContentLanguage(); |
383 | 384 | return !$msg->exists() ? '' : $msg; |
384 | 385 | } |
| 386 | + |
| 387 | + |
| 388 | + |
| 389 | + /** |
| 390 | + * Transclude an interwiki link. |
| 391 | + */ |
| 392 | + public static function interwikiTransclude( $title ) { |
| 393 | + |
| 394 | + // If we have a wikiID, we will use it to get an access to the remote database |
| 395 | + // if not, we will use the API URL to retrieve the data through a HTTP Get |
| 396 | + |
| 397 | + $wikiID = $title->getTransWikiID( ); |
| 398 | + $transAPI = $title->getTransAPI( ); |
| 399 | + |
| 400 | + if ( $wikiID !== '') { |
| 401 | + |
| 402 | + $finalText = self::fetchTemplateFromDB( $wikiID, $title ); |
| 403 | + return $finalText; |
| 404 | + |
| 405 | + } else if( $transAPI !== '' ) { |
| 406 | + |
| 407 | + $fullTitle = $title->getNsText().':'.$title->getText(); |
| 408 | + |
| 409 | + $url1 = $transAPI."?action=query&prop=revisions&titles=$fullTitle&rvprop=content&format=json"; |
| 410 | + |
| 411 | + if ( strlen( $url1 ) > 255 ) { |
| 412 | + return false; |
| 413 | + } |
| 414 | + |
| 415 | + $finalText = self::fetchTemplateHTTPMaybeFromCache( $url1 ); |
| 416 | + |
| 417 | + $url2 = $transAPI."?action=parse&text={{".$fullTitle."}}&prop=templates&format=json"; |
| 418 | + |
| 419 | + $get = Http::get( $url2 ); |
| 420 | + $myArray = FormatJson::decode($get, true); |
| 421 | + |
| 422 | + if ( ! empty( $myArray['parse'] )) { |
| 423 | + $templates = $myArray['parse']['templates']; |
| 424 | + } |
| 425 | + |
| 426 | + // TODO: The templates are retrieved one by one. We should get them all in 1 request |
| 427 | + // Here, we preload and cache the subtemplates |
| 428 | + for ($i = 0 ; $i < count( $templates ) ; $i++) { |
| 429 | + $newTitle = $templates[$i]['*']; |
| 430 | + |
| 431 | + $url = $transAPI."?action=query&prop=revisions&titles=$newTitle&rvprop=content&format=json"; |
| 432 | + |
| 433 | + // $newText is unused, but requesting it will put the template in the cache |
| 434 | + $newText = self::fetchTemplateHTTPMaybeFromCache( $url ); |
| 435 | + |
| 436 | + } |
| 437 | + return $finalText; |
| 438 | + |
| 439 | + } |
| 440 | + return false; |
| 441 | + } |
| 442 | + |
| 443 | + public static function fetchTemplateFromDB ( $wikiID, $title ) { |
| 444 | + |
| 445 | + $revision = Revision::loadFromTitleForeignWiki( $wikiID, $title ); |
| 446 | + |
| 447 | + if ( $revision ) { |
| 448 | + $text = $revision->getText(); |
| 449 | + return $text; |
| 450 | + } |
| 451 | + |
| 452 | + return false; |
| 453 | + } |
| 454 | + |
| 455 | + public static function fetchTemplateHTTPMaybeFromCache( $url ) { |
| 456 | + global $wgTranscludeCacheExpiry; |
| 457 | + $dbr = wfGetDB( DB_SLAVE ); |
| 458 | + $tsCond = $dbr->timestamp( time() - $wgTranscludeCacheExpiry ); |
| 459 | + $obj = $dbr->selectRow( 'transcache', array('tc_time', 'tc_contents' ), |
| 460 | + array( 'tc_url' => $url, "tc_time >= " . $dbr->addQuotes( $tsCond ) ) ); |
| 461 | + |
| 462 | + if ( $obj ) { |
| 463 | + return $obj->tc_contents; |
| 464 | + } |
| 465 | + |
| 466 | + $get = Http::get( $url ); |
| 467 | + |
| 468 | + $content = FormatJson::decode( $get, true ); |
| 469 | + |
| 470 | + if ( ! empty($content['query']['pages']) ) { |
| 471 | + |
| 472 | + $page = array_pop( $content['query']['pages'] ); |
| 473 | + $text = $page['revisions'][0]['*']; |
| 474 | + |
| 475 | + } else { |
| 476 | + |
| 477 | + return wfMsg( 'scarytranscludefailed', $url ); |
| 478 | + |
| 479 | + } |
| 480 | + |
| 481 | + $dbw = wfGetDB( DB_MASTER ); |
| 482 | + $dbw->replace( 'transcache', array('tc_url'), array( |
| 483 | + 'tc_url' => $url, |
| 484 | + 'tc_time' => $dbw->timestamp( ), |
| 485 | + 'tc_contents' => $text) |
| 486 | + ); |
| 487 | + |
| 488 | + return $text; |
| 489 | + } |
| 490 | + |
| 491 | + |
| 492 | + |
| 493 | + |
385 | 494 | } |
Property changes on: branches/iwtransclusion/phase3v3/includes/interwiki/Interwiki.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
386 | 495 | Merged /branches/iwtransclusion/phase3/includes/interwiki/Interwiki.php:r69541,69723,69730 |
387 | 496 | Merged /branches/iwtransclusion/phase3v2/includes/interwiki/Interwiki.php:r87105 |
Index: branches/iwtransclusion/phase3v3/includes/Revision.php |
— | — | @@ -156,6 +156,30 @@ |
157 | 157 | } |
158 | 158 | |
159 | 159 | /** |
| 160 | + * Stores the origin wiki of a revision in case it is a foreign wiki |
| 161 | + */ |
| 162 | + function setWikiID( $wikiID ) { |
| 163 | + $this->mWikiID = $wikiID; |
| 164 | + } |
| 165 | + |
| 166 | + /** |
| 167 | + * Load the current revision of a given page of a foreign wiki. |
| 168 | + * The WikiID is stored for further use, such as loadText() and getTimestampFromId() |
| 169 | + */ |
| 170 | + public static function loadFromTitleForeignWiki( $wikiID, $title ) { |
| 171 | + $dbr = wfGetDB( DB_SLAVE, array(), $wikiID ); |
| 172 | + |
| 173 | + $revision = self::loadFromTitle( $dbr, $title ); |
| 174 | + |
| 175 | + if( $revision ) { |
| 176 | + $revision->setWikiID( $wikiID ); |
| 177 | + } |
| 178 | + |
| 179 | + return $revision; |
| 180 | + |
| 181 | + } |
| 182 | + |
| 183 | + /** |
160 | 184 | * Load either the current, or a specified, revision |
161 | 185 | * that's attached to a given page. If not attached |
162 | 186 | * to that page, will return null. |
— | — | @@ -390,6 +414,7 @@ |
391 | 415 | throw new MWException( 'Revision constructor passed invalid row format.' ); |
392 | 416 | } |
393 | 417 | $this->mUnpatrolled = null; |
| 418 | + $this->mWikiID = false; |
394 | 419 | } |
395 | 420 | |
396 | 421 | /** |
— | — | @@ -437,7 +462,8 @@ |
438 | 463 | if( isset( $this->mTitle ) ) { |
439 | 464 | return $this->mTitle; |
440 | 465 | } |
441 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 466 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
| 467 | + |
442 | 468 | $row = $dbr->selectRow( |
443 | 469 | array( 'page', 'revision' ), |
444 | 470 | array( 'page_namespace', 'page_title' ), |
— | — | @@ -577,7 +603,7 @@ |
578 | 604 | if( $this->mUnpatrolled !== null ) { |
579 | 605 | return $this->mUnpatrolled; |
580 | 606 | } |
581 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 607 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
582 | 608 | $this->mUnpatrolled = $dbr->selectField( 'recentchanges', |
583 | 609 | 'rc_id', |
584 | 610 | array( // Add redundant user,timestamp condition so we can use the existing index |
— | — | @@ -931,7 +957,7 @@ |
932 | 958 | |
933 | 959 | if( !$row ) { |
934 | 960 | // Text data is immutable; check slaves first. |
935 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 961 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
936 | 962 | $row = $dbr->selectRow( 'text', |
937 | 963 | array( 'old_text', 'old_flags' ), |
938 | 964 | array( 'old_id' => $this->getTextId() ), |
— | — | @@ -940,7 +966,7 @@ |
941 | 967 | |
942 | 968 | if( !$row && wfGetLB()->getServerCount() > 1 ) { |
943 | 969 | // Possible slave lag! |
944 | | - $dbw = wfGetDB( DB_MASTER ); |
| 970 | + $dbw = wfGetDB( DB_MASTER, array(), $this->mWikiID ); |
945 | 971 | $row = $dbw->selectRow( 'text', |
946 | 972 | array( 'old_text', 'old_flags' ), |
947 | 973 | array( 'old_id' => $this->getTextId() ), |
— | — | @@ -1051,7 +1077,7 @@ |
1052 | 1078 | * @return String |
1053 | 1079 | */ |
1054 | 1080 | static function getTimestampFromId( $title, $id ) { |
1055 | | - $dbr = wfGetDB( DB_SLAVE ); |
| 1081 | + $dbr = wfGetDB( DB_SLAVE, array(), $this->mWikiID ); |
1056 | 1082 | // Casting fix for DB2 |
1057 | 1083 | if ( $id == '' ) { |
1058 | 1084 | $id = 0; |
— | — | @@ -1061,7 +1087,7 @@ |
1062 | 1088 | $timestamp = $dbr->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ ); |
1063 | 1089 | if ( $timestamp === false && wfGetLB()->getServerCount() > 1 ) { |
1064 | 1090 | # Not in slave, try master |
1065 | | - $dbw = wfGetDB( DB_MASTER ); |
| 1091 | + $dbw = wfGetDB( DB_MASTER, array(), $this->mWikiID ); |
1066 | 1092 | $timestamp = $dbw->selectField( 'revision', 'rev_timestamp', $conds, __METHOD__ ); |
1067 | 1093 | } |
1068 | 1094 | return wfTimestamp( TS_MW, $timestamp ); |
Property changes on: branches/iwtransclusion/phase3v3/includes/Revision.php |
___________________________________________________________________ |
Modified: svn:mergeinfo |
1069 | 1095 | Merged /branches/iwtransclusion/phase3/includes/Revision.php:r69730 |
1070 | 1096 | Merged /branches/iwtransclusion/phase3v2/includes/Revision.php:r87105 |