if ($pageCount > 1 && $enumRevMode)
$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');
+ if (!is_null($params['diffto'])) {
+ if ($params['diffto'] == 'cur')
+ $params['diffto'] = 0;
+ if ((!ctype_digit($params['diffto']) || $params['diffto'] < 0)
+ && $params['diffto'] != 'prev' && $params['diffto'] != 'next')
+ $this->dieUsage('rvdiffto must be set to a non-negative number, "prev", "next" or "cur"', 'diffto');
+ // Check whether the revision exists and is readable,
+ // DifferenceEngine returns a rather ambiguous empty
+ // string if that's not the case
+ if ($params['diffto'] != 0) {
+ $difftoRev = Revision::newFromID($params['diffto']);
+ if (!$difftoRev)
+ $this->dieUsageMsg(array('nosuchrevid', $params['diffto']));
+ if (!$difftoRev->userCan(Revision::DELETED_TEXT)) {
+ $this->setWarning("Couldn't diff to r{$difftoRev->getID()}: content is hidden");
+ $params['diffto'] = null;
+ }
+ }
+ }
+
$this->addTables('revision');
$this->addFields(Revision::selectFields());
$this->addTables('page');
$this->fld_size = isset ($prop['size']);
$this->fld_user = isset ($prop['user']);
$this->token = $params['token'];
+ $this->diffto = $params['diffto'];
if ( !is_null($this->token) || $pageCount > 0) {
$this->addFields( Revision::selectPageFields() );
}
private function extractRowInfo( $revision ) {
-
+ $title = $revision->getTitle();
$vals = array ();
if ($this->fld_ids) {
if (strval($comment) !== '')
$vals['comment'] = $comment;
}
- }
-
- if(!is_null($this->token) || ($this->fld_content && $this->expandTemplates))
- $title = $revision->getTitle();
+ }
if(!is_null($this->token))
{
} else if ($this->fld_content) {
$vals['texthidden'] = '';
}
+
+ if (!is_null($this->diffto)) {
+ global $wgAPIMaxUncachedDiffs;
+ static $n = 0; // Numer of uncached diffs we've had
+ if($n< $wgAPIMaxUncachedDiffs) {
+ $engine = new DifferenceEngine($title, $revision->getID(), $this->diffto);
+ $difftext = $engine->getDiffBody();
+ $vals['diff']['from'] = $engine->getOldid();
+ $vals['diff']['to'] = $engine->getNewid();
+ ApiResult::setContent($vals['diff'], $difftext);
+ if(!$engine->wasCacheHit())
+ $n++;
+ } else {
+ $vals['diff']['notcached'] = '';
+ }
+ }
return $vals;
}
ApiBase :: PARAM_ISMULTI => true
),
'continue' => null,
+ 'diffto' => null,
);
}
'section' => 'only retrieve the content of this section',
'token' => 'Which tokens to obtain for each revision',
'continue' => 'When more results are available, use this to continue',
+ 'diffto' => array('Revision ID to diff each revision to.',
+ 'Use "prev", "next" and "cur" for the previous, next and current revision respectively.'),
);
}
var $mOldRev, $mNewRev;
var $mRevisionsLoaded = false; // Have the revisions been loaded
var $mTextLoaded = 0; // How many text blobs have been loaded, 0, 1 or 2?
+ var $mCacheHit = false; // Was the diff fetched from cache?
var $htmldiff;
protected $unhide = false;
$this->mNewid = intval($old);
$this->mOldid = $this->mTitle->getPreviousRevisionID( $this->mNewid );
} elseif ( 'next' === $new ) {
- # Show diff between revision $old and the previous one.
- # Get previous one from DB.
- #
+ # Show diff between revision $old and the next one.
+ # Get next one from DB.
$this->mOldid = intval($old);
$this->mNewid = $this->mTitle->getNextRevisionID( $this->mOldid );
if ( false === $this->mNewid ) {
function getTitle() {
return $this->mTitle;
}
+
+ function wasCacheHit() {
+ return $this->mCacheHit;
+ }
+
+ function getOldid() {
+ return $this->mOldid;
+ }
+
+ function getNewid() {
+ return $this->mNewid;
+ }
function showDiffPage( $diffOnly = false ) {
global $wgUser, $wgOut, $wgUseExternalEditor, $wgUseRCPatrol, $wgEnableHtmlDiff;
function getDiffBody() {
global $wgMemc;
wfProfileIn( __METHOD__ );
+ $this->mCacheHit = true;
// Check if the diff should be hidden from this user
+ if ( !$this->loadRevisionData() )
+ return '';
if ( $this->mOldRev && !$this->mOldRev->userCan(Revision::DELETED_TEXT) ) {
return '';
} else if ( $this->mNewRev && !$this->mNewRev->userCan(Revision::DELETED_TEXT) ) {
return '';
+ } else if ( $this->mOldRev && $this->mNewRev && $this->mOldRev->getID() == $this->mNewRev->getID() ) {
+ return '';
}
// Cacheable?
$key = false;
}
} // don't try to load but save the result
}
+ $this->mCacheHit = false;
// Loadtext is permission safe, this just clears out the diff
if ( !$this->loadText() ) {
function localiseLineNumbersCb( $matches ) {
global $wgLang;
- return wfMsgExt( 'lineno', array( 'parseinline' ), $wgLang->formatNum( $matches[1] ) );
+ return wfMsgExt( 'lineno', array (), $wgLang->formatNum( $matches[1] ) );
}
// Load the new revision object
$this->mNewRev = $this->mNewid
- ? Revision::newFromId( $this->mNewid )
- : Revision::newFromTitle( $this->mTitle );
+ ? Revision::newFromId( $this->mNewid )
+ : Revision::newFromTitle( $this->mTitle );
if( !$this->mNewRev instanceof Revision )
- return false;
+ return false;
// Update the new revision ID in case it was 0 (makes life easier doing UI stuff)
$this->mNewid = $this->mNewRev->getId();