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