43 'linktable' =>
'redirect',
47 'showredirects' =>
false,
56 'linktable' =>
'pagelinks',
57 'indexes' => [
'pl_namespace',
'pl_backlinks_namespace' ],
58 'from_namespace' =>
true,
59 'showredirects' =>
true,
64 'linktable' =>
'templatelinks',
65 'indexes' => [
'tl_namespace',
'tl_backlinks_namespace' ],
66 'from_namespace' =>
true,
67 'showredirects' =>
true,
72 'linktable' =>
'imagelinks',
73 'indexes' => [
'il_to',
'il_backlinks_namespace' ],
74 'from_namespace' =>
true,
76 'exampletitle' =>
'File:Example.jpg',
77 'showredirects' =>
true,
94 parent::__construct( $query, $moduleName, self::$settings[$moduleName][
'code'] );
103 $this->
run( $resultPageSet );
112 $db = $this->
getDB();
114 $prop = array_fill_keys( $params[
'prop'],
true );
115 $emptyString = $db->addQuotes(
'' );
118 $titles = $pageSet->getGoodAndMissingPages();
119 $map = $pageSet->getGoodAndMissingTitlesByNamespace();
123 foreach ( $pageSet->getSpecialPages() as $id =>
$title ) {
130 $hasNS = !isset(
$settings[
'to_namespace'] );
132 if ( isset( $this->linksMigration::$mapping[
$settings[
'linktable']] ) ) {
133 list( $bl_namespace, $bl_title ) = $this->linksMigration->getTitleFields(
$settings[
'linktable'] );
135 $bl_namespace =
"{$p}_namespace";
136 $bl_title =
"{$p}_title";
140 $bl_namespace =
$settings[
'to_namespace'];
141 $bl_title =
"{$p}_to";
143 $titles = array_filter( $titles,
static function (
$t ) use ( $bl_namespace ) {
144 return $t->getNamespace() === $bl_namespace;
146 $map = array_intersect_key( $map, [ $bl_namespace =>
true ] );
148 $bl_from =
"{$p}_from";
153 if ( $params[
'namespace'] !==
null && count( $params[
'namespace'] ) === 0 ) {
161 if ( $hasNS && count( $map ) > 1 ) {
162 $sortby[$bl_namespace] =
'ns';
165 foreach ( $map as $nsTitles ) {
167 $key = key( $nsTitles );
168 if ( $theTitle ===
null ) {
171 if ( count( $nsTitles ) > 1 || $key !== $theTitle ) {
172 $sortby[$bl_title] =
'title';
177 if ( $params[
'namespace'] !==
null ) {
178 if ( empty(
$settings[
'from_namespace'] ) ) {
179 if ( $this->
getConfig()->
get( MainConfigNames::MiserMode ) ) {
180 $miser_ns = $params[
'namespace'];
182 $this->
addWhereFld(
'page_namespace', $params[
'namespace'] );
185 $this->
addWhereFld(
"{$p}_from_namespace", $params[
'namespace'] );
186 if ( !empty(
$settings[
'from_namespace'] )
187 && $params[
'namespace'] !==
null && count( $params[
'namespace'] ) > 1
189 $sortby[
"{$p}_from_namespace"] =
'int';
193 $sortby[$bl_from] =
'int';
196 if ( $params[
'continue'] !==
null ) {
197 $cont = explode(
'|', $params[
'continue'] );
200 $i = count( $sortby ) - 1;
201 foreach ( array_reverse( $sortby,
true ) as $field =>
$type ) {
210 $v = $db->addQuotes( $v );
214 if ( $where ===
'' ) {
215 $where =
"$field >= $v";
217 $where =
"$field > $v OR ($field = $v AND ($where))";
226 list( $idxNoFromNS, $idxWithFromNS ) =
$settings[
'indexes'] ?? [
'',
'' ];
228 if ( isset( $this->linksMigration::$mapping[
$settings[
'linktable']] ) ) {
230 $queryInfo = $this->linksMigration->getQueryInfo(
$settings[
'linktable'] );
231 $this->
addTables( array_merge( [
'page' ], $queryInfo[
'tables'] ) );
234 if ( in_array(
'linktarget', $queryInfo[
'tables'] ) ) {
235 $idxWithFromNS .=
'_target_id';
239 $this->
addTables( [ $settings[
'linktable'],
'page' ] );
241 $this->
addWhere(
"$bl_from = page_id" );
244 $this->
addWhere(
"rd_interwiki = $emptyString OR rd_interwiki IS NULL" );
247 $this->
addFields( array_keys( $sortby ) );
248 $this->
addFields( [
'bl_namespace' => $bl_namespace,
'bl_title' => $bl_title ] );
249 if ( $resultPageSet ===
null ) {
250 $fld_pageid = isset( $prop[
'pageid'] );
251 $fld_title = isset( $prop[
'title'] );
252 $fld_redirect = isset( $prop[
'redirect'] );
255 $this->
addFieldsIf( [
'page_title',
'page_namespace' ], $fld_title );
256 $this->
addFieldsIf(
'page_is_redirect', $fld_redirect );
259 $fld_fragment = isset( $prop[
'fragment'] );
260 $this->
addFieldsIf(
'rd_fragment', $fld_fragment );
262 $this->
addFields( $resultPageSet->getPageTableFields() );
265 $this->
addFieldsIf(
'page_namespace', $miser_ns !==
null );
270 $this->
addWhere( $db->makeWhereFrom2d( $map, $bl_namespace, $bl_title ) );
273 foreach ( $titles as
$t ) {
274 if (
$t->getNamespace() == $bl_namespace ) {
275 $where[] =
"$bl_title = " . $db->addQuotes(
$t->getDBkey() );
281 if ( $params[
'show'] !==
null ) {
283 $show = array_fill_keys( $params[
'show'],
true );
284 if ( isset( $show[
'fragment'] ) && isset( $show[
'!fragment'] ) ||
285 isset( $show[
'redirect'] ) && isset( $show[
'!redirect'] )
289 $this->
addWhereIf(
"rd_fragment != $emptyString", isset( $show[
'fragment'] ) );
291 "rd_fragment = $emptyString OR rd_fragment IS NULL",
292 isset( $show[
'!fragment'] )
294 $this->
addWhereIf( [
'page_is_redirect' => 1 ], isset( $show[
'redirect'] ) );
295 $this->
addWhereIf( [
'page_is_redirect' => 0 ], isset( $show[
'!redirect'] ) );
299 $this->
addOption(
'ORDER BY', array_keys( $sortby ) );
305 if ( $params[
'namespace'] !==
null && !empty(
$settings[
'from_namespace'] ) ) {
307 $this->
addOption(
'USE INDEX', [ $settings[
'linktable'] => $idxWithFromNS ] );
309 } elseif ( !isset( $this->linksMigration::$mapping[
$settings[
'linktable']] ) ) {
311 $this->
addOption(
'USE INDEX', [ $settings[
'linktable'] => $idxNoFromNS ] );
315 $this->
addOption(
'LIMIT', $params[
'limit'] + 1 );
319 if ( $resultPageSet ===
null ) {
326 foreach (
$res as $row ) {
327 if ( ++$count > $params[
'limit'] ) {
334 if ( $miser_ns !==
null && !in_array( $row->page_namespace, $miser_ns ) ) {
340 $id = $map[$row->bl_namespace][$row->bl_title];
345 $vals[
'pageid'] = (int)$row->page_id;
353 if ( $fld_fragment && $row->rd_fragment !==
null && $row->rd_fragment !==
'' ) {
354 $vals[
'fragment'] = $row->rd_fragment;
357 if ( $fld_redirect ) {
358 $vals[
'redirect'] = (bool)$row->page_is_redirect;
369 foreach (
$res as $row ) {
370 if ( ++$count > $params[
'limit'] ) {
377 if ( $miser_ns !==
null && !in_array( $row->page_namespace, $miser_ns ) ) {
384 $resultPageSet->populateFromTitles( $titles );
390 foreach ( $sortby as $field => $v ) {
391 $cont[] = $row->$field;
430 if ( empty(
$settings[
'from_namespace'] ) &&
431 $this->
getConfig()->
get( MainConfigNames::MiserMode ) ) {
433 'api-help-param-limited-in-miser-mode',
437 if ( !empty(
$settings[
'showredirects'] ) ) {
448 if ( !empty(
$settings[
'showredirects'] ) ) {
449 $show[] =
'redirect';
450 $show[] =
'!redirect';
453 $show = array_merge( $show,
$settings[
'show'] );
461 unset( $ret[
'show'] );
472 $etitle = rawurlencode(
$title );
475 "action=query&prop={$name}&titles={$etitle}"
476 =>
"apihelp-$path-example-simple",
477 "action=query&generator={$name}&titles={$etitle}&prop=info"
478 =>
"apihelp-$path-example-generator",
484 return "https://www.mediawiki.org/wiki/Special:MyLanguage/API:{$name}";
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
dieContinueUsageIf( $condition)
Die with the 'badcontinue' error.
const PARAM_HELP_MSG_APPEND
((string|array|Message)[]) Specify additional i18n messages to append to the normal message for this ...
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
const LIMIT_BIG1
Fast query, standard limit.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
getModulePath()
Get the path to this module.
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
const LIMIT_BIG2
Fast query, apihighlimits limit.
getModuleName()
Get the name of the module being executed by this instance.
This class contains a list of pages that the client has requested.
This implements prop=redirects, prop=linkshere, prop=catmembers, prop=transcludedin,...
setContinue( $row, $sortby)
executeGenerator( $resultPageSet)
Execute this module as a generator.
static array $settings
Data for the various modules implemented by this class.
getHelpUrls()
Return links to more detailed help pages about the module.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
run(ApiPageSet $resultPageSet=null)
getExamplesMessages()
Returns usage examples for this module.
__construct(ApiQuery $query, $moduleName, LinksMigration $linksMigration)
getCacheMode( $params)
Get the cache mode for the data generated by this module.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
LinksMigration $linksMigration
static addTitleInfo(&$arr, $title, $prefix='')
Add information (title and namespace) about a Title object to a result array.
addWhereIf( $value, $condition)
Same as addWhere(), but add the WHERE clauses only if a condition is met.
addFields( $value)
Add a set of fields to select to the internal array.
addPageSubItem( $pageId, $item, $elemname=null)
Same as addPageSubItems(), but one element of $data at a time.
addOption( $name, $value=null)
Add an option such as LIMIT or USE INDEX.
addTables( $tables, $alias=null)
Add a set of tables to the internal array.
getDB()
Get the Query database connection (read-only)
executeGenderCacheFromResultWrapper(IResultWrapper $res, $fname=__METHOD__, $fieldPrefix='page')
Preprocess the result set to fill the GenderCache with the necessary information before using self::a...
select( $method, $extraQuery=[], array &$hookData=null)
Execute a SELECT query based on the values in the internal arrays.
addFieldsIf( $value, $condition)
Same as addFields(), but add the fields only if a condition is met.
addJoinConds( $join_conds)
Add a set of JOIN conditions to the internal array.
addWhereFld( $field, $value)
Equivalent to addWhere( [ $field => $value ] )
addWhere( $value)
Add a set of WHERE clauses to the internal array.
setContinueEnumParameter( $paramName, $paramValue)
Overridden to set the generator param if in generator mode.
getPageSet()
Get the PageSet object to work on.
This is the main query class.
A class containing constants representing the names of configuration variables.
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.