r78824 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r78823‎ | r78824 | r78825 >
Date:20:35, 22 December 2010
Author:catrope
Status:resolved (Comments)
Tags:
Comment:
(bug 14869) Add API module for accessing QueryPage-based special pages. Took 2.5 years and a flight to England to get this done, but there you go :)
Modified paths:
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQuery.php (modified) (history)
  • /trunk/phase3/includes/api/ApiQueryQueryPage.php (added) (history)

Diff [purge]

Index: trunk/phase3/includes/api/ApiQuery.php
@@ -88,6 +88,7 @@
8989 'users' => 'ApiQueryUsers',
9090 'random' => 'ApiQueryRandom',
9191 'protectedtitles' => 'ApiQueryProtectedTitles',
 92+ 'querypage' => 'ApiQueryQueryPage',
9293 );
9394
9495 private $mQueryMetaModules = array(
Index: trunk/phase3/includes/api/ApiQueryQueryPage.php
@@ -0,0 +1,179 @@
 2+<?php
 3+/**
 4+ * API for MediaWiki 1.8+
 5+ *
 6+ * Created on Sep 10, 2007
 7+ *
 8+ * Copyright © 2010 Roan Kattouw <Firstname>.<Lastname>@gmail.com
 9+ *
 10+ * This program is free software; you can redistribute it and/or modify
 11+ * it under the terms of the GNU General Public License as published by
 12+ * the Free Software Foundation; either version 2 of the License, or
 13+ * (at your option) any later version.
 14+ *
 15+ * This program is distributed in the hope that it will be useful,
 16+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 18+ * GNU General Public License for more details.
 19+ *
 20+ * You should have received a copy of the GNU General Public License along
 21+ * with this program; if not, write to the Free Software Foundation, Inc.,
 22+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 23+ * http://www.gnu.org/copyleft/gpl.html
 24+ *
 25+ * @file
 26+ */
 27+
 28+if ( !defined( 'MEDIAWIKI' ) ) {
 29+ // Eclipse helper - will be ignored in production
 30+ require_once( 'ApiQueryBase.php' );
 31+}
 32+
 33+/**
 34+ * Query module to get the results of a QueryPage-based special page
 35+ *
 36+ * @ingroup API
 37+ */
 38+class ApiQueryQueryPage extends ApiQueryGeneratorBase {
 39+ private $qpMap;
 40+
 41+ public function __construct( $query, $moduleName ) {
 42+ parent::__construct( $query, $moduleName, 'qp' );
 43+
 44+ // We need to do this to make sure $wgQueryPages is set up
 45+ // This SUCKS
 46+ global $IP;
 47+ require_once( "$IP/includes/QueryPage.php" );
 48+
 49+ // Build mapping from special page names to QueryPage classes
 50+ global $wgQueryPages;
 51+ $this->qpMap = array();
 52+ foreach ( $wgQueryPages as $page ) {
 53+ $this->qpMap[$page[1]] = $page[0];
 54+ }
 55+ }
 56+
 57+ public function execute() {
 58+ $this->run();
 59+ }
 60+
 61+ public function executeGenerator( $resultPageSet ) {
 62+ $this->run( $resultPageSet );
 63+ }
 64+
 65+ public function run( $resultPageSet = null ) {
 66+ global $wgUser;
 67+ $params = $this->extractRequestParams();
 68+ $result = $this->getResult();
 69+
 70+ $qp = new $this->qpMap[$params['page']]();
 71+ if ( !$qp->userCanExecute( $wgUser ) ) {
 72+ $this->dieUsageMsg( array( 'specialpage-cantexecute' ) );
 73+ }
 74+
 75+ $r = array( 'name' => $params['page'] );
 76+ if ( $qp->isCached() ) {
 77+ if ( !$qp->isCacheable() ) {
 78+ $r['disabled'] = '';
 79+ } else {
 80+ $r['cached'] = '';
 81+ $ts = $qp->getCachedTimestamp();
 82+ if ( $ts ) {
 83+ $r['cachedTimestamp'] = wfTimestamp( TS_ISO_8601, $ts );
 84+ }
 85+ }
 86+ }
 87+ $result->addValue( array( 'query' ), $this->getModuleName(), $r );
 88+
 89+ $res = $qp->doQuery( $params['limit'] + 1, $params['offset'] );
 90+ $count = 0;
 91+ $titles = array();
 92+ foreach ( $res as $row ) {
 93+ if ( ++$count > $params['limit'] ) {
 94+ // We've had enough
 95+ $this->setContinueEnumParameter( 'offset', $params['offset'] + $params['limit'] );
 96+ break;
 97+ }
 98+
 99+ $title = Title::makeTitle( $row->namespace, $row->title );
 100+ if ( is_null( $resultPageSet ) ) {
 101+ $data = array( 'value' => $row->value );
 102+ if ( $qp->usesTimestamps() ) {
 103+ $data['timestamp'] = wfTimestamp( TS_ISO_8601, $row->value );
 104+ }
 105+ self::addTitleInfo( $data, $title );
 106+
 107+ foreach ( $row as $field => $value ) {
 108+ if ( !in_array( $field, array( 'namespace', 'title', 'value', 'qc_type' ) ) ) {
 109+ $data['databaseResult'][$field] = $value;
 110+ }
 111+ }
 112+
 113+ $fit = $result->addValue( array( 'query', $this->getModuleName(), 'results' ), null, $data );
 114+ if ( !$fit ) {
 115+ $this->setContinueEnumParameter( 'offset', $params['offset'] + $count - 1 );
 116+ break;
 117+ }
 118+ } else {
 119+ $titles[] = $title;
 120+ }
 121+ }
 122+ if ( is_null( $resultPageSet ) ) {
 123+ $result->setIndexedTagName_internal( array( 'query', $this->getModuleName(), 'results' ), 'page' );
 124+ } else {
 125+ $resultPageSet->populateFromTitles( $titles );
 126+ }
 127+ }
 128+
 129+ public function getCacheMode( $params ) {
 130+ $qp = new $this->qpMap[$params['page']]();
 131+ if ( $qp->getRestriction() != '' ) {
 132+ return 'private';
 133+ }
 134+ return 'public';
 135+ }
 136+
 137+ public function getAllowedParams() {
 138+ return array(
 139+ 'page' => array(
 140+ ApiBase::PARAM_TYPE => array_keys( $this->qpMap ),
 141+ ApiBase::PARAM_REQUIRED => true
 142+ ),
 143+ 'offset' => 0,
 144+ 'limit' => array(
 145+ ApiBase::PARAM_DFLT => 10,
 146+ ApiBase::PARAM_TYPE => 'limit',
 147+ ApiBase::PARAM_MIN => 1,
 148+ ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1,
 149+ ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2
 150+ ),
 151+ );
 152+ }
 153+
 154+ public function getParamDescription() {
 155+ return array(
 156+ 'page' => 'The name of the special page',
 157+ 'offset' => 'When more results are available, use this to continue',
 158+ 'limit' => 'Number of results to return',
 159+ );
 160+ }
 161+
 162+ public function getDescription() {
 163+ return 'Get a list provide by a QueryPage-based special page';
 164+ }
 165+
 166+ public function getPossibleErrors() {
 167+ return array_merge( parent::getPossibleErrors(), array(
 168+ ) );
 169+ }
 170+
 171+ protected function getExamples() {
 172+ return array(
 173+
 174+ );
 175+ }
 176+
 177+ public function getVersion() {
 178+ return __CLASS__ . ': $Id$';
 179+ }
 180+}
Property changes on: trunk/phase3/includes/api/ApiQueryQueryPage.php
___________________________________________________________________
Added: svn:eol-style
1181 + native
Added: svn:keywords
2182 + Id
Index: trunk/phase3/includes/AutoLoader.php
@@ -332,6 +332,7 @@
333333 'ApiQueryLogEvents' => 'includes/api/ApiQueryLogEvents.php',
334334 'ApiQueryPageProps' => 'includes/api/ApiQueryPageProps.php',
335335 'ApiQueryProtectedTitles' => 'includes/api/ApiQueryProtectedTitles.php',
 336+ 'ApiQueryQueryPage' => 'includes/api/ApiQueryQueryPage.php',
336337 'ApiQueryRandom' => 'includes/api/ApiQueryRandom.php',
337338 'ApiQueryRecentChanges' => 'includes/api/ApiQueryRecentChanges.php',
338339 'ApiQueryRevisions' => 'includes/api/ApiQueryRevisions.php',

Follow-up revisions

RevisionCommit summaryAuthorDate
r78825RELEASE-NOTES for r78824, r78786reedy20:38, 22 December 2010
r78837Per bug 14869 being fixed, bug 8130 and bug 14020 have been fixed. Marking th...reedy21:30, 22 December 2010
r78844Fixup date and uppercase parameter from r78824reedy21:50, 22 December 2010
r79198Followup r78824: add missing messagecatrope20:20, 29 December 2010
r86322Per CR on r78824 (#c12467): Some query pages are useless/redundant, since we ...demon17:04, 18 April 2011
r92762Fix r78824 after some misunderstandings in the CR comments. The querypage API...catrope18:03, 21 July 2011
r93426MFT to REL1_18...hashar20:20, 28 July 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r53149(bug 14869) Allow access to QueryPage-based special pages via API...btongminh21:51, 12 July 2009
r78786Merge querypage-work2 branch from trunk. The most relevant changes are:...catrope14:16, 22 December 2010

Comments

#Comment by X! (talk | contribs)   20:42, 22 December 2010

Hooray for England!

#Comment by Bryan (talk | contribs)   21:47, 22 December 2010
+ * Created on Sep 10, 2007

Either your commit message is wrong (3.5 years) or the date is.

+					$r['cachedTimestamp'] = wfTimestamp( TS_ISO_8601, $ts );

API result data keys are generally fully lower case.

#Comment by Duplicatebug (talk | contribs)   18:43, 29 December 2010

The message for 'specialpage-cantexecute' is missing.

#Comment by Catrope (talk | contribs)   20:21, 29 December 2010

Fixed in r79198.

#Comment by Duplicatebug (talk | contribs)   18:56, 29 December 2010

The page MIMEsearch, LinkSearch and FileDuplicateSearch are useless, because there are need a input param (The normal special page has a form for the input).

  • MIMEsearch has no api module
  • LinkSearch is available per list=exturlusage
  • FileDuplicateSearch is available per prop=duplicatefiles
#Comment by Catrope (talk | contribs)   20:23, 29 December 2010

Yes, they're useless. I guess we could try to filter them out somehow, but I don't have the inclination or the time to do that in the foreseeable future.

#Comment by Duplicatebug (talk | contribs)   21:15, 7 January 2011

bug 26629 request a api module for Special:MIMESearch

#Comment by Jarry1250 (talk | contribs)   21:20, 6 March 2011

Couldn't get this to work:

Tried api.php?action=query&list=querypage&qppage=Unusedimages on my local wiki, and don't get the same output (0 files) as the special page (1 file).

In fact, I couldn't get an API output for Unusedimages, Uncategorizedpages or Mostrevisions.

Running 83399 (i.e. latest SVN) as of today.

#Comment by Aaron Schulz (talk | contribs)   20:18, 14 June 2011

This should be more like QueryPage::execute() in terms of checking isCached() and isCacheable(). Right now it always calls $qp->doQuery(), which will run the whole query live if it happens not to be cached. This won't affect wmf since a cached list will happen to be there from previous shell script runs. It still seems a bit wrong though.

#Comment by Krinkle (talk | contribs)   23:05, 20 July 2011

Yeah, if (caching expensive specialpages) is on, and a certain special page hasn't been ran yet calling the api should not result in a query.

If a wiki has that mode off though, it's fine to run the query since viewing the specialpage would run the query as well if I remember correctly.

#Comment by Catrope (talk | contribs)   17:57, 21 July 2011
	function doQuery( $offset = false, $limit = false ) {
		if ( $this->isCached() && $this->isCacheable() ) {
			return $this->fetchFromCache( $limit, $offset );
		} else {
			return $this->reallyDoQuery( $limit, $offset );
		}
	}

So it does hit the cache properly.

#Comment by Catrope (talk | contribs)   18:04, 21 July 2011

Krinkle explained to me that the culprit was in still calling doQuery() on a disabled query page. Fixed in r92762.

Status & tagging log