MediaWiki master
ForeignAPIFile.php
Go to the documentation of this file.
1<?php
8
17
23class ForeignAPIFile extends File {
25 private $mExists;
27 private $mInfo;
28
30 protected $repoClass = ForeignAPIRepo::class;
31
38 public function __construct( $title, $repo, $info, $exists = false ) {
39 parent::__construct( $title, $repo );
40
41 $this->mInfo = $info;
42 $this->mExists = $exists;
43
44 $this->assertRepoDefined();
45 }
46
52 public static function newFromTitle( Title $title, $repo ) {
53 $data = $repo->fetchImageQuery( [
54 'titles' => 'File:' . $title->getDBkey(),
55 'iiprop' => self::getProps(),
56 'prop' => 'imageinfo',
57 'iimetadataversion' => MediaHandler::getMetadataVersion(),
58 // extmetadata is language-dependent, accessing the current language here
59 // would be problematic, so we just get them all
60 'iiextmetadatamultilang' => 1,
61 ] );
62
63 $info = $repo->getImageInfo( $data );
64
65 if ( $info ) {
66 $lastRedirect = count( $data['query']['redirects'] ?? [] ) - 1;
67 if ( $lastRedirect >= 0 ) {
68 // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
69 $newtitle = Title::newFromText( $data['query']['redirects'][$lastRedirect]['to'] );
70 $img = new self( $newtitle, $repo, $info, true );
71 $img->redirectedFrom( $title->getDBkey() );
72 } else {
73 $img = new self( $title, $repo, $info, true );
74 }
75
76 return $img;
77 } else {
78 return null;
79 }
80 }
81
86 public static function getProps() {
87 return 'timestamp|user|comment|url|size|sha1|metadata|mime|mediatype|extmetadata';
88 }
89
93 public function getRepo() {
94 return $this->repo;
95 }
96
97 // Dummy functions...
98
102 public function exists() {
103 return $this->mExists;
104 }
105
109 public function getPath() {
110 return false;
111 }
112
118 public function transform( $params, $flags = 0 ) {
119 if ( !$this->canRender() ) {
120 // show icon
121 return parent::transform( $params, $flags );
122 }
123
124 // Note, the this->canRender() check above implies
125 // that we have a handler, and it can do makeParamString.
126 $otherParams = $this->handler->makeParamString( $params );
127 $width = $params['width'] ?? -1;
128 $height = $params['height'] ?? -1;
129 $thumbUrl = false;
130
131 if ( $width > 0 || $height > 0 ) {
132 // Only query the remote if there are dimensions
133 $thumbUrl = $this->repo->getThumbUrlFromCache(
134 $this->getName(),
135 $width,
136 $height,
137 $otherParams
138 );
139 } elseif ( $this->getMediaType() === MEDIATYPE_AUDIO ) {
140 // This has no dimensions, but we still need to pass a value to getTransform()
141 $thumbUrl = '/';
142 }
143 if ( $thumbUrl === false ) {
144 global $wgLang;
145
146 return $this->repo->getThumbError(
147 $this->getName(),
148 $width,
149 $height,
150 $otherParams,
151 $wgLang->getCode()
152 );
153 }
154
155 return $this->handler->getTransform( $this, 'bogus', $thumbUrl, $params );
156 }
157
158 // Info we can get from API...
159
164 public function getWidth( $page = 1 ) {
165 return (int)( $this->mInfo['width'] ?? 0 );
166 }
167
172 public function getHeight( $page = 1 ) {
173 return (int)( $this->mInfo['height'] ?? 0 );
174 }
175
179 public function getMetadata() {
180 if ( isset( $this->mInfo['metadata'] ) ) {
181 return serialize( self::parseMetadata( $this->mInfo['metadata'] ) );
182 }
183
184 return false;
185 }
186
187 public function getMetadataArray(): array {
188 if ( isset( $this->mInfo['metadata'] ) ) {
189 return self::parseMetadata( $this->mInfo['metadata'] );
190 }
191
192 return [];
193 }
194
199 public function getExtendedMetadata() {
200 return $this->mInfo['extmetadata'] ?? null;
201 }
202
207 public static function parseMetadata( $metadata ) {
208 if ( !is_array( $metadata ) ) {
209 return [ '_error' => $metadata ];
210 }
211 '@phan-var array[] $metadata';
212 $ret = [];
213 foreach ( $metadata as $meta ) {
214 $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
215 }
216
217 return $ret;
218 }
219
224 private static function parseMetadataValue( $metadata ) {
225 if ( !is_array( $metadata ) ) {
226 return $metadata;
227 }
228 '@phan-var array[] $metadata';
229 $ret = [];
230 foreach ( $metadata as $meta ) {
231 $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
232 }
233
234 return $ret;
235 }
236
240 public function getSize() {
241 return isset( $this->mInfo['size'] ) ? intval( $this->mInfo['size'] ) : null;
242 }
243
247 public function getUrl() {
248 return isset( $this->mInfo['url'] ) ? strval( $this->mInfo['url'] ) : null;
249 }
250
258 public function getDescriptionShortUrl() {
259 if ( isset( $this->mInfo['descriptionshorturl'] ) ) {
260 return $this->mInfo['descriptionshorturl'];
261 } elseif ( isset( $this->mInfo['pageid'] ) ) {
262 $url = $this->repo->makeUrl( [ 'curid' => $this->mInfo['pageid'] ] );
263 if ( $url !== false ) {
264 return $url;
265 }
266 }
267 return null;
268 }
269
270 public function getUploader( int $audience = self::FOR_PUBLIC, ?Authority $performer = null ): ?UserIdentity {
271 if ( isset( $this->mInfo['user'] ) ) {
272 return UserIdentityValue::newExternal( $this->getRepoName(), $this->mInfo['user'] );
273 }
274 return null;
275 }
276
282 public function getDescription( $audience = self::FOR_PUBLIC, ?Authority $performer = null ) {
283 return isset( $this->mInfo['comment'] ) ? strval( $this->mInfo['comment'] ) : null;
284 }
285
289 public function getSha1() {
290 return isset( $this->mInfo['sha1'] )
291 ? \Wikimedia\base_convert( strval( $this->mInfo['sha1'] ), 16, 36, 31 )
292 : null;
293 }
294
298 public function getTimestamp() {
299 return wfTimestamp( TS_MW,
300 isset( $this->mInfo['timestamp'] )
301 ? strval( $this->mInfo['timestamp'] )
302 : null
303 );
304 }
305
309 public function getMimeType() {
310 if ( !isset( $this->mInfo['mime'] ) ) {
311 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
312 $this->mInfo['mime'] = $magic->getMimeTypeFromExtensionOrNull( $this->getExtension() );
313 }
314
315 return $this->mInfo['mime'];
316 }
317
321 public function getMediaType() {
322 if ( isset( $this->mInfo['mediatype'] ) ) {
323 return $this->mInfo['mediatype'];
324 }
325 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
326
327 return $magic->getMediaType( null, $this->getMimeType() );
328 }
329
333 public function getDescriptionUrl() {
334 return $this->mInfo['descriptionurl'] ?? false;
335 }
336
342 public function getThumbPath( $suffix = '' ) {
343 if ( !$this->repo->canCacheThumbs() ) {
344 return null;
345 }
346
347 $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath();
348 if ( $suffix ) {
349 $path .= $suffix . '/';
350 }
351 return $path;
352 }
353
357 protected function getThumbnails() {
358 $dir = $this->getThumbPath( $this->getName() );
359 $iter = $this->repo->getBackend()->getFileList( [ 'dir' => $dir ] );
360
361 $files = [];
362 if ( $iter ) {
363 foreach ( $iter as $file ) {
364 $files[] = $file;
365 }
366 }
367
368 return $files;
369 }
370
372 public function purgeCache( $options = [] ) {
373 $this->purgeThumbnails( $options );
374 $this->purgeDescriptionPage();
375 }
376
377 private function purgeDescriptionPage() {
378 $services = MediaWikiServices::getInstance();
379 $langCode = $services->getContentLanguageCode()->toString();
380
381 // Key must match File::getDescriptionText
382 $key = $this->repo->getLocalCacheKey( 'file-remote-description', $langCode, md5( $this->getName() ) );
383 $services->getMainWANObjectCache()->delete( $key );
384 }
385
389 public function purgeThumbnails( $options = [] ) {
390 $key = $this->repo->getLocalCacheKey( 'file-thumb-url', sha1( $this->getName() ) );
391 MediaWikiServices::getInstance()->getMainWANObjectCache()->delete( $key );
392
393 $files = $this->getThumbnails();
394 // Give media handler a chance to filter the purge list
395 $handler = $this->getHandler();
396 if ( $handler ) {
397 $handler->filterThumbnailPurgeList( $files, $options );
398 }
399
400 $dir = $this->getThumbPath( $this->getName() );
401 $purgeList = [];
402 foreach ( $files as $file ) {
403 $purgeList[] = "{$dir}{$file}";
404 }
405
406 # Delete the thumbnails
407 $this->repo->quickPurgeBatch( $purgeList );
408 # Clear out the thumbnail directory if empty
409 $this->repo->quickCleanDir( $dir );
410 }
411
417 public function isTransformedLocally() {
418 return false;
419 }
420}
421
423class_alias( ForeignAPIFile::class, 'ForeignAPIFile' );
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
const MEDIATYPE_AUDIO
Definition defines.php:19
if(MW_ENTRY_POINT==='index') if(!defined( 'MW_NO_SESSION') &&MW_ENTRY_POINT !=='cli' $wgLang
Definition Setup.php:551
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:68
Base media handler class.
Base class for the output of MediaHandler::doTransform() and File::transform().
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:79
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:891
assertRepoDefined()
Assert that $this->repo is set to a valid FileRepo instance.
Definition File.php:2542
Title string false $title
Definition File.php:129
getName()
Return the name of this file.
Definition File.php:347
Foreign file accessible through api.php requests.
__construct( $title, $repo, $info, $exists=false)
getDescription( $audience=self::FOR_PUBLIC, ?Authority $performer=null)
isTransformedLocally()
The thumbnail is created on the foreign server and fetched over internet.
getDescriptionShortUrl()
Get short description URL for a file based on the foreign API response, or if unavailable,...
static newFromTitle(Title $title, $repo)
getThumbPath( $suffix='')
Only useful if we're locally caching thumbs anyway...
getMetadataArray()
Get the unserialized handler-specific metadata STUB.
purgeCache( $options=[])
Purge shared caches such as thumbnails and DB data caching STUB Overridden by LocalFile....
static getProps()
Get the property string for iiprop and aiprop.
getUploader(int $audience=self::FOR_PUBLIC, ?Authority $performer=null)
Get the identity of the file uploader.
A foreign repository for a remote MediaWiki accessible through api.php requests.
Service locator for MediaWiki core services.
Represents a title within MediaWiki.
Definition Title.php:69
getDBkey()
Get the main part with underscores.
Definition Title.php:1028
Value object representing a user's identity.
This interface represents the authority associated with the current execution context,...
Definition Authority.php:23
Interface for objects representing user identity.