MediaWiki 1.41.2
ForeignAPIFile.php
Go to the documentation of this file.
1<?php
26
32class ForeignAPIFile extends File {
34 private $mExists;
36 private $mInfo;
37
38 protected $repoClass = ForeignAPIRepo::class;
39
46 public function __construct( $title, $repo, $info, $exists = false ) {
47 parent::__construct( $title, $repo );
48
49 $this->mInfo = $info;
50 $this->mExists = $exists;
51
52 $this->assertRepoDefined();
53 }
54
60 public static function newFromTitle( Title $title, $repo ) {
61 $data = $repo->fetchImageQuery( [
62 'titles' => 'File:' . $title->getDBkey(),
63 'iiprop' => self::getProps(),
64 'prop' => 'imageinfo',
65 'iimetadataversion' => MediaHandler::getMetadataVersion(),
66 // extmetadata is language-dependent, accessing the current language here
67 // would be problematic, so we just get them all
68 'iiextmetadatamultilang' => 1,
69 ] );
70
71 $info = $repo->getImageInfo( $data );
72
73 if ( $info ) {
74 $lastRedirect = count( $data['query']['redirects'] ?? [] ) - 1;
75 if ( $lastRedirect >= 0 ) {
76 // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
77 $newtitle = Title::newFromText( $data['query']['redirects'][$lastRedirect]['to'] );
78 $img = new self( $newtitle, $repo, $info, true );
79 $img->redirectedFrom( $title->getDBkey() );
80 } else {
81 $img = new self( $title, $repo, $info, true );
82 }
83
84 return $img;
85 } else {
86 return null;
87 }
88 }
89
94 public static function getProps() {
95 return 'timestamp|user|comment|url|size|sha1|metadata|mime|mediatype|extmetadata';
96 }
97
101 public function getRepo() {
102 return $this->repo;
103 }
104
105 // Dummy functions...
106
110 public function exists() {
111 return $this->mExists;
112 }
113
117 public function getPath() {
118 return false;
119 }
120
126 public function transform( $params, $flags = 0 ) {
127 if ( !$this->canRender() ) {
128 // show icon
129 return parent::transform( $params, $flags );
130 }
131
132 // Note, the this->canRender() check above implies
133 // that we have a handler, and it can do makeParamString.
134 $otherParams = $this->handler->makeParamString( $params );
135 $width = $params['width'] ?? -1;
136 $height = $params['height'] ?? -1;
137 $thumbUrl = false;
138
139 if ( $width > 0 || $height > 0 ) {
140 // Only query the remote if there are dimensions
141 $thumbUrl = $this->repo->getThumbUrlFromCache(
142 $this->getName(),
143 $width,
144 $height,
145 $otherParams
146 );
147 } elseif ( $this->getMediaType() === MEDIATYPE_AUDIO ) {
148 // This has no dimensions, but we still need to pass a value to getTransform()
149 $thumbUrl = '/';
150 }
151 if ( $thumbUrl === false ) {
152 global $wgLang;
153
154 return $this->repo->getThumbError(
155 $this->getName(),
156 $width,
157 $height,
158 $otherParams,
159 $wgLang->getCode()
160 );
161 }
162
163 return $this->handler->getTransform( $this, 'bogus', $thumbUrl, $params );
164 }
165
166 // Info we can get from API...
167
172 public function getWidth( $page = 1 ) {
173 return (int)( $this->mInfo['width'] ?? 0 );
174 }
175
180 public function getHeight( $page = 1 ) {
181 return (int)( $this->mInfo['height'] ?? 0 );
182 }
183
187 public function getMetadata() {
188 if ( isset( $this->mInfo['metadata'] ) ) {
189 return serialize( self::parseMetadata( $this->mInfo['metadata'] ) );
190 }
191
192 return false;
193 }
194
198 public function getMetadataArray(): array {
199 if ( isset( $this->mInfo['metadata'] ) ) {
200 return self::parseMetadata( $this->mInfo['metadata'] );
201 }
202
203 return [];
204 }
205
210 public function getExtendedMetadata() {
211 return $this->mInfo['extmetadata'] ?? null;
212 }
213
218 public static function parseMetadata( $metadata ) {
219 if ( !is_array( $metadata ) ) {
220 return [ '_error' => $metadata ];
221 }
222 '@phan-var array[] $metadata';
223 $ret = [];
224 foreach ( $metadata as $meta ) {
225 $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
226 }
227
228 return $ret;
229 }
230
235 private static function parseMetadataValue( $metadata ) {
236 if ( !is_array( $metadata ) ) {
237 return $metadata;
238 }
239 '@phan-var array[] $metadata';
240 $ret = [];
241 foreach ( $metadata as $meta ) {
242 $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
243 }
244
245 return $ret;
246 }
247
251 public function getSize() {
252 return isset( $this->mInfo['size'] ) ? intval( $this->mInfo['size'] ) : null;
253 }
254
258 public function getUrl() {
259 return isset( $this->mInfo['url'] ) ? strval( $this->mInfo['url'] ) : null;
260 }
261
269 public function getDescriptionShortUrl() {
270 if ( isset( $this->mInfo['descriptionshorturl'] ) ) {
271 return $this->mInfo['descriptionshorturl'];
272 } elseif ( isset( $this->mInfo['pageid'] ) ) {
273 $url = $this->repo->makeUrl( [ 'curid' => $this->mInfo['pageid'] ] );
274 if ( $url !== false ) {
275 return $url;
276 }
277 }
278 return null;
279 }
280
281 public function getUploader( int $audience = self::FOR_PUBLIC, Authority $performer = null ): ?UserIdentity {
282 if ( isset( $this->mInfo['user'] ) ) {
283 // We don't know if the foreign repo will have a real interwiki prefix,
284 // treat this user as a foreign imported user. Maybe we can do better?
285 return UserIdentityValue::newExternal( $this->getRepoName(), $this->mInfo['user'] );
286 }
287 return null;
288 }
289
295 public function getDescription( $audience = self::FOR_PUBLIC, Authority $performer = null ) {
296 return isset( $this->mInfo['comment'] ) ? strval( $this->mInfo['comment'] ) : null;
297 }
298
302 public function getSha1() {
303 return isset( $this->mInfo['sha1'] )
304 ? Wikimedia\base_convert( strval( $this->mInfo['sha1'] ), 16, 36, 31 )
305 : null;
306 }
307
311 public function getTimestamp() {
312 return wfTimestamp( TS_MW,
313 isset( $this->mInfo['timestamp'] )
314 ? strval( $this->mInfo['timestamp'] )
315 : null
316 );
317 }
318
322 public function getMimeType() {
323 if ( !isset( $this->mInfo['mime'] ) ) {
324 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
325 $this->mInfo['mime'] = $magic->getMimeTypeFromExtensionOrNull( $this->getExtension() );
326 }
327
328 return $this->mInfo['mime'];
329 }
330
334 public function getMediaType() {
335 if ( isset( $this->mInfo['mediatype'] ) ) {
336 return $this->mInfo['mediatype'];
337 }
338 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
339
340 return $magic->getMediaType( null, $this->getMimeType() );
341 }
342
346 public function getDescriptionUrl() {
347 return $this->mInfo['descriptionurl'] ?? false;
348 }
349
355 public function getThumbPath( $suffix = '' ) {
356 if ( !$this->repo->canCacheThumbs() ) {
357 return null;
358 }
359
360 $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath();
361 if ( $suffix ) {
362 $path .= $suffix . '/';
363 }
364 return $path;
365 }
366
370 protected function getThumbnails() {
371 $dir = $this->getThumbPath( $this->getName() );
372 $iter = $this->repo->getBackend()->getFileList( [ 'dir' => $dir ] );
373
374 $files = [];
375 if ( $iter ) {
376 foreach ( $iter as $file ) {
377 $files[] = $file;
378 }
379 }
380
381 return $files;
382 }
383
384 public function purgeCache( $options = [] ) {
385 $this->purgeThumbnails( $options );
386 $this->purgeDescriptionPage();
387 }
388
389 private function purgeDescriptionPage() {
390 $services = MediaWikiServices::getInstance();
391 $langCode = $services->getContentLanguage()->getCode();
392
393 // Key must match File::getDescriptionText
394 $key = $this->repo->getLocalCacheKey( 'file-remote-description', $langCode, md5( $this->getName() ) );
395 $services->getMainWANObjectCache()->delete( $key );
396 }
397
401 public function purgeThumbnails( $options = [] ) {
402 $key = $this->repo->getLocalCacheKey( 'file-thumb-url', sha1( $this->getName() ) );
403 MediaWikiServices::getInstance()->getMainWANObjectCache()->delete( $key );
404
405 $files = $this->getThumbnails();
406 // Give media handler a chance to filter the purge list
407 $handler = $this->getHandler();
408 if ( $handler ) {
409 $handler->filterThumbnailPurgeList( $files, $options );
410 }
411
412 $dir = $this->getThumbPath( $this->getName() );
413 $purgeList = [];
414 foreach ( $files as $file ) {
415 $purgeList[] = "{$dir}{$file}";
416 }
417
418 # Delete the thumbnails
419 $this->repo->quickPurgeBatch( $purgeList );
420 # Clear out the thumbnail directory if empty
421 $this->repo->quickCleanDir( $dir );
422 }
423
429 public function isTransformedLocally() {
430 return false;
431 }
432}
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
if(!defined( 'MW_NO_SESSION') &&! $wgCommandLineMode $wgLang
Definition Setup.php:535
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:88
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:70
assertRepoDefined()
Assert that $this->repo is set to a valid FileRepo instance.
Definition File.php:2460
getName()
Return the name of this file.
Definition File.php:336
FileRepo LocalRepo ForeignAPIRepo false $repo
Some member variables can be lazy-initialised using __get().
Definition File.php:117
canRender()
Checks if the output of transform() for this file is likely to be valid.
Definition File.php:866
Title string false $title
Definition File.php:120
Foreign file accessible through api.php requests.
getThumbPath( $suffix='')
Only useful if we're locally caching thumbs anyway...
getDescription( $audience=self::FOR_PUBLIC, Authority $performer=null)
__construct( $title, $repo, $info, $exists=false)
getUploader(int $audience=self::FOR_PUBLIC, Authority $performer=null)
Get the identity of the file uploader.
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)
static newFromTitle(Title $title, $repo)
purgeThumbnails( $options=[])
transform( $params, $flags=0)
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.
static getMetadataVersion()
Get metadata version.
Service locator for MediaWiki core services.
Represents a title within MediaWiki.
Definition Title.php:76
getDBkey()
Get the main part with underscores.
Definition Title.php:1049
Value object representing a user's identity.
This interface represents the authority associated the current execution context, such as a web reque...
Definition Authority.php:37
Interface for objects representing user identity.
const MEDIATYPE_AUDIO
Definition defines.php:32
return true
Definition router.php:92
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42