(bug 14869) Add API module for accessing QueryPage-based special pages. Took 2.5...
authorRoan Kattouw <catrope@users.mediawiki.org>
Wed, 22 Dec 2010 20:35:37 +0000 (20:35 +0000)
committerRoan Kattouw <catrope@users.mediawiki.org>
Wed, 22 Dec 2010 20:35:37 +0000 (20:35 +0000)
includes/AutoLoader.php
includes/api/ApiQuery.php
includes/api/ApiQueryQueryPage.php [new file with mode: 0644]

index d3fbf1d..9f273f8 100644 (file)
@@ -332,6 +332,7 @@ $wgAutoloadLocalClasses = array(
        'ApiQueryLogEvents' => 'includes/api/ApiQueryLogEvents.php',
        'ApiQueryPageProps' => 'includes/api/ApiQueryPageProps.php',
        'ApiQueryProtectedTitles' => 'includes/api/ApiQueryProtectedTitles.php',
+       'ApiQueryQueryPage' => 'includes/api/ApiQueryQueryPage.php',
        'ApiQueryRandom' => 'includes/api/ApiQueryRandom.php',
        'ApiQueryRecentChanges' => 'includes/api/ApiQueryRecentChanges.php',
        'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',
index d2ed22b..0c05eb6 100644 (file)
@@ -88,6 +88,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..bc4008f
--- /dev/null
@@ -0,0 +1,179 @@
+<?php
+/**
+ * API for MediaWiki 1.8+
+ *
+ * Created on Sep 10, 2007
+ *
+ * Copyright © 2010 Roan Kattouw <Firstname>.<Lastname>@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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+       // Eclipse helper - will be ignored in production
+       require_once( 'ApiQueryBase.php' );
+}
+
+/**
+ * Query module to get the results of a QueryPage-based special page
+ *
+ * @ingroup API
+ */
+class ApiQueryQueryPage extends ApiQueryGeneratorBase {
+       private $qpMap;
+       
+       public function __construct( $query, $moduleName ) {
+               parent::__construct( $query, $moduleName, 'qp' );
+               
+               // We need to do this to make sure $wgQueryPages is set up
+               // This SUCKS
+               global $IP;
+               require_once( "$IP/includes/QueryPage.php" );
+               
+               // Build mapping from special page names to QueryPage classes
+               global $wgQueryPages;
+               $this->qpMap = array();
+               foreach ( $wgQueryPages as $page ) {
+                       $this->qpMap[$page[1]] = $page[0];
+               }
+       }
+       
+       public function execute() {
+               $this->run();
+       }
+       
+       public function executeGenerator( $resultPageSet ) {
+               $this->run( $resultPageSet );
+       }
+
+       public function run( $resultPageSet = null ) {
+               global $wgUser;
+               $params = $this->extractRequestParams();
+               $result = $this->getResult();
+               
+               $qp = new $this->qpMap[$params['page']]();
+               if ( !$qp->userCanExecute( $wgUser ) ) {
+                       $this->dieUsageMsg( array( 'specialpage-cantexecute' ) );
+               }
+               
+               $r = array( 'name' => $params['page'] );
+               if ( $qp->isCached() ) {
+                       if ( !$qp->isCacheable() ) {
+                               $r['disabled'] = '';
+                       } else {
+                               $r['cached'] = '';
+                               $ts = $qp->getCachedTimestamp();
+                               if ( $ts ) {
+                                       $r['cachedTimestamp'] = wfTimestamp( TS_ISO_8601, $ts );
+                               }
+                       }
+               }
+               $result->addValue( array( 'query' ), $this->getModuleName(), $r );
+               
+               $res = $qp->doQuery( $params['limit'] + 1, $params['offset'] );
+               $count = 0;
+               $titles = array();
+               foreach ( $res as $row ) {
+                       if ( ++$count > $params['limit'] ) {
+                               // We've had enough
+                               $this->setContinueEnumParameter( 'offset', $params['offset'] + $params['limit'] );
+                               break;
+                       }
+                       
+                       $title = Title::makeTitle( $row->namespace, $row->title );
+                       if ( is_null( $resultPageSet ) ) {
+                               $data = array( 'value' => $row->value );
+                               if ( $qp->usesTimestamps() ) {
+                                       $data['timestamp'] = wfTimestamp( TS_ISO_8601, $row->value );
+                               }
+                               self::addTitleInfo( $data, $title );
+                               
+                               foreach ( $row as $field => $value ) {
+                                       if ( !in_array( $field, array( 'namespace', 'title', 'value', 'qc_type' ) ) ) {
+                                               $data['databaseResult'][$field] = $value;
+                                       }
+                               }
+                               
+                               $fit = $result->addValue( array( 'query', $this->getModuleName(), 'results' ), null, $data );
+                               if ( !$fit ) {
+                                       $this->setContinueEnumParameter( 'offset', $params['offset'] + $count - 1 );
+                                       break;
+                               }
+                       } else {
+                               $titles[] = $title;
+                       }
+               }
+               if ( is_null( $resultPageSet ) ) {
+                       $result->setIndexedTagName_internal( array( 'query', $this->getModuleName(), 'results' ), 'page' );
+               } else {
+                       $resultPageSet->populateFromTitles( $titles );
+               }
+       }
+       
+       public function getCacheMode( $params ) {
+               $qp = new $this->qpMap[$params['page']]();
+               if ( $qp->getRestriction() != '' ) {
+                       return 'private';
+               }
+               return 'public';
+       }
+
+       public function getAllowedParams() {
+               return array(
+                       'page' => array(
+                               ApiBase::PARAM_TYPE => array_keys( $this->qpMap ),
+                               ApiBase::PARAM_REQUIRED => true
+                       ),
+                       '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
+                       ),
+               );
+       }
+       
+       public function getParamDescription() {
+               return array(
+                       'page' => 'The name of the special page',
+                       'offset' => 'When more results are available, use this to continue',
+                       'limit' => 'Number of results to return',
+               );
+       }
+
+       public function getDescription() {
+               return 'Get a list provide by a QueryPage-based special page';
+       }
+
+       public function getPossibleErrors() {
+               return array_merge( parent::getPossibleErrors(), array(
+               ) );
+       }
+
+       protected function getExamples() {
+               return array(
+                       
+               );
+       }
+
+       public function getVersion() {
+               return __CLASS__ . ': $Id$';
+       }
+}