MediaWiki  master
ForeignAPIFile.php
Go to the documentation of this file.
1 <?php
26 
32 class 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 = isset( $data['query']['redirects'] )
75  ? count( $data['query']['redirects'] ) - 1
76  : -1;
77  if ( $lastRedirect >= 0 ) {
78  // @phan-suppress-next-line PhanTypeArraySuspiciousNullable
79  $newtitle = Title::newFromText( $data['query']['redirects'][$lastRedirect]['to'] );
80  $img = new self( $newtitle, $repo, $info, true );
81  $img->redirectedFrom( $title->getDBkey() );
82  } else {
83  $img = new self( $title, $repo, $info, true );
84  }
85 
86  return $img;
87  } else {
88  return null;
89  }
90  }
91 
96  public static function getProps() {
97  return 'timestamp|user|comment|url|size|sha1|metadata|mime|mediatype|extmetadata';
98  }
99 
103  public function getRepo() {
104  return $this->repo;
105  }
106 
107  // Dummy functions...
108 
112  public function exists() {
113  return $this->mExists;
114  }
115 
119  public function getPath() {
120  return false;
121  }
122 
128  public function transform( $params, $flags = 0 ) {
129  if ( !$this->canRender() ) {
130  // show icon
131  return parent::transform( $params, $flags );
132  }
133 
134  // Note, the this->canRender() check above implies
135  // that we have a handler, and it can do makeParamString.
136  $otherParams = $this->handler->makeParamString( $params );
137  $width = $params['width'] ?? -1;
138  $height = $params['height'] ?? -1;
139 
140  $thumbUrl = $this->repo->getThumbUrlFromCache(
141  $this->getName(),
142  $width,
143  $height,
144  $otherParams
145  );
146  if ( $thumbUrl === false ) {
147  global $wgLang;
148 
149  return $this->repo->getThumbError(
150  $this->getName(),
151  $width,
152  $height,
153  $otherParams,
154  $wgLang->getCode()
155  );
156  }
157 
158  return $this->handler->getTransform( $this, 'bogus', $thumbUrl, $params );
159  }
160 
161  // Info we can get from API...
162 
167  public function getWidth( $page = 1 ) {
168  return isset( $this->mInfo['width'] ) ? intval( $this->mInfo['width'] ) : 0;
169  }
170 
175  public function getHeight( $page = 1 ) {
176  return isset( $this->mInfo['height'] ) ? intval( $this->mInfo['height'] ) : 0;
177  }
178 
182  public function getMetadata() {
183  if ( isset( $this->mInfo['metadata'] ) ) {
184  return serialize( self::parseMetadata( $this->mInfo['metadata'] ) );
185  }
186 
187  return false;
188  }
189 
193  public function getMetadataArray(): array {
194  if ( isset( $this->mInfo['metadata'] ) ) {
195  return self::parseMetadata( $this->mInfo['metadata'] );
196  }
197 
198  return [];
199  }
200 
205  public function getExtendedMetadata() {
206  return $this->mInfo['extmetadata'] ?? null;
207  }
208 
213  public static function parseMetadata( $metadata ) {
214  if ( !is_array( $metadata ) ) {
215  return [ '_error' => $metadata ];
216  }
217  '@phan-var array[] $metadata';
218  $ret = [];
219  foreach ( $metadata as $meta ) {
220  $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
221  }
222 
223  return $ret;
224  }
225 
230  private static function parseMetadataValue( $metadata ) {
231  if ( !is_array( $metadata ) ) {
232  return $metadata;
233  }
234  '@phan-var array[] $metadata';
235  $ret = [];
236  foreach ( $metadata as $meta ) {
237  $ret[$meta['name']] = self::parseMetadataValue( $meta['value'] );
238  }
239 
240  return $ret;
241  }
242 
246  public function getSize() {
247  return isset( $this->mInfo['size'] ) ? intval( $this->mInfo['size'] ) : null;
248  }
249 
253  public function getUrl() {
254  return isset( $this->mInfo['url'] ) ? strval( $this->mInfo['url'] ) : null;
255  }
256 
264  public function getDescriptionShortUrl() {
265  if ( isset( $this->mInfo['descriptionshorturl'] ) ) {
266  return $this->mInfo['descriptionshorturl'];
267  } elseif ( isset( $this->mInfo['pageid'] ) ) {
268  $url = $this->repo->makeUrl( [ 'curid' => $this->mInfo['pageid'] ] );
269  if ( $url !== false ) {
270  return $url;
271  }
272  }
273  return null;
274  }
275 
276  public function getUploader( int $audience = self::FOR_PUBLIC, Authority $performer = null ) : ?UserIdentity {
277  if ( isset( $this->mInfo['user'] ) ) {
278  // We don't know if the foreign repo will have a real interwiki prefix,
279  // treat this user as a foreign imported user. Maybe we can do better?
280  return UserIdentityValue::newExternal( $this->getRepoName(), $this->mInfo['user'] );
281  }
282  return null;
283  }
284 
290  public function getDescription( $audience = self::FOR_PUBLIC, Authority $performer = null ) {
291  return isset( $this->mInfo['comment'] ) ? strval( $this->mInfo['comment'] ) : null;
292  }
293 
297  public function getSha1() {
298  return isset( $this->mInfo['sha1'] )
299  ? Wikimedia\base_convert( strval( $this->mInfo['sha1'] ), 16, 36, 31 )
300  : null;
301  }
302 
306  public function getTimestamp() {
307  return wfTimestamp( TS_MW,
308  isset( $this->mInfo['timestamp'] )
309  ? strval( $this->mInfo['timestamp'] )
310  : null
311  );
312  }
313 
317  public function getMimeType() {
318  if ( !isset( $this->mInfo['mime'] ) ) {
319  $magic = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer();
320  $this->mInfo['mime'] = $magic->getMimeTypeFromExtensionOrNull( $this->getExtension() );
321  }
322 
323  return $this->mInfo['mime'];
324  }
325 
329  public function getMediaType() {
330  if ( isset( $this->mInfo['mediatype'] ) ) {
331  return $this->mInfo['mediatype'];
332  }
333  $magic = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer();
334 
335  return $magic->getMediaType( null, $this->getMimeType() );
336  }
337 
341  public function getDescriptionUrl() {
342  return $this->mInfo['descriptionurl'] ?? false;
343  }
344 
350  public function getThumbPath( $suffix = '' ) {
351  if ( !$this->repo->canCacheThumbs() ) {
352  return null;
353  }
354 
355  $path = $this->repo->getZonePath( 'thumb' ) . '/' . $this->getHashPath();
356  if ( $suffix ) {
357  $path .= $suffix . '/';
358  }
359  return $path;
360  }
361 
365  protected function getThumbnails() {
366  $dir = $this->getThumbPath( $this->getName() );
367  $iter = $this->repo->getBackend()->getFileList( [ 'dir' => $dir ] );
368 
369  $files = [];
370  if ( $iter ) {
371  foreach ( $iter as $file ) {
372  $files[] = $file;
373  }
374  }
375 
376  return $files;
377  }
378 
379  public function purgeCache( $options = [] ) {
380  $this->purgeThumbnails( $options );
381  $this->purgeDescriptionPage();
382  }
383 
384  private function purgeDescriptionPage() {
385  $services = MediaWikiServices::getInstance();
386  $url = $this->repo->getDescriptionRenderUrl(
387  $this->getName(),
388  $services->getContentLanguage()->getCode()
389  );
390 
391  $key = $this->repo->getLocalCacheKey( 'file-remote-description', md5( $url ) );
392  $services->getMainWANObjectCache()->delete( $key );
393  }
394 
398  public function purgeThumbnails( $options = [] ) {
399  $key = $this->repo->getLocalCacheKey( 'file-thumb-url', sha1( $this->getName() ) );
400  MediaWikiServices::getInstance()->getMainWANObjectCache()->delete( $key );
401 
402  $files = $this->getThumbnails();
403  // Give media handler a chance to filter the purge list
404  $handler = $this->getHandler();
405  if ( $handler ) {
406  $handler->filterThumbnailPurgeList( $files, $options );
407  }
408 
409  $dir = $this->getThumbPath( $this->getName() );
410  $purgeList = [];
411  foreach ( $files as $file ) {
412  $purgeList[] = "{$dir}{$file}";
413  }
414 
415  # Delete the thumbnails
416  $this->repo->quickPurgeBatch( $purgeList );
417  # Clear out the thumbnail directory if empty
418  $this->repo->quickCleanDir( $dir );
419  }
420 
426  public function isTransformedLocally() {
427  return false;
428  }
429 }
File\getExtension
getExtension()
Get the file extension, e.g.
Definition: File.php:345
MediaWiki\User\UserIdentityValue
Value object representing a user's identity.
Definition: UserIdentityValue.php:35
ForeignAPIFile\getUploader
getUploader(int $audience=self::FOR_PUBLIC, Authority $performer=null)
Get the identity of the file uploader.
Definition: ForeignAPIFile.php:276
ForeignAPIFile\getMimeType
getMimeType()
Definition: ForeignAPIFile.php:317
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:385
File\$repo
FileRepo LocalRepo ForeignAPIRepo bool $repo
Some member variables can be lazy-initialised using __get().
Definition: File.php:113
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:180
ForeignAPIFile\getThumbPath
getThumbPath( $suffix='')
Only useful if we're locally caching thumbs anyway...
Definition: ForeignAPIFile.php:350
MediaHandler\getMetadataVersion
static getMetadataVersion()
Get metadata version.
Definition: MediaHandler.php:293
MediaHandler\filterThumbnailPurgeList
filterThumbnailPurgeList(&$files, $options)
Remove files from the purge list.
Definition: MediaHandler.php:963
true
return true
Definition: router.php:90
ForeignAPIFile\getDescription
getDescription( $audience=self::FOR_PUBLIC, Authority $performer=null)
Definition: ForeignAPIFile.php:290
ForeignAPIFile\newFromTitle
static newFromTitle(Title $title, $repo)
Definition: ForeignAPIFile.php:60
wfTimestamp
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
Definition: GlobalFunctions.php:1692
ForeignAPIFile\exists
exists()
Definition: ForeignAPIFile.php:112
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
ForeignAPIFile\isTransformedLocally
isTransformedLocally()
The thumbnail is created on the foreign server and fetched over internet.
Definition: ForeignAPIFile.php:426
serialize
serialize()
Definition: ApiMessageTrait.php:138
$wgLang
$wgLang
Definition: Setup.php:796
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:39
ForeignAPIFile\getRepo
getRepo()
Definition: ForeignAPIFile.php:103
ForeignAPIFile\getMetadata
getMetadata()
Definition: ForeignAPIFile.php:182
File\$path
string $path
The storage path corresponding to one of the zones.
Definition: File.php:143
MediaWiki\MediaWikiServices\getInstance
static getInstance()
Returns the global default instance of the top level service locator.
Definition: MediaWikiServices.php:241
ForeignAPIFile\$mInfo
array $mInfo
Definition: ForeignAPIFile.php:36
ForeignAPIFile\getExtendedMetadata
getExtendedMetadata()
Definition: ForeignAPIFile.php:205
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:66
Title\getDBkey
getDBkey()
Get the main part with underscores.
Definition: Title.php:1058
ForeignAPIFile\purgeCache
purgeCache( $options=[])
Purge shared caches such as thumbnails and DB data caching STUB Overridden by LocalFile.
Definition: ForeignAPIFile.php:379
File\$url
string $url
The URL corresponding to one of the four basic zones.
Definition: File.php:134
ForeignAPIFile\getThumbnails
getThumbnails()
Definition: ForeignAPIFile.php:365
ForeignAPIFile\getDescriptionShortUrl
getDescriptionShortUrl()
Get short description URL for a file based on the foreign API response, or if unavailable,...
Definition: ForeignAPIFile.php:264
ForeignAPIFile\__construct
__construct( $title, $repo, $info, $exists=false)
Definition: ForeignAPIFile.php:46
ForeignAPIFile\getWidth
getWidth( $page=1)
Definition: ForeignAPIFile.php:167
ForeignAPIFile\getUrl
getUrl()
Definition: ForeignAPIFile.php:253
ForeignAPIFile\getDescriptionUrl
getDescriptionUrl()
Definition: ForeignAPIFile.php:341
ForeignAPIFile\getSize
getSize()
Definition: ForeignAPIFile.php:246
MediaWiki\Permissions\Authority
This interface represents the authority associated the current execution context, such as a web reque...
Definition: Authority.php:35
File\canRender
canRender()
Checks if the output of transform() for this file is likely to be valid.
Definition: File.php:883
ForeignAPIFile\getPath
getPath()
Definition: ForeignAPIFile.php:119
ForeignAPIFile\getTimestamp
getTimestamp()
Definition: ForeignAPIFile.php:306
File\$handler
MediaHandler $handler
Definition: File.php:131
File\$title
Title string bool $title
Definition: File.php:116
ForeignAPIFile\parseMetadataValue
static parseMetadataValue( $metadata)
Definition: ForeignAPIFile.php:230
ForeignAPIFile\getMediaType
getMediaType()
Definition: ForeignAPIFile.php:329
ForeignAPIFile\getHeight
getHeight( $page=1)
Definition: ForeignAPIFile.php:175
File\getName
getName()
Return the name of this file.
Definition: File.php:330
ForeignAPIFile\transform
transform( $params, $flags=0)
Definition: ForeignAPIFile.php:128
File\getRepoName
getRepoName()
Returns the name of the repository.
Definition: File.php:2022
ForeignAPIFile\purgeThumbnails
purgeThumbnails( $options=[])
Definition: ForeignAPIFile.php:398
Title
Represents a title within MediaWiki.
Definition: Title.php:49
File\assertRepoDefined
assertRepoDefined()
Assert that $this->repo is set to a valid FileRepo instance.
Definition: File.php:2469
ForeignAPIFile\getSha1
getSha1()
Definition: ForeignAPIFile.php:297
ForeignAPIFile\parseMetadata
static parseMetadata( $metadata)
Definition: ForeignAPIFile.php:213
ForeignAPIFile\getProps
static getProps()
Get the property string for iiprop and aiprop.
Definition: ForeignAPIFile.php:96
ForeignAPIFile\purgeDescriptionPage
purgeDescriptionPage()
Definition: ForeignAPIFile.php:384
ForeignAPIFile\getMetadataArray
getMetadataArray()
Definition: ForeignAPIFile.php:193
File\getHandler
getHandler()
Get a MediaHandler instance for this file.
Definition: File.php:1545
ForeignAPIFile
Foreign file accessible through api.php requests.
Definition: ForeignAPIFile.php:32
ForeignAPIFile\$repoClass
$repoClass
Definition: ForeignAPIFile.php:38
ForeignAPIFile\$mExists
bool $mExists
Definition: ForeignAPIFile.php:34
File\getHashPath
getHashPath()
Get the filename hash component of the directory including trailing slash, e.g.
Definition: File.php:1687