84 $prop = array_fill_keys( $params[
'prop'],
true );
89 'version' => $params[
'metadataversion'],
90 'language' => $params[
'extmetadatalanguage'],
91 'multilang' => $params[
'extmetadatamultilang'],
92 'extmetadatafilter' => $params[
'extmetadatafilter'],
96 if ( isset( $params[
'badfilecontexttitle'] ) ) {
97 $badFileContextTitle = Title::newFromText( $params[
'badfilecontexttitle'] );
98 if ( !$badFileContextTitle || $badFileContextTitle->isExternal() ) {
100 $this->
dieWithError( [
'apierror-bad-badfilecontexttitle', $p ],
'invalid-title' );
103 $badFileContextTitle =
null;
106 $pageIds = $this->
getPageSet()->getGoodAndMissingTitlesByNamespace();
107 if ( !empty( $pageIds[
NS_FILE] ) ) {
108 $titles = array_keys( $pageIds[
NS_FILE] );
112 if ( $params[
'continue'] !==
null ) {
114 $fromTitle = $cont[0];
115 $fromTimestamp = $cont[1];
117 foreach ( $titles as $key => $title ) {
118 if ( $title < $fromTitle ) {
119 unset( $titles[$key] );
127 $findTitles = array_map(
static function ( $title ) use ( $performer ) {
130 'private' => $performer,
134 if ( $params[
'localonly'] ) {
135 $images = $this->repoGroup->getLocalRepo()->findFiles( $findTitles );
137 $images = $this->repoGroup->findFiles( $findTitles );
141 foreach ( $titles as $title ) {
143 $pageId = $pageIds[
NS_FILE][$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',
''
165 $img = $images[$title];
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 );
190 if ( count( $pageIds[
NS_FILE] ) == 1 ) {
197 $start ??
wfTimestamp( TS::ISO_8601, $img->getTimestamp() )
207 $finalThumbParams = $this->
mergeThumbParams( $img, $scale, $params[
'urlparam'] );
213 if ( $badFileContextTitle && $finalThumbParams ) {
214 $finalThumbParams[
'targetlang'] = $badFileContextTitle->getPageLanguage()->getCode();
221 ( $start ===
null || $img->getTimestamp() <= $start ) &&
222 ( $params[
'end'] ===
null || $img->getTimestamp() >= $params[
'end'] )
227 static::getInfo( $img, $prop, $result,
228 $finalThumbParams, $opts
232 if ( count( $pageIds[
NS_FILE] ) == 1 ) {
235 wfTimestamp( TS::ISO_8601, $img->getTimestamp() ) );
246 $count = ( $gotOne ? 1 : 0 );
247 $oldies = $img->getHistory( $params[
'limit'] - $count + 1, $start, $params[
'end'] );
249 foreach ( $oldies as $oldie ) {
250 if ( ++$count > $params[
'limit'] ) {
254 if ( count( $pageIds[
NS_FILE] ) == 1 ) {
256 wfTimestamp( TS::ISO_8601, $oldie->getTimestamp() ) );
262 static::getInfo( $oldie, $prop, $result,
263 $finalThumbParams, $opts
267 if ( count( $pageIds[
NS_FILE] ) == 1 ) {
269 wfTimestamp( TS::ISO_8601, $oldie->getTimestamp() ) );
416 public static function getInfo( $file, $prop, $result, $thumbParams =
null, $opts =
false ) {
421 if ( !$opts || is_string( $opts ) ) {
423 'version' => $opts ?:
'latest',
424 'language' => $services->getContentLanguage(),
425 'multilang' =>
false,
426 'extmetadatafilter' => [],
427 'revdelUser' =>
null,
430 $version = $opts[
'version'];
436 $exists = $file->exists();
440 $hasDbMetadata = $exists
445 if ( isset( $prop[
'timestamp'] ) && $hasDbMetadata ) {
446 $vals[
'timestamp'] =
wfTimestamp( TS::ISO_8601, $file->getTimestamp() );
450 if ( isset( $opts[
'revdelUser'] ) && $opts[
'revdelUser'] ) {
451 $revdelUser = $opts[
'revdelUser'];
452 $canShowField =
static function ( $field ) use ( $file, $revdelUser ) {
453 return $file->userCan( $field, $revdelUser );
456 $canShowField =
static function ( $field ) use ( $file ) {
457 return !$file->isDeleted( $field );
461 $user = isset( $prop[
'user'] );
462 $userid = isset( $prop[
'userid'] );
464 if ( ( $user || $userid ) && $hasDbMetadata ) {
465 if ( $file->isDeleted( File::DELETED_USER ) ) {
466 $vals[
'userhidden'] =
true;
469 if ( $canShowField( File::DELETED_USER ) ) {
471 $uploader = $file->getUploader( File::RAW );
473 $vals[
'user'] = $uploader ? $uploader->getName() :
'';
476 $vals[
'userid'] = $uploader ? $uploader->getId() : 0;
478 if ( $uploader && $services->getUserNameUtils()->isTemp( $uploader->getName() ) ) {
479 $vals[
'temp'] =
true;
481 if ( $uploader && !$uploader->isRegistered() ) {
482 $vals[
'anon'] =
true;
489 if ( ( isset( $prop[
'size'] ) || isset( $prop[
'dimensions'] ) ) && $hasDbMetadata ) {
490 $vals[
'size'] = (int)$file->getSize();
491 $vals[
'width'] = (int)$file->getWidth();
492 $vals[
'height'] = (int)$file->getHeight();
497 $pageCount = $file->pageCount();
498 if ( $pageCount !==
false ) {
499 $vals[
'pagecount'] = $pageCount;
503 $length = $file->getLength();
506 $vals[
'duration'] = (float)$length;
511 $pcomment = isset( $prop[
'parsedcomment'] );
512 $comment = isset( $prop[
'comment'] );
514 if ( ( $pcomment || $comment ) && $hasDbMetadata ) {
515 if ( $file->isDeleted( File::DELETED_COMMENT ) ) {
516 $vals[
'commenthidden'] =
true;
519 if ( $canShowField( File::DELETED_COMMENT ) ) {
521 $vals[
'parsedcomment'] = $services->getCommentFormatter()->format(
522 $file->getDescription( File::RAW ), $file->getTitle() );
525 $vals[
'comment'] = $file->getDescription( File::RAW );
530 $canonicaltitle = isset( $prop[
'canonicaltitle'] );
531 $url = isset( $prop[
'url'] );
532 $sha1 = isset( $prop[
'sha1'] );
533 $meta = isset( $prop[
'metadata'] );
534 $extmetadata = isset( $prop[
'extmetadata'] );
535 $commonmeta = isset( $prop[
'commonmetadata'] );
536 $mime = isset( $prop[
'mime'] );
537 $mediatype = isset( $prop[
'mediatype'] );
538 $archive = isset( $prop[
'archivename'] );
539 $bitdepth = isset( $prop[
'bitdepth'] );
540 $uploadwarning = isset( $prop[
'uploadwarning'] );
542 if ( $uploadwarning ) {
546 if ( $file->isDeleted( File::DELETED_FILE ) ) {
547 $vals[
'filehidden'] =
true;
551 if ( $anyHidden && $file->isDeleted( File::DELETED_RESTRICTED ) ) {
552 $vals[
'suppressed'] =
true;
556 if ( isset( $opts[
'revdelUser'] ) && $opts[
'revdelUser']
557 && !$file->userCan( File::DELETED_FILE, $opts[
'revdelUser'] )
560 } elseif ( $file->isDeleted( File::DELETED_FILE ) ) {
564 if ( $canonicaltitle ) {
565 $vals[
'canonicaltitle'] = $file->getTitle()->getPrefixedText();
569 $urlUtils = $services->getUrlUtils();
572 if ( $thumbParams !==
null ) {
573 $thumbParams[
'requestProvenance'] =
'imageinfo';
574 $mto = $file->transform( $thumbParams );
575 self::$transformCount++;
576 if ( $mto && !$mto->isError() ) {
577 $vals[
'thumburl'] = (string)$urlUtils->expand( $mto->getUrl(),
PROTO_CURRENT );
581 if ( $mto->getUrl() !== $file->getUrl() ) {
582 $vals[
'thumbwidth'] = (int)$mto->getWidth();
583 $vals[
'thumbheight'] = (int)$mto->getHeight();
585 $vals[
'thumbwidth'] = (int)$file->getWidth();
586 $vals[
'thumbheight'] = (int)$file->getHeight();
589 if ( isset( $prop[
'thumbmime'] ) && $file->getHandler() ) {
590 [ , $mime ] = $file->getHandler()->getThumbType(
591 $mto->getExtension(), $file->getMimeType(), $thumbParams );
592 $vals[
'thumbmime'] = $mime;
595 Linker::processResponsiveImages( $file, $mto, [
596 'width' => $vals[
'thumbwidth'],
597 'height' => $vals[
'thumbheight']
599 foreach ( $mto->responsiveUrls as $density =>
$url ) {
600 $vals[
'responsiveUrls'][$density] = (string)$urlUtils->expand(
$url,
PROTO_CURRENT );
602 } elseif ( $mto && $mto->isError() ) {
604 '@phan-var MediaTransformError $mto';
605 $vals[
'thumberror'] = $mto->toText();
608 $vals[
'url'] = (string)$urlUtils->expand( $file->appendRequestProvenance( $file->getFullUrl(), [
609 'format' =>
'original',
610 'generator' =>
'imageinfo',
613 $vals[
'descriptionurl'] = (string)$urlUtils->expand( $file->getDescriptionUrl(),
PROTO_CURRENT );
615 $shortDescriptionUrl = $file->getDescriptionShortUrl();
616 if ( $shortDescriptionUrl !==
null ) {
617 $vals[
'descriptionshorturl'] = (string)$urlUtils->expand( $shortDescriptionUrl,
PROTO_CURRENT );
622 $vals[
'filemissing'] =
true;
625 if ( $sha1 && $exists ) {
626 $vals[
'sha1'] = \Wikimedia\base_convert( $file->getSha1(), 36, 16, 40 );
629 if ( $meta && $exists ) {
630 $metadata = $file->getMetadataArray();
631 if ( $metadata && $version !==
'latest' ) {
632 $metadata = $file->convertMetadataVersion( $metadata, $version );
634 $vals[
'metadata'] = $metadata ? static::processMetaData( $metadata, $result ) :
null;
636 if ( $commonmeta && $exists ) {
637 $metaArray = $file->getCommonMetaArray();
638 $vals[
'commonmetadata'] = $metaArray ? static::processMetaData( $metaArray, $result ) : [];
641 if ( $extmetadata && $exists ) {
648 $format->getContext()->setLanguage( $opts[
'language'] );
649 $extmetaArray = $format->fetchExtendedMetadata( $file );
650 if ( $opts[
'extmetadatafilter'] ) {
651 $extmetaArray = array_intersect_key(
652 $extmetaArray, array_fill_keys( $opts[
'extmetadatafilter'],
true )
655 $vals[
'extmetadata'] = $extmetaArray;
658 if ( $mime && $exists ) {
659 $vals[
'mime'] = $file->getMimeType();
662 if ( $mediatype && $exists ) {
663 $vals[
'mediatype'] = $file->getMediaType();
666 if ( $archive && $file->isOld() ) {
668 '@phan-var OldLocalFile $file';
669 $vals[
'archivename'] = $file->getArchiveName();
672 if ( $bitdepth && $exists ) {
673 $vals[
'bitdepth'] = $file->getBitDepth();
738 ParamValidator::PARAM_ISMULTI =>
true,
739 ParamValidator::PARAM_DEFAULT =>
'timestamp|user',
740 ParamValidator::PARAM_TYPE => static::getPropertyNames(),
744 ParamValidator::PARAM_TYPE =>
'limit',
745 ParamValidator::PARAM_DEFAULT => 1,
746 IntegerDef::PARAM_MIN => 1,
751 ParamValidator::PARAM_TYPE =>
'timestamp'
754 ParamValidator::PARAM_TYPE =>
'timestamp'
757 ParamValidator::PARAM_TYPE =>
'integer',
758 ParamValidator::PARAM_DEFAULT => -1,
760 'apihelp-query+imageinfo-param-urlwidth',
765 ParamValidator::PARAM_TYPE =>
'integer',
766 ParamValidator::PARAM_DEFAULT => -1
768 'metadataversion' => [
769 ParamValidator::PARAM_TYPE =>
'string',
770 ParamValidator::PARAM_DEFAULT =>
'1',
772 'extmetadatalanguage' => [
773 ParamValidator::PARAM_TYPE =>
'string',
774 ParamValidator::PARAM_DEFAULT =>
775 $this->contentLanguage->getCode(),
777 'extmetadatamultilang' => [
778 ParamValidator::PARAM_TYPE =>
'boolean',
779 ParamValidator::PARAM_DEFAULT =>
false,
781 'extmetadatafilter' => [
782 ParamValidator::PARAM_TYPE =>
'string',
783 ParamValidator::PARAM_ISMULTI =>
true,
786 ParamValidator::PARAM_DEFAULT =>
'',
787 ParamValidator::PARAM_TYPE =>
'string',
789 'badfilecontexttitle' => [
790 ParamValidator::PARAM_TYPE =>
'string',
796 ParamValidator::PARAM_TYPE =>
'boolean',
797 ParamValidator::PARAM_DEFAULT =>
false,