MediaWiki master
ForeignAPIFile.php
Go to the documentation of this file.
1<?php
8
17use Wikimedia\Timestamp\TimestampFormat as TS;
18
24class ForeignAPIFile extends File {
26 private $mExists;
28 private $mInfo;
29
31 protected $repoClass = ForeignAPIRepo::class;
32
39 public function __construct( $title, $repo, $info, $exists = false ) {
40 parent::__construct( $title, $repo );
41
42 $this->mInfo = $info;
43 $this->mExists = $exists;
44
45 $this->assertRepoDefined();
46 }
47
53 public static function newFromTitle( Title $title, $repo ) {
54 $data = $repo->fetchImageQuery( [
55 'titles' => 'File:' . $title->getDBkey(),
56 'iiprop' => self::getProps(),
57 'prop' => 'imageinfo',
58 'iimetadataversion' => MediaHandler::getMetadataVersion(),
59 // extmetadata is language-dependent, accessing the current language here
60 // would be problematic, so we just get them all
61 'iiextmetadatamultilang' => 1,
62 ] );
63
64 $info = $repo->getImageInfo( $data );
65
66 if ( $info ) {
67 $lastRedirect = count( $data['query']['redirects'] ?? [] ) - 1;
68 if ( $lastRedirect >= 0 ) {
69 // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
70 $newtitle = Title::newFromText( $data['query']['redirects'][$lastRedirect]['to'] );
71 $img = new self( $newtitle, $repo, $info, true );
72 $img->redirectedFrom( $title->getDBkey() );
73 } else {
74 $img = new self( $title, $repo, $info, true );
75 }
76
77 return $img;
78 } else {
79 return null;
80 }
81 }
82
87 public static function getProps() {
88 return 'timestamp|user|comment|url|size|sha1|metadata|mime|mediatype|extmetadata';
89 }
90
94 public function getRepo() {
95 return $this->repo;
96 }
97
98 // Dummy functions...
99
103 public function exists() {
104 return $this->mExists;
105 }
106
110 public function getPath() {
111 return false;
112 }
113
119 public function transform( $params, $flags = 0 ) {
120 if ( !$this->canRender() ) {
121 // show icon
122 return parent::transform( $params, $flags );
123 }
124
125 // Note, the this->canRender() check above implies
126 // that we have a handler, and it can do makeParamString.
127 $otherParams = $this->handler->makeParamString( $params );
128 $width = $params['width'] ?? -1;
129 $height = $params['height'] ?? -1;
130 $thumbUrl = false;
131
132 if ( $width > 0 || $height > 0 ) {
133 // Only query the remote if there are dimensions
134 $thumbUrl = $this->repo->getThumbUrlFromCache(
135 $this->getName(),
136 $width,
137 $height,
138 $otherParams
139 );
140 } elseif ( $this->getMediaType() === MEDIATYPE_AUDIO ) {
141 // This has no dimensions, but we still need to pass a value to getTransform()
142 $thumbUrl = '/';
143 }
144 if ( $thumbUrl === false ) {
145 return $this->repo->getThumbError(
146 $this->getName(),
147 $width,
148 $height,
149 $otherParams,
150 $this->handler->getLanguage()->getCode()
151 );
152 }
153
154 return $this->handler->getTransform( $this, 'bogus', $thumbUrl, $params );
155 }
156
157 // Info we can get from API...
158
163 public function getWidth( $page = 1 ) {
164 return (int)( $this->mInfo['width'] ?? 0 );
165 }
166
171 public function getHeight( $page = 1 ) {
172 return (int)( $this->mInfo['height'] ?? 0 );
173 }
174
178 public function getMetadata() {
179 if ( isset( $this->mInfo['metadata'] ) ) {
180 return serialize( self::parseMetadata( $this->mInfo['metadata'] ) );
181 }
182
183 return false;
184 }
185
186 public function getMetadataArray(): array {
187 if ( isset( $this->mInfo['metadata'] ) ) {
188 return self::parseMetadata( $this->mInfo['metadata'] );
189 }
190
191 return [];
192 }
193
198 public function getExtendedMetadata() {
199 return $this->mInfo['extmetadata'] ?? null;
200 }
201
206 public static function parseMetadata( $metadata ) {
207 if ( !is_array( $metadata ) ) {
208 return [ '_error' => $metadata ];
209 }
210 '@phan-var array[] $metadata';
211 $ret = [];
212 foreach ( $metadata as $meta ) {
213 $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
214 }
215
216 return $ret;
217 }
218
223 private static function parseMetadataValue( $metadata ) {
224 if ( !is_array( $metadata ) ) {
225 return $metadata;
226 }
227 '@phan-var array[] $metadata';
228 $ret = [];
229 foreach ( $metadata as $meta ) {
230 $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
231 }
232
233 return $ret;
234 }
235
239 public function getSize() {
240 return isset( $this->mInfo['size'] ) ? intval( $this->mInfo['size'] ) : null;
241 }
242
246 public function getUrl() {
247 return isset( $this->mInfo['url'] ) ? strval( $this->mInfo['url'] ) : null;
248 }
249
257 public function getDescriptionShortUrl() {
258 if ( isset( $this->mInfo['descriptionshorturl'] ) ) {
259 return $this->mInfo['descriptionshorturl'];
260 } elseif ( isset( $this->mInfo['pageid'] ) ) {
261 $url = $this->repo->makeUrl( [ 'curid' => $this->mInfo['pageid'] ] );
262 if ( $url !== false ) {
263 return $url;
264 }
265 }
266 return null;
267 }
268
269 public function getUploader( int $audience = self::FOR_PUBLIC, ?Authority $performer = null ): ?UserIdentity {
270 if ( isset( $this->mInfo['user'] ) ) {
271 return UserIdentityValue::newExternal( $this->getRepoName(), $this->mInfo['user'] );
272 }
273 return null;
274 }
275
281 public function getDescription( $audience = self::FOR_PUBLIC, ?Authority $performer = null ) {
282 return isset( $this->mInfo['comment'] ) ? strval( $this->mInfo['comment'] ) : null;
283 }
284
288 public function getSha1() {
289 return isset( $this->mInfo['sha1'] )
290 ? \Wikimedia\base_convert( strval( $this->mInfo['sha1'] ), 16, 36, 31 )
291 : null;
292 }
293
297 public function getTimestamp() {
298 return wfTimestamp( TS::MW,
299 isset( $this->mInfo['timestamp'] )
300 ? strval( $this->mInfo['timestamp'] )
301 : null
302 );
303 }
304
308 public function getMimeType() {
309 if ( !isset( $this->mInfo['mime'] ) ) {
310 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
311 $this->mInfo['mime'] = $magic->getMimeTypeFromExtensionOrNull( $this->getExtension() ) ?? 'unknown/unknown';
312 }
313
314 return $this->mInfo['mime'];
315 }
316
320 public function getMediaType() {
321 if ( isset( $this->mInfo['mediatype'] ) ) {
322 return $this->mInfo['mediatype'];
323 }
324 $magic = MediaWikiServices::getInstance()->getMimeAnalyzer();
325
326 return $magic->getMediaType( null, $this->getMimeType() );
327 }
328
332 public function getDescriptionUrl() {
333 return $this->mInfo['descriptionurl'] ?? false;
334 }
335
341 public function getThumbPath( $suffix = '' ) {
342 if ( !$this->repo->canCacheThumbs() ) {
343 return null;
344 }
345
346 $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath();
347 if ( $suffix ) {
348 $path .= $suffix . '/';
349 }
350 return $path;
351 }
352
356 protected function getThumbnails() {
357 $dir = $this->getThumbPath( $this->getName() );
358 $iter = $this->repo->getBackend()->getFileList( [ 'dir' => $dir ] );
359
360 $files = [];
361 if ( $iter ) {
362 foreach ( $iter as $file ) {
363 $files[] = $file;
364 }
365 }
366
367 return $files;
368 }
369
371 public function purgeCache( $options = [] ) {
372 $this->purgeThumbnails( $options );
373 $this->purgeDescriptionPage();
374 }
375
376 private function purgeDescriptionPage() {
377 $services = MediaWikiServices::getInstance();
378 $langCode = $services->getContentLanguageCode()->toString();
379
380 // Key must match File::getDescriptionText
381 $key = $this->repo->getLocalCacheKey( 'file-remote-description', $langCode, md5( $this->getName() ) );
382 $services->getMainWANObjectCache()->delete( $key );
383 }
384
388 public function purgeThumbnails( $options = [] ) {
389 $key = $this->repo->getLocalCacheKey( 'file-thumb-url', sha1( $this->getName() ) );
390 MediaWikiServices::getInstance()->getMainWANObjectCache()->delete( $key );
391
392 $files = $this->getThumbnails();
393 // Give media handler a chance to filter the purge list
394 $handler = $this->getHandler();
395 if ( $handler ) {
396 $handler->filterThumbnailPurgeList( $files, $options );
397 }
398
399 $dir = $this->getThumbPath( $this->getName() );
400 $purgeList = [];
401 foreach ( $files as $file ) {
402 $purgeList[] = "{$dir}{$file}";
403 }
404
405 # Delete the thumbnails
406 $this->repo->quickPurgeBatch( $purgeList );
407 # Clear out the thumbnail directory if empty
408 $this->repo->quickCleanDir( $dir );
409 }
410
416 public function isTransformedLocally() {
417 return false;
418 }
419}
420
422class_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(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:69
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:80
FileRepo LocalRepo ForeignAPIRepo false $repo
Some member variables can be lazy-initialised using __get().
Definition File.php:127
canRender()
Checks if the output of transform() for this file is likely to be valid.
Definition File.php:941
assertRepoDefined()
Assert that $this->repo is set to a valid FileRepo instance.
Definition File.php:2553
Title string false $title
Definition File.php:130
getName()
Return the name of this file.
Definition File.php:348
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.
Base media handler class.
Base class for the output of MediaHandler::doTransform() and File::transform().
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.