summaryrefslogtreecommitdiff
path: root/includes/api/ApiQueryRevisions.php
diff options
context:
space:
mode:
authorPierre Schmitz <pierre@archlinux.de>2009-06-10 13:00:47 +0200
committerPierre Schmitz <pierre@archlinux.de>2009-06-10 13:00:47 +0200
commit72e90545454c0e014318fa3c81658e035aac58c1 (patch)
tree9212e3f46868989c4d57ae9a5c8a1a80e4dc0702 /includes/api/ApiQueryRevisions.php
parent565a0ccc371ec1a2a0e9b39487cbac18e6f60e25 (diff)
applying patch to version 1.15.0
Diffstat (limited to 'includes/api/ApiQueryRevisions.php')
-rw-r--r--includes/api/ApiQueryRevisions.php155
1 files changed, 113 insertions, 42 deletions
diff --git a/includes/api/ApiQueryRevisions.php b/includes/api/ApiQueryRevisions.php
index 977e792b..ca9152ad 100644
--- a/includes/api/ApiQueryRevisions.php
+++ b/includes/api/ApiQueryRevisions.php
@@ -100,9 +100,29 @@ class ApiQueryRevisions extends ApiQueryBase {
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->addFields(Revision::selectFields());
+ $this->addTables('page');
$this->addWhere('page_id = rev_page');
$prop = array_flip($params['prop']);
@@ -116,6 +136,7 @@ class ApiQueryRevisions extends ApiQueryBase {
$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() );
@@ -134,7 +155,7 @@ class ApiQueryRevisions extends ApiQueryBase {
$this->addTables('text');
$this->addWhere('rev_text_id=old_id');
$this->addFields('old_id');
- $this->addFields( Revision::selectTextFields() );
+ $this->addFields(Revision::selectTextFields());
$this->fld_content = true;
@@ -176,9 +197,14 @@ class ApiQueryRevisions extends ApiQueryBase {
if (is_null($params['startid']) && is_null($params['endid']))
$this->addWhereRange('rev_timestamp', $params['dir'],
$params['start'], $params['end']);
- else
+ else {
$this->addWhereRange('rev_id', $params['dir'],
$params['startid'], $params['endid']);
+ // One of start and end can be set
+ // If neither is set, this does nothing
+ $this->addWhereRange('rev_timestamp', $params['dir'],
+ $params['start'], $params['end'], false);
+ }
// must manually initialize unset limit
if (is_null($limit))
@@ -186,14 +212,18 @@ class ApiQueryRevisions extends ApiQueryBase {
$this->validateLimit('limit', $limit, 1, $userMax, $botMax);
// There is only one ID, use it
- $this->addWhereFld('rev_page', current(array_keys($pageSet->getGoodTitles())));
+ $this->addWhereFld('rev_page', reset(array_keys($pageSet->getGoodTitles())));
if(!is_null($params['user'])) {
$this->addWhereFld('rev_user_text', $params['user']);
- } elseif (!is_null( $params['excludeuser'])) {
+ } elseif (!is_null($params['excludeuser'])) {
$this->addWhere('rev_user_text != ' .
$this->getDB()->addQuotes($params['excludeuser']));
}
+ if(!is_null($params['user']) || !is_null($params['excludeuser'])) {
+ // Paranoia: avoid brute force searches (bug 17342)
+ $this->addWhere('rev_deleted & ' . Revision::DELETED_USER . ' = 0');
+ }
}
elseif ($revCount > 0) {
$max = $this->getMain()->canApiHighLimits() ? $botMax : $userMax;
@@ -204,6 +234,10 @@ class ApiQueryRevisions extends ApiQueryBase {
// Get all revision IDs
$this->addWhereFld('rev_id', array_keys($revs));
+ if(!is_null($params['continue']))
+ $this->addWhere("rev_id >= '" . intval($params['continue']) . "'");
+ $this->addOption('ORDER BY', 'rev_id');
+
// assumption testing -- we should never get more then $revCount rows.
$limit = $revCount;
}
@@ -220,6 +254,22 @@ class ApiQueryRevisions extends ApiQueryBase {
// Get all page IDs
$this->addWhereFld('page_id', array_keys($titles));
+ // Every time someone relies on equality propagation, god kills a kitten :)
+ $this->addWhereFld('rev_page', array_keys($titles));
+
+ if(!is_null($params['continue']))
+ {
+ $cont = explode('|', $params['continue']);
+ if(count($cont) != 2)
+ $this->dieUsage("Invalid continue param. You should pass the original " .
+ "value returned by the previous query", "_badcontinue");
+ $pageid = intval($cont[0]);
+ $revid = intval($cont[1]);
+ $this->addWhere("rev_page > '$pageid' OR " .
+ "(rev_page = '$pageid' AND " .
+ "rev_id >= '$revid')");
+ }
+ $this->addOption('ORDER BY', 'rev_page, rev_id');
// assumption testing -- we should never get more then $pageCount rows.
$limit = $pageCount;
@@ -242,37 +292,30 @@ class ApiQueryRevisions extends ApiQueryBase {
$this->setContinueEnumParameter('startid', intval($row->rev_id));
break;
}
-
$revision = new Revision( $row );
- $this->getResult()->addValue(
- array (
- 'query',
- 'pages',
- $revision->getPage(),
- 'revisions'),
- null,
- $this->extractRowInfo( $revision ));
- }
- $db->freeResult($res);
-
- // Ensure that all revisions are shown as '<rev>' elements
- $result = $this->getResult();
- if ($result->getIsRawMode()) {
- $data =& $result->getData();
- foreach ($data['query']['pages'] as & $page) {
- if (is_array($page) && array_key_exists('revisions', $page)) {
- $result->setIndexedTagName($page['revisions'], 'rev');
- }
+ //
+ $fit = $this->addPageSubItem($revision->getPage(), $this->extractRowInfo($revision), 'rev');
+ if(!$fit)
+ {
+ if($enumRevMode)
+ $this->setContinueEnumParameter('startid', intval($row->rev_id));
+ else if($revCount > 0)
+ $this->setContinueEnumParameter('continue', intval($row->rev_id));
+ else
+ $this->setContinueEnumParameter('continue', intval($row->rev_page) .
+ '|' . intval($row->rev_id));
+ break;
}
}
+ $db->freeResult($res);
}
private function extractRowInfo( $revision ) {
-
+ $title = $revision->getTitle();
$vals = array ();
if ($this->fld_ids) {
- $vals['revid'] = $revision->getId();
+ $vals['revid'] = intval($revision->getId());
// $vals['oldid'] = intval($row->rev_text_id); // todo: should this be exposed?
}
@@ -280,9 +323,13 @@ class ApiQueryRevisions extends ApiQueryBase {
$vals['minor'] = '';
if ($this->fld_user) {
- $vals['user'] = $revision->getUserText();
- if (!$revision->getUser())
- $vals['anon'] = '';
+ if ($revision->isDeleted(Revision::DELETED_USER)) {
+ $vals['userhidden'] = '';
+ } else {
+ $vals['user'] = $revision->getUserText();
+ if (!$revision->getUser())
+ $vals['anon'] = '';
+ }
}
if ($this->fld_timestamp) {
@@ -290,17 +337,18 @@ class ApiQueryRevisions extends ApiQueryBase {
}
if ($this->fld_size && !is_null($revision->getSize())) {
- $vals['size'] = $revision->getSize();
+ $vals['size'] = intval($revision->getSize());
}
if ($this->fld_comment) {
- $comment = $revision->getComment();
- if (strval($comment) !== '')
- $vals['comment'] = $comment;
- }
-
- if(!is_null($this->token) || ($this->fld_content && $this->expandTemplates))
- $title = $revision->getTitle();
+ if ($revision->isDeleted(Revision::DELETED_COMMENT)) {
+ $vals['commenthidden'] = '';
+ } else {
+ $comment = $revision->getComment();
+ if (strval($comment) !== '')
+ $vals['comment'] = $comment;
+ }
+ }
if(!is_null($this->token))
{
@@ -314,8 +362,8 @@ class ApiQueryRevisions extends ApiQueryBase {
$vals[$t . 'token'] = $val;
}
}
-
- if ($this->fld_content) {
+
+ if ($this->fld_content && !$revision->isDeleted(Revision::DELETED_TEXT)) {
global $wgParser;
$text = $revision->getText();
# Expand templates after getting section content because
@@ -341,6 +389,24 @@ class ApiQueryRevisions extends ApiQueryBase {
$text = $wgParser->preprocess( $text, $title, new ParserOptions() );
}
ApiResult :: setContent($vals, $text);
+ } 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;
}
@@ -398,6 +464,8 @@ class ApiQueryRevisions extends ApiQueryBase {
ApiBase :: PARAM_TYPE => array_keys($this->getTokenFunctions()),
ApiBase :: PARAM_ISMULTI => true
),
+ 'continue' => null,
+ 'diffto' => null,
);
}
@@ -416,6 +484,9 @@ class ApiQueryRevisions extends ApiQueryBase {
'generatexml' => 'generate XML parse tree for revision content',
'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.'),
);
}
@@ -448,6 +519,6 @@ class ApiQueryRevisions extends ApiQueryBase {
}
public function getVersion() {
- return __CLASS__ . ': $Id: ApiQueryRevisions.php 44719 2008-12-17 16:34:01Z catrope $';
+ return __CLASS__ . ': $Id: ApiQueryRevisions.php 48642 2009-03-20 20:21:38Z midom $';
}
}