]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - includes/api/ApiQueryRevisions.php
MediaWiki 1.15.0
[autoinstallsdev/mediawiki.git] / includes / api / ApiQueryRevisions.php
index 977e792b77c327ffae443f2867b371da5163f437..ca9152adc940a80c8e9e3e0c0525a67507f58f4b 100644 (file)
@@ -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 $';
        }
 }