API: (bug 16858) Revamped list=deletedrevs to make listing deleted contributions...
authorRoan Kattouw <catrope@users.mediawiki.org>
Mon, 12 Jan 2009 16:39:04 +0000 (16:39 +0000)
committerRoan Kattouw <catrope@users.mediawiki.org>
Mon, 12 Jan 2009 16:39:04 +0000 (16:39 +0000)
RELEASE-NOTES
includes/api/ApiQueryDeletedrevs.php

index d744a0c..c16d887 100644 (file)
@@ -44,6 +44,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 16798) JSON encoding errors for some characters outside the BMP
 * (bug 16629) prop=info&inprop=protection lists empty legacy protections
   incorrectly
+* (bug 16858) Revamped list=deletedrevs to make listing deleted contributions
+  and listing all deleted pages possible
 
 === Languages updated in 1.15 ===
 
index fcb80d5..36490eb 100644 (file)
@@ -56,11 +56,24 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                $fld_len = isset($prop['len']);
                $fld_content = isset($prop['content']);
                $fld_token = isset($prop['token']);
-
+               
                $result = $this->getResult();
                $pageSet = $this->getPageSet();
                $titles = $pageSet->getTitles();
                $data = array();
+               
+               // This module operates in three modes:
+               // 'revs': List deleted revs for certain titles
+               // 'user': List deleted revs by a certain user
+               // 'all': List all deleted revs
+               $mode = 'all';
+               if(count($titles) > 0)
+                       $mode = 'revs';
+               else if(!is_null($params['user']))
+                       $mode = 'user';
+               
+               if(!is_null($params['user']) && !is_null($params['excludeuser']))
+                               $this->dieUsage('user and excludeuser cannot be used together', 'badparams');
 
                $this->addTables('archive');
                $this->addFields(array('ar_title', 'ar_namespace', 'ar_timestamp'));
@@ -102,17 +115,63 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        $token = $wgUser->editToken();
 
                // We need a custom WHERE clause that matches all titles.
-               if(count($titles) > 0)
+               if($mode == 'revs')
                {
                        $lb = new LinkBatch($titles);
                        $where = $lb->constructSet('ar', $db);
                        $this->addWhere($where);
-               } else {
-                       $this->dieUsage('You have to specify a page title or titles');
+               }
+               elseif($mode == 'all')
+               {
+                       $this->addWhereFld('ar_namespace', $params['namespace']);
+                       if(!is_null($params['from']))
+                       {
+                               $from = $this->getDB()->strencode($this->titleToKey($params['from']));
+                               $this->addWhere("ar_title >= '$from'");
+                       }
+               }
+               
+               if(!is_null($params['user'])) {
+                       $this->addWhereFld('ar_user_text', $params['user']);
+               } elseif(!is_null($params['excludeuser'])) {
+                       $this->addWhere('ar_user_text != ' .
+                               $this->getDB()->addQuotes($params['excludeuser']));
+               }
+               
+               if(!is_null($params['continue']) && $mode == 'all')
+               {
+                       $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");
+                       $title = $this->getDB()->strencode($this->titleToKey($cont[0]));
+                       $ts = $this->getDB()->strencode($cont[1]);
+                       $this->addWhere("ar_title > '$title' OR " .
+                                       "(ar_title = '$title' AND " .
+                                       "ar_timestamp >= '$ts')");
                }
 
                $this->addOption('LIMIT', $limit + 1);
-               $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']);
+               $this->addOption('USE INDEX', array('archive' => ($mode == 'user' ? 'usertext_timestamp' : 'name_title_timestamp')));
+               if($mode == 'all')
+               {
+                       if($params['unique'])
+                       {
+                               $this->addOption('GROUP BY', 'ar_title');
+                               $this->addOption('ORDER BY', 'ar_title');
+                       }
+                       else
+                               $this->addOption('ORDER BY', 'ar_title, ar_timestamp');
+               }
+               else
+               {
+                       if($mode == 'revs')
+                       {
+                               // Sort by ns and title in the same order as timestamp for efficiency
+                               $this->addWhereRange('ar_namespace', $params['dir'], null, null);
+                               $this->addWhereRange('ar_title', $params['dir'], null, null);
+                       }
+                       $this->addWhereRange('ar_timestamp', $params['dir'], $params['start'], $params['end']);
+               }
                $res = $this->select(__METHOD__);
                $pages = array();
                $count = 0;
