MediaWiki  1.34.0
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' ],
238  ApiBase::PARAM_ISMULTI => true,
239  ApiBase::PARAM_DFLT => 'thumbnail|name',
240  ],
241  'thumbsize' => [
242  ApiBase::PARAM_TYPE => 'integer',
243  ApiBase::PARAM_DFLT => 50,
244  ],
245  'limit' => [
246  ApiBase::PARAM_DFLT => 50,
247  ApiBase::PARAM_TYPE => 'limit',
248  ApiBase::PARAM_MIN => 1,
249  ApiBase::PARAM_MAX => 50,
250  ApiBase::PARAM_MAX2 => 100,
251  ],
252  'license' => [
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 }
ApiQueryPageImages\setResultValues
setResultValues(array $prop, $pageId, $fileName, $size)
For a given page, set API return values for thumbnail and pageimage as needed.
Definition: ApiQueryPageImages.php:191
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:63
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:316
ApiQueryBase\addFields
addFields( $value)
Add a set of fields to select to the internal array.
Definition: ApiQueryBase.php:193
ApiQuery
This is the main query class.
Definition: ApiQuery.php:37
ApiQueryPageImages\getExamplesMessages
getExamplesMessages()
Returns usage examples for this module.Return value has query strings as keys, with values being eith...
Definition: ApiQueryPageImages.php:267
ApiQueryPageImages\getAllowedParams
getAllowedParams()
Return an array describing all possible parameters to this module.
Definition: ApiQueryPageImages.php:234
ApiBase\dieWithError
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition: ApiBase.php:2014
ApiBase\PARAM_HELP_MSG
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition: ApiBase.php:131
ApiQueryPageImages\__construct
__construct(ApiQuery $query, $moduleName)
Definition: ApiQueryPageImages.php:30
ApiBase\PARAM_TYPE
const PARAM_TYPE
(string|string[]) Either an array of allowed value strings, or a string type as described below.
Definition: ApiBase.php:94
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:640
NS_FILE
const NS_FILE
Definition: Defines.php:66
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
$res
$res
Definition: testCompression.php:52
ApiQueryPageImages\PARAM_LICENSE_ANY
const PARAM_LICENSE_ANY
@const API parameter value for images with any type of license
Definition: ApiQueryPageImages.php:24
ApiBase\PARAM_MIN
const PARAM_MIN
(integer) Lowest value allowed for the parameter, for PARAM_TYPE 'integer' and 'limit'.
Definition: ApiBase.php:106
ApiQueryPageImages
Expose image information for a page via a new prop=pageimages API.
Definition: ApiQueryPageImages.php:14
ApiQueryPageImages\getCacheMode
getCacheMode( $params)
Get the cache mode for the data generated by this module.
Definition: ApiQueryPageImages.php:179
ApiQueryBase
This is a base class for all Query modules.
Definition: ApiQueryBase.php:34
PROTO_CURRENT
const PROTO_CURRENT
Definition: Defines.php:202
ApiBase\PARAM_MAX
const PARAM_MAX
(integer) Max value allowed for the parameter, for PARAM_TYPE 'integer' and 'limit'.
Definition: ApiBase.php:97
ApiQueryBase\addTables
addTables( $tables, $alias=null)
Add a set of tables to the internal array.
Definition: ApiQueryBase.php:161
ApiQueryBase\select
select( $method, $extraQuery=[], array &$hookData=null)
Execute a SELECT query based on the values in the internal arrays.
Definition: ApiQueryBase.php:375
ApiBase\extractRequestParams
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:761
$title
$title
Definition: testCompression.php:34
ApiBase\dieContinueUsageIf
dieContinueUsageIf( $condition)
Die with the 'badcontinue' error.
Definition: ApiBase.php:2208
ApiBase\encodeParamName
encodeParamName( $paramName)
This method mangles parameter name based on the prefix supplied to the constructor.
Definition: ApiBase.php:739
ApiQueryBase\getPageSet
getPageSet()
Get the PageSet object to work on.
Definition: ApiQueryBase.php:132
ApiQueryPageImages\getTitles
getTitles()
Gets the set of titles to get page images for.
Definition: ApiQueryPageImages.php:46
wfFindFile
wfFindFile( $title, $options=[])
Find a file.
Definition: GlobalFunctions.php:2604
PageImages\getPropName
static getPropName( $isFree)
Get property name used in page_props table.
Definition: PageImages.php:38
ApiBase\PARAM_DFLT
const PARAM_DFLT
(null|boolean|integer|string) Default value of the parameter.
Definition: ApiBase.php:55
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
(boolean) Accept multiple pipe-separated values for this parameter (e.g.
Definition: ApiBase.php:58
ApiBase\PARAM_MAX2
const PARAM_MAX2
(integer) Max value allowed for the parameter for users with the apihighlimits right,...
Definition: ApiBase.php:103
ApiQueryBase\addWhere
addWhere( $value)
Add a set of WHERE clauses to the internal array.
Definition: ApiQueryBase.php:228
ApiQueryBase\setContinueEnumParameter
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
Definition: ApiQueryBase.php:492
ApiQueryPageImages\getPropNames
static getPropNames( $license)
Get property names used in page_props table.
Definition: ApiQueryPageImages.php:166
ApiQueryPageImages\PARAM_LICENSE_FREE
const PARAM_LICENSE_FREE
@const API parameter value for free images
Definition: ApiQueryPageImages.php:19
ApiQueryPageImages\execute
execute()
Evaluates the parameters, performs the requested retrieval of page images, and sets up the result.
Definition: ApiQueryPageImages.php:76
wfExpandUrl
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
Definition: GlobalFunctions.php:491
ApiQueryPageImages\getHelpUrls
getHelpUrls()
Definition: ApiQueryPageImages.php:278