Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 96
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiQueryImages
0.00% covered (danger)
0.00%
0 / 95
0.00% covered (danger)
0.00%
0 / 8
600
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 executeGenerator
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 run
0.00% covered (danger)
0.00%
0 / 60
0.00% covered (danger)
0.00%
0 / 1
306
 getCacheMode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
2
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 getHelpUrls
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 */
8
9namespace MediaWiki\Api;
10
11use MediaWiki\Deferred\LinksUpdate\ImageLinksTable;
12use MediaWiki\Linker\LinksMigration;
13use MediaWiki\Title\Title;
14use Wikimedia\ParamValidator\ParamValidator;
15use Wikimedia\ParamValidator\TypeDef\IntegerDef;
16
17/**
18 * This query adds an "<images>" subelement to all pages with the list of
19 * images embedded into those pages.
20 *
21 * @ingroup API
22 */
23class ApiQueryImages extends ApiQueryGeneratorBase {
24
25    public function __construct(
26        ApiQuery $query,
27        string $moduleName,
28        private readonly LinksMigration $linksMigration,
29    ) {
30        parent::__construct( $query, $moduleName, 'im' );
31    }
32
33    public function execute() {
34        $this->run();
35    }
36
37    /** @inheritDoc */
38    public function executeGenerator( $resultPageSet ) {
39        $this->run( $resultPageSet );
40    }
41
42    /**
43     * @param ApiPageSet|null $resultPageSet
44     */
45    private function run( $resultPageSet = null ) {
46        $pages = $this->getPageSet()->getGoodPages();
47        if ( $pages === [] ) {
48            return; // nothing to do
49        }
50
51        $params = $this->extractRequestParams();
52        $queryInfo = $this->linksMigration->getQueryInfo( 'imagelinks' );
53
54        $this->addTables( $queryInfo['tables'] );
55        $this->addFields( [ 'il_from', 'lt_title' ] );
56        $this->addJoinConds( $queryInfo['joins'] );
57
58        $this->addWhereFld( 'il_from', array_keys( $pages ) );
59        if ( $params['continue'] !== null ) {
60            $cont = $this->parseContinueParamOrDie( $params['continue'], [ 'int', 'string' ] );
61            $op = $params['dir'] == 'descending' ? '<=' : '>=';
62            $comparison = [
63                'il_from' => $cont[0],
64                'lt_namespace' => NS_FILE,
65                'lt_title' => $cont[1],
66            ];
67            $this->addWhere( $this->getDB()->buildComparison( $op, $comparison ) );
68        }
69
70        $sort = ( $params['dir'] == 'descending' ? ' DESC' : '' );
71        // Don't order by il_from if it's constant in the WHERE clause
72        if ( count( $pages ) === 1 ) {
73            $this->addOption( 'ORDER BY', 'lt_title' . $sort );
74        } else {
75            $this->addOption( 'ORDER BY', [
76                'il_from' . $sort,
77                'lt_title' . $sort
78            ] );
79        }
80        $this->addOption( 'LIMIT', $params['limit'] + 1 );
81
82        if ( $params['images'] ) {
83            $images = [];
84            foreach ( $params['images'] as $img ) {
85                $title = Title::newFromText( $img );
86                if ( !$title || $title->getNamespace() !== NS_FILE ) {
87                    $this->addWarning( [ 'apiwarn-notfile', wfEscapeWikiText( $img ) ] );
88                } else {
89                    $images[] = $title->getDBkey();
90                }
91            }
92            if ( !$images ) {
93                // No titles so no results
94                return;
95            }
96            $this->addWhereFld( 'lt_title', $images );
97            $this->addWhereFld( 'lt_namespace', NS_FILE );
98        }
99
100        $this->setVirtualDomain( ImageLinksTable::VIRTUAL_DOMAIN );
101        $res = $this->select( __METHOD__ );
102        $this->resetVirtualDomain();
103
104        if ( $resultPageSet === null ) {
105            $count = 0;
106            foreach ( $res as $row ) {
107                if ( ++$count > $params['limit'] ) {
108                    // We've reached the one extra which shows that
109                    // there are additional pages to be had. Stop here...
110                    $this->setContinueEnumParameter( 'continue', $row->il_from . '|' . $row->lt_title );
111                    break;
112                }
113                $vals = [];
114                ApiQueryBase::addTitleInfo( $vals, Title::makeTitle( NS_FILE, $row->lt_title ) );
115                $fit = $this->addPageSubItem( $row->il_from, $vals );
116                if ( !$fit ) {
117                    $this->setContinueEnumParameter( 'continue', $row->il_from . '|' . $row->lt_title );
118                    break;
119                }
120            }
121        } else {
122            $titles = [];
123            $count = 0;
124            foreach ( $res as $row ) {
125                if ( ++$count > $params['limit'] ) {
126                    // We've reached the one extra which shows that
127                    // there are additional pages to be had. Stop here...
128                    $this->setContinueEnumParameter( 'continue', $row->il_from . '|' . $row->lt_title );
129                    break;
130                }
131                $titles[] = Title::makeTitle( NS_FILE, $row->lt_title );
132            }
133            $resultPageSet->populateFromTitles( $titles );
134        }
135    }
136
137    /** @inheritDoc */
138    public function getCacheMode( $params ) {
139        return 'public';
140    }
141
142    /** @inheritDoc */
143    public function getAllowedParams() {
144        return [
145            'limit' => [
146                ParamValidator::PARAM_DEFAULT => 10,
147                ParamValidator::PARAM_TYPE => 'limit',
148                IntegerDef::PARAM_MIN => 1,
149                IntegerDef::PARAM_MAX => ApiBase::LIMIT_BIG1,
150                IntegerDef::PARAM_MAX2 => ApiBase::LIMIT_BIG2
151            ],
152            'continue' => [
153                ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
154            ],
155            'images' => [
156                ParamValidator::PARAM_ISMULTI => true,
157            ],
158            'dir' => [
159                ParamValidator::PARAM_DEFAULT => 'ascending',
160                ParamValidator::PARAM_TYPE => [
161                    'ascending',
162                    'descending'
163                ]
164            ],
165        ];
166    }
167
168    /** @inheritDoc */
169    protected function getExamplesMessages() {
170        $title = Title::newMainPage()->getPrefixedText();
171        $mp = rawurlencode( $title );
172
173        return [
174            "action=query&prop=images&titles={$mp}"
175                => 'apihelp-query+images-example-simple',
176            "action=query&generator=images&titles={$mp}&prop=info"
177                => 'apihelp-query+images-example-generator',
178        ];
179    }
180
181    /** @inheritDoc */
182    public function getHelpUrls() {
183        return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Images';
184    }
185}
186
187/** @deprecated class alias since 1.43 */
188class_alias( ApiQueryImages::class, 'ApiQueryImages' );