@@ -122,7 +181,11 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                        if(++$count > $limit)
                        {
                                // We've had enough
-                               $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp));
+                               if($mode == 'all')
+                                       $this->setContinueEnumParameter('continue', $this->keyToTitle($row->ar_title) . '|' .
+                                               $row->ar_timestamp);
+                               else
+                                       $this->setContinueEnumParameter('start', wfTimestamp(TS_ISO_8601, $row->ar_timestamp));
                                break;
                        }
 
@@ -183,6 +246,19 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                                ),
                                ApiBase :: PARAM_DFLT => 'older'
                        ),
+                       'from' => null,
+                       'continue' => null,
+                       'unique' => false,
+                       'user' => array(
+                               ApiBase :: PARAM_TYPE => 'user'
+                       ),
+                       'excludeuser' => array(
+                               ApiBase :: PARAM_TYPE => 'user'
+                       ),
+                       'namespace' => array(
+                               ApiBase :: PARAM_TYPE => 'namespace',
+                               ApiBase :: PARAM_DFLT => 0,
+                       ),
                        'limit' => array(
                                ApiBase :: PARAM_DFLT => 10,
                                ApiBase :: PARAM_TYPE => 'limit',
@@ -202,30 +278,47 @@ class ApiQueryDeletedrevs extends ApiQueryBase {
                                        'token'
                                ),
                                ApiBase :: PARAM_ISMULTI => true
-                       )
+                       ),
                );
        }
 
        public function getParamDescription() {
                return array (
-                       'start' => 'The timestamp to start enumerating from',
-                       'end' => 'The timestamp to stop enumerating at',
-                       'dir' => 'The direction in which to enumerate',
+                       'start' => 'The timestamp to start enumerating from. (1,2)',
+                       'end' => 'The timestamp to stop enumerating at. (1,2)',
+                       'dir' => 'The direction in which to enumerate. (1,2)',
                        'limit' => 'The maximum amount of revisions to list',
-                       'prop' => 'Which properties to get'
+                       'prop' => 'Which properties to get',
+                       'namespace' => 'Only list pages in this namespace (3)',
+                       'user' => 'Only list revisions by this user',
+                       'excludeuser' => 'Don\'t list revisions by this user',
+                       'from' => 'Start listing at this title (3)',
+                       'continue' => 'When more results are available, use this to continue (3)',
+                       'unique' => 'List only one revision for each page (3)',
                );
        }
 
        public function getDescription() {
-               return 'List deleted revisions.';
+               return array(   'List deleted revisions.',
+                               'This module operates in three modes:',
+                               '1) List deleted revisions for the given title(s), sorted by timestamp',
+                               '2) List deleted contributions for the given user, sorted by timestamp (no titles specified)',
+                               '3) List all deleted revisions in the given namespace, sorted by title and timestamp (no titles specified, druser not set)',
+                               'Certain parameters only apply to some modes and are ignored in others.',
+                               'For instance, a parameter marked (1) only applies to mode 1 and is ignored in modes 2 and 3.',
+               );
        }
 
        protected function getExamples() {
                return array (
-                       'List the first 50 deleted revisions',
+                       'List the last deleted revisions of Main Page and Talk:Main Page, with content (mode 1):',
+                       '  api.php?action=query&list=deletedrevs&titles=Main%20Page|Talk:Main%20Page&drprop=user|comment|content',
+                       'List the last 50 deleted contributions by Bob (mode 2):',
+                       '  api.php?action=query&list=deletedrevs&druser=Bob&drlimit=50',
+                       'List the first 50 deleted revisions in the main namespace (mode 3):',
                        '  api.php?action=query&list=deletedrevs&drdir=newer&drlimit=50',
-                       'List the last deleted revisions of Main Page and Talk:Main Page, with content:',
-                       '  api.php?action=query&list=deletedrevs&titles=Main%20Page|Talk:Main%20Page&drprop=user|comment|content'
+                       'List the first 50 deleted pages in the Talk namespace (mode 3):',
+                       '  api.php?action=query&list=deletedrevs&drdir=newer&drlimit=50&drnamespace=1&drunique',
                );
        }