MediaWiki r47890 - Code Review

Jump to: navigation, search
Repository:MediaWiki
Revision:r47889‎ | r47890 (on ViewVC)‎ | r47891 >
Date:13:25, 28 February 2009
Author:catrope
Status:resolved (Comments)
Tags:
Comment:
* API: (bug 13209) Add rvdiffto parameter to prop=revisions
* Add $wgAPIMaxUncachedDiffs (default 1) which controls how many non-cached diffs will be served per request
* Tweak DifferenceEngine.php a bit to make cache status accessible, and remove a useless 'parseinline' which broke diff generation in the API
Modified paths:

Diff [purge]

Index: trunk/phase3/includes/diff/DifferenceEngine.php
===================================================================
--- trunk/phase3/includes/diff/DifferenceEngine.php	(revision 47889)
+++ trunk/phase3/includes/diff/DifferenceEngine.php	(revision 47890)
@@ -27,6 +27,7 @@
 	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;
@@ -52,9 +53,8 @@
 			$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 ) {
@@ -76,6 +76,18 @@
 	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;
@@ -537,11 +549,16 @@
 	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;
@@ -559,6 +576,7 @@
 				}
 			} // 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() ) {
@@ -691,7 +709,7 @@
 
 	function localiseLineNumbersCb( $matches ) {
 		global $wgLang;
-		return wfMsgExt( 'lineno', array( 'parseinline' ), $wgLang->formatNum( $matches[1] ) );
+		return wfMsgExt( 'lineno', array (), $wgLang->formatNum( $matches[1] ) );
 	}
 
 
@@ -773,10 +791,10 @@
 
 		// 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();
Index: trunk/phase3/includes/api/ApiQueryRevisions.php
===================================================================
--- trunk/phase3/includes/api/ApiQueryRevisions.php	(revision 47889)
+++ trunk/phase3/includes/api/ApiQueryRevisions.php	(revision 47890)
@@ -100,6 +100,26 @@
 		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');
@@ -116,6 +136,7 @@
 		$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() );
@@ -288,7 +309,7 @@
 	}
 
 	private function extractRowInfo( $revision ) {
-
+		$title = $revision->getTitle();
 		$vals = array ();
 
 		if ($this->fld_ids) {
@@ -325,11 +346,8 @@
 				if (strval($comment) !== '')
 					$vals['comment'] = $comment;
 			}
-		}
+		}	
 
-		if(!is_null($this->token) || ($this->fld_content && $this->expandTemplates))
-			$title = $revision->getTitle();
-
 		if(!is_null($this->token))
 		{
 			$tokenFunctions = $this->getTokenFunctions();
@@ -372,6 +390,22 @@
 		} 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;
 	}
 
@@ -429,6 +463,7 @@
 				ApiBase :: PARAM_ISMULTI => true
 			),
 			'continue' => null,
+			'diffto' => null,
 		);
 	}
 
@@ -448,6 +483,8 @@
 			'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.'),
 		);
 	}
 
Index: trunk/phase3/includes/api/ApiBase.php
===================================================================
--- trunk/phase3/includes/api/ApiBase.php	(revision 47889)
+++ trunk/phase3/includes/api/ApiBase.php	(revision 47890)
@@ -988,4 +988,4 @@
 	public static function getBaseVersion() {
 		return __CLASS__ . ': $Id$';
 	}
-}
\ No newline at end of file
+}
Index: trunk/phase3/includes/DefaultSettings.php
===================================================================
--- trunk/phase3/includes/DefaultSettings.php	(revision 47889)
+++ trunk/phase3/includes/DefaultSettings.php	(revision 47890)
@@ -3562,6 +3562,12 @@
 $wgAPIMaxResultSize = 8388608;
 
 /**
+ * The maximum number of uncached diffs that can be retrieved in one API
+ * request. Set this to 0 to disable API diffs altogether
+ */
+$wgAPIMaxUncachedDiffs = 1;
+
+/**
  * Parser test suite files to be run by parserTests.php when no specific
  * filename is passed to it.
  *
Index: trunk/phase3/RELEASE-NOTES
===================================================================
--- trunk/phase3/RELEASE-NOTES	(revision 47889)
+++ trunk/phase3/RELEASE-NOTES	(revision 47890)
@@ -265,6 +265,7 @@
   aliases already listed in siprop=namespaces
 * (bug 17529) rvend ignored when rvstartid is specified
 * (bug 17626) Added uiprop=email to list=userinfo
+* (bug 13209) Added rvdiffto parameter to prop=revisions
 
 === Languages updated in 1.15 ===
 

Follow-up revisions

Rev.Commit summaryAuthorDate
r48216(bug 17863) Fix regression from r47890 that broke Show changes on the edit fo...catrope11:00, 9 March 2009

Comments

#Comment by Siebrand (Talk | contribs)   18:42, 8 March 2009

FIXME: In UI page edit, "Show changes" now gives a diff between the 2 previous versions, instead of between the latest version and the editor version.

Status & tagging log

Personal tools
Namespaces
Variants
Views
Actions
Site
Support
Download
Development
Communication
Toolbox