55 $prefixOrRepoGroup =
null,
56 $repoGroupOrContentLanguage =
null,
57 $contentLanguageOrBadFileLookup =
null,
58 $badFileLookupOrUnused =
null
62 if ( !is_string( $prefixOrRepoGroup ) ) {
69 $prefix = $prefixOrRepoGroup;
74 parent::__construct( $query, $moduleName, $prefix );
76 $services = MediaWikiServices::getInstance();
77 $this->repoGroup =
$repoGroup ?? $services->getRepoGroup();
78 $this->contentLanguage =
$contentLanguage ?? $services->getContentLanguage();
79 $this->badFileLookup =
$badFileLookup ?? $services->getBadFileLookup();
85 $prop = array_fill_keys( $params[
'prop'],
true );
90 'version' => $params[
'metadataversion'],
91 'language' => $params[
'extmetadatalanguage'],
92 'multilang' => $params[
'extmetadatamultilang'],
93 'extmetadatafilter' => $params[
'extmetadatafilter'],
97 if ( isset( $params[
'badfilecontexttitle'] ) ) {
98 $badFileContextTitle = Title::newFromText( $params[
'badfilecontexttitle'] );
99 if ( !$badFileContextTitle ) {
101 $this->
dieWithError( [
'apierror-bad-badfilecontexttitle', $p ],
'invalid-title' );
104 $badFileContextTitle =
null;
107 $pageIds = $this->
getPageSet()->getGoodAndMissingTitlesByNamespace();
108 if ( !empty( $pageIds[
NS_FILE] ) ) {
109 $titles = array_keys( $pageIds[
NS_FILE] );
113 if ( $params[
'continue'] !==
null ) {
114 $cont = explode(
'|', $params[
'continue'] );
116 $fromTitle = strval( $cont[0] );
117 $fromTimestamp = $cont[1];
119 foreach ( $titles as $key =>
$title ) {
120 if (
$title < $fromTitle ) {
121 unset( $titles[$key] );
129 $findTitles = array_map(
static function (
$title ) use ( $performer ) {
132 'private' => $performer,
136 if ( $params[
'localonly'] ) {
137 $images = $this->repoGroup->getLocalRepo()->findFiles( $findTitles );
139 $images = $this->repoGroup->findFiles( $findTitles );
143 foreach ( $titles as
$title ) {
146 $start =
$title === $fromTitle ? $fromTimestamp : $params[
'start'];
148 if ( !isset( $images[
$title] ) ) {
149 if ( isset( $prop[
'uploadwarning'] ) || isset( $prop[
'badfile'] ) ) {
151 $images[
$title] = $this->repoGroup->getLocalRepo()->newFile(
$title );
153 $info[
'imagerepository'] =
'';
156 [
'query',
'pages', (
int)$pageId ],
157 'imagerepository',
''
167 if ( self::getTransformCount() >= self::TRANSFORM_LIMIT ) {
168 if ( count( $pageIds[
NS_FILE] ) == 1 ) {
171 $start ??
wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
180 if ( !isset( $info[
'imagerepository'] ) ) {
181 $info[
'imagerepository'] = $img->getRepoName();
183 if ( isset( $prop[
'badfile'] ) ) {
184 $info[
'badfile'] = (bool)$this->badFileLookup->isBadFile(
$title, $badFileContextTitle );
187 $fit = $result->addValue( [
'query',
'pages' ], (
int)$pageId, $info );
189 if ( count( $pageIds[
NS_FILE] ) == 1 ) {
196 $start ??
wfTimestamp( TS_ISO_8601, $img->getTimestamp() )
206 $finalThumbParams = $this->
mergeThumbParams( $img, $scale, $params[
'urlparam'] );
212 ( $start ===
null || $img->getTimestamp() <= $start ) &&
213 ( $params[
'end'] ===
null || $img->getTimestamp() >= $params[
'end'] )
218 static::getInfo( $img, $prop, $result,
219 $finalThumbParams, $opts
223 if ( count( $pageIds[
NS_FILE] ) == 1 ) {
226 wfTimestamp( TS_ISO_8601, $img->getTimestamp() ) );
237 $count = ( $gotOne ? 1 : 0 );
238 $oldies = $img->getHistory( $params[
'limit'] - $count + 1, $start, $params[
'end'] );
240 foreach ( $oldies as $oldie ) {
241 if ( ++$count > $params[
'limit'] ) {
245 if ( count( $pageIds[
NS_FILE] ) == 1 ) {
247 wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
253 static::getInfo( $oldie, $prop, $result,
254 $finalThumbParams, $opts
258 if ( count( $pageIds[
NS_FILE] ) == 1 ) {
260 wfTimestamp( TS_ISO_8601, $oldie->getTimestamp() ) );
281 if ( $params[
'urlwidth'] != -1 ) {
283 $scale[
'width'] = $params[
'urlwidth'];
284 $scale[
'height'] = $params[
'urlheight'];
285 } elseif ( $params[
'urlheight'] != -1 ) {
289 $scale[
'height'] = $params[
'urlheight'];
290 } elseif ( $params[
'urlparam'] ) {
310 if ( $thumbParams ===
null ) {
314 if ( !isset( $thumbParams[
'width'] ) && isset( $thumbParams[
'height'] ) ) {
319 if ( $image->getWidth() <= 0 ) {
320 $thumbParams[
'width'] = max( $this->
getConfig()->
get(
'ThumbLimits' ) );
322 $thumbParams[
'width'] = $image->getWidth();
326 if ( !$otherParams ) {
332 $h = $image->getHandler();
339 $paramList = $h->parseParamString( $otherParams );
350 if ( isset( $paramList[
'width'] ) && isset( $thumbParams[
'width'] ) ) {
351 if ( (
int)$paramList[
'width'] != (
int)$thumbParams[
'width'] ) {
353 [
'apiwarn-urlparamwidth', $p, $paramList[
'width'], $thumbParams[
'width'] ]
358 foreach ( $paramList as $name => $value ) {
359 if ( !$h->validateParam( $name, $value ) ) {
366 $finalParams = $thumbParams + $paramList;
383 $h = $image->getHandler();
390 if ( !$h->normaliseParams( $image, $finalParams ) ) {
410 public static function getInfo(
$file, $prop, $result, $thumbParams =
null, $opts =
false ) {
413 if ( !$opts || is_string( $opts ) ) {
415 'version' => $opts ?:
'latest',
416 'language' => MediaWikiServices::getInstance()->getContentLanguage(),
417 'multilang' =>
false,
418 'extmetadatafilter' => [],
419 'revdelUser' =>
null,
422 $version = $opts[
'version'];
424 ApiResult::META_TYPE =>
'assoc',
428 $exists =
$file->exists();
432 if ( isset( $prop[
'timestamp'] ) && $exists ) {
437 if ( isset( $opts[
'revdelUser'] ) && $opts[
'revdelUser'] ) {
438 $revdelUser = $opts[
'revdelUser'];
439 $canShowField =
static function ( $field ) use (
$file, $revdelUser ) {
440 return $file->userCan( $field, $revdelUser );
443 $canShowField =
static function ( $field ) use (
$file ) {
444 return !
$file->isDeleted( $field );
448 $user = isset( $prop[
'user'] );
449 $userid = isset( $prop[
'userid'] );
451 if ( ( $user || $userid ) && $exists ) {
452 if (
$file->isDeleted( File::DELETED_USER ) ) {
453 $vals[
'userhidden'] =
true;
456 if ( $canShowField( File::DELETED_USER ) ) {
458 $uploader =
$file->getUploader( File::RAW );
460 $vals[
'user'] = $uploader ? $uploader->getName() :
'';
463 $vals[
'userid'] = $uploader ? $uploader->getId() : 0;
465 if ( $uploader && !$uploader->isRegistered() ) {
466 $vals[
'anon'] =
true;
473 if ( ( isset( $prop[
'size'] ) || isset( $prop[
'dimensions'] ) ) && $exists ) {
474 $vals[
'size'] = (int)
$file->getSize();
475 $vals[
'width'] = (int)
$file->getWidth();
476 $vals[
'height'] = (int)
$file->getHeight();
478 $pageCount =
$file->pageCount();
479 if ( $pageCount !==
false ) {
480 $vals[
'pagecount'] = $pageCount;
484 $length =
$file->getLength();
487 $vals[
'duration'] = (float)$length;
491 $pcomment = isset( $prop[
'parsedcomment'] );
492 $comment = isset( $prop[
'comment'] );
494 if ( ( $pcomment || $comment ) && $exists ) {
495 if (
$file->isDeleted( File::DELETED_COMMENT ) ) {
496 $vals[
'commenthidden'] =
true;
499 if ( $canShowField( File::DELETED_COMMENT ) ) {
502 $file->getDescription( File::RAW ),
$file->getTitle() );
505 $vals[
'comment'] =
$file->getDescription( File::RAW );
510 $canonicaltitle = isset( $prop[
'canonicaltitle'] );
511 $url = isset( $prop[
'url'] );
512 $sha1 = isset( $prop[
'sha1'] );
513 $meta = isset( $prop[
'metadata'] );
514 $extmetadata = isset( $prop[
'extmetadata'] );
515 $commonmeta = isset( $prop[
'commonmetadata'] );
516 $mime = isset( $prop[
'mime'] );
517 $mediatype = isset( $prop[
'mediatype'] );
518 $archive = isset( $prop[
'archivename'] );
519 $bitdepth = isset( $prop[
'bitdepth'] );
520 $uploadwarning = isset( $prop[
'uploadwarning'] );
522 if ( $uploadwarning ) {
523 $vals[
'html'] = SpecialUpload::getExistsWarning( UploadBase::getExistsWarning(
$file ) );
526 if (
$file->isDeleted( File::DELETED_FILE ) ) {
527 $vals[
'filehidden'] =
true;
531 if ( $anyHidden &&
$file->isDeleted( File::DELETED_RESTRICTED ) ) {
532 $vals[
'suppressed'] =
true;
536 if ( isset( $opts[
'revdelUser'] ) && $opts[
'revdelUser']
537 && !
$file->userCan( File::DELETED_FILE, $opts[
'revdelUser'] )
540 } elseif (
$file->isDeleted( File::DELETED_FILE ) ) {
544 if ( $canonicaltitle ) {
545 $vals[
'canonicaltitle'] =
$file->getTitle()->getPrefixedText();
550 if ( $thumbParams !==
null ) {
551 $mto =
$file->transform( $thumbParams );
552 self::$transformCount++;
553 if ( $mto && !$mto->isError() ) {
558 if ( $mto->getUrl() !==
$file->getUrl() ) {
559 $vals[
'thumbwidth'] = (int)$mto->getWidth();
560 $vals[
'thumbheight'] = (int)$mto->getHeight();
562 $vals[
'thumbwidth'] = (int)
$file->getWidth();
563 $vals[
'thumbheight'] = (int)
$file->getHeight();
566 if ( isset( $prop[
'thumbmime'] ) &&
$file->getHandler() ) {
567 list( ,
$mime ) =
$file->getHandler()->getThumbType(
568 $mto->getExtension(),
$file->getMimeType(), $thumbParams );
569 $vals[
'thumbmime'] =
$mime;
573 'width' => $vals[
'thumbwidth'],
574 'height' => $vals[
'thumbheight']
576 foreach ( $mto->responsiveUrls as $density => $url ) {
579 } elseif ( $mto && $mto->isError() ) {
581 '@phan-var MediaTransformError $mto';
582 $vals[
'thumberror'] = $mto->toText();
589 $shortDescriptionUrl =
$file->getDescriptionShortUrl();
590 if ( $shortDescriptionUrl !==
null ) {
596 $vals[
'filemissing'] =
true;
599 if ( $sha1 && $exists ) {
600 $vals[
'sha1'] = Wikimedia\base_convert(
$file->getSha1(), 36, 16, 40 );
603 if ( $meta && $exists ) {
604 $metadata =
$file->getMetadataArray();
605 if ( $metadata && $version !==
'latest' ) {
606 $metadata =
$file->convertMetadataVersion( $metadata, $version );
608 $vals[
'metadata'] = $metadata ? static::processMetaData( $metadata, $result ) :
null;
610 if ( $commonmeta && $exists ) {
611 $metaArray =
$file->getCommonMetaArray();
612 $vals[
'commonmetadata'] = $metaArray ? static::processMetaData( $metaArray, $result ) : [];
615 if ( $extmetadata && $exists ) {
622 $format->getContext()->setLanguage( $opts[
'language'] );
623 $extmetaArray = $format->fetchExtendedMetadata(
$file );
624 if ( $opts[
'extmetadatafilter'] ) {
625 $extmetaArray = array_intersect_key(
626 $extmetaArray, array_fill_keys( $opts[
'extmetadatafilter'],
true )
629 $vals[
'extmetadata'] = $extmetaArray;
632 if (
$mime && $exists ) {
633 $vals[
'mime'] =
$file->getMimeType();
636 if ( $mediatype && $exists ) {
637 $vals[
'mediatype'] =
$file->getMediaType();
640 if ( $archive &&
$file->isOld() ) {
642 '@phan-var OldLocalFile $file';
643 $vals[
'archivename'] =
$file->getArchiveName();
646 if ( $bitdepth && $exists ) {
647 $vals[
'bitdepth'] =
$file->getBitDepth();
671 if ( is_array( $metadata ) ) {
672 foreach ( $metadata as $key => $value ) {
675 ApiResult::META_BC_BOOLS => [
'value' ],
677 if ( is_array( $value ) ) {
678 $r[
'value'] = static::processMetaData( $value, $result );
680 $r[
'value'] = $value;
685 ApiResult::setIndexedTagName( $retval,
'metadata' );
704 if ( $start ===
null ) {
705 $start = $img->getTimestamp();
708 return $img->getOriginalTitle()->getDBkey() .
'|' . $start;
736 'apihelp-query+imageinfo-param-urlwidth',
744 'metadataversion' => [
748 'extmetadatalanguage' => [
751 $this->contentLanguage->getCode(),
753 'extmetadatamultilang' => [
757 'extmetadatafilter' => [
765 'badfilecontexttitle' => [
771 'localonly' =>
false,
782 return array_keys( static::getPropertyMessages( $filter ) );
792 return array_diff_key(
794 'timestamp' =>
'apihelp-query+imageinfo-paramvalue-prop-timestamp',
795 'user' =>
'apihelp-query+imageinfo-paramvalue-prop-user',
796 'userid' =>
'apihelp-query+imageinfo-paramvalue-prop-userid',
797 'comment' =>
'apihelp-query+imageinfo-paramvalue-prop-comment',
798 'parsedcomment' =>
'apihelp-query+imageinfo-paramvalue-prop-parsedcomment',
799 'canonicaltitle' =>
'apihelp-query+imageinfo-paramvalue-prop-canonicaltitle',
800 'url' =>
'apihelp-query+imageinfo-paramvalue-prop-url',
801 'size' =>
'apihelp-query+imageinfo-paramvalue-prop-size',
802 'dimensions' =>
'apihelp-query+imageinfo-paramvalue-prop-dimensions',
803 'sha1' =>
'apihelp-query+imageinfo-paramvalue-prop-sha1',
804 'mime' =>
'apihelp-query+imageinfo-paramvalue-prop-mime',
805 'thumbmime' =>
'apihelp-query+imageinfo-paramvalue-prop-thumbmime',
806 'mediatype' =>
'apihelp-query+imageinfo-paramvalue-prop-mediatype',
807 'metadata' =>
'apihelp-query+imageinfo-paramvalue-prop-metadata',
808 'commonmetadata' =>
'apihelp-query+imageinfo-paramvalue-prop-commonmetadata',
809 'extmetadata' =>
'apihelp-query+imageinfo-paramvalue-prop-extmetadata',
810 'archivename' =>
'apihelp-query+imageinfo-paramvalue-prop-archivename',
811 'bitdepth' =>
'apihelp-query+imageinfo-paramvalue-prop-bitdepth',
812 'uploadwarning' =>
'apihelp-query+imageinfo-paramvalue-prop-uploadwarning',
813 'badfile' =>
'apihelp-query+imageinfo-paramvalue-prop-badfile',
815 array_fill_keys( $filter,
true )
821 'action=query&titles=File:Albert%20Einstein%20Head.jpg&prop=imageinfo'
822 =>
'apihelp-query+imageinfo-example-simple',
823 'action=query&titles=File:Test.jpg&prop=imageinfo&iilimit=50&' .
824 'iiend=2007-12-31T23:59:59Z&iiprop=timestamp|user|url'
825 =>
'apihelp-query+imageinfo-example-dated',
830 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Imageinfo';
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.
getModulePrefix()
Get parameter prefix (usually two letters or an empty string).
dieContinueUsageIf( $condition)
Die with the 'badcontinue' error.
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.
getResult()
Get the result object.
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
const PARAM_HELP_MSG
(string|array|Message) Specify an alternative i18n documentation message for this parameter.
addWarning( $msg, $code=null, $data=null)
Add a warning for this module.
const LIMIT_BIG2
Fast query, apihighlimits limit.
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.
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.
getCacheMode( $params)
Get the cache mode for the data generated by this module.
getScale( $params)
From parameters, construct a 'scale' array.
BadFileLookup $badFileLookup
__construct(ApiQuery $query, $moduleName, $prefixOrRepoGroup=null, $repoGroupOrContentLanguage=null, $contentLanguageOrBadFileLookup=null, $badFileLookupOrUnused=null)
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.
Language $contentLanguage
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.
Implements some public methods and some protected utility functions which are required by multiple ch...
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
static processResponsiveImages( $file, $thumb, $hp)
Process responsive images: add 1.5x and 2x subimages to the thumbnail, where applicable.
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...
Prioritized list of file repositories.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.