summaryrefslogtreecommitdiff
path: root/includes/api/ApiPageSet.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/api/ApiPageSet.php')
-rw-r--r--includes/api/ApiPageSet.php560
1 files changed, 427 insertions, 133 deletions
diff --git a/includes/api/ApiPageSet.php b/includes/api/ApiPageSet.php
index 0f5be6b2..074efe4b 100644
--- a/includes/api/ApiPageSet.php
+++ b/includes/api/ApiPageSet.php
@@ -4,7 +4,7 @@
*
* Created on Sep 24, 2006
*
- * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
+ * Copyright © 2006, 2013 Yuri Astrakhan "<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
@@ -36,52 +36,177 @@
* the second instance for all their work.
*
* @ingroup API
+ * @since 1.21 derives from ApiBase instead of ApiQueryBase
*/
-class ApiPageSet extends ApiQueryBase {
+class ApiPageSet extends ApiBase {
- private $mAllPages; // [ns][dbkey] => page_id or negative when missing
- private $mTitles, $mGoodTitles, $mMissingTitles, $mInvalidTitles;
- private $mMissingPageIDs, $mRedirectTitles, $mSpecialTitles;
- private $mNormalizedTitles, $mInterwikiTitles;
- private $mResolveRedirects, $mPendingRedirectIDs;
- private $mConvertTitles, $mConvertedTitles;
- private $mGoodRevIDs, $mMissingRevIDs;
- private $mFakePageId;
-
- private $mRequestedPageFields;
+ /**
+ * Constructor flag: The new instance of ApiPageSet will ignore the 'generator=' parameter
+ * @since 1.21
+ */
+ const DISABLE_GENERATORS = 1;
+
+ private $mDbSource;
+ private $mParams;
+ private $mResolveRedirects;
+ private $mConvertTitles;
+ private $mAllowGenerator;
+
+ private $mAllPages = array(); // [ns][dbkey] => page_id or negative when missing
+ private $mTitles = array();
+ private $mGoodTitles = array();
+ private $mMissingTitles = array();
+ private $mInvalidTitles = array();
+ private $mMissingPageIDs = array();
+ private $mRedirectTitles = array();
+ private $mSpecialTitles = array();
+ private $mNormalizedTitles = array();
+ private $mInterwikiTitles = array();
+ private $mPendingRedirectIDs = array();
+ private $mConvertedTitles = array();
+ private $mGoodRevIDs = array();
+ private $mMissingRevIDs = array();
+ private $mFakePageId = -1;
+ private $mCacheMode = 'public';
+ private $mRequestedPageFields = array();
+ private $mDefaultNamespace = NS_MAIN;
/**
* Constructor
- * @param $query ApiBase
- * @param $resolveRedirects bool Whether redirects should be resolved
- * @param $convertTitles bool
+ * @param $dbSource ApiBase Module implementing getDB().
+ * Allows PageSet to reuse existing db connection from the shared state like ApiQuery.
+ * @param int $flags Zero or more flags like DISABLE_GENERATORS
+ * @param int $defaultNamespace the namespace to use if none is specified by a prefix.
+ * @since 1.21 accepts $flags instead of two boolean values
*/
- public function __construct( $query, $resolveRedirects = false, $convertTitles = false ) {
- parent::__construct( $query, 'query' );
+ public function __construct( ApiBase $dbSource, $flags = 0, $defaultNamespace = NS_MAIN ) {
+ parent::__construct( $dbSource->getMain(), $dbSource->getModuleName() );
+ $this->mDbSource = $dbSource;
+ $this->mAllowGenerator = ( $flags & ApiPageSet::DISABLE_GENERATORS ) == 0;
+ $this->mDefaultNamespace = $defaultNamespace;
- $this->mAllPages = array();
- $this->mTitles = array();
- $this->mGoodTitles = array();
- $this->mMissingTitles = array();
- $this->mInvalidTitles = array();
- $this->mMissingPageIDs = array();
- $this->mRedirectTitles = array();
- $this->mNormalizedTitles = array();
- $this->mInterwikiTitles = array();
- $this->mGoodRevIDs = array();
- $this->mMissingRevIDs = array();
- $this->mSpecialTitles = array();
+ $this->profileIn();
+ $this->mParams = $this->extractRequestParams();
+ $this->mResolveRedirects = $this->mParams['redirects'];
+ $this->mConvertTitles = $this->mParams['converttitles'];
+ $this->profileOut();
+ }
- $this->mRequestedPageFields = array();
- $this->mResolveRedirects = $resolveRedirects;
- if ( $resolveRedirects ) {
- $this->mPendingRedirectIDs = array();
- }
+ /**
+ * In case execute() is not called, call this method to mark all relevant parameters as used
+ * This prevents unused parameters from being reported as warnings
+ */
+ public function executeDryRun() {
+ $this->executeInternal( true );
+ }
- $this->mConvertTitles = $convertTitles;
- $this->mConvertedTitles = array();
+ /**
+ * Populate the PageSet from the request parameters.
+ */
+ public function execute() {
+ $this->executeInternal( false );
+ }
+
+ /**
+ * Populate the PageSet from the request parameters.
+ * @param bool $isDryRun If true, instantiates generator, but only to mark relevant parameters as used
+ */
+ private function executeInternal( $isDryRun ) {
+ $this->profileIn();
- $this->mFakePageId = - 1;
+ $generatorName = $this->mAllowGenerator ? $this->mParams['generator'] : null;
+ if ( isset( $generatorName ) ) {
+ $dbSource = $this->mDbSource;
+ $isQuery = $dbSource instanceof ApiQuery;
+ if ( !$isQuery ) {
+ // If the parent container of this pageset is not ApiQuery, we must create it to run generator
+ $dbSource = $this->getMain()->getModuleManager()->getModule( 'query' );
+ // Enable profiling for query module because it will be used for db sql profiling
+ $dbSource->profileIn();
+ }
+ $generator = $dbSource->getModuleManager()->getModule( $generatorName, null, true );
+ if ( $generator === null ) {
+ $this->dieUsage( 'Unknown generator=' . $generatorName, 'badgenerator' );
+ }
+ if ( !$generator instanceof ApiQueryGeneratorBase ) {
+ $this->dieUsage( "Module $generatorName cannot be used as a generator", 'badgenerator' );
+ }
+ // Create a temporary pageset to store generator's output,
+ // add any additional fields generator may need, and execute pageset to populate titles/pageids
+ $tmpPageSet = new ApiPageSet( $dbSource, ApiPageSet::DISABLE_GENERATORS );
+ $generator->setGeneratorMode( $tmpPageSet );
+ $this->mCacheMode = $generator->getCacheMode( $generator->extractRequestParams() );
+
+ if ( !$isDryRun ) {
+ $generator->requestExtraData( $tmpPageSet );
+ }
+ $tmpPageSet->executeInternal( $isDryRun );
+
+ // populate this pageset with the generator output
+ $this->profileOut();
+ $generator->profileIn();
+
+ if ( !$isDryRun ) {
+ $generator->executeGenerator( $this );
+ wfRunHooks( 'APIQueryGeneratorAfterExecute', array( &$generator, &$this ) );
+ $this->resolvePendingRedirects();
+ } else {
+ // Prevent warnings from being reported on these parameters
+ $main = $this->getMain();
+ foreach ( $generator->extractRequestParams() as $paramName => $param ) {
+ $main->getVal( $generator->encodeParamName( $paramName ) );
+ }
+ }
+ $generator->profileOut();
+ $this->profileIn();
+
+ if ( !$isQuery ) {
+ // If this pageset is not part of the query, we called profileIn() above
+ $dbSource->profileOut();
+ }
+ } else {
+ // Only one of the titles/pageids/revids is allowed at the same time
+ $dataSource = null;
+ if ( isset( $this->mParams['titles'] ) ) {
+ $dataSource = 'titles';
+ }
+ if ( isset( $this->mParams['pageids'] ) ) {
+ if ( isset( $dataSource ) ) {
+ $this->dieUsage( "Cannot use 'pageids' at the same time as '$dataSource'", 'multisource' );
+ }
+ $dataSource = 'pageids';
+ }
+ if ( isset( $this->mParams['revids'] ) ) {
+ if ( isset( $dataSource ) ) {
+ $this->dieUsage( "Cannot use 'revids' at the same time as '$dataSource'", 'multisource' );
+ }
+ $dataSource = 'revids';
+ }
+
+ if ( !$isDryRun ) {
+ // Populate page information with the original user input
+ switch( $dataSource ) {
+ case 'titles':
+ $this->initFromTitles( $this->mParams['titles'] );
+ break;
+ case 'pageids':
+ $this->initFromPageIds( $this->mParams['pageids'] );
+ break;
+ case 'revids':
+ if ( $this->mResolveRedirects ) {
+ $this->setWarning( 'Redirect resolution cannot be used together with the revids= parameter. ' .
+ 'Any redirects the revids= point to have not been resolved.' );
+ }
+ $this->mResolveRedirects = false;
+ $this->initFromRevIDs( $this->mParams['revids'] );
+ break;
+ default:
+ // Do nothing - some queries do not need any of the data sources.
+ break;
+ }
+ }
+ }
+ $this->profileOut();
}
/**
@@ -93,9 +218,33 @@ class ApiPageSet extends ApiQueryBase {
}
/**
- * Request an additional field from the page table. Must be called
- * before execute()
- * @param $fieldName string Field name
+ * Return the parameter name that is the source of data for this PageSet
+ *
+ * If multiple source parameters are specified (e.g. titles and pageids),
+ * one will be named arbitrarily.
+ *
+ * @return string|null
+ */
+ public function getDataSource() {
+ if ( $this->mAllowGenerator && isset( $this->mParams['generator'] ) ) {
+ return 'generator';
+ }
+ if ( isset( $this->mParams['titles'] ) ) {
+ return 'titles';
+ }
+ if ( isset( $this->mParams['pageids'] ) ) {
+ return 'pageids';
+ }
+ if ( isset( $this->mParams['revids'] ) ) {
+ return 'revids';
+ }
+ return null;
+ }
+
+ /**
+ * Request an additional field from the page table.
+ * Must be called before execute()
+ * @param string $fieldName Field name
*/
public function requestField( $fieldName ) {
$this->mRequestedPageFields[$fieldName] = null;
@@ -104,7 +253,7 @@ class ApiPageSet extends ApiQueryBase {
/**
* Get the value of a custom field previously requested through
* requestField()
- * @param $fieldName string Field name
+ * @param string $fieldName Field name
* @return mixed Field value
*/
public function getCustomField( $fieldName ) {
@@ -207,14 +356,39 @@ class ApiPageSet extends ApiQueryBase {
/**
* Get a list of redirect resolutions - maps a title to its redirect
- * target.
- * @return array prefixed_title (string) => Title object
+ * target, as an array of output-ready arrays
+ * @return array
*/
public function getRedirectTitles() {
return $this->mRedirectTitles;
}
/**
+ * Get a list of redirect resolutions - maps a title to its redirect
+ * target.
+ * @param $result ApiResult
+ * @return array of prefixed_title (string) => Title object
+ * @since 1.21
+ */
+ public function getRedirectTitlesAsResult( $result = null ) {
+ $values = array();
+ foreach ( $this->getRedirectTitles() as $titleStrFrom => $titleTo ) {
+ $r = array(
+ 'from' => strval( $titleStrFrom ),
+ 'to' => $titleTo->getPrefixedText(),
+ );
+ if ( $titleTo->getFragment() !== '' ) {
+ $r['tofragment'] = $titleTo->getFragment();
+ }
+ $values[] = $r;
+ }
+ if ( !empty( $values ) && $result ) {
+ $result->setIndexedTagName( $values, 'r' );
+ }
+ return $values;
+ }
+
+ /**
* Get a list of title normalizations - maps a title to its normalized
* version.
* @return array raw_prefixed_title (string) => prefixed_title (string)
@@ -224,6 +398,27 @@ class ApiPageSet extends ApiQueryBase {
}
/**
+ * Get a list of title normalizations - maps a title to its normalized
+ * version in the form of result array.
+ * @param $result ApiResult
+ * @return array of raw_prefixed_title (string) => prefixed_title (string)
+ * @since 1.21
+ */
+ public function getNormalizedTitlesAsResult( $result = null ) {
+ $values = array();
+ foreach ( $this->getNormalizedTitles() as $rawTitleStr => $titleStr ) {
+ $values[] = array(
+ 'from' => $rawTitleStr,
+ 'to' => $titleStr
+ );
+ }
+ if ( !empty( $values ) && $result ) {
+ $result->setIndexedTagName( $values, 'n' );
+ }
+ return $values;
+ }
+
+ /**
* Get a list of title conversions - maps a title to its converted
* version.
* @return array raw_prefixed_title (string) => prefixed_title (string)
@@ -233,6 +428,27 @@ class ApiPageSet extends ApiQueryBase {
}
/**
+ * Get a list of title conversions - maps a title to its converted
+ * version as a result array.
+ * @param $result ApiResult
+ * @return array of (from, to) strings
+ * @since 1.21
+ */
+ public function getConvertedTitlesAsResult( $result = null ) {
+ $values = array();
+ foreach ( $this->getConvertedTitles() as $rawTitleStr => $titleStr ) {
+ $values[] = array(
+ 'from' => $rawTitleStr,
+ 'to' => $titleStr
+ );
+ }
+ if ( !empty( $values ) && $result ) {
+ $result->setIndexedTagName( $values, 'c' );
+ }
+ return $values;
+ }
+
+ /**
* Get a list of interwiki titles - maps a title to its interwiki
* prefix.
* @return array raw_prefixed_title (string) => interwiki_prefix (string)
@@ -242,6 +458,33 @@ class ApiPageSet extends ApiQueryBase {
}
/**
+ * Get a list of interwiki titles - maps a title to its interwiki
+ * prefix as result.
+ * @param $result ApiResult
+ * @param $iwUrl boolean
+ * @return array raw_prefixed_title (string) => interwiki_prefix (string)
+ * @since 1.21
+ */
+ public function getInterwikiTitlesAsResult( $result = null, $iwUrl = false ) {
+ $values = array();
+ foreach ( $this->getInterwikiTitles() as $rawTitleStr => $interwikiStr ) {
+ $item = array(
+ 'title' => $rawTitleStr,
+ 'iw' => $interwikiStr,
+ );
+ if ( $iwUrl ) {
+ $title = Title::newFromText( $rawTitleStr );
+ $item['url'] = $title->getFullURL( '', false, PROTO_CURRENT );
+ }
+ $values[] = $item;
+ }
+ if ( !empty( $values ) && $result ) {
+ $result->setIndexedTagName( $values, 'i' );
+ }
+ return $values;
+ }
+
+ /**
* Get the list of revision IDs (requested with the revids= parameter)
* @return array revID (int) => pageID (int)
*/
@@ -258,6 +501,25 @@ class ApiPageSet extends ApiQueryBase {
}
/**
+ * Revision IDs that were not found in the database as result array.
+ * @param $result ApiResult
+ * @return array of revision IDs
+ * @since 1.21
+ */
+ public function getMissingRevisionIDsAsResult( $result = null ) {
+ $values = array();
+ foreach ( $this->getMissingRevisionIDs() as $revid ) {
+ $values[$revid] = array(
+ 'revid' => $revid
+ );
+ }
+ if ( !empty( $values ) && $result ) {
+ $result->setIndexedTagName( $values, 'rev' );
+ }
+ return $values;
+ }
+
+ /**
* Get the list of titles with negative namespace
* @return array Title
*/
@@ -274,55 +536,8 @@ class ApiPageSet extends ApiQueryBase {
}
/**
- * Populate the PageSet from the request parameters.
- */
- public function execute() {
- $this->profileIn();
- $params = $this->extractRequestParams();
-
- // Only one of the titles/pageids/revids is allowed at the same time
- $dataSource = null;
- if ( isset( $params['titles'] ) ) {
- $dataSource = 'titles';
- }
- if ( isset( $params['pageids'] ) ) {
- if ( isset( $dataSource ) ) {
- $this->dieUsage( "Cannot use 'pageids' at the same time as '$dataSource'", 'multisource' );
- }
- $dataSource = 'pageids';
- }
- if ( isset( $params['revids'] ) ) {
- if ( isset( $dataSource ) ) {
- $this->dieUsage( "Cannot use 'revids' at the same time as '$dataSource'", 'multisource' );
- }
- $dataSource = 'revids';
- }
-
- switch ( $dataSource ) {
- case 'titles':
- $this->initFromTitles( $params['titles'] );
- break;
- case 'pageids':
- $this->initFromPageIds( $params['pageids'] );
- break;
- case 'revids':
- if ( $this->mResolveRedirects ) {
- $this->setWarning( 'Redirect resolution cannot be used together with the revids= parameter. ' .
- 'Any redirects the revids= point to have not been resolved.' );
- }
- $this->mResolveRedirects = false;
- $this->initFromRevIDs( $params['revids'] );
- break;
- default:
- // Do nothing - some queries do not need any of the data sources.
- break;
- }
- $this->profileOut();
- }
-
- /**
* Populate this PageSet from a list of Titles
- * @param $titles array of Title objects
+ * @param array $titles of Title objects
*/
public function populateFromTitles( $titles ) {
$this->profileIn();
@@ -332,7 +547,7 @@ class ApiPageSet extends ApiQueryBase {
/**
* Populate this PageSet from a list of page IDs
- * @param $pageIDs array of page IDs
+ * @param array $pageIDs of page IDs
*/
public function populateFromPageIDs( $pageIDs ) {
$this->profileIn();
@@ -353,7 +568,7 @@ class ApiPageSet extends ApiQueryBase {
/**
* Populate this PageSet from a list of revision IDs
- * @param $revIDs array of revision IDs
+ * @param array $revIDs of revision IDs
*/
public function populateFromRevisionIDs( $revIDs ) {
$this->profileIn();
@@ -385,12 +600,11 @@ class ApiPageSet extends ApiQueryBase {
}
/**
- * Resolve redirects, if applicable
+ * Do not use, does nothing, will be removed
+ * @deprecated 1.21
*/
public function finishPageSetGeneration() {
- $this->profileIn();
- $this->resolvePendingRedirects();
- $this->profileOut();
+ wfDeprecated( __METHOD__, '1.21' );
}
/**
@@ -407,7 +621,7 @@ class ApiPageSet extends ApiQueryBase {
* #5 Substitute the original LinkBatch object with the new list
* #6 Repeat from step #1
*
- * @param $titles array of Title objects or strings
+ * @param array $titles of Title objects or strings
*/
private function initFromTitles( $titles ) {
// Get validated and normalized title objects
@@ -434,10 +648,10 @@ class ApiPageSet extends ApiQueryBase {
/**
* Does the same as initFromTitles(), but is based on page IDs instead
- * @param $pageids array of page IDs
+ * @param array $pageids of page IDs
*/
private function initFromPageIds( $pageids ) {
- if ( !count( $pageids ) ) {
+ if ( !$pageids ) {
return;
}
@@ -447,7 +661,7 @@ class ApiPageSet extends ApiQueryBase {
$pageids = self::getPositiveIntegers( $pageids );
$res = null;
- if ( count( $pageids ) ) {
+ if ( !empty( $pageids ) ) {
$set = array(
'page_id' => $pageids
);
@@ -460,7 +674,7 @@ class ApiPageSet extends ApiQueryBase {
$this->profileDBOut();
}
- $this->initFromQueryResult( $res, $remaining, false ); // process PageIDs
+ $this->initFromQueryResult( $res, $remaining, false ); // process PageIDs
// Resolve any found redirects
$this->resolvePendingRedirects();
@@ -470,9 +684,9 @@ class ApiPageSet extends ApiQueryBase {
* Iterate through the result of the query on 'page' table,
* and for each row create and store title object and save any extra fields requested.
* @param $res ResultWrapper DB Query result
- * @param $remaining array of either pageID or ns/title elements (optional).
+ * @param array $remaining of either pageID or ns/title elements (optional).
* If given, any missing items will go to $mMissingPageIDs and $mMissingTitles
- * @param $processTitles bool Must be provided together with $remaining.
+ * @param bool $processTitles Must be provided together with $remaining.
* If true, treat $remaining as an array of [ns][title]
* If false, treat it as an array of [pageIDs]
*/
@@ -499,7 +713,7 @@ class ApiPageSet extends ApiQueryBase {
$this->processDbRow( $row );
// Need gender information
- if( MWNamespace::hasGenderDistinction( $row->page_namespace ) ) {
+ if ( MWNamespace::hasGenderDistinction( $row->page_namespace ) ) {
$usernames[] = $row->page_title;
}
}
@@ -518,7 +732,7 @@ class ApiPageSet extends ApiQueryBase {
$this->mTitles[] = $title;
// need gender information
- if( MWNamespace::hasGenderDistinction( $ns ) ) {
+ if ( MWNamespace::hasGenderDistinction( $ns ) ) {
$usernames[] = $dbkey;
}
}
@@ -541,10 +755,10 @@ class ApiPageSet extends ApiQueryBase {
/**
* Does the same as initFromTitles(), but is based on revision IDs
* instead
- * @param $revids array of revision IDs
+ * @param array $revids of revision IDs
*/
private function initFromRevIDs( $revids ) {
- if ( !count( $revids ) ) {
+ if ( !$revids ) {
return;
}
@@ -555,14 +769,14 @@ class ApiPageSet extends ApiQueryBase {
$revids = self::getPositiveIntegers( $revids );
- if ( count( $revids ) ) {
+ if ( !empty( $revids ) ) {
$tables = array( 'revision', 'page' );
$fields = array( 'rev_id', 'rev_page' );
$where = array( 'rev_id' => $revids, 'rev_page = page_id' );
// Get pageIDs data from the `page` table
$this->profileDBIn();
- $res = $db->select( $tables, $fields, $where, __METHOD__ );
+ $res = $db->select( $tables, $fields, $where, __METHOD__ );
foreach ( $res as $row ) {
$revid = intval( $row->rev_id );
$pageid = intval( $row->rev_page );
@@ -670,44 +884,63 @@ class ApiPageSet extends ApiQueryBase {
}
/**
+ * Get the cache mode for the data generated by this module.
+ * All PageSet users should take into account whether this returns a more-restrictive
+ * cache mode than the using module itself. For possible return values and other
+ * details about cache modes, see ApiMain::setCacheMode()
+ *
+ * Public caching will only be allowed if *all* the modules that supply
+ * data for a given request return a cache mode of public.
+ *
+ * @param $params
+ * @return string
+ * @since 1.21
+ */
+ public function getCacheMode( $params = null ) {
+ return $this->mCacheMode;
+ }
+
+ /**
* Given an array of title strings, convert them into Title objects.
- * Alternativelly, an array of Title objects may be given.
+ * Alternatively, an array of Title objects may be given.
* This method validates access rights for the title,
* and appends normalization values to the output.
*
- * @param $titles array of Title objects or strings
+ * @param array $titles of Title objects or strings
* @return LinkBatch
*/
private function processTitlesArray( $titles ) {
- $genderCache = GenderCache::singleton();
- $genderCache->doTitlesArray( $titles, __METHOD__ );
-
+ $usernames = array();
$linkBatch = new LinkBatch();
foreach ( $titles as $title ) {
- $titleObj = is_string( $title ) ? Title::newFromText( $title ) : $title;
+ if ( is_string( $title ) ) {
+ $titleObj = Title::newFromText( $title, $this->mDefaultNamespace );
+ } else {
+ $titleObj = $title;
+ }
if ( !$titleObj ) {
// Handle invalid titles gracefully
- $this->mAllpages[0][$title] = $this->mFakePageId;
+ $this->mAllPages[0][$title] = $this->mFakePageId;
$this->mInvalidTitles[$this->mFakePageId] = $title;
$this->mFakePageId--;
continue; // There's nothing else we can do
}
$unconvertedTitle = $titleObj->getPrefixedText();
$titleWasConverted = false;
- $iw = $titleObj->getInterwiki();
- if ( strval( $iw ) !== '' ) {
+ if ( $titleObj->isExternal() ) {
// This title is an interwiki link.
- $this->mInterwikiTitles[$titleObj->getPrefixedText()] = $iw;
+ $this->mInterwikiTitles[$unconvertedTitle] = $titleObj->getInterwiki();
} else {
// Variants checking
global $wgContLang;
if ( $this->mConvertTitles &&
- count( $wgContLang->getVariants() ) > 1 &&
+ count( $wgContLang->getVariants() ) > 1 &&
!$titleObj->exists() ) {
- // Language::findVariantLink will modify titleObj into
+ // Language::findVariantLink will modify titleText and titleObj into
// the canonical variant if possible
- $wgContLang->findVariantLink( $title, $titleObj );
+ $titleText = is_string( $title ) ? $title : $titleObj->getPrefixedText();
+ $wgContLang->findVariantLink( $titleText, $titleObj );
$titleWasConverted = $unconvertedTitle !== $titleObj->getPrefixedText();
}
@@ -728,16 +961,36 @@ class ApiPageSet extends ApiQueryBase {
// namespace is localized or the capitalization is
// different
if ( $titleWasConverted ) {
- $this->mConvertedTitles[$title] = $titleObj->getPrefixedText();
+ $this->mConvertedTitles[$unconvertedTitle] = $titleObj->getPrefixedText();
+ // In this case the page can't be Special.
+ if ( is_string( $title ) && $title !== $unconvertedTitle ) {
+ $this->mNormalizedTitles[$title] = $unconvertedTitle;
+ }
} elseif ( is_string( $title ) && $title !== $titleObj->getPrefixedText() ) {
$this->mNormalizedTitles[$title] = $titleObj->getPrefixedText();
}
+
+ // Need gender information
+ if ( MWNamespace::hasGenderDistinction( $titleObj->getNamespace() ) ) {
+ $usernames[] = $titleObj->getText();
+ }
}
+ // Get gender information
+ $genderCache = GenderCache::singleton();
+ $genderCache->doQuery( $usernames, __METHOD__ );
return $linkBatch;
}
/**
+ * Get the database connection (read-only)
+ * @return DatabaseBase
+ */
+ protected function getDB() {
+ return $this->mDbSource->getDB();
+ }
+
+ /**
* Returns the input array of integers with all values < 0 removed
*
* @param $array array
@@ -747,7 +1000,7 @@ class ApiPageSet extends ApiQueryBase {
// bug 25734 API: possible issue with revids validation
// It seems with a load of revision rows, MySQL gets upset
// Remove any < 0 integers, as they can't be valid
- foreach( $array as $i => $int ) {
+ foreach ( $array as $i => $int ) {
if ( $int < 0 ) {
unset( $array[$i] );
}
@@ -756,8 +1009,8 @@ class ApiPageSet extends ApiQueryBase {
return $array;
}
- public function getAllowedParams() {
- return array(
+ public function getAllowedParams( $flags = 0 ) {
+ $result = array(
'titles' => array(
ApiBase::PARAM_ISMULTI => true
),
@@ -768,15 +1021,59 @@ class ApiPageSet extends ApiQueryBase {
'revids' => array(
ApiBase::PARAM_TYPE => 'integer',
ApiBase::PARAM_ISMULTI => true
- )
+ ),
+ 'redirects' => false,
+ 'converttitles' => false,
);
+ if ( $this->mAllowGenerator ) {
+ if ( $flags & ApiBase::GET_VALUES_FOR_HELP ) {
+ $result['generator'] = array(
+ ApiBase::PARAM_TYPE => $this->getGenerators()
+ );
+ } else {
+ $result['generator'] = null;
+ }
+ }
+ return $result;
+ }
+
+ private static $generators = null;
+
+ /**
+ * Get an array of all available generators
+ * @return array
+ */
+ private function getGenerators() {
+ if ( self::$generators === null ) {
+ $query = $this->mDbSource;
+ if ( !( $query instanceof ApiQuery ) ) {
+ // If the parent container of this pageset is not ApiQuery,
+ // we must create it to get module manager
+ $query = $this->getMain()->getModuleManager()->getModule( 'query' );
+ }
+ $gens = array();
+ $mgr = $query->getModuleManager();
+ foreach ( $mgr->getNamesWithClasses() as $name => $class ) {
+ if ( is_subclass_of( $class, 'ApiQueryGeneratorBase' ) ) {
+ $gens[] = $name;
+ }
+ }
+ sort( $gens );
+ self::$generators = $gens;
+ }
+ return self::$generators;
}
public function getParamDescription() {
return array(
'titles' => 'A list of titles to work on',
'pageids' => 'A list of page IDs to work on',
- 'revids' => 'A list of revision IDs to work on'
+ 'revids' => 'A list of revision IDs to work on',
+ 'generator' => array( 'Get the list of pages to work on by executing the specified query module.',
+ 'NOTE: generator parameter names must be prefixed with a \'g\', see examples' ),
+ 'redirects' => 'Automatically resolve redirects',
+ 'converttitles' => array( 'Convert titles to other variants if necessary. Only works if the wiki\'s content language supports variant conversion.',
+ 'Languages that support variant conversion include ' . implode( ', ', LanguageConverter::$languagesWithVariants ) ),
);
}
@@ -784,10 +1081,7 @@ class ApiPageSet extends ApiQueryBase {
return array_merge( parent::getPossibleErrors(), array(
array( 'code' => 'multisource', 'info' => "Cannot use 'pageids' at the same time as 'dataSource'" ),
array( 'code' => 'multisource', 'info' => "Cannot use 'revids' at the same time as 'dataSource'" ),
+ array( 'code' => 'badgenerator', 'info' => 'Module $generatorName cannot be used as a generator' ),
) );
}
-
- public function getVersion() {
- return __CLASS__ . ': $Id$';
- }
}