MediaWiki REL1_34
ApiQueryPageImages.php
Go to the documentation of this file.
1<?php
2
15
19 const PARAM_LICENSE_FREE = 'free';
20
24 const PARAM_LICENSE_ANY = 'any';
25
30 public function __construct( ApiQuery $query, $moduleName ) {
31 parent::__construct( $query, $moduleName, 'pi' );
32 }
33
46 protected function getTitles() {
47 $pageSet = $this->getPageSet();
48 $titles = $pageSet->getGoodTitles();
49
50 // T98791: We want foreign files to be treated like local files
51 // in #execute, so include the set of missing filespace pages,
52 // which were initially rejected in ApiPageSet#execute.
53 $missingTitles = $pageSet->getMissingTitlesByNamespace();
54 $missingFileTitles = $missingTitles[NS_FILE] ?? [];
55
56 // $titles is a map of ID to title object, which is ideal,
57 // whereas $missingFileTitles is a map of title text to ID.
58 $missingFileTitles = array_map( function ( $text ) {
59 return Title::newFromText( $text, NS_FILE );
60 }, array_flip( $missingFileTitles ) );
61
62 // N.B. We can't use array_merge here as it doesn't preserve
63 // keys.
64 foreach ( $missingFileTitles as $id => $title ) {
65 $titles[$id] = $title;
66 }
67
68 return $titles;
69 }
70
76 public function execute() {
77 $params = $this->extractRequestParams();
78 $prop = array_flip( $params['prop'] );
79 if ( !count( $prop ) ) {
80 $this->dieWithError(
81 [ 'apierror-paramempty', $this->encodeParamName( 'prop' ) ], 'noprop'
82 );
83 }
84
85 $allTitles = $this->getTitles();
86
87 if ( count( $allTitles ) === 0 ) {
88 return;
89 }
90
91 // Find the offset based on the continue param
92 $offset = 0;
93 if ( isset( $params['continue'] ) ) {
94 // Get the position (not the key) of the 'continue' page within the
95 // array of titles. Set this as the offset.
96 $pageIds = array_keys( $allTitles );
97 $offset = array_search( intval( $params['continue'] ), $pageIds );
98 // If the 'continue' page wasn't found, die with error
99 $this->dieContinueUsageIf( !$offset );
100 }
101
102 $limit = $params['limit'];
103 // Slice the part of the array we want to find images for
104 $titles = array_slice( $allTitles, $offset, $limit, true );
105
106 // Get the next item in the title array and use it to set the continue value
107 $nextItemArray = array_slice( $allTitles, $offset + $limit, 1, true );
108 if ( $nextItemArray ) {
109 $this->setContinueEnumParameter( 'continue', key( $nextItemArray ) );
110 }
111
112 // Find any titles in the file namespace so we can handle those separately
113 $filePageTitles = [];
114 foreach ( $titles as $id => $title ) {
115 if ( $title->inNamespace( NS_FILE ) ) {
116 $filePageTitles[$id] = $title;
117 unset( $titles[$id] );
118 }
119 }
120
121 $size = $params['thumbsize'];
122 // Extract page images from the page_props table
123 if ( count( $titles ) > 0 ) {
124 $this->addTables( 'page_props' );
125 $this->addFields( [ 'pp_page', 'pp_propname', 'pp_value' ] );
126 $this->addWhere( [ 'pp_page' => array_keys( $titles ),
127 'pp_propname' => self::getPropNames( $params['license'] ) ] );
128
129 $res = $this->select( __METHOD__ );
130
131 $buffer = [];
132 $propNameAny = PageImages::getPropName( false );
133 foreach ( $res as $row ) {
134 $pageId = $row->pp_page;
135 if ( !array_key_exists( $pageId, $buffer ) || $row->pp_propname === $propNameAny ) {
136 $buffer[$pageId] = $row;
137 }
138 }
139
140 foreach ( $buffer as $pageId => $row ) {
141 $fileName = $row->pp_value;
142 $this->setResultValues( $prop, $pageId, $fileName, $size );
143 }
144 // End page props image extraction
145 }
146
147 // Extract images from file namespace pages. In this case we just use
148 // the file itself rather than searching for a page_image. (Bug 50252)
149 foreach ( $filePageTitles as $pageId => $title ) {
150 $fileName = $title->getDBkey();
151 $this->setResultValues( $prop, $pageId, $fileName, $size );
152 }
153 }
154
166 protected static function getPropNames( $license ) {
167 if ( $license === self::PARAM_LICENSE_FREE ) {
168 return PageImages::getPropName( true );
169 }
170 return [ PageImages::getPropName( true ), PageImages::getPropName( false ) ];
171 }
172
179 public function getCacheMode( $params ) {
180 return 'public';
181 }
182
191 protected function setResultValues( array $prop, $pageId, $fileName, $size ) {
192 $vals = [];
193 if ( isset( $prop['thumbnail'] ) || isset( $prop['original'] ) ) {
194 $file = wfFindFile( $fileName );
195 if ( $file ) {
196 if ( isset( $prop['thumbnail'] ) ) {
197 $thumb = $file->transform( [ 'width' => $size, 'height' => $size ] );
198 if ( $thumb && $thumb->getUrl() ) {
199 // You can request a thumb 1000x larger than the original
200 // which (in case of bitmap original) will return a Thumb object
201 // that will lie about its size but have the original as an image.
202 $reportedSize = $thumb->fileIsSource() ? $file : $thumb;
203 $vals['thumbnail'] = [
204 'source' => wfExpandUrl( $thumb->getUrl(), PROTO_CURRENT ),
205 'width' => $reportedSize->getWidth(),
206 'height' => $reportedSize->getHeight(),
207 ];
208 }
209 }
210
211 if ( isset( $prop['original'] ) ) {
212 $original_url = wfExpandUrl( $file->getUrl(), PROTO_CURRENT );
213
214 $vals['original'] = [
215 'source' => $original_url,
216 'width' => $file->getWidth(),
217 'height' => $file->getHeight()
218 ];
219 }
220 }
221 }
222
223 if ( isset( $prop['name'] ) ) {
224 $vals['pageimage'] = $fileName;
225 }
226
227 $this->getResult()->addValue( [ 'query', 'pages' ], $pageId, $vals );
228 }
229
234 public function getAllowedParams() {
235 return [
236 'prop' => [
237 ApiBase::PARAM_TYPE => [ 'thumbnail', 'name', 'original' ],
239 ApiBase::PARAM_DFLT => 'thumbnail|name',
240 ],
241 'thumbsize' => [
242 ApiBase::PARAM_TYPE => 'integer',
244 ],
245 'limit' => [
247 ApiBase::PARAM_TYPE => 'limit',
249 ApiBase::PARAM_MAX => 50,
250 ApiBase::PARAM_MAX2 => 100,
251 ],
252 'license' => [
253 ApiBase::PARAM_TYPE => [ self::PARAM_LICENSE_FREE, self::PARAM_LICENSE_ANY ],
254 ApiBase::PARAM_ISMULTI => false,
255 ApiBase::PARAM_DFLT => $this->getConfig()->get( 'PageImagesAPIDefaultLicense' ),
256 ],
257 'continue' => [
258 ApiBase::PARAM_TYPE => 'integer',
259 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
260 ],
261 ];
262 }
263
267 protected function getExamplesMessages() {
268 return [
269 'action=query&prop=pageimages&titles=Albert%20Einstein&pithumbsize=100' =>
270 'apihelp-query+pageimages-example-1',
271 ];
272 }
273
278 public function getHelpUrls() {
279 return "https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:PageImages#API";
280 }
281
282}
addWhere( $conds)
addFields( $fields)
addTables( $tables, $alias=null)
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfFindFile( $title, $options=[])
Find a file.
const PARAM_MAX2
(integer) Max value allowed for the parameter for users with the apihighlimits right,...
Definition ApiBase.php:103
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition ApiBase.php:739
const PARAM_MAX
(integer) Max value allowed for the parameter, for PARAM_TYPE 'integer' and 'limit'.
Definition ApiBase.php:97
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition ApiBase.php:2014
dieContinueUsageIf( $condition)
Die with the 'badcontinue' error.
Definition ApiBase.php:2208
const PARAM_TYPE
(string|string[]) Either an array of allowed value strings, or a string type as described below.
Definition ApiBase.php:94
const PARAM_DFLT
(null|boolean|integer|string) Default value of the parameter.
Definition ApiBase.php:55
const PARAM_MIN
(integer) Lowest value allowed for the parameter, for PARAM_TYPE 'integer' and 'limit'.
Definition ApiBase.php:106
getResult()
Get the result object.
Definition ApiBase.php:640
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:761
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:131
const PARAM_ISMULTI
(boolean) Accept multiple pipe-separated values for this parameter (e.g.
Definition ApiBase.php:58
This is a base class for all Query modules.
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
select( $method, $extraQuery=[], array &$hookData=null)
Execute a SELECT query based on the values in the internal arrays.
getPageSet()
Get the PageSet object to work on.
Expose image information for a page via a new prop=pageimages API.
__construct(ApiQuery $query, $moduleName)
getExamplesMessages()
Returns usage examples for this module.Return value has query strings as keys, with values being eith...
const PARAM_LICENSE_ANY
@const API parameter value for images with any type of license
const PARAM_LICENSE_FREE
@const API parameter value for free images
execute()
Evaluates the parameters, performs the requested retrieval of page images, and sets up the result.
static getPropNames( $license)
Get property names used in page_props table.
getCacheMode( $params)
Get the cache mode for the data generated by this module.
setResultValues(array $prop, $pageId, $fileName, $size)
For a given page, set API return values for thumbnail and pageimage as needed.
getTitles()
Gets the set of titles to get page images for.
getAllowedParams()
Return an array describing all possible parameters to this module.
This is the main query class.
Definition ApiQuery.php:37
const NS_FILE
Definition Defines.php:75
const PROTO_CURRENT
Definition Defines.php:211
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42