Index: trunk/phase3/includes/diff/DifferenceEngine.php |
— | — | @@ -27,6 +27,7 @@ |
28 | 28 | var $mOldRev, $mNewRev; |
29 | 29 | var $mRevisionsLoaded = false; // Have the revisions been loaded |
30 | 30 | var $mTextLoaded = 0; // How many text blobs have been loaded, 0, 1 or 2? |
| 31 | + var $mCacheHit = false; // Was the diff fetched from cache? |
31 | 32 | var $htmldiff; |
32 | 33 | |
33 | 34 | protected $unhide = false; |
— | — | @@ -52,9 +53,8 @@ |
53 | 54 | $this->mNewid = intval($old); |
54 | 55 | $this->mOldid = $this->mTitle->getPreviousRevisionID( $this->mNewid ); |
55 | 56 | } elseif ( 'next' === $new ) { |
56 | | - # Show diff between revision $old and the previous one. |
57 | | - # Get previous one from DB. |
58 | | - # |
| 57 | + # Show diff between revision $old and the next one. |
| 58 | + # Get next one from DB. |
59 | 59 | $this->mOldid = intval($old); |
60 | 60 | $this->mNewid = $this->mTitle->getNextRevisionID( $this->mOldid ); |
61 | 61 | if ( false === $this->mNewid ) { |
— | — | @@ -76,6 +76,18 @@ |
77 | 77 | function getTitle() { |
78 | 78 | return $this->mTitle; |
79 | 79 | } |
| 80 | + |
| 81 | + function wasCacheHit() { |
| 82 | + return $this->mCacheHit; |
| 83 | + } |
| 84 | + |
| 85 | + function getOldid() { |
| 86 | + return $this->mOldid; |
| 87 | + } |
| 88 | + |
| 89 | + function getNewid() { |
| 90 | + return $this->mNewid; |
| 91 | + } |
80 | 92 | |
81 | 93 | function showDiffPage( $diffOnly = false ) { |
82 | 94 | global $wgUser, $wgOut, $wgUseExternalEditor, $wgUseRCPatrol, $wgEnableHtmlDiff; |
— | — | @@ -537,11 +549,16 @@ |
538 | 550 | function getDiffBody() { |
539 | 551 | global $wgMemc; |
540 | 552 | wfProfileIn( __METHOD__ ); |
| 553 | + $this->mCacheHit = true; |
541 | 554 | // Check if the diff should be hidden from this user |
| 555 | + if ( !$this->loadRevisionData() ) |
| 556 | + return ''; |
542 | 557 | if ( $this->mOldRev && !$this->mOldRev->userCan(Revision::DELETED_TEXT) ) { |
543 | 558 | return ''; |
544 | 559 | } else if ( $this->mNewRev && !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) { |
545 | 560 | return ''; |
| 561 | + } else if ( $this->mOldRev && $this->mNewRev && $this->mOldRev->getID() == $this->mNewRev->getID() ) { |
| 562 | + return ''; |
546 | 563 | } |
547 | 564 | // Cacheable? |
548 | 565 | $key = false; |
— | — | @@ -559,6 +576,7 @@ |
560 | 577 | } |
561 | 578 | } // don't try to load but save the result |
562 | 579 | } |
| 580 | + $this->mCacheHit = false; |
563 | 581 | |
564 | 582 | // Loadtext is permission safe, this just clears out the diff |
565 | 583 | if ( !$this->loadText() ) { |
— | — | @@ -691,7 +709,7 @@ |
692 | 710 | |
693 | 711 | function localiseLineNumbersCb( $matches ) { |
694 | 712 | global $wgLang; |
695 | | - return wfMsgExt( 'lineno', array( 'parseinline' ), $wgLang->formatNum( $matches[1] ) ); |
| 713 | + return wfMsgExt( 'lineno', array (), $wgLang->formatNum( $matches[1] ) ); |
696 | 714 | } |
697 | 715 | |
698 | 716 | |
— | — | @@ -773,10 +791,10 @@ |
774 | 792 | |
775 | 793 | // Load the new revision object |
776 | 794 | $this->mNewRev = $this->mNewid |
777 | | - ? Revision::newFromId( $this->mNewid ) |
778 | | - : Revision::newFromTitle( $this->mTitle ); |
| 795 | + ? Revision::newFromId( $this->mNewid ) |
| 796 | + : Revision::newFromTitle( $this->mTitle ); |
779 | 797 | if( !$this->mNewRev instanceof Revision ) |
780 | | - return false; |
| 798 | + return false; |
781 | 799 | |
782 | 800 | // Update the new revision ID in case it was 0 (makes life easier doing UI stuff) |
783 | 801 | $this->mNewid = $this->mNewRev->getId(); |
Index: trunk/phase3/includes/api/ApiQueryRevisions.php |
— | — | @@ -100,6 +100,26 @@ |
101 | 101 | if ($pageCount > 1 && $enumRevMode) |
102 | 102 | $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start and end parameters may only be used on a single page.', 'multpages'); |
103 | 103 | |
| 104 | + if (!is_null($params['diffto'])) { |
| 105 | + if ($params['diffto'] == 'cur') |
| 106 | + $params['diffto'] = 0; |
| 107 | + if ((!ctype_digit($params['diffto']) || $params['diffto'] < 0) |
| 108 | + && $params['diffto'] != 'prev' && $params['diffto'] != 'next') |
| 109 | + $this->dieUsage('rvdiffto must be set to a non-negative number, "prev", "next" or "cur"', 'diffto'); |
| 110 | + // Check whether the revision exists and is readable, |
| 111 | + // DifferenceEngine returns a rather ambiguous empty |
| 112 | + // string if that's not the case |
| 113 | + if ($params['diffto'] != 0) { |
| 114 | + $difftoRev = Revision::newFromID($params['diffto']); |
| 115 | + if (!$difftoRev) |
| 116 | + $this->dieUsageMsg(array('nosuchrevid', $params['diffto'])); |
| 117 | + if (!$difftoRev->userCan(Revision::DELETED_TEXT)) { |
| 118 | + $this->setWarning("Couldn't diff to r{$difftoRev->getID()}: content is hidden"); |
| 119 | + $params['diffto'] = null; |
| 120 | + } |
| 121 | + } |
| 122 | + } |
| 123 | + |
104 | 124 | $this->addTables('revision'); |
105 | 125 | $this->addFields(Revision::selectFields()); |
106 | 126 | $this->addTables('page'); |
— | — | @@ -116,6 +136,7 @@ |
117 | 137 | $this->fld_size = isset ($prop['size']); |
118 | 138 | $this->fld_user = isset ($prop['user']); |
119 | 139 | $this->token = $params['token']; |
| 140 | + $this->diffto = $params['diffto']; |
120 | 141 | |
121 | 142 | if ( !is_null($this->token) || $pageCount > 0) { |
122 | 143 | $this->addFields( Revision::selectPageFields() ); |
— | — | @@ -288,7 +309,7 @@ |
289 | 310 | } |
290 | 311 | |
291 | 312 | private function extractRowInfo( $revision ) { |
292 | | - |
| 313 | + $title = $revision->getTitle(); |
293 | 314 | $vals = array (); |
294 | 315 | |
295 | 316 | if ($this->fld_ids) { |
— | — | @@ -325,11 +346,8 @@ |
326 | 347 | if (strval($comment) !== '') |
327 | 348 | $vals['comment'] = $comment; |
328 | 349 | } |
329 | | - } |
| 350 | + } |
330 | 351 | |
331 | | - if(!is_null($this->token) || ($this->fld_content && $this->expandTemplates)) |
332 | | - $title = $revision->getTitle(); |
333 | | - |
334 | 352 | if(!is_null($this->token)) |
335 | 353 | { |
336 | 354 | $tokenFunctions = $this->getTokenFunctions(); |
— | — | @@ -372,6 +390,22 @@ |
373 | 391 | } else if ($this->fld_content) { |
374 | 392 | $vals['texthidden'] = ''; |
375 | 393 | } |
| 394 | + |
| 395 | + if (!is_null($this->diffto)) { |
| 396 | + global $wgAPIMaxUncachedDiffs; |
| 397 | + static $n = 0; // Numer of uncached diffs we've had |
| 398 | + if($n< $wgAPIMaxUncachedDiffs) { |
| 399 | + $engine = new DifferenceEngine($title, $revision->getID(), $this->diffto); |
| 400 | + $difftext = $engine->getDiffBody(); |
| 401 | + $vals['diff']['from'] = $engine->getOldid(); |
| 402 | + $vals['diff']['to'] = $engine->getNewid(); |
| 403 | + ApiResult::setContent($vals['diff'], $difftext); |
| 404 | + if(!$engine->wasCacheHit()) |
| 405 | + $n++; |
| 406 | + } else { |
| 407 | + $vals['diff']['notcached'] = ''; |
| 408 | + } |
| 409 | + } |
376 | 410 | return $vals; |
377 | 411 | } |
378 | 412 | |
— | — | @@ -429,6 +463,7 @@ |
430 | 464 | ApiBase :: PARAM_ISMULTI => true |
431 | 465 | ), |
432 | 466 | 'continue' => null, |
| 467 | + 'diffto' => null, |
433 | 468 | ); |
434 | 469 | } |
435 | 470 | |
— | — | @@ -448,6 +483,8 @@ |
449 | 484 | 'section' => 'only retrieve the content of this section', |
450 | 485 | 'token' => 'Which tokens to obtain for each revision', |
451 | 486 | 'continue' => 'When more results are available, use this to continue', |
| 487 | + 'diffto' => array('Revision ID to diff each revision to.', |
| 488 | + 'Use "prev", "next" and "cur" for the previous, next and current revision respectively.'), |
452 | 489 | ); |
453 | 490 | } |
454 | 491 | |
Index: trunk/phase3/includes/api/ApiBase.php |
— | — | @@ -988,4 +988,4 @@ |
989 | 989 | public static function getBaseVersion() { |
990 | 990 | return __CLASS__ . ': $Id$'; |
991 | 991 | } |
992 | | -} |
\ No newline at end of file |
| 992 | +} |
Index: trunk/phase3/includes/DefaultSettings.php |
— | — | @@ -3562,6 +3562,12 @@ |
3563 | 3563 | $wgAPIMaxResultSize = 8388608; |
3564 | 3564 | |
3565 | 3565 | /** |
| 3566 | + * The maximum number of uncached diffs that can be retrieved in one API |
| 3567 | + * request. Set this to 0 to disable API diffs altogether |
| 3568 | + */ |
| 3569 | +$wgAPIMaxUncachedDiffs = 1; |
| 3570 | + |
| 3571 | +/** |
3566 | 3572 | * Parser test suite files to be run by parserTests.php when no specific |
3567 | 3573 | * filename is passed to it. |
3568 | 3574 | * |
Index: trunk/phase3/RELEASE-NOTES |
— | — | @@ -265,6 +265,7 @@ |
266 | 266 | aliases already listed in siprop=namespaces |
267 | 267 | * (bug 17529) rvend ignored when rvstartid is specified |
268 | 268 | * (bug 17626) Added uiprop=email to list=userinfo |
| 269 | +* (bug 13209) Added rvdiffto parameter to prop=revisions |
269 | 270 | |
270 | 271 | === Languages updated in 1.15 === |
271 | 272 | |