r27890 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r27889‎ | r27890 | r27891 >
Date:16:41, 27 November 2007
Author:catrope
Status:old
Tags:
Comment:
API: Adding diff generation to prop=revisions.
This implementation outputs normal diff output (with < and >) rather than unified, and always uses native PHP diff (i.e. ignores $wgExternalDiffEngine). An implementation that honors $wgExternalDiffEngine and outputs a unified diff will follow later.
Modified paths:
  • /trunk/phase3/RELEASE-NOTES (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryRevisions.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/api/ApiQueryRevisions.php
@@ -45,14 +45,14 @@
4646 $fld_comment = false, $fld_user = false, $fld_content = false;
4747
4848 public function execute() {
49 - $limit = $startid = $endid = $start = $end = $dir = $prop = $user = $excludeuser = null;
 49+ $limit = $startid = $endid = $start = $end = $dir = $prop = $user = $excludeuser = $diffto = $difftoprev = null;
5050 extract($this->extractRequestParams());
5151
5252 // If any of those parameters are used, work in 'enumeration' mode.
5353 // Enum mode can only be used when exactly one page is provided.
54 - // Enumerating revisions on multiple pages make it extremelly
55 - // difficult to manage continuations and require additional sql indexes
56 - $enumRevMode = (!is_null($user) || !is_null($excludeuser) || !is_null($limit) || !is_null($startid) || !is_null($endid) || $dir === 'newer' || !is_null($start) || !is_null($end));
 54+ // Enumerating revisions on multiple pages make it extremely
 55+ // difficult to manage continuations and require additional SQL indexes
 56+ $enumRevMode = (!is_null($user) || !is_null($excludeuser) || !is_null($limit) || !is_null($startid) || !is_null($endid) || $dir === 'newer' || !is_null($start) || !is_null($end) | !$difftoprev);
5757
5858
5959 $pageSet = $this->getPageSet();
@@ -67,7 +67,7 @@
6868 $this->dieUsage('The revids= parameter may not be used with the list options (limit, startid, endid, dirNewer, start, end).', 'revids');
6969
7070 if ($pageCount > 1 && $enumRevMode)
71 - $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');
 71+ $this->dieUsage('titles, pageids or a generator was used to supply multiple pages, but the limit, startid, endid, dirNewer, user, excludeuser, start, end and difftoprev parameters may only be used on a single page.', 'multpages');
7272
7373 $this->addTables('revision');
7474 $this->addWhere('rev_deleted=0');
@@ -86,12 +86,36 @@
8787 $this->fld_comment = $this->addFieldsIf('rev_comment', isset ($prop['comment']));
8888 $this->fld_size = $this->addFieldsIf('rev_len', isset ($prop['size']));
8989
 90+ if($diffto || $difftoprev)
 91+ $this->formatter = new DiffFormatter;
 92+ if($diffto)
 93+ {
 94+ global $wgContLang;
 95+ $difftoRev = Revision::newFromID($diffto);
 96+ if(!($difftoRev instanceof Revision))
 97+ $this->dieUsage("There is no revision with ID $diffto", 'nosuchrev');
 98+ $this->diffOldText = $difftoRev->revText();
 99+ if($this->diffOldText == '') // deleted revision
 100+ $this->dieUsage("There is no revision with ID $diffto", 'nosuchrev'); // fake non-existence
 101+ $this->diffOldText = explode("\n", $wgContLang->segmentForDiff($this->diffOldText));
 102+ $this->diffto = $diffto;
 103+ }
 104+ else
 105+ $this->diffto = false;
 106+ if($difftoprev)
 107+ {
 108+ $this->revCache = array();
 109+ $this->difftoprev = true;
 110+ }
 111+ else
 112+ $this->difftoprev = false;
 113+
90114 if (isset ($prop['user'])) {
91115 $this->addFields('rev_user');
92116 $this->addFields('rev_user_text');
93117 $this->fld_user = true;
94118 }
95 - if (isset ($prop['content'])) {
 119+ if (isset ($prop['content']) || !is_null($diffto) || $difftoprev) {
96120
97121 // For each page we will request, the user must have read rights for that page
98122 foreach ($pageSet->getGoodTitles() as $title) {
@@ -107,17 +131,17 @@
108132 $this->addFields('old_text');
109133 $this->addFields('old_flags');
110134
111 - $this->fld_content = true;
 135+ $this->fld_content = isset($prop['content']);
112136
113137 $this->expandTemplates = $expandtemplates;
114138 }
115139
116 - $userMax = ($this->fld_content ? 50 : 500);
117 - $botMax = ($this->fld_content ? 200 : 10000);
 140+ $userMax = ($this->fld_content || $diffto || $difftoprev ? 50 : 500);
 141+ $botMax = ($this->fld_content || $diffto || $difftoprev ? 200 : 10000);
118142
119143 if ($enumRevMode) {
120144
121 - // This is mostly to prevent parameter errors (and optimize sql?)
 145+ // This is mostly to prevent parameter errors (and optimize SQL?)
122146 if (!is_null($startid) && !is_null($start))
123147 $this->dieUsage('start and startid cannot be used together', 'badparams');
124148
@@ -205,7 +229,41 @@
206230 $this->extractRowInfo($row));
207231 }
208232 $db->freeResult($res);
209 -
 233+
 234+ if($this->difftoprev)
 235+ {
 236+ global $wgContLang;
 237+ ksort($this->revCache, SORT_NUMERIC);
 238+ $previousRevID = null;
 239+ $oldText = null;
 240+ $data =& $this->getResult()->getData();
 241+ $pageID = current(array_keys($pageSet->getGoodTitles()));
 242+ $this->diffArr = array();
 243+ foreach($this->revCache as $revid => $revtext)
 244+ {
 245+ $r = array();
 246+ if(is_null($previousRevID))
 247+ {
 248+ // First run
 249+ $previousRevID = $revid;
 250+ $oldText = explode("\n", $wgContLang->segmentForDiff($revtext));
 251+ continue;
 252+ }
 253+ $newText = explode("\n", $wgContLang->segmentForDiff($revtext));
 254+ $diff = new Diff($oldText, $newText);
 255+ $r['from'] = $previousRevID;
 256+ ApiResult::setContent($r, $wgContLang->unsegmentForDiff($this->formatter->format($diff)));
 257+ $diffArr[$revid] = $r;
 258+
 259+ $previousRevID = $revid;
 260+ $oldText = $newText;
 261+ }
 262+ // Now that $this->diffArr is filled with diffprev elements, add them to the result
 263+ foreach($data['query']['pages'][$pageID]['revisions'] as &$rev)
 264+ if(isset($diffArr[$rev['revid']]))
 265+ $rev['difftoprev'] = $diffArr[$rev['revid']];
 266+ }
 267+
210268 // Ensure that all revisions are shown as '<rev>' elements
211269 $result = $this->getResult();
212270 if ($result->getIsRawMode()) {
@@ -248,8 +306,9 @@
249307 $vals['comment'] = $row->rev_comment;
250308 }
251309
 310+ if ($this->fld_content || $this->diffto || $this->difftoprev)
 311+ $text = Revision :: getRevisionText($row);
252312 if ($this->fld_content) {
253 - $text = Revision :: getRevisionText($row);
254313 if ($this->expandTemplates) {
255314 global $wgParser;
256315 $text = $wgParser->preprocess( $text, Title::newFromID($row->rev_page), new ParserOptions() );
@@ -257,6 +316,18 @@
258317 ApiResult :: setContent($vals, $text);
259318 }
260319
 320+ if($this->diffto)
 321+ {
 322+ global $wgContLang;
 323+ $newText = explode("\n", $wgContLang->segmentForDiff($text));
 324+ $diff = new Diff($this->diffOldText, $newText);
 325+ $vals['diffto']['from'] = $this->diffto;
 326+ ApiResult::setContent($vals['diffto'], $wgContLang->unsegmentForDiff($this->formatter->format($diff)));
 327+ }
 328+ if($this->difftoprev)
 329+ // Cache the revision's content for later use
 330+ $this->revCache[$row->rev_id] = $text;
 331+
261332 return $vals;
262333 }
263334
@@ -308,6 +379,10 @@
309380 ),
310381
311382 'expandtemplates' => false,
 383+ 'diffto' => array(
 384+ ApiBase :: PARAM_TYPE => 'integer'
 385+ ),
 386+ 'difftoprev' => false,
312387 );
313388 }
314389
@@ -322,7 +397,9 @@
323398 'dir' => 'direction of enumeration - towards "newer" or "older" revisions (enum)',
324399 'user' => 'only include revisions made by user',
325400 'excludeuser' => 'exclude revisions made by user',
326 - 'expandtemplates' => 'expand templates in revision content'
 401+ 'expandtemplates' => 'expand templates in revision content',
 402+ 'diffto' => 'Revision number to compare all revisions with',
 403+ 'difftoprev' => 'Diff each revision to the previous one (enum)',
327404 );
328405 }
329406
Index: trunk/phase3/RELEASE-NOTES
@@ -297,6 +297,7 @@
298298 * Outputting list of all user preferences rather than having to request them by
299299 name
300300 * (bug 11206) api.php should honor maxlag
 301+* Added diff generation to prop=revisions
301302
302303 === Languages updated in 1.12 ===
303304

Follow-up revisions

RevisionCommit summaryAuthorDate
r27906Fix regressions in r27759 -- pages already marked in link cache at link parsi...brion20:45, 27 November 2007

Status & tagging log