API: Add 'wrfromtitle' and 'wrtotitle' to list=watchlistraw
authorBrad Jorsch <bjorsch@wikimedia.org>
Wed, 13 May 2015 18:42:39 +0000 (14:42 -0400)
committerLegoktm <legoktm.wikipedia@gmail.com>
Thu, 21 May 2015 15:33:47 +0000 (15:33 +0000)
Naming is "fromtitle" rather than just "from" because "from" parameters
in API query modules generally mean a title without namespace, and this
should make use of the client-supplied namespace.

Bug: T98985
Change-Id: I8370f47f6eed71ea97a44a66eb6be2a8f89fea53

includes/api/ApiQueryBase.php
includes/api/ApiQueryWatchlistRaw.php
includes/api/i18n/en.json
includes/api/i18n/qqq.json

index 89e92b8..c66e21b 100644 (file)
@@ -504,7 +504,7 @@ abstract class ApiQueryBase extends ApiBase {
         * capitalization settings.
         *
         * @param string $titlePart Title part
-        * @param int $defaultNamespace Namespace of the title
+        * @param int $namespace Namespace of the title
         * @return string DBkey (no namespace prefix)
         */
        public function titlePartToKey( $titlePart, $namespace = NS_MAIN ) {
@@ -525,6 +525,24 @@ abstract class ApiQueryBase extends ApiBase {
                return substr( $t->getDbKey(), 0, -1 );
        }
 
+       /**
+        * Convert an input title or title prefix into a namespace constant and dbkey.
+        *
+        * @since 1.26
+        * @param string $titlePart Title part
+        * @param int $defaultNamespace Default namespace if none is given
+        * @return array (int, string) Namespace number and DBkey
+        */
+       public function prefixedTitlePartToKey( $titlePart, $defaultNamespace = NS_MAIN ) {
+               $t = Title::newFromText( $titlePart . 'x', $defaultNamespace );
+               if ( !$t || $t->hasFragment() || $t->isExternal() ) {
+                       // Invalid title (e.g. bad chars) or contained a '#'.
+                       $this->dieUsageMsg( array( 'invalidtitle', $titlePart ) );
+               }
+
+               return array( $t->getNamespace(), substr( $t->getDbKey(), 0, -1 ) );
+       }
+
        /**
         * Gets the personalised direction parameter description
         *
index 493c192..f45d7d7 100644 (file)
@@ -83,6 +83,28 @@ class ApiQueryWatchlistRaw extends ApiQueryGeneratorBase {
                        );
                }
 
+               if ( isset( $params['fromtitle'] ) ) {
+                       list( $ns, $title ) = $this->prefixedTitlePartToKey( $params['fromtitle'] );
+                       $title = $this->getDB()->addQuotes( $title );
+                       $op = $params['dir'] == 'ascending' ? '>' : '<';
+                       $this->addWhere(
+                               "wl_namespace $op $ns OR " .
+                               "(wl_namespace = $ns AND " .
+                               "wl_title $op= $title)"
+                       );
+               }
+
+               if ( isset( $params['totitle'] ) ) {
+                       list( $ns, $title ) = $this->prefixedTitlePartToKey( $params['totitle'] );
+                       $title = $this->getDB()->addQuotes( $title );
+                       $op = $params['dir'] == 'ascending' ? '<' : '>'; // Reversed from above!
+                       $this->addWhere(
+                               "wl_namespace $op $ns OR " .
+                               "(wl_namespace = $ns AND " .
+                               "wl_title $op= $title)"
+                       );
+               }
+
                $sort = ( $params['dir'] == 'descending' ? ' DESC' : '' );
                // Don't ORDER BY wl_namespace if it's constant in the WHERE clause
                if ( count( $params['namespace'] ) == 1 ) {
@@ -172,6 +194,12 @@ class ApiQueryWatchlistRaw extends ApiQueryGeneratorBase {
                                ),
                                ApiBase::PARAM_HELP_MSG => 'api-help-param-direction',
                        ),
+                       'fromtitle' => array(
+                               ApiBase::PARAM_TYPE => 'string'
+                       ),
+                       'totitle' => array(
+                               ApiBase::PARAM_TYPE => 'string'
+                       ),
                );
        }
 
index 1e83a92..9411207 100644 (file)
        "apihelp-query+watchlistraw-param-show": "Only list items that meet these criteria.",
        "apihelp-query+watchlistraw-param-owner": "Used along with $1token to access a different user's watchlist.",
        "apihelp-query+watchlistraw-param-token": "A security token (available in the user's [[Special:Preferences#mw-prefsection-watchlist|preferences]]) to allow access to another user's watchlist.",
+       "apihelp-query+watchlistraw-param-fromtitle": "Title (with namespace prefix) to begin enumerating from.",
+       "apihelp-query+watchlistraw-param-totitle": "Title (with namespace prefix) to stop enumerating at.",
        "apihelp-query+watchlistraw-example-simple": "List pages on the current user's watchlist.",
        "apihelp-query+watchlistraw-example-generator": "Fetch page info for pages on the current user's watchlist.",
 
index 1398afd..82b169e 100644 (file)
        "apihelp-query+watchlistraw-param-show": "{{doc-apihelp-param|query+watchlistraw|show}}",
        "apihelp-query+watchlistraw-param-owner": "{{doc-apihelp-param|query+watchlistraw|owner}}",
        "apihelp-query+watchlistraw-param-token": "{{doc-apihelp-param|query+watchlistraw|token}}",
+       "apihelp-query+watchlistraw-param-fromtitle": "{{doc-apihelp-param|query+watchlistraw|fromtitle}}",
+       "apihelp-query+watchlistraw-param-totitle": "{{doc-apihelp-param|query+watchlistraw|totitle}}",
        "apihelp-query+watchlistraw-example-simple": "{{doc-apihelp-example|query+watchlistraw}}",
        "apihelp-query+watchlistraw-example-generator": "{{doc-apihelp-example|query+watchlistraw}}",
        "apihelp-revisiondelete-description": "{{doc-apihelp-description|revisiondelete}}",