* API: help screen now shows default and allowed parameter values
authorYuri Astrakhan <yurik@users.mediawiki.org>
Mon, 16 Oct 2006 00:08:03 +0000 (00:08 +0000)
committerYuri Astrakhan <yurik@users.mediawiki.org>
Mon, 16 Oct 2006 00:08:03 +0000 (00:08 +0000)
* API: added experimental watchlist rss/atom feed
* API: if available, json_encode() will be used
* API: opensearch parameter changed to "search=" (more descriptive)
* API: minor parameter cleanup, a wrapper for Feed class

13 files changed:
includes/AutoLoader.php
includes/api/ApiBase.php
includes/api/ApiFeedWatchlist.php [new file with mode: 0644]
includes/api/ApiFormatBase.php
includes/api/ApiFormatJson.php
includes/api/ApiFormatXml.php
includes/api/ApiMain.php
includes/api/ApiOpenSearch.php
includes/api/ApiQueryAllpages.php
includes/api/ApiQueryBase.php
includes/api/ApiQueryRevisions.php
includes/api/ApiQueryWatchlist.php
includes/api/ApiResult.php

index 35cb4c8..e3eae5a 100644 (file)
@@ -237,6 +237,8 @@ function __autoload($className) {
 
                // API classes
                'ApiBase' => 'includes/api/ApiBase.php',
+               'ApiFormatFeedWrapper' => 'includes/api/ApiFormatBase.php',
+               'ApiFeedWatchlist' => 'includes/api/ApiFeedWatchlist.php',
                'ApiFormatBase' => 'includes/api/ApiFormatBase.php',
                'Services_JSON' => 'includes/api/ApiFormatJson_json.php',
                'ApiFormatJson' => 'includes/api/ApiFormatJson.php',
index 9e000a0..3853e18 100644 (file)
@@ -95,7 +95,7 @@ abstract class ApiBase {
         * it should override this method to return an instance of that formatter.
         * A value of null means the default format will be used.  
         */
-       public function getCustomFormatModule() {
+       public function getCustomPrinter() {
                return null;
        }
 
@@ -150,10 +150,24 @@ abstract class ApiBase {
 
                        $paramsDescription = $this->getParamDescription();
                        $msg = '';
-                       foreach (array_keys($params) as $paramName) {
+                       $paramPrefix = "\n" . str_repeat(' ', 19);
+                       foreach ($params as $paramName => &$paramSettings) {
                                $desc = isset ($paramsDescription[$paramName]) ? $paramsDescription[$paramName] : '';
                                if (is_array($desc))
-                                       $desc = implode("\n" . str_repeat(' ', 19), $desc);
+                                       $desc = implode($paramPrefix, $desc);
+                               if (isset ($paramSettings[self :: PARAM_TYPE])) {
+                                       $type = $paramSettings[self :: PARAM_TYPE];
+                                       if (is_array($type)) {
+                                               $desc .= $paramPrefix . 'Allowed values: '. implode(', ', $type);
+                                       }
+                               }
+                               
+                               $default = is_array($paramSettings) 
+                                       ? (isset ($paramSettings[self :: PARAM_DFLT]) ? $paramSettings[self :: PARAM_DFLT] : null)
+                                       : $paramSettings;
+                               if (!is_null($default) && $default !== false)
+                                       $desc .= $paramPrefix . "Default: $default";
+                                       
                                $msg .= sprintf("  %-14s - %s\n", $this->encodeParamName($paramName), $desc);
                        }
                        return $msg;
diff --git a/includes/api/ApiFeedWatchlist.php b/includes/api/ApiFeedWatchlist.php
new file mode 100644 (file)
index 0000000..c5af302
--- /dev/null
@@ -0,0 +1,111 @@
+<?php
+
+
+/*
+ * Created on Oct 13, 2006
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2006 Yuri Astrakhan <FirstnameLastname@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+if (!defined('MEDIAWIKI')) {
+       // Eclipse helper - will be ignored in production
+       require_once ("ApiBase.php");
+}
+
+class ApiFeedWatchlist extends ApiBase {
+
+       public function __construct($main, $action) {
+               parent :: __construct($main, $action);
+       }
+
+       public function getCustomPrinter() {
+               return new ApiFormatFeedWrapper($this->getMain());
+       }
+
+       public function execute() {
+               $feedformat = null;
+               extract($this->extractRequestParams());
+
+               // Prepare nested request
+               $params = new FauxRequest(array (
+                       'action' => 'query',
+                       'meta' => 'siteinfo',
+                       'siprop' => 'general',
+                       'list' => 'watchlist',
+                       'wlstart' => wfTimestamp(TS_MW, time() - intval( 3 * 86400 )), // limit to 3 days
+                       'wllimit' => 50
+               ));
+
+               // Execute
+               $module = new ApiMain($params);
+               $module->execute();
+
+               // Get clean data
+               $result = & $module->getResult();
+               $result->SanitizeData();
+               $data = & $result->GetData();
+
+               $feedItems = array ();
+               foreach ($data['query']['watchlist'] as $index => & $info) {
+                       $title = $info['title'];
+                       $titleUrl = Title :: newFromText($title)->getFullUrl();
+                       $feedItems[] = new FeedItem($title, '', $titleUrl, $info['timestamp'], $info['user']);
+               }
+
+               global $wgFeedClasses, $wgSitename, $wgContLanguageCode;
+               $feedTitle = $wgSitename . ' - ' . wfMsgForContent('watchlist') . ' [' . $wgContLanguageCode . ']';
+               $feedUrl = Title :: makeTitle(NS_SPECIAL, 'Watchlist')->getFullUrl();
+               $feed = new $wgFeedClasses[$feedformat] ($feedTitle, '!Watchlist!', $feedUrl);
+
+               ApiFormatFeedWrapper :: setResult($this->getResult(), $feed, $feedItems);
+       }
+
+       protected function GetAllowedParams() {
+               global $wgFeedClasses;
+               $feedFormatNames = array_keys($wgFeedClasses);
+               return array (
+                       'feedformat' => array (
+                               ApiBase :: PARAM_DFLT => 'rss',
+                               ApiBase :: PARAM_TYPE => $feedFormatNames
+                       )
+               );
+       }
+
+       protected function GetParamDescription() {
+               return array (
+                       'feedformat' => 'The format of the feed'
+               );
+       }
+
+       protected function GetDescription() {
+               return 'This module returns a watchlist feed';
+       }
+
+       protected function GetExamples() {
+               return array (
+                       'api.php?action=feedwatchlist'
+               );
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id:$';
+       }
+}
+?>
\ No newline at end of file
index c886a15..e185158 100644 (file)
@@ -75,6 +75,12 @@ abstract class ApiFormatBase extends ApiBase {
        function initPrinter($isError) {
                $isHtml = $this->getIsHtml();
                $mime = $isHtml ? 'text/html' : $this->getMimeType();
+               
+               // Some printers (ex. Feed) do their own header settings,
+               // in which case $mime will be set to null
+               if (is_null($mime))
+                       return; // skip any initialization
+                       
                header("Content-Type: $mime; charset=utf-8;");
                header("Cache-Control: private, s-maxage=0, max-age=0");
                
@@ -159,4 +165,60 @@ abstract class ApiFormatBase extends ApiBase {
                return __CLASS__ . ': $Id$';
        }
 }
+
+/**
+ * This printer is used to wrap an instance of the Feed class 
+ */
+class ApiFormatFeedWrapper extends ApiFormatBase {
+
+       public function __construct($main) {
+               parent :: __construct($main, 'feed');
+       }
+
+       /**
+        * Call this method to initialize output data
+        */
+       public static function setResult($result, $feed, $feedItems) {
+               // Store output in the Result data.
+               // This way we can check during execution if any error has occured
+               $data =& $result->getData();
+               $data['_feed'] = $feed;
+               $data['_feeditems'] = $feedItems;
+       }
+
+       /**
+        * Feed does its own headers
+        */
+       public function getMimeType() {
+               return null;
+       }
+
+       /**
+        * Optimization - no need to sanitize data that will not be needed
+        */
+       public function getNeedsRawData() {
+               return true;
+       }
+       
+       public function execute() {
+               $data =& $this->getResultData();
+               if (isset($data['_feed']) && isset($data['_feeditems'])) {
+                       $feed =& $data['_feed'];
+                       $items =& $data['_feeditems'];
+
+                       $feed->outHeader();
+                       foreach($items as &$item)
+                               $feed->outItem($item);
+                       $feed->outFooter();
+               } else {
+                       // Error has occured, print something usefull
+                       // TODO: make this error more informative using $this->dieDebug() or similar
+                       wfHttpError(500, 'Internal Server Error', '');
+               }
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id:$';
+       }
+}
 ?>
\ No newline at end of file
index 7949700..62c03f2 100644 (file)
@@ -40,8 +40,13 @@ class ApiFormatJson extends ApiFormatBase {
        }
 
        public function execute() {
-               $json = new Services_JSON();
-               $this->printText($json->encode($this->getResultData(), true));
+               if (!function_exists('json_encode') || $this->getIsHtml()) {
+                       $json = new Services_JSON();
+                       $this->printText($json->encode($this->getResultData(), $this->getIsHtml()));
+               } else {
+                       $this->printText(json_encode($this->getResultData()));
+               }
+
        }
 
        protected function getDescription() {
index 11efcf9..f4bf838 100644 (file)
@@ -31,6 +31,8 @@ if (!defined('MEDIAWIKI')) {
 
 class ApiFormatXml extends ApiFormatBase {
 
+       private $mRootElemName = 'api';
+
        public function __construct($main, $format) {
                parent :: __construct($main, $format);
        }
@@ -42,6 +44,10 @@ class ApiFormatXml extends ApiFormatBase {
        public function getNeedsRawData() {
                return true;
        }
+       
+       public function setRootElement($rootElemName) {
+               $this->mRootElemName = $rootElemName;
+       }
 
        public function execute() {
                $xmlindent = null;
@@ -53,7 +59,7 @@ class ApiFormatXml extends ApiFormatBase {
                        $xmlindent = null;
 
                $this->printText('<?xml version="1.0" encoding="utf-8"?>');
-               $this->recXmlPrint('api', $this->getResultData(), $xmlindent);
+               $this->recXmlPrint($this->mRootElemName, $this->getResultData(), $xmlindent);
        }
 
        /**
index caf069b..53f0cf1 100644 (file)
@@ -47,6 +47,7 @@ class ApiMain extends ApiBase {
                'help' => 'ApiHelp',
                'login' => 'ApiLogin',
                'opensearch' => 'ApiOpenSearch',
+               'feedwatchlist' => 'ApiFeedWatchlist',
                'query' => 'ApiQuery'
        );
 
@@ -188,7 +189,7 @@ class ApiMain extends ApiBase {
                if (!$this->mInternalMode) {
                        
                        // See if custom printer is used
-                       $this->mPrinter = $module->getCustomFormatModule();                             
+                       $this->mPrinter = $module->getCustomPrinter();                          
                        
                        if (is_null($this->mPrinter)) {
                                // Create an appropriate printer
@@ -303,6 +304,7 @@ class ApiMain extends ApiBase {
                $vers[] = ApiBase :: getBaseVersion();
                $vers[] = ApiFormatBase :: getBaseVersion();
                $vers[] = ApiQueryBase :: getBaseVersion();
+               $vers[] = ApiFormatFeedWrapper :: getVersion(); // not accessible with format=xxx
                return $vers;
        }
 }
index e3b8777..2778037 100644 (file)
@@ -26,7 +26,7 @@
 
 if (!defined('MEDIAWIKI')) {
        // Eclipse helper - will be ignored in production
-       require_once ("ApiFormatBase.php");
+       require_once ("ApiBase.php");
 }
 
 class ApiOpenSearch extends ApiBase {
@@ -35,12 +35,12 @@ class ApiOpenSearch extends ApiBase {
                parent :: __construct($main, $action);
        }
 
-       public function getCustomFormatModule() {
+       public function getCustomPrinter() {
                return $this->getMain()->createPrinterByName('json');
        }
 
        public function execute() {
-               $command = null;
+               $search = null;
                extract($this->ExtractRequestParams());
                
                // Prepare nested request
@@ -49,7 +49,7 @@ class ApiOpenSearch extends ApiBase {
                        'list' => 'allpages',
                        'apnamespace' => 0,
                        'aplimit' => 10,
-                       'apprefix' => $command
+                       'apprefix' => $search
                ));
                
                // Execute
@@ -59,29 +59,31 @@ class ApiOpenSearch extends ApiBase {
                // Get clean data
                $result =& $module->getResult();
                $result->SanitizeData();
-               $data = $result->GetData();
+               $data =& $result->GetData();
                
                // Reformat useful data for future printing by JSON engine
                $srchres = array();
                foreach ($data['query']['allpages'] as $pageid => &$pageinfo) {
+                       // Note: this data will no be printable by the xml engine
+                       // because it does not support lists of unnamed items
                        $srchres[] = $pageinfo['title'];
                }
                
                // Set top level elements
                $result = $this->getResult();
-               $result->addValue(null, 0, $command);
+               $result->addValue(null, 0, $search);
                $result->addValue(null, 1, $srchres);
        }
        
        protected function GetAllowedParams() {
                return array (
-                       'command' => null
+                       'search' => null
                );
        }
 
        protected function GetParamDescription() {
                return array (
-                       'command' => 'Search string'
+                       'search' => 'Search string'
                );
        }
 
@@ -91,7 +93,7 @@ class ApiOpenSearch extends ApiBase {
 
        protected function GetExamples() {
                return array (
-                       'api.php?action=opensearch&command=Te'
+                       'api.php?action=opensearch&search=Te'
                );
        }
 
index 7c6f01b..6c09245 100644 (file)
@@ -96,10 +96,7 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
                while ($row = $db->fetchObject($res)) {
                        if (++ $count > $limit) {
                                // We've reached the one extra which shows that there are additional pages to be had. Stop here...
-                               $msg = array (
-                                       'continue' => $this->encodeParamName('from'
-                               ) . '=' . ApiQueryBase :: keyToTitle($row->page_title));
-                               $this->getResult()->addValue('query-status', 'allpages', $msg);
+                               $this->setContinueEnumParameter('from', ApiQueryBase :: keyToTitle($row->page_title));
                                break;
                        }
 
@@ -154,9 +151,9 @@ class ApiQueryAllpages extends ApiQueryGeneratorBase {
                return array (
                        'from' => 'The page title to start enumerating from.',
                        'prefix' => 'Search for all page titles that begin with this value.',
-                       'namespace' => 'The namespace to enumerate. Default 0 (Main).',
-                       'filterredir' => 'Which pages to list: "all" (default), "redirects", or "nonredirects"',
-                       'limit' => 'How many total pages to return'
+                       'namespace' => 'The namespace to enumerate.',
+                       'filterredir' => 'Which pages to list.',
+                       'limit' => 'How many total pages to return.'
                );
        }
 
index d688806..0f8a17f 100644 (file)
@@ -32,7 +32,7 @@ if (!defined('MEDIAWIKI')) {
 abstract class ApiQueryBase extends ApiBase {
 
        private $mQueryModule;
-    
+
        public function __construct($query, $moduleName, $paramPrefix = '') {
                parent :: __construct($query->getMain(), $moduleName, $paramPrefix);
                $this->mQueryModule = $query;
@@ -52,6 +52,13 @@ abstract class ApiQueryBase extends ApiBase {
                return $this->mQueryModule;
        }
 
+       protected function setContinueEnumParameter($paramName, $paramValue) {
+               $msg = array (
+                       $this->encodeParamName($paramName
+               ) => $paramValue);
+               $this->getResult()->addValue('query-continue', $this->getModuleName(), $msg);
+       }
+
        /**
         * Get the Query database connection (readonly)
         */
index a059ffc..1fbc357 100644 (file)
@@ -48,7 +48,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                // Enum mode can only be used when exactly one page is provided.
                // Enumerating revisions on multiple pages make it extremelly 
                // difficult to manage continuations and require additional sql indexes  
-               $enumRevMode = ($limit !== 0 || $startid !== 0 || $endid !== 0 || $dirNewer || isset ($start) || isset ($end));
+               $enumRevMode = (!is_null($limit) || !is_null($startid) || !is_null($endid) || $dirNewer || !is_null($start) || !is_null($end));
 
                $pageSet = $this->getPageSet();
                $pageCount = $pageSet->getGoodTitleCount();
@@ -79,7 +79,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                $options = array ();
 
                $showTimestamp = $showUser = $showComment = $showContent = false;
-               if (isset ($prop)) {
+               if (!is_null($prop)) {
                        foreach ($prop as $p) {
                                switch ($p) {
                                        case 'timestamp' :
@@ -115,10 +115,10 @@ class ApiQueryRevisions extends ApiQueryBase {
                if ($enumRevMode) {
 
                        // This is mostly to prevent parameter errors (and optimize sql?)
-                       if ($startid !== 0 && isset ($start))
+                       if (!is_null($startid) && !is_null($start))
                                $this->dieUsage('start and startid cannot be used together', 'badparams');
 
-                       if ($endid !== 0 && isset ($end))
+                       if (!is_null($endid) && !is_null($end))
                                $this->dieUsage('end and endid cannot be used together', 'badparams');
 
                        // This code makes an assumption that sorting by rev_id and rev_timestamp produces
@@ -127,22 +127,22 @@ class ApiQueryRevisions extends ApiQueryBase {
                        // Switching to rev_id removes the potential problem of having more than 
                        // one row with the same timestamp for the same page. 
                        // The order needs to be the same as start parameter to avoid SQL filesort.
-                       $options['ORDER BY'] = ($startid !== 0 ? 'rev_id' : 'rev_timestamp') . ($dirNewer ? '' : ' DESC');
+                       $options['ORDER BY'] = (!is_null($startid) ? 'rev_id' : 'rev_timestamp') . ($dirNewer ? '' : ' DESC');
 
                        $before = ($dirNewer ? '<=' : '>=');
                        $after = ($dirNewer ? '>=' : '<=');
 
-                       if ($startid !== 0)
+                       if (!is_null($startid))
                                $where[] = 'rev_id' . $after . intval($startid);
-                       if ($endid !== 0)
+                       if (!is_null($endid))
                                $where[] = 'rev_id' . $before . intval($endid);
-                       if (isset ($start))
+                       if (!is_null($start))
                                $where[] = 'rev_timestamp' . $after . $db->addQuotes($start);
-                       if (isset ($end))
+                       if (!is_null($end))
                                $where[] = 'rev_timestamp' . $before . $db->addQuotes($end);
 
                        // must manually initialize unset limit
-                       if (!isset ($limit))
+                       if (!!is_null($limit))
                                $limit = 10;
 
                        $this->validateLimit($this->encodeParamName('limit'), $limit, 1, $userMax, $botMax);
@@ -188,12 +188,7 @@ class ApiQueryRevisions extends ApiQueryBase {
                                // We've reached the one extra which shows that there are additional pages to be had. Stop here...
                                if (!$enumRevMode)
                                        ApiBase :: dieDebug(__METHOD__, 'Got more rows then expected'); // bug report
-
-                               $startStr = 'startid=' . $row->rev_id;
-                               $msg = array (
-                                       'continue' => $startStr
-                               );
-                               $this->getResult()->addValue('query-status', 'revisions', $msg);
+                               $this->setContinueEnumParameter('startid', $row->rev_id);
                                break;
                        }
 
@@ -250,14 +245,18 @@ class ApiQueryRevisions extends ApiQueryBase {
                                )
                        ),
                        'limit' => array (
-                               ApiBase :: PARAM_DFLT => 0,
+                               ApiBase :: PARAM_DFLT => null,
                                ApiBase :: PARAM_TYPE => 'limit',
                                ApiBase :: PARAM_MIN => 0,
                                ApiBase :: PARAM_MAX1 => 50,
                                ApiBase :: PARAM_MAX2 => 500
                        ),
-                       'startid' => 0,
-                       'endid' => 0,
+                       'startid' => array (
+                               ApiBase :: PARAM_TYPE => 'integer'
+                       ),
+                       'endid' => array (
+                               ApiBase :: PARAM_TYPE => 'integer'
+                       ),
                        'start' => array (
                                ApiBase :: PARAM_TYPE => 'timestamp'
                        ),
@@ -276,7 +275,7 @@ class ApiQueryRevisions extends ApiQueryBase {
 
        protected function getParamDescription() {
                return array (
-                       'prop' => 'Which properties to get for each revision: user|timestamp|comment|content',
+                       'prop' => 'Which properties to get for each revision.',
                        'limit' => 'limit how many revisions will be returned (enum)',
                        'startid' => 'from which revision id to start enumeration (enum)',
                        'endid' => 'stop revision enumeration on this revid (enum)',
index af0b57f..ab4a240 100644 (file)
@@ -66,7 +66,8 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
 
                $options = array (
                        'LIMIT' => $limit +1,
-                       'ORDER BY' => 'rc_timestamp' . ($dirNewer ? '' : ' DESC'));
+                       'ORDER BY' => 'rc_timestamp' . ($dirNewer ? '' : ' DESC'
+               ));
 
                if (is_null($resultPageSet)) {
                        $fields = array (
@@ -81,10 +82,12 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                                'rc_this_oldid AS rev_id',
                                'rc_last_oldid',
                                'rc_id',
-       //                      'rc_patrolled',
                                'rc_new AS page_is_new'
+                                       //                      'rc_patrolled'  
+       
                        );
-               } elseif ($allrev) {
+               }
+               elseif ($allrev) {
                        $fields = array (
                                'rc_this_oldid AS rev_id',
                                'rc_namespace AS page_namespace',
@@ -113,10 +116,10 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
 
                if (isset ($start))
                        $where[] = 'rc_timestamp' . $after . $db->addQuotes($start);
-                       
+
                if (isset ($end))
                        $where[] = 'rc_timestamp' . $before . $db->addQuotes($end);
-               
+
                if (!isset ($start) && !isset ($end))
                        $where[] = "rc_timestamp > ''";
 
@@ -129,10 +132,7 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                while ($row = $db->fetchObject($res)) {
                        if (++ $count > $limit) {
                                // We've reached the one extra which shows that there are additional pages to be had. Stop here...
-                               $msg = array (
-                                       'continue' => $this->encodeParamName('from'
-                               ) . '=' . $row->rev_timestamp);
-                               $this->getResult()->addValue('query-status', 'watchlist', $msg);
+                               $this->setContinueEnumParameter('from', $row->rev_timestamp);
                                break;
                        }
 
@@ -144,25 +144,15 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                                        $id = intval($row->page_id);
 
                                        $data[] = array (
-                                               'ns' => $title->getNamespace(),
-                                               'title' => $title->getPrefixedText(),
-                                               'id' => intval($row->page_id),
-                                               'comment' => $row->rev_comment,
-                                               'isuser' => $row->rev_user,
-                                               'user' => $row->rev_user_text,
-                                               'timestamp' => $row->rev_timestamp,
-                                               'minor' => $row->rev_minor_edit,
-                                               'rev_id' => $row->rev_id,
-                                               'rc_last_oldid' => $row->rc_last_oldid,
-                                               'rc_id' => $row->rc_id,
-//                                             'rc_patrolled' => $row->rc_patrolled,
-                                               'isnew' => $row->page_is_new
-                                       );
-                               } elseif ($allrev) {
+                                       'ns' => $title->getNamespace(), 'title' => $title->getPrefixedText(), 'id' => intval($row->page_id), 'comment' => $row->rev_comment, 'isuser' => $row->rev_user, 'user' => $row->rev_user_text, 'timestamp' => $row->rev_timestamp, 'minor' => $row->rev_minor_edit, 'rev_id' => $row->rev_id, 'rc_last_oldid' => $row->rc_last_oldid, 'rc_id' => $row->rc_id,
+                                               //                                              'rc_patrolled' => $row->rc_patrolled,
+       'isnew' => $row->page_is_new);
+                               }
+                               elseif ($allrev) {
                                        $data[] = intval($row->rev_id);
                                } else {
                                        $data[] = intval($row->page_id);
-                               }                               
+                               }
                        }
                }
                $db->freeResult($res);
@@ -170,11 +160,12 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
                if (is_null($resultPageSet)) {
                        ApiResult :: setIndexedTagName($data, 'p');
                        $this->getResult()->addValue('query', 'watchlist', $data);
-               } elseif ($allrev) {
+               }
+               elseif ($allrev) {
                        $resultPageSet->populateFromRevisionIDs($data);
                } else {
                        $resultPageSet->populateFromPageIDs($data);
-               }                               
+               }
        }
 
        protected function getAllowedParams() {
@@ -210,12 +201,12 @@ class ApiQueryWatchlist extends ApiQueryGeneratorBase {
 
        protected function getParamDescription() {
                return array (
-                       'allrev' => 'Include multiple revisions of the same page within given timeframe',
+                       'allrev' => 'Include multiple revisions of the same page within given timeframe.',
                        'start' => 'The timestamp to start enumerating from.',
                        'end' => 'The timestamp to end enumerating.',
                        'namespace' => 'Filter changes to only the given namespace(s).',
-                       'dir' => 'In which direction to enumerate pages "older" (default), or "newer")',
-                       'limit' => 'How many total pages to return per request'
+                       'dir' => 'In which direction to enumerate pages.',
+                       'limit' => 'How many total pages to return per request.'
                );
        }
 
index 8421afa..7f0a1fb 100644 (file)
@@ -73,11 +73,19 @@ class ApiResult extends ApiBase {
        /**
         * Adds the content element to the array.
         * Use this function instead of hardcoding the '*' element.
+        * @param string $subElemName when present, content element is created as a sub item of the arr.
+        *  Use this parameter to create elements in format <elem>text</elem> without attributes
         */
-       public static function setContent(& $arr, $value) {
+       public static function setContent(& $arr, $value, $subElemName = null) {
                if (is_array($value))
                        ApiBase :: dieDebug(__METHOD__, 'Bad parameter');
-               ApiResult :: setElement($arr, '*', $value);
+               if (is_null($subElemName)) {
+                       ApiResult :: setElement($arr, '*', $value);
+               } else {
+                       if (!isset ($arr[$subElemName]))
+                               $arr[$subElemName] = array ();
+                       ApiResult :: setElement($arr[$subElemName], '*', $value);
+               }
        }
 
        //      public static function makeContentElement($tag, $value) {