MediaWiki fundraising/REL1_35
ApiQueryImageInfo.php
Go to the documentation of this file.
1<?php
24
31 public const TRANSFORM_LIMIT = 50;
32 private static $transformCount = 0;
33
34 public function __construct( ApiQuery $query, $moduleName, $prefix = 'ii' ) {
35 // We allow a subclass to override the prefix, to create a related API
36 // module. Some other parts of MediaWiki construct this with a null
37 // $prefix, which used to be ignored when this only took two arguments
38 if ( $prefix === null ) {
39 $prefix = 'ii';
40 }
41 parent::__construct( $query, $moduleName, $prefix );
42 }
43
44 public function execute() {
45 $params = $this->extractRequestParams();
46
47 $prop = array_flip( $params['prop'] );
48
49 $scale = $this->getScale( $params );
50
51 $opts = [
52 'version' => $params['metadataversion'],
53 'language' => $params['extmetadatalanguage'],
54 'multilang' => $params['extmetadatamultilang'],
55 'extmetadatafilter' => $params['extmetadatafilter'],
56 'revdelUser' => $this->getUser(),
57 ];
58
59 if ( isset( $params['badfilecontexttitle'] ) ) {
60 $badFileContextTitle = Title::newFromText( $params['badfilecontexttitle'] );
61 if ( !$badFileContextTitle ) {
62 $p = $this->getModulePrefix();
63 $this->dieWithError( [ 'apierror-bad-badfilecontexttitle', $p ], 'invalid-title' );
64 }
65 } else {
66 $badFileContextTitle = null;
67 }
68
69 $pageIds = $this->getPageSet()->getGoodAndMissingTitlesByNamespace();
70 if ( !empty( $pageIds[NS_FILE] ) ) {
71 $titles = array_keys( $pageIds[NS_FILE] );
72 asort( $titles ); // Ensure the order is always the same
73
74 $fromTitle = null;
75 if ( $params['continue'] !== null ) {
76 $cont = explode( '|', $params['continue'] );
77 $this->dieContinueUsageIf( count( $cont ) != 2 );
78 $fromTitle = strval( $cont[0] );
79 $fromTimestamp = $cont[1];
80 // Filter out any titles before $fromTitle
81 foreach ( $titles as $key => $title ) {
82 if ( $title < $fromTitle ) {
83 unset( $titles[$key] );
84 } else {
85 break;
86 }
87 }
88 }
89
90 $user = $this->getUser();
91 $findTitles = array_map( function ( $title ) use ( $user ) {
92 return [
93 'title' => $title,
94 'private' => $user,
95 ];
96 }, $titles );
97
98 $services = MediaWikiServices::getInstance();
99 $repoGroup = $services->getRepoGroup();
100 if ( $params['localonly'] ) {
101 $images = $repoGroup->getLocalRepo()->findFiles( $findTitles );
102 } else {
103 $images = $repoGroup->findFiles( $findTitles );
104 }
105
106 $result = $this->getResult();
107 foreach ( $titles as $title ) {
108 $info = [];
109 $pageId = $pageIds[NS_FILE][$title];
110 $start = $title === $fromTitle ? $fromTimestamp : $params['start'];
111
112 if ( !isset( $images[$title] ) ) {
113 if ( isset( $prop['uploadwarning'] ) || isset( $prop['badfile'] ) ) {
114 // uploadwarning and badfile need info about non-existing files
115 $images[$title] = $repoGroup->getLocalRepo()->newFile( $title );
116 // Doesn't exist, so set an empty image repository
117 $info['imagerepository'] = '';
118 } else {
119 $result->addValue(
120 [ 'query', 'pages', (int)$pageId ],
121 'imagerepository', ''
122 );
123 // The above can't fail because it doesn't increase the result size
124 continue;
125 }
126 }
127
129 $img = $images[$title];
130
131 if ( self::getTransformCount() >= self::TRANSFORM_LIMIT ) {
132 if ( count( $pageIds[NS_FILE] ) == 1 ) {
133 // See the 'the user is screwed' comment below
134 $this->setContinueEnumParameter( 'start',
135 $start ?? wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
136 );
137 } else {
138 $this->setContinueEnumParameter( 'continue',
139 $this->getContinueStr( $img, $start ) );
140 }
141 break;
142 }
143
144 if ( !isset( $info['imagerepository'] ) ) {
145 $info['imagerepository'] = $img->getRepoName();
146 }
147 if ( isset( $prop['badfile'] ) ) {
148 $info['badfile'] = (bool)$services->getBadFileLookup()
149 ->isBadFile( $title, $badFileContextTitle );
150 }
151
152 $fit = $result->addValue( [ 'query', 'pages' ], (int)$pageId, $info );
153 if ( !$fit ) {
154 if ( count( $pageIds[NS_FILE] ) == 1 ) {
155 // The user is screwed. imageinfo can't be solely
156 // responsible for exceeding the limit in this case,
157 // so set a query-continue that just returns the same
158 // thing again. When the violating queries have been
159 // out-continued, the result will get through
160 $this->setContinueEnumParameter( 'start',
161 $start ?? wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
162 );
163 } else {
164 $this->setContinueEnumParameter( 'continue',
165 $this->getContinueStr( $img, $start ) );
166 }
167 break;
168 }
169
170 // Check if we can make the requested thumbnail, and get transform parameters.
171 $finalThumbParams = $this->mergeThumbParams( $img, $scale, $params['urlparam'] );
172
173 // Get information about the current version first
174 // Check that the current version is within the start-end boundaries
175 $gotOne = false;
176 if (
177 ( $start === null || $img->getTimestamp() <= $start ) &&
178 ( $params['end'] === null || $img->getTimestamp() >= $params['end'] )
179 ) {
180 $gotOne = true;
181
182 $fit = $this->addPageSubItem( $pageId,
183 static::getInfo( $img, $prop, $result,
184 $finalThumbParams, $opts
185 )
186 );
187 if ( !$fit ) {
188 if ( count( $pageIds[NS_FILE] ) == 1 ) {
189 // See the 'the user is screwed' comment above
190 $this->setContinueEnumParameter( 'start',
191 wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) );
192 } else {
193 $this->setContinueEnumParameter( 'continue',
194 $this->getContinueStr( $img ) );
195 }
196 break;
197 }
198 }
199
200 // Now get the old revisions
201 // Get one more to facilitate query-continue functionality
202 $count = ( $gotOne ? 1 : 0 );
203 $oldies = $img->getHistory( $params['limit'] - $count + 1, $start, $params['end'] );
205 foreach ( $oldies as $oldie ) {
206 if ( ++$count > $params['limit'] ) {
207 // We've reached the extra one which shows that there are
208 // additional pages to be had. Stop here...
209 // Only set a query-continue if there was only one title
210 if ( count( $pageIds[NS_FILE] ) == 1 ) {
211 $this->setContinueEnumParameter( 'start',
212 wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
213 }
214 break;
215 }
216 $fit = self::getTransformCount() < self::TRANSFORM_LIMIT &&
217 $this->addPageSubItem( $pageId,
218 static::getInfo( $oldie, $prop, $result,
219 $finalThumbParams, $opts
220 )
221 );
222 if ( !$fit ) {
223 if ( count( $pageIds[NS_FILE] ) == 1 ) {
224 $this->setContinueEnumParameter( 'start',
225 wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
226 } else {
227 $this->setContinueEnumParameter( 'continue',
228 $this->getContinueStr( $oldie ) );
229 }
230 break;
231 }
232 }
233 if ( !$fit ) {
234 break;
235 }
236 }
237 }
238 }
239
245 public function getScale( $params ) {
246 if ( $params['urlwidth'] != -1 ) {
247 $scale = [];
248 $scale['width'] = $params['urlwidth'];
249 $scale['height'] = $params['urlheight'];
250 } elseif ( $params['urlheight'] != -1 ) {
251 // Height is specified but width isn't
252 // Don't set $scale['width']; this signals mergeThumbParams() to fill it with the image's width
253 $scale = [];
254 $scale['height'] = $params['urlheight'];
255 } elseif ( $params['urlparam'] ) {
256 // Audio files might not have a width/height.
257 $scale = [];
258 } else {
259 $scale = null;
260 }
261
262 return $scale;
263 }
264
274 protected function mergeThumbParams( $image, $thumbParams, $otherParams ) {
275 if ( $thumbParams === null ) {
276 // No scaling requested
277 return null;
278 }
279 if ( !isset( $thumbParams['width'] ) && isset( $thumbParams['height'] ) ) {
280 // We want to limit only by height in this situation, so pass the
281 // image's full width as the limiting width. But some file types
282 // don't have a width of their own, so pick something arbitrary so
283 // thumbnailing the default icon works.
284 if ( $image->getWidth() <= 0 ) {
285 $thumbParams['width'] = max( $this->getConfig()->get( 'ThumbLimits' ) );
286 } else {
287 $thumbParams['width'] = $image->getWidth();
288 }
289 }
290
291 if ( !$otherParams ) {
292 $this->checkParameterNormalise( $image, $thumbParams );
293 return $thumbParams;
294 }
295 $p = $this->getModulePrefix();
296
297 $h = $image->getHandler();
298 if ( !$h ) {
299 $this->addWarning( [ 'apiwarn-nothumb-noimagehandler', wfEscapeWikiText( $image->getName() ) ] );
300
301 return $thumbParams;
302 }
303
304 $paramList = $h->parseParamString( $otherParams );
305 if ( !$paramList ) {
306 // Just set a warning (instead of dieWithError), as in many cases
307 // we could still render the image using width and height parameters,
308 // and this type of thing could happen between different versions of
309 // handlers.
310 $this->addWarning( [ 'apiwarn-badurlparam', $p, wfEscapeWikiText( $image->getName() ) ] );
311 $this->checkParameterNormalise( $image, $thumbParams );
312 return $thumbParams;
313 }
314
315 if ( isset( $paramList['width'] ) && isset( $thumbParams['width'] ) ) {
316 if ( (int)$paramList['width'] != (int)$thumbParams['width'] ) {
317 $this->addWarning(
318 [ 'apiwarn-urlparamwidth', $p, $paramList['width'], $thumbParams['width'] ]
319 );
320 }
321 }
322
323 foreach ( $paramList as $name => $value ) {
324 if ( !$h->validateParam( $name, $value ) ) {
325 $this->dieWithError(
326 [ 'apierror-invalidurlparam', $p, wfEscapeWikiText( $name ), wfEscapeWikiText( $value ) ]
327 );
328 }
329 }
330
331 $finalParams = $thumbParams + $paramList;
332 $this->checkParameterNormalise( $image, $finalParams );
333 return $finalParams;
334 }
335
347 protected function checkParameterNormalise( $image, $finalParams ) {
348 $h = $image->getHandler();
349 if ( !$h ) {
350 return;
351 }
352 // Note: normaliseParams modifies the array in place, but we aren't interested
353 // in the actual normalised version, only if we can actually normalise them,
354 // so we use the functions scope to throw away the normalisations.
355 if ( !$h->normaliseParams( $image, $finalParams ) ) {
356 $this->dieWithError( [ 'apierror-urlparamnormal', wfEscapeWikiText( $image->getName() ) ] );
357 }
358 }
359
375 public static function getInfo( $file, $prop, $result, $thumbParams = null, $opts = false ) {
376 $anyHidden = false;
377
378 if ( !$opts || is_string( $opts ) ) {
379 $opts = [
380 'version' => $opts ?: 'latest',
381 'language' => MediaWikiServices::getInstance()->getContentLanguage(),
382 'multilang' => false,
383 'extmetadatafilter' => [],
384 'revdelUser' => null,
385 ];
386 }
387 $version = $opts['version'];
388 $vals = [
389 ApiResult::META_TYPE => 'assoc',
390 ];
391
392 // Some information will be unavailable if the file does not exist. T221812
393 $exists = $file->exists();
394
395 // Timestamp is shown even if the file is revdelete'd in interface
396 // so do same here.
397 if ( isset( $prop['timestamp'] ) && $exists ) {
398 $vals['timestamp'] = wfTimestamp( TS_ISO_8601, $file->getTimestamp() );
399 }
400
401 // Handle external callers who don't pass revdelUser
402 if ( isset( $opts['revdelUser'] ) && $opts['revdelUser'] ) {
403 $revdelUser = $opts['revdelUser'];
404 $canShowField = function ( $field ) use ( $file, $revdelUser ) {
405 return $file->userCan( $field, $revdelUser );
406 };
407 } else {
408 $canShowField = function ( $field ) use ( $file ) {
409 return !$file->isDeleted( $field );
410 };
411 }
412
413 $user = isset( $prop['user'] );
414 $userid = isset( $prop['userid'] );
415
416 if ( ( $user || $userid ) && $exists ) {
417 if ( $file->isDeleted( File::DELETED_USER ) ) {
418 $vals['userhidden'] = true;
419 $anyHidden = true;
420 }
421 if ( $canShowField( File::DELETED_USER ) ) {
422 if ( $user ) {
423 $vals['user'] = $file->getUser();
424 }
425 if ( $userid ) {
426 $vals['userid'] = $file->getUser( 'id' );
427 }
428 if ( !$file->getUser( 'id' ) ) {
429 $vals['anon'] = true;
430 }
431 }
432 }
433
434 // This is shown even if the file is revdelete'd in interface
435 // so do same here.
436 if ( ( isset( $prop['size'] ) || isset( $prop['dimensions'] ) ) && $exists ) {
437 $vals['size'] = (int)$file->getSize();
438 $vals['width'] = (int)$file->getWidth();
439 $vals['height'] = (int)$file->getHeight();
440
441 $pageCount = $file->pageCount();
442 if ( $pageCount !== false ) {
443 $vals['pagecount'] = $pageCount;
444 }
445
446 // length as in how many seconds long a video is.
447 $length = $file->getLength();
448 if ( $length ) {
449 // Call it duration, because "length" can be ambiguous.
450 $vals['duration'] = (float)$length;
451 }
452 }
453
454 $pcomment = isset( $prop['parsedcomment'] );
455 $comment = isset( $prop['comment'] );
456
457 if ( ( $pcomment || $comment ) && $exists ) {
458 if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
459 $vals['commenthidden'] = true;
460 $anyHidden = true;
461 }
462 if ( $canShowField( File::DELETED_COMMENT ) ) {
463 if ( $pcomment ) {
464 $vals['parsedcomment'] = Linker::formatComment(
465 $file->getDescription( File::RAW ), $file->getTitle() );
466 }
467 if ( $comment ) {
468 $vals['comment'] = $file->getDescription( File::RAW );
469 }
470 }
471 }
472
473 $canonicaltitle = isset( $prop['canonicaltitle'] );
474 $url = isset( $prop['url'] );
475 $sha1 = isset( $prop['sha1'] );
476 $meta = isset( $prop['metadata'] );
477 $extmetadata = isset( $prop['extmetadata'] );
478 $commonmeta = isset( $prop['commonmetadata'] );
479 $mime = isset( $prop['mime'] );
480 $mediatype = isset( $prop['mediatype'] );
481 $archive = isset( $prop['archivename'] );
482 $bitdepth = isset( $prop['bitdepth'] );
483 $uploadwarning = isset( $prop['uploadwarning'] );
484
485 if ( $uploadwarning ) {
486 $vals['html'] = SpecialUpload::getExistsWarning( UploadBase::getExistsWarning( $file ) );
487 }
488
489 if ( $file->isDeleted( File::DELETED_FILE ) ) {
490 $vals['filehidden'] = true;
491 $anyHidden = true;
492 }
493
494 if ( $anyHidden && $file->isDeleted( File::DELETED_RESTRICTED ) ) {
495 $vals['suppressed'] = true;
496 }
497
498 if ( !$canShowField( File::DELETED_FILE ) ) {
499 // Early return, tidier than indenting all following things one level
500 return $vals;
501 }
502
503 if ( $canonicaltitle ) {
504 $vals['canonicaltitle'] = $file->getTitle()->getPrefixedText();
505 }
506
507 if ( $url ) {
508 if ( $exists ) {
509 if ( $thumbParams !== null ) {
510 $mto = $file->transform( $thumbParams );
511 self::$transformCount++;
512 if ( $mto && !$mto->isError() ) {
513 $vals['thumburl'] = wfExpandUrl( $mto->getUrl(), PROTO_CURRENT );
514
515 // T25834 - If the URLs are the same, we haven't resized it, so shouldn't give the wanted
516 // thumbnail sizes for the thumbnail actual size
517 if ( $mto->getUrl() !== $file->getUrl() ) {
518 $vals['thumbwidth'] = (int)$mto->getWidth();
519 $vals['thumbheight'] = (int)$mto->getHeight();
520 } else {
521 $vals['thumbwidth'] = (int)$file->getWidth();
522 $vals['thumbheight'] = (int)$file->getHeight();
523 }
524
525 if ( isset( $prop['thumbmime'] ) && $file->getHandler() ) {
526 list( , $mime ) = $file->getHandler()->getThumbType(
527 $mto->getExtension(), $file->getMimeType(), $thumbParams );
528 $vals['thumbmime'] = $mime;
529 }
530 } elseif ( $mto && $mto->isError() ) {
532 '@phan-var MediaTransformError $mto';
533 $vals['thumberror'] = $mto->toText();
534 }
535 }
536 $vals['url'] = wfExpandUrl( $file->getFullUrl(), PROTO_CURRENT );
537 }
538 $vals['descriptionurl'] = wfExpandUrl( $file->getDescriptionUrl(), PROTO_CURRENT );
539
540 $shortDescriptionUrl = $file->getDescriptionShortUrl();
541 if ( $shortDescriptionUrl !== null ) {
542 $vals['descriptionshorturl'] = wfExpandUrl( $shortDescriptionUrl, PROTO_CURRENT );
543 }
544 }
545
546 if ( !$exists ) {
547 $vals['filemissing'] = true;
548 }
549
550 if ( $sha1 && $exists ) {
551 $vals['sha1'] = Wikimedia\base_convert( $file->getSha1(), 36, 16, 40 );
552 }
553
554 if ( $meta && $exists ) {
555 Wikimedia\suppressWarnings();
556 $metadata = unserialize( $file->getMetadata() );
557 Wikimedia\restoreWarnings();
558 if ( $metadata && $version !== 'latest' ) {
559 $metadata = $file->convertMetadataVersion( $metadata, $version );
560 }
561 $vals['metadata'] = $metadata ? static::processMetaData( $metadata, $result ) : null;
562 }
563 if ( $commonmeta && $exists ) {
564 $metaArray = $file->getCommonMetaArray();
565 $vals['commonmetadata'] = $metaArray ? static::processMetaData( $metaArray, $result ) : [];
566 }
567
568 if ( $extmetadata && $exists ) {
569 // Note, this should return an array where all the keys
570 // start with a letter, and all the values are strings.
571 // Thus there should be no issue with format=xml.
572 $format = new FormatMetadata;
573 $format->setSingleLanguage( !$opts['multilang'] );
574 // @phan-suppress-next-line PhanUndeclaredMethod
575 $format->getContext()->setLanguage( $opts['language'] );
576 $extmetaArray = $format->fetchExtendedMetadata( $file );
577 if ( $opts['extmetadatafilter'] ) {
578 $extmetaArray = array_intersect_key(
579 $extmetaArray, array_flip( $opts['extmetadatafilter'] )
580 );
581 }
582 $vals['extmetadata'] = $extmetaArray;
583 }
584
585 if ( $mime && $exists ) {
586 $vals['mime'] = $file->getMimeType();
587 }
588
589 if ( $mediatype && $exists ) {
590 $vals['mediatype'] = $file->getMediaType();
591 }
592
593 if ( $archive && $file->isOld() ) {
595 '@phan-var OldLocalFile $file';
596 $vals['archivename'] = $file->getArchiveName();
597 }
598
599 if ( $bitdepth && $exists ) {
600 $vals['bitdepth'] = $file->getBitDepth();
601 }
602
603 return $vals;
604 }
605
613 protected static function getTransformCount() {
615 }
616
622 public static function processMetaData( $metadata, $result ) {
623 $retval = [];
624 if ( is_array( $metadata ) ) {
625 foreach ( $metadata as $key => $value ) {
626 $r = [
627 'name' => $key,
628 ApiResult::META_BC_BOOLS => [ 'value' ],
629 ];
630 if ( is_array( $value ) ) {
631 $r['value'] = static::processMetaData( $value, $result );
632 } else {
633 $r['value'] = $value;
634 }
635 $retval[] = $r;
636 }
637 }
638 ApiResult::setIndexedTagName( $retval, 'metadata' );
639
640 return $retval;
641 }
642
643 public function getCacheMode( $params ) {
644 if ( $this->userCanSeeRevDel() ) {
645 return 'private';
646 }
647
648 return 'public';
649 }
650
656 protected function getContinueStr( $img, $start = null ) {
657 if ( $start === null ) {
658 $start = $img->getTimestamp();
659 }
660
661 return $img->getOriginalTitle()->getDBkey() . '|' . $start;
662 }
663
664 public function getAllowedParams() {
665 return [
666 'prop' => [
668 ApiBase::PARAM_DFLT => 'timestamp|user',
669 ApiBase::PARAM_TYPE => static::getPropertyNames(),
670 ApiBase::PARAM_HELP_MSG_PER_VALUE => static::getPropertyMessages(),
671 ],
672 'limit' => [
673 ApiBase::PARAM_TYPE => 'limit',
678 ],
679 'start' => [
680 ApiBase::PARAM_TYPE => 'timestamp'
681 ],
682 'end' => [
683 ApiBase::PARAM_TYPE => 'timestamp'
684 ],
685 'urlwidth' => [
686 ApiBase::PARAM_TYPE => 'integer',
689 'apihelp-query+imageinfo-param-urlwidth',
691 ],
692 ],
693 'urlheight' => [
694 ApiBase::PARAM_TYPE => 'integer',
696 ],
697 'metadataversion' => [
698 ApiBase::PARAM_TYPE => 'string',
699 ApiBase::PARAM_DFLT => '1',
700 ],
701 'extmetadatalanguage' => [
702 ApiBase::PARAM_TYPE => 'string',
704 MediaWikiServices::getInstance()->getContentLanguage()->getCode(),
705 ],
706 'extmetadatamultilang' => [
707 ApiBase::PARAM_TYPE => 'boolean',
708 ApiBase::PARAM_DFLT => false,
709 ],
710 'extmetadatafilter' => [
711 ApiBase::PARAM_TYPE => 'string',
713 ],
714 'urlparam' => [
716 ApiBase::PARAM_TYPE => 'string',
717 ],
718 'badfilecontexttitle' => [
719 ApiBase::PARAM_TYPE => 'string',
720 ],
721 'continue' => [
722 ApiBase::PARAM_HELP_MSG => 'api-help-param-continue',
723 ],
724 'localonly' => false,
725 ];
726 }
727
734 public static function getPropertyNames( $filter = [] ) {
735 return array_keys( static::getPropertyMessages( $filter ) );
736 }
737
744 public static function getPropertyMessages( $filter = [] ) {
745 return array_diff_key(
746 [
747 'timestamp' => 'apihelp-query+imageinfo-paramvalue-prop-timestamp',
748 'user' => 'apihelp-query+imageinfo-paramvalue-prop-user',
749 'userid' => 'apihelp-query+imageinfo-paramvalue-prop-userid',
750 'comment' => 'apihelp-query+imageinfo-paramvalue-prop-comment',
751 'parsedcomment' => 'apihelp-query+imageinfo-paramvalue-prop-parsedcomment',
752 'canonicaltitle' => 'apihelp-query+imageinfo-paramvalue-prop-canonicaltitle',
753 'url' => 'apihelp-query+imageinfo-paramvalue-prop-url',
754 'size' => 'apihelp-query+imageinfo-paramvalue-prop-size',
755 'dimensions' => 'apihelp-query+imageinfo-paramvalue-prop-dimensions',
756 'sha1' => 'apihelp-query+imageinfo-paramvalue-prop-sha1',
757 'mime' => 'apihelp-query+imageinfo-paramvalue-prop-mime',
758 'thumbmime' => 'apihelp-query+imageinfo-paramvalue-prop-thumbmime',
759 'mediatype' => 'apihelp-query+imageinfo-paramvalue-prop-mediatype',
760 'metadata' => 'apihelp-query+imageinfo-paramvalue-prop-metadata',
761 'commonmetadata' => 'apihelp-query+imageinfo-paramvalue-prop-commonmetadata',
762 'extmetadata' => 'apihelp-query+imageinfo-paramvalue-prop-extmetadata',
763 'archivename' => 'apihelp-query+imageinfo-paramvalue-prop-archivename',
764 'bitdepth' => 'apihelp-query+imageinfo-paramvalue-prop-bitdepth',
765 'uploadwarning' => 'apihelp-query+imageinfo-paramvalue-prop-uploadwarning',
766 'badfile' => 'apihelp-query+imageinfo-paramvalue-prop-badfile',
767 ],
768 array_flip( $filter )
769 );
770 }
771
772 protected function getExamplesMessages() {
773 return [
774 'action=query&titles=File:Albert%20Einstein%20Head.jpg&prop=imageinfo'
775 => 'apihelp-query+imageinfo-example-simple',
776 'action=query&titles=File:Test.jpg&prop=imageinfo&iilimit=50&' .
777 'iiend=2007-12-31T23:59:59Z&iiprop=timestamp|user|url'
778 => 'apihelp-query+imageinfo-example-dated',
779 ];
780 }
781
782 public function getHelpUrls() {
783 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Imageinfo';
784 }
785}
unserialize( $serialized)
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1437
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
Definition ApiBase.php:507
const PARAM_MAX2
Definition ApiBase.php:86
const PARAM_MAX
Definition ApiBase.php:82
dieContinueUsageIf( $condition)
Die with the 'badcontinue' error.
Definition ApiBase.php:1617
const PARAM_TYPE
Definition ApiBase.php:78
const PARAM_DFLT
Definition ApiBase.php:70
const PARAM_HELP_MSG_PER_VALUE
((string|array|Message)[]) When PARAM_TYPE is an array, this is an array mapping those values to $msg...
Definition ApiBase.php:195
const PARAM_MIN
Definition ApiBase.php:90
const LIMIT_BIG1
Fast query, standard limit.
Definition ApiBase.php:220
getResult()
Get the result object.
Definition ApiBase.php:620
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:772
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
Definition ApiBase.php:162
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
Definition ApiBase.php:1356
const LIMIT_BIG2
Fast query, apihighlimits limit.
Definition ApiBase.php:222
const PARAM_ISMULTI
Definition ApiBase.php:74
This is a base class for all Query modules.
setContinueEnumParameter( $paramName, $paramValue)
Set a query-continue value.
addPageSubItem( $pageId, $item, $elemname=null)
Same as addPageSubItems(), but one element of $data at a time.
getPageSet()
Get the PageSet object to work on Stable to override.
userCanSeeRevDel()
Check whether the current user has permission to view revision-deleted fields.
A query action to get image information and upload history.
checkParameterNormalise( $image, $finalParams)
Verify that the final image parameters can be normalised.
mergeThumbParams( $image, $thumbParams, $otherParams)
Validate and merge scale parameters with handler thumb parameters, give error if invalid.
__construct(ApiQuery $query, $moduleName, $prefix='ii')
Stable to call.
getCacheMode( $params)
Get the cache mode for the data generated by this module.
getScale( $params)
From parameters, construct a 'scale' array.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
getHelpUrls()
Return links to more detailed help pages about the module.
static getPropertyNames( $filter=[])
Returns all possible parameters to iiprop.
execute()
Evaluates the parameters, performs the requested query, and sets up the result.
getContinueStr( $img, $start=null)
static getInfo( $file, $prop, $result, $thumbParams=null, $opts=false)
Get result information for an image revision.
static getTransformCount()
Get the count of image transformations performed.
static getPropertyMessages( $filter=[])
Returns messages for all possible parameters to iiprop.
static processMetaData( $metadata, $result)
getExamplesMessages()
Returns usage examples for this module.
This is the main query class.
Definition ApiQuery.php:37
getUser()
Stable to override.
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:63
Format Image metadata values into a human readable form.
setSingleLanguage( $val)
Trigger only outputting single language for multilanguage fields.
static formatComment( $comment, $title=null, $local=false, $wikiId=null)
This function is called by all recent changes variants, by the page history, and by the user contribu...
Definition Linker.php:1199
MediaWikiServices is the service locator for the application scope of MediaWiki.
const NS_FILE
Definition Defines.php:76
const PROTO_CURRENT
Definition Defines.php:212
$mime
Definition router.php:60
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42