From cb7471a46ecd27e512a153be15af9a2554b6f431 Mon Sep 17 00:00:00 2001 From: Bryan Tong Minh Date: Sun, 12 Jul 2009 21:51:47 +0000 Subject: [PATCH] (bug 14869) Allow access to QueryPage-based special pages via API Only brokenredirects for now, until I find out which other special pages are suitable. --- RELEASE-NOTES | 1 + includes/AutoLoader.php | 1 + includes/QueryPage.php | 6 +- includes/api/ApiQuery.php | 1 + includes/api/ApiQueryQuerypage.php | 137 +++++++++++++++++++++++++++++ 5 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 includes/api/ApiQueryQuerypage.php diff --git a/RELEASE-NOTES b/RELEASE-NOTES index c60ff671c1..064cdc6b43 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -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 === diff --git a/includes/AutoLoader.php b/includes/AutoLoader.php index 6174b36e49..53966a87f3 100644 --- a/includes/AutoLoader.php +++ b/includes/AutoLoader.php @@ -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', diff --git a/includes/QueryPage.php b/includes/QueryPage.php index a8abee3385..dc22a8c5cf 100644 --- a/includes/QueryPage.php +++ b/includes/QueryPage.php @@ -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; diff --git a/includes/api/ApiQuery.php b/includes/api/ApiQuery.php index e3719e0d50..4836533e6d 100644 --- a/includes/api/ApiQuery.php +++ b/includes/api/ApiQuery.php @@ -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 index 0000000000..f77d411b50 --- /dev/null +++ b/includes/api/ApiQueryQuerypage.php @@ -0,0 +1,137 @@ + + * + * 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 -- 2.20.1