MediaWiki master
ForeignAPIFile.php
Go to the documentation of this file.
1<?php
26
32class ForeignAPIFile extends File {
34 private $mExists;
36 private $mInfo;
37
39 protected $repoClass = ForeignAPIRepo::class;
40
47 public function __construct( $title, $repo, $info, $exists = false ) {
48 parent::__construct( $title, $repo );
49
50 $this->mInfo = $info;
51 $this->mExists = $exists;
52
53 $this->assertRepoDefined();
54 }
55
61 public static function newFromTitle( Title $title, $repo ) {
62 $data = $repo->fetchImageQuery( [
63 'titles' => 'File:' . $title->getDBkey(),
64 'iiprop' => self::getProps(),
65 'prop' => 'imageinfo',
66 'iimetadataversion' => MediaHandler::getMetadataVersion(),
67 // extmetadata is language-dependent, accessing the current language here
68 // would be problematic, so we just get them all
69 'iiextmetadatamultilang' => 1,
70 ] );
71
72 $info = $repo->getImageInfo( $data );
73
74 if ( $info ) {
75 $lastRedirect = count( $data['query']['redirects'] ?? [] ) - 1;
76 if ( $lastRedirect >= 0 ) {
77 // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
78 $newtitle = Title::newFromText( $data['query']['redirects'][$lastRedirect]['to'] );
79 $img = new self( $newtitle, $repo, $info, true );
80 $img->redirectedFrom( $title->getDBkey() );
81 } else {
82 $img = new self( $title, $repo, $info, true );
83 }
84
85 return $img;
86 } else {
87 return null;
88 }
89 }
90
95 public static function getProps() {
96 return 'timestamp|user|comment|url|size|sha1|metadata|mime|mediatype|extmetadata';
97 }
98
102 public function getRepo() {
103 return $this->repo;
104 }
105
106 // Dummy functions...
107
111 public function exists() {
112 return $this->mExists;
113 }
114
118 public function getPath() {
119 return false;
120 }
121
127 public function transform( $params, $flags = 0 ) {
128 if ( !$this->canRender() ) {
129 // show icon
130 return parent::transform( $params, $flags );
131 }
132
133 // Note, the this->canRender() check above implies
134 // that we have a handler, and it can do makeParamString.
135 $otherParams = $this->handler->makeParamString( $params );
136 $width = $params['width'] ?? -1;
137 $height = $params['height'] ?? -1;
138 $thumbUrl = false;
139
140 if ( $width > 0 || $height > 0 ) {
141 // Only query the remote if there are dimensions
142 $thumbUrl = $this->repo->getThumbUrlFromCache(
143 $this->getName(),
144 $width,
145 $height,
146 $otherParams
147 );
148 } elseif ( $this->getMediaType() === MEDIATYPE_AUDIO ) {
149 // This has no dimensions, but we still need to pass a value to getTransform()
150 $thumbUrl = '/';
151 }
152 if ( $thumbUrl === false ) {
153 global $wgLang;
154
155 return $this->repo->getThumbError(
156 $this->getName(),
157 $width,
158 $height,
159 $otherParams,
160 $wgLang->getCode()
161 );
162 }
163
164 return $this->handler->getTransform( $this, 'bogus', $thumbUrl, $params );
165 }
166
167 // Info we can get from API...
168
173 public function getWidth( $page = 1 ) {
174 return (int)( $this->mInfo['width'] ?? 0 );
175 }
176
181 public function getHeight( $page = 1 ) {
182 return (int)( $this->mInfo['height'] ?? 0 );
183 }
184
188 public function getMetadata() {
189 if ( isset( $this->mInfo['metadata'] ) ) {
190 return serialize( self::parseMetadata( $this->mInfo['metadata'] ) );
191 }
192
193 return false;
194 }
195
196 public function getMetadataArray(): array {
197 if ( isset( $this->mInfo['metadata'] ) ) {
198 return self::parseMetadata( $this->mInfo['metadata'] );
199 }
200
201 return [];
202 }
203
208 public function getExtendedMetadata() {
209 return $this->mInfo['extmetadata'] ?? null;
210 }
211
216 public static function parseMetadata( $metadata ) {
217 if ( !is_array( $metadata ) ) {
218 return [ '_error' => $metadata ];
219 }
220 '@phan-var array[] $metadata';
221 $ret = [];
222 foreach ( $metadata as $meta ) {
223 $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
224 }
225
226 return $ret;
227 }
228
233 private static function parseMetadataValue( $metadata ) {
234 if ( !is_array( $metadata ) ) {
235 return $metadata;
236 }
237 '@phan-var array[] $metadata';
238 $ret = [];
239 foreach ( $metadata as $meta ) {
240 $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
241 }
242
243 return $ret;
244 }
245
249 public function getSize() {
250 return isset( $this->mInfo['size'] ) ? intval( $this->mInfo['size'] ) : null;
251 }
252
256 public function getUrl() {
257 return isset( $this->mInfo['url'] ) ? strval( $this->mInfo['url'] ) : null;
258 }
259
267 public function getDescriptionShortUrl() {
268 if ( isset( $this->mInfo['descriptionshorturl'] ) ) {
269 return $this->mInfo['descriptionshorturl'];
270 } elseif ( isset( $this->mInfo['pageid'] ) ) {
271 $url = $this->repo->makeUrl( [ 'curid' => $this->mInfo['pageid'] ] );
272 if ( $url !== false ) {
273 return $url;
274 }
275 }
276 return null;
277 }
278
279 public function getUploader( int $audience = self::FOR_PUBLIC, ?Authority $performer = null ): ?UserIdentity {
280 if ( isset( $this->mInfo['user'] ) ) {
281 return UserIdentityValue::newExternal( $this->getRepoName(), $this->mInfo['user'] );
282 }
283 return null;
284 }
285
291 public function getDescription( $audience = self::FOR_PUBLIC, ?Authority $performer = null ) {
292 return isset( $this->mInfo['comment'] ) ? strval( $this->mInfo['comment'] ) : null;
293 }
294
298 public function getSha1() {
299 return isset( $this->mInfo['sha1'] )
300 ? Wikimedia\base_convert( strval( $this->mInfo['sha1'] ), 16, 36, 31 )
301 : null;
302 }
303
307 public function getTimestamp() {
308 return wfTimestamp( TS_MW,
309 isset( $this->mInfo['timestamp'] )
310 ? strval( $this->mInfo['timestamp'] )
311 : null
312 );
313 }
314
318 public function getMimeType() {
319 if ( !isset( $this->mInfo['mime'] ) ) {
320 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
321 $this->mInfo['mime'] = $magic->getMimeTypeFromExtensionOrNull( $this->getExtension() );
322 }
323
324 return $this->mInfo['mime'];
325 }
326
330 public function getMediaType() {
331 if ( isset( $this->mInfo['mediatype'] ) ) {
332 return $this->mInfo['mediatype'];
333 }
334 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
335
336 return $magic->getMediaType( null, $this->getMimeType() );
337 }
338
342 public function getDescriptionUrl() {
343 return $this->mInfo['descriptionurl'] ?? false;
344 }
345
351 public function getThumbPath( $suffix = '' ) {
352 if ( !$this->repo->canCacheThumbs() ) {
353 return null;
354 }
355
356 $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath();
357 if ( $suffix ) {
358 $path .= $suffix . '/';
359 }
360 return $path;
361 }
362
366 protected function getThumbnails() {
367 $dir = $this->getThumbPath( $this->getName() );
368 $iter = $this->repo->getBackend()->getFileList( [ 'dir' => $dir ] );
369
370 $files = [];
371 if ( $iter ) {
372 foreach ( $iter as $file ) {
373 $files[] = $file;
374 }
375 }
376
377 return $files;
378 }
379
380 public function purgeCache( $options = [] ) {
381 $this->purgeThumbnails( $options );
382 $this->purgeDescriptionPage();
383 }
384
385 private function purgeDescriptionPage() {
386 $services = MediaWikiServices::getInstance();
387 $langCode = $services->getContentLanguageCode()->toString();
388
389 // Key must match File::getDescriptionText
390 $key = $this->repo->getLocalCacheKey( 'file-remote-description', $langCode, md5( $this->getName() ) );
391 $services->getMainWANObjectCache()->delete( $key );
392 }
393
397 public function purgeThumbnails( $options = [] ) {
398 $key = $this->repo->getLocalCacheKey( 'file-thumb-url', sha1( $this->getName() ) );
399 MediaWikiServices::getInstance()->getMainWANObjectCache()->delete( $key );
400
401 $files = $this->getThumbnails();
402 // Give media handler a chance to filter the purge list
403 $handler = $this->getHandler();
404 if ( $handler ) {
405 $handler->filterThumbnailPurgeList( $files, $options );
406 }
407
408 $dir = $this->getThumbPath( $this->getName() );
409 $purgeList = [];
410 foreach ( $files as $file ) {
411 $purgeList[] = "{$dir}{$file}";
412 }
413
414 # Delete the thumbnails
415 $this->repo->quickPurgeBatch( $purgeList );
416 # Clear out the thumbnail directory if empty
417 $this->repo->quickCleanDir( $dir );
418 }
419
425 public function isTransformedLocally() {
426 return false;
427 }
428}
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
if(!defined( 'MW_NO_SESSION') &&MW_ENTRY_POINT !=='cli' $wgLang
Definition Setup.php:570
array $params
The job parameters.
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:79
assertRepoDefined()
Assert that $this->repo is set to a valid FileRepo instance.
Definition File.php:2487
getName()
Return the name of this file.
Definition File.php:347
FileRepo LocalRepo ForeignAPIRepo false $repo
Some member variables can be lazy-initialised using __get().
Definition File.php:126
canRender()
Checks if the output of transform() for this file is likely to be valid.
Definition File.php:889
Title string false $title
Definition File.php:129
Foreign file accessible through api.php requests.
getThumbPath( $suffix='')
Only useful if we're locally caching thumbs anyway...
__construct( $title, $repo, $info, $exists=false)
purgeCache( $options=[])
Purge shared caches such as thumbnails and DB data caching STUB Overridden by LocalFile.
isTransformedLocally()
The thumbnail is created on the foreign server and fetched over internet.
static parseMetadata( $metadata)
getMetadataArray()
Get the unserialized handler-specific metadata STUB.
static newFromTitle(Title $title, $repo)
purgeThumbnails( $options=[])
getUploader(int $audience=self::FOR_PUBLIC, ?Authority $performer=null)
Get the identity of the file uploader.
transform( $params, $flags=0)
getDescription( $audience=self::FOR_PUBLIC, ?Authority $performer=null)
getDescriptionShortUrl()
Get short description URL for a file based on the foreign API response, or if unavailable,...
static getProps()
Get the property string for iiprop and aiprop.
Service locator for MediaWiki core services.
Represents a title within MediaWiki.
Definition Title.php:78
getDBkey()
Get the main part with underscores.
Definition Title.php:1032
Value object representing a user's identity.
This interface represents the authority associated with the current execution context,...
Definition Authority.php:37
Interface for objects representing user identity.
const MEDIATYPE_AUDIO
Definition defines.php:33