(bug 14869) Allow access to QueryPage-based special pages via API
authorBryan Tong Minh <btongminh@users.mediawiki.org>
Sun, 12 Jul 2009 21:51:47 +0000 (21:51 +0000)
committerBryan Tong Minh <btongminh@users.mediawiki.org>
Sun, 12 Jul 2009 21:51:47 +0000 (21:51 +0000)
Only brokenredirects for now, until I find out which other special pages are suitable.

RELEASE-NOTES
includes/AutoLoader.php
includes/QueryPage.php
includes/api/ApiQuery.php
includes/api/ApiQueryQuerypage.php [new file with mode: 0644]

index c60ff67..064cdc6 100644 (file)
@@ -290,6 +290,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * Added snippet field to list=search output
 * (bug 17809) Add number of users in user groups to meta=siteinfo
 * (bug 18533) Add readonly reason to readonly exception
+* (bug 14869) Allow access to QueryPage-based special pages via API
 
 === Languages updated in 1.16 ===
 
index 6174b36..53966a8 100644 (file)
@@ -302,6 +302,7 @@ $wgAutoloadLocalClasses = array(
        'ApiQueryLangLinks' => 'includes/api/ApiQueryLangLinks.php',
        'ApiQueryLinks' => 'includes/api/ApiQueryLinks.php',
        'ApiQueryLogEvents' => 'includes/api/ApiQueryLogEvents.php',
+       'ApiQueryQuerypage' => 'includes/api/ApiQueryQuerypage.php',
        'ApiQueryProtectedTitles' => 'includes/api/ApiQueryProtectedTitles.php',
        'ApiQueryRandom' => 'includes/api/ApiQueryRandom.php',
        'ApiQueryRecentChanges'=> 'includes/api/ApiQueryRecentChanges.php',
index a8abee3..dc22a8c 100644 (file)
@@ -176,10 +176,10 @@ class QueryPage {
         * Formats the result as something that can be understood by the API.
         * Defaults to setting id, ns and title
         */
-       function formatApiResult( $result ) {
+       function formatApiResult( $row ) {
                $title = Title::makeTitle( $row->namespace, $row->title );
                return array(
-                                               'pageid' => intval( $row->id ),
+                                               //'pageid' => intval( $row->id ),
                                                'ns' => intval( $title->getNamespace() ),
                                                'title' => $title->getPrefixedText(),
                );
@@ -361,7 +361,7 @@ class QueryPage {
         *              'count'         => number of results,
         *              'dbr'           => the database used for fetching the data
         */
-       protected function reallyDoQuery( $offset, $limit ) {
+       public function reallyDoQuery( $offset, $limit ) {
                $result = array( 'disabled' => false );
                
                $this->offset = $offset;
index e3719e0..4836533 100644 (file)
@@ -81,6 +81,7 @@ class ApiQuery extends ApiBase {
                'users' => 'ApiQueryUsers',
                'random' => 'ApiQueryRandom',
                'protectedtitles' => 'ApiQueryProtectedTitles',
+               'querypage' => 'ApiQueryQuerypage',
        );
 
        private $mQueryMetaModules = array (
diff --git a/includes/api/ApiQueryQuerypage.php b/includes/api/ApiQueryQuerypage.php
new file mode 100644 (file)
index 0000000..f77d411
--- /dev/null
@@ -0,0 +1,137 @@
+<?php
+
+/*
+ * Created on Jul 12, 2009
+ *
+ * API for MediaWiki 1.8+
+ *
+ * Copyright (C) 2009 Bryan Tong Minh <Bryan.TongMinh@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 ('ApiQueryBase.php');
+}
+
+/**
+ * Query module to access querypages
+ *
+ * @ingroup API
+ */
+class ApiQueryQuerypage extends ApiQueryBase {
+       static $queryPages = array( 
+               'brokenredirects' => 'BrokenRedirectsPage' 
+       );
+       
+       public function __construct($query, $moduleName) {
+               parent :: __construct($query, $moduleName, 'qp');
+       }
+
+       public function execute() {
+               $this->run();
+       }
+
+       public function executeGenerator($resultPageSet) {
+               $this->run( $resultPageSet );
+       }
+
+       private function run($resultPageSet = null) {
+               $params = $this->extractRequestParams();
+               $offset = $params['offset'];
+               $limit = $params['limit'];
+               
+               // Try to find an entry in $wgQueryPages
+               $qpName = $params['querypage'];
+               if ( is_null( $qpName ) )
+                       $this->dieUsageMsg( array( 'missingparam', 'querypage' ) );
+               if ( !isset( self::$queryPages[$qpName] ) )
+                       $this->dieUsage( 'Querypage unrecognized', 'unknownquerypage' );
+               
+               $qpClass = self::$queryPages[$qpName];
+               $qpInstance = new $qpClass;
+               $result = $qpInstance->reallyDoQuery( $offset, $limit + 1 );
+               
+               $apiResult = $this->getResult();
+               $count = 0;
+               while ( $row = $result['dbr']->fetchObject( $result['result'] ) ) {
+                       if ( ++ $count > $limit ) {
+                               // We've reached the one extra which shows that there are additional pages to be had. Stop here...
+                               $this->setContinueEnumParameter( 'offset', $offset + $count - 1 );
+                               break;
+                       }                       
+                       if ( is_null( $resultPageSet ) ) {
+                               // Normal mode; let the query page make a sensible result out of it
+                               $vals = $qpInstance->formatApiResult( $row );
+                               $fit = $apiResult->addValue( array( 'query', $this->getModuleName() ), null, $vals );
+                               if( !$fit )
+                               {
+                                       $this->setContinueEnumParameter( 'offset', $params['offset'] + $count );
+                                       break;
+                               }
+                       } else {
+                               // Generator mode; not yet supported
+                               $resultPageSet->processDbRow( $row );
+                       }
+               }
+
+
+               if ( is_null( $resultPageSet ) ) {
+                       $apiResult->setIndexedTagName_internal( array( 'query', $this->getModuleName()), 'p' );
+               }
+       }
+
+       public function getAllowedParams() {
+
+               return array (
+                       'offset' => 0,
+                       'limit' => array (
+                               ApiBase :: PARAM_DFLT => 10,
+                               ApiBase :: PARAM_TYPE => 'limit',
+                               ApiBase :: PARAM_MIN => 1,
+                               ApiBase :: PARAM_MAX => ApiBase :: LIMIT_BIG1,
+                               ApiBase :: PARAM_MAX2 => ApiBase :: LIMIT_BIG2
+                       ),
+                       'querypage' => array(
+                               ApiBase :: PARAM_TYPE => array_keys( self::$queryPages )
+                       ),
+               );
+       }
+
+       public function getParamDescription() {
+               return array (
+                       'offset' => 'The offset to start enumerating from.',
+                       'limit' => 'How many total pages to return.',
+                       'querypage' => 'Which querypage to use',
+               );
+       }
+
+       public function getDescription() {
+               return 'Query one of the builtin query pages.';
+       }
+
+       protected function getExamples() {
+               return array (
+                       ' Query a list of broken redirects',
+                       '  api.php?action=query&list=querypage&qpquerypage=brokenredirects',
+               );
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id:$';
+       }
+}
\ No newline at end of file