MediaWiki  master
File.php
Go to the documentation of this file.
1 <?php
9 use Wikimedia\AtEase\AtEase;
10 
33 // @phan-file-suppress PhanTypeMissingReturn false positives
61 abstract class File implements IDBAccessObject {
62  // Bitfield values akin to the Revision deletion constants
63  public const DELETED_FILE = 1;
64  public const DELETED_COMMENT = 2;
65  public const DELETED_USER = 4;
66  public const DELETED_RESTRICTED = 8;
67 
69  public const RENDER_NOW = 1;
74  public const RENDER_FORCE = 2;
75 
76  public const DELETE_SOURCE = 1;
77 
78  // Audience options for File::getDescription()
79  public const FOR_PUBLIC = 1;
80  public const FOR_THIS_USER = 2;
81  public const RAW = 3;
82 
83  // Options for File::thumbName()
84  public const THUMB_FULL_NAME = 1;
85 
106  public $repo;
107 
109  protected $title;
110 
112  protected $lastError;
113 
115  protected $redirected;
116 
118  protected $redirectedTitle;
119 
121  protected $fsFile;
122 
124  protected $handler;
125 
127  protected $url;
128 
130  protected $extension;
131 
133  protected $name;
134 
136  protected $path;
137 
139  protected $hashPath;
140 
144  protected $pageCount;
145 
147  protected $transformScript;
148 
150  protected $redirectTitle;
151 
153  protected $canRender;
154 
158  protected $isSafeFile;
159 
161  protected $repoClass = FileRepo::class;
162 
164  protected $tmpBucketedThumbCache = [];
165 
176  public function __construct( $title, $repo ) {
177  // Some subclasses do not use $title, but set name/title some other way
178  if ( $title !== false ) {
179  $title = self::normalizeTitle( $title, 'exception' );
180  }
181  $this->title = $title;
182  $this->repo = $repo;
183  }
184 
194  public static function normalizeTitle( $title, $exception = false ) {
195  $ret = $title;
196  if ( $ret instanceof Title ) {
197  # Normalize NS_MEDIA -> NS_FILE
198  if ( $ret->getNamespace() == NS_MEDIA ) {
199  $ret = Title::makeTitleSafe( NS_FILE, $ret->getDBkey() );
200  # Sanity check the title namespace
201  } elseif ( $ret->getNamespace() !== NS_FILE ) {
202  $ret = null;
203  }
204  } else {
205  # Convert strings to Title objects
206  $ret = Title::makeTitleSafe( NS_FILE, (string)$ret );
207  }
208  if ( !$ret && $exception !== false ) {
209  throw new MWException( "`$title` is not a valid file title." );
210  }
211 
212  return $ret;
213  }
214 
215  public function __get( $name ) {
216  $function = [ $this, 'get' . ucfirst( $name ) ];
217  if ( !is_callable( $function ) ) {
218  return null;
219  } else {
220  $this->$name = $function();
221 
222  return $this->$name;
223  }
224  }
225 
234  public static function normalizeExtension( $extension ) {
235  $lower = strtolower( $extension );
236  $squish = [
237  'htm' => 'html',
238  'jpeg' => 'jpg',
239  'mpeg' => 'mpg',
240  'tiff' => 'tif',
241  'ogv' => 'ogg' ];
242  if ( isset( $squish[$lower] ) ) {
243  return $squish[$lower];
244  } elseif ( preg_match( '/^[0-9a-z]+$/', $lower ) ) {
245  return $lower;
246  } else {
247  return '';
248  }
249  }
250 
259  public static function checkExtensionCompatibility( File $old, $new ) {
260  $oldMime = $old->getMimeType();
261  $n = strrpos( $new, '.' );
262  $newExt = self::normalizeExtension( $n ? substr( $new, $n + 1 ) : '' );
263  $mimeMagic = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer();
264 
265  return $mimeMagic->isMatchingExtension( $newExt, $oldMime );
266  }
267 
273  public function upgradeRow() {
274  }
275 
283  public static function splitMime( $mime ) {
284  if ( strpos( $mime, '/' ) !== false ) {
285  return explode( '/', $mime, 2 );
286  } else {
287  return [ $mime, 'unknown' ];
288  }
289  }
290 
298  public static function compare( File $a, File $b ) {
299  return strcmp( $a->getName(), $b->getName() );
300  }
301 
307  public function getName() {
308  if ( $this->name === null ) {
309  $this->assertRepoDefined();
310  $this->name = $this->repo->getNameFromTitle( $this->title );
311  }
312 
313  return $this->name;
314  }
315 
321  public function getExtension() {
322  if ( !isset( $this->extension ) ) {
323  $n = strrpos( $this->getName(), '.' );
324  $this->extension = self::normalizeExtension(
325  $n ? substr( $this->getName(), $n + 1 ) : '' );
326  }
327 
328  return $this->extension;
329  }
330 
336  public function getTitle() {
337  return $this->title;
338  }
339 
345  public function getOriginalTitle() {
346  if ( $this->redirected ) {
347  return $this->getRedirectedTitle();
348  }
349 
350  return $this->title;
351  }
352 
358  public function getUrl() {
359  if ( !isset( $this->url ) ) {
360  $this->assertRepoDefined();
361  $ext = $this->getExtension();
362  $this->url = $this->repo->getZoneUrl( 'public', $ext ) . '/' . $this->getUrlRel();
363  }
364 
365  return $this->url;
366  }
367 
374  public function getDescriptionShortUrl() {
375  return null;
376  }
377 
385  public function getFullUrl() {
386  return wfExpandUrl( $this->getUrl(), PROTO_RELATIVE );
387  }
388 
392  public function getCanonicalUrl() {
393  return wfExpandUrl( $this->getUrl(), PROTO_CANONICAL );
394  }
395 
399  public function getViewURL() {
400  if ( $this->mustRender() ) {
401  if ( $this->canRender() ) {
402  return $this->createThumb( $this->getWidth() );
403  } else {
404  wfDebug( __METHOD__ . ': supposed to render ' . $this->getName() .
405  ' (' . $this->getMimeType() . "), but can't!\n" );
406 
407  return $this->getUrl(); # hm... return NULL?
408  }
409  } else {
410  return $this->getUrl();
411  }
412  }
413 
427  public function getPath() {
428  if ( !isset( $this->path ) ) {
429  $this->assertRepoDefined();
430  $this->path = $this->repo->getZonePath( 'public' ) . '/' . $this->getRel();
431  }
432 
433  return $this->path;
434  }
435 
443  public function getLocalRefPath() {
444  $this->assertRepoDefined();
445  if ( !isset( $this->fsFile ) ) {
446  $starttime = microtime( true );
447  $this->fsFile = $this->repo->getLocalReference( $this->getPath() );
448 
449  $statTiming = microtime( true ) - $starttime;
450  MediaWikiServices::getInstance()->getStatsdDataFactory()->timing(
451  'media.thumbnail.generate.fetchoriginal', 1000 * $statTiming );
452 
453  if ( !$this->fsFile ) {
454  $this->fsFile = false; // null => false; cache negative hits
455  }
456  }
457 
458  return ( $this->fsFile )
459  ? $this->fsFile->getPath()
460  : false;
461  }
462 
473  public function getWidth( $page = 1 ) {
474  return false;
475  }
476 
487  public function getHeight( $page = 1 ) {
488  return false;
489  }
490 
500  public function getThumbnailBucket( $desiredWidth, $page = 1 ) {
502 
503  $imageWidth = $this->getWidth( $page );
504 
505  if ( $imageWidth === false ) {
506  return false;
507  }
508 
509  if ( $desiredWidth > $imageWidth ) {
510  return false;
511  }
512 
513  if ( !$wgThumbnailBuckets ) {
514  return false;
515  }
516 
517  $sortedBuckets = $wgThumbnailBuckets;
518 
519  sort( $sortedBuckets );
520 
521  foreach ( $sortedBuckets as $bucket ) {
522  if ( $bucket >= $imageWidth ) {
523  return false;
524  }
525 
526  if ( $bucket - $wgThumbnailMinimumBucketDistance > $desiredWidth ) {
527  return $bucket;
528  }
529  }
530 
531  // Image is bigger than any available bucket
532  return false;
533  }
534 
545  public function getDisplayWidthHeight( $maxWidth, $maxHeight, $page = 1 ) {
546  if ( !$maxWidth || !$maxHeight ) {
547  // should never happen
548  throw new MWException( 'Using a choice from $wgImageLimits that is 0x0' );
549  }
550 
551  $width = $this->getWidth( $page );
552  $height = $this->getHeight( $page );
553  if ( !$width || !$height ) {
554  return [ 0, 0 ];
555  }
556 
557  // Calculate the thumbnail size.
558  if ( $width <= $maxWidth && $height <= $maxHeight ) {
559  // Vectorized image, do nothing.
560  } elseif ( $width / $height >= $maxWidth / $maxHeight ) {
561  # The limiting factor is the width, not the height.
562  $height = round( $height * $maxWidth / $width );
563  $width = $maxWidth;
564  // Note that $height <= $maxHeight now.
565  } else {
566  $newwidth = floor( $width * $maxHeight / $height );
567  $height = round( $height * $newwidth / $width );
568  $width = $newwidth;
569  // Note that $height <= $maxHeight now, but might not be identical
570  // because of rounding.
571  }
572  return [ $width, $height ];
573  }
574 
582  public function getUser( $type = 'text' ) {
583  return null;
584  }
585 
591  public function getLength() {
592  $handler = $this->getHandler();
593  if ( $handler ) {
594  return $handler->getLength( $this );
595  } else {
596  return 0;
597  }
598  }
599 
605  public function isVectorized() {
606  $handler = $this->getHandler();
607  if ( $handler ) {
608  return $handler->isVectorized( $this );
609  } else {
610  return false;
611  }
612  }
613 
625  public function getAvailableLanguages() {
626  $handler = $this->getHandler();
627  if ( $handler ) {
628  return $handler->getAvailableLanguages( $this );
629  } else {
630  return [];
631  }
632  }
633 
641  public function getMatchedLanguage( $userPreferredLanguage ) {
642  $handler = $this->getHandler();
643  if ( $handler ) {
645  $userPreferredLanguage,
647  );
648  }
649 
650  return null;
651  }
652 
660  public function getDefaultRenderLanguage() {
661  $handler = $this->getHandler();
662  if ( $handler ) {
663  return $handler->getDefaultRenderLanguage( $this );
664  } else {
665  return null;
666  }
667  }
668 
679  public function canAnimateThumbIfAppropriate() {
680  $handler = $this->getHandler();
681  if ( !$handler ) {
682  // We cannot handle image whatsoever, thus
683  // one would not expect it to be animated
684  // so true.
685  return true;
686  }
687 
688  return !$this->allowInlineDisplay()
689  // Image is not animated, so one would
690  // not expect thumb to be
691  || !$handler->isAnimatedImage( $this )
692  // Image is animated, but thumbnail isn't.
693  // This is unexpected to the user.
694  || $handler->canAnimateThumbnail( $this );
695  }
696 
703  public function getMetadata() {
704  return false;
705  }
706 
713  public function getCommonMetaArray() {
714  $handler = $this->getHandler();
715 
716  if ( !$handler ) {
717  return false;
718  }
719 
720  return $handler->getCommonMetaArray( $this );
721  }
722 
731  public function convertMetadataVersion( $metadata, $version ) {
732  $handler = $this->getHandler();
733  if ( !is_array( $metadata ) ) {
734  // Just to make the return type consistent
735  $metadata = unserialize( $metadata );
736  }
737  if ( $handler ) {
738  return $handler->convertMetadataVersion( $metadata, $version );
739  } else {
740  return $metadata;
741  }
742  }
743 
750  public function getBitDepth() {
751  return 0;
752  }
753 
760  public function getSize() {
761  return false;
762  }
763 
771  public function getMimeType() {
772  return 'unknown/unknown';
773  }
774 
782  public function getMediaType() {
783  return MEDIATYPE_UNKNOWN;
784  }
785 
798  public function canRender() {
799  if ( !isset( $this->canRender ) ) {
800  $this->canRender = $this->getHandler() && $this->handler->canRender( $this ) && $this->exists();
801  }
802 
803  return $this->canRender;
804  }
805 
810  protected function getCanRender() {
811  return $this->canRender();
812  }
813 
824  public function mustRender() {
825  return $this->getHandler() && $this->handler->mustRender( $this );
826  }
827 
833  public function allowInlineDisplay() {
834  return $this->canRender();
835  }
836 
850  public function isSafeFile() {
851  if ( !isset( $this->isSafeFile ) ) {
852  $this->isSafeFile = $this->getIsSafeFileUncached();
853  }
854 
855  return $this->isSafeFile;
856  }
857 
863  protected function getIsSafeFile() {
864  return $this->isSafeFile();
865  }
866 
872  protected function getIsSafeFileUncached() {
873  global $wgTrustedMediaFormats;
874 
875  if ( $this->allowInlineDisplay() ) {
876  return true;
877  }
878  if ( $this->isTrustedFile() ) {
879  return true;
880  }
881 
882  $type = $this->getMediaType();
883  $mime = $this->getMimeType();
884  # wfDebug( "LocalFile::isSafeFile: type= $type, mime= $mime\n" );
885 
886  if ( !$type || $type === MEDIATYPE_UNKNOWN ) {
887  return false; # unknown type, not trusted
888  }
889  if ( in_array( $type, $wgTrustedMediaFormats ) ) {
890  return true;
891  }
892 
893  if ( $mime === "unknown/unknown" ) {
894  return false; # unknown type, not trusted
895  }
896  if ( in_array( $mime, $wgTrustedMediaFormats ) ) {
897  return true;
898  }
899 
900  return false;
901  }
902 
916  protected function isTrustedFile() {
917  # this could be implemented to check a flag in the database,
918  # look for signatures, etc
919  return false;
920  }
921 
931  public function load( $flags = 0 ) {
932  }
933 
941  public function exists() {
942  return $this->getPath() && $this->repo->fileExists( $this->path );
943  }
944 
951  public function isVisible() {
952  return $this->exists();
953  }
954 
958  private function getTransformScript() {
959  if ( !isset( $this->transformScript ) ) {
960  $this->transformScript = false;
961  if ( $this->repo ) {
962  $script = $this->repo->getThumbScriptUrl();
963  if ( $script ) {
964  $this->transformScript = wfAppendQuery( $script, [ 'f' => $this->getName() ] );
965  }
966  }
967  }
968 
969  return $this->transformScript;
970  }
971 
979  public function getUnscaledThumb( $handlerParams = [] ) {
980  $hp =& $handlerParams;
981  $page = $hp['page'] ?? false;
982  $width = $this->getWidth( $page );
983  if ( !$width ) {
984  return $this->iconThumb();
985  }
986  $hp['width'] = $width;
987  // be sure to ignore any height specification as well (T64258)
988  unset( $hp['height'] );
989 
990  return $this->transform( $hp );
991  }
992 
1002  public function thumbName( $params, $flags = 0 ) {
1003  $name = ( $this->repo && !( $flags & self::THUMB_FULL_NAME ) )
1004  ? $this->repo->nameForThumb( $this->getName() )
1005  : $this->getName();
1006 
1007  return $this->generateThumbName( $name, $params );
1008  }
1009 
1017  public function generateThumbName( $name, $params ) {
1018  if ( !$this->getHandler() ) {
1019  return null;
1020  }
1021  $extension = $this->getExtension();
1022  list( $thumbExt, ) = $this->getHandler()->getThumbType(
1023  $extension, $this->getMimeType(), $params );
1024  $thumbName = $this->getHandler()->makeParamString( $params );
1025 
1026  if ( $this->repo->supportsSha1URLs() ) {
1027  $thumbName .= '-' . $this->getSha1() . '.' . $thumbExt;
1028  } else {
1029  $thumbName .= '-' . $name;
1030 
1031  if ( $thumbExt != $extension ) {
1032  $thumbName .= ".$thumbExt";
1033  }
1034  }
1035 
1036  return $thumbName;
1037  }
1038 
1056  public function createThumb( $width, $height = -1 ) {
1057  $params = [ 'width' => $width ];
1058  if ( $height != -1 ) {
1059  $params['height'] = $height;
1060  }
1061  $thumb = $this->transform( $params );
1062  if ( !$thumb || $thumb->isError() ) {
1063  return '';
1064  }
1065 
1066  return $thumb->getUrl();
1067  }
1068 
1078  protected function transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ) {
1079  global $wgIgnoreImageErrors;
1080 
1081  $handler = $this->getHandler();
1082  if ( $handler && $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
1083  return $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
1084  } else {
1085  return new MediaTransformError( 'thumbnail_error',
1086  $params['width'], 0, wfMessage( 'thumbnail-dest-create' ) );
1087  }
1088  }
1089 
1098  public function transform( $params, $flags = 0 ) {
1099  global $wgThumbnailEpoch;
1100 
1101  do {
1102  if ( !$this->canRender() ) {
1103  $thumb = $this->iconThumb();
1104  break; // not a bitmap or renderable image, don't try
1105  }
1106 
1107  // Get the descriptionUrl to embed it as comment into the thumbnail. T21791.
1108  $descriptionUrl = $this->getDescriptionUrl();
1109  if ( $descriptionUrl ) {
1110  $params['descriptionUrl'] = wfExpandUrl( $descriptionUrl, PROTO_CANONICAL );
1111  }
1112 
1113  $handler = $this->getHandler();
1114  $script = $this->getTransformScript();
1115  if ( $script && !( $flags & self::RENDER_NOW ) ) {
1116  // Use a script to transform on client request, if possible
1117  $thumb = $handler->getScriptedTransform( $this, $script, $params );
1118  if ( $thumb ) {
1119  break;
1120  }
1121  }
1122 
1123  $normalisedParams = $params;
1124  $handler->normaliseParams( $this, $normalisedParams );
1125 
1126  $thumbName = $this->thumbName( $normalisedParams );
1127  $thumbUrl = $this->getThumbUrl( $thumbName );
1128  $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path
1129 
1130  if ( $this->repo ) {
1131  // Defer rendering if a 404 handler is set up...
1132  if ( $this->repo->canTransformVia404() && !( $flags & self::RENDER_NOW ) ) {
1133  // XXX: Pass in the storage path even though we are not rendering anything
1134  // and the path is supposed to be an FS path. This is due to getScalerType()
1135  // getting called on the path and clobbering $thumb->getUrl() if it's false.
1136  $thumb = $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
1137  break;
1138  }
1139  // Check if an up-to-date thumbnail already exists...
1140  wfDebug( __METHOD__ . ": Doing stat for $thumbPath\n" );
1141  if ( !( $flags & self::RENDER_FORCE ) && $this->repo->fileExists( $thumbPath ) ) {
1142  $timestamp = $this->repo->getFileTimestamp( $thumbPath );
1143  if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) {
1144  // XXX: Pass in the storage path even though we are not rendering anything
1145  // and the path is supposed to be an FS path. This is due to getScalerType()
1146  // getting called on the path and clobbering $thumb->getUrl() if it's false.
1147  $thumb = $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
1148  $thumb->setStoragePath( $thumbPath );
1149  break;
1150  }
1151  } elseif ( $flags & self::RENDER_FORCE ) {
1152  wfDebug( __METHOD__ . " forcing rendering per flag File::RENDER_FORCE\n" );
1153  }
1154 
1155  // If the backend is ready-only, don't keep generating thumbnails
1156  // only to return transformation errors, just return the error now.
1157  if ( $this->repo->getReadOnlyReason() !== false ) {
1158  $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags );
1159  break;
1160  }
1161  }
1162 
1163  $tmpFile = $this->makeTransformTmpFile( $thumbPath );
1164 
1165  if ( !$tmpFile ) {
1166  $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags );
1167  } else {
1168  $thumb = $this->generateAndSaveThumb( $tmpFile, $params, $flags );
1169  }
1170  } while ( false );
1171 
1172  return is_object( $thumb ) ? $thumb : false;
1173  }
1174 
1182  public function generateAndSaveThumb( $tmpFile, $transformParams, $flags ) {
1183  global $wgIgnoreImageErrors;
1184 
1185  $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
1186 
1187  $handler = $this->getHandler();
1188 
1189  $normalisedParams = $transformParams;
1190  $handler->normaliseParams( $this, $normalisedParams );
1191 
1192  $thumbName = $this->thumbName( $normalisedParams );
1193  $thumbUrl = $this->getThumbUrl( $thumbName );
1194  $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path
1195 
1196  $tmpThumbPath = $tmpFile->getPath();
1197 
1198  if ( $handler->supportsBucketing() ) {
1199  $this->generateBucketsIfNeeded( $normalisedParams, $flags );
1200  }
1201 
1202  $starttime = microtime( true );
1203 
1204  // Actually render the thumbnail...
1205  $thumb = $handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $transformParams );
1206  $tmpFile->bind( $thumb ); // keep alive with $thumb
1207 
1208  $statTiming = microtime( true ) - $starttime;
1209  $stats->timing( 'media.thumbnail.generate.transform', 1000 * $statTiming );
1210 
1211  if ( !$thumb ) { // bad params?
1212  $thumb = false;
1213  } elseif ( $thumb->isError() ) { // transform error
1215  '@phan-var MediaTransformError $thumb';
1216  $this->lastError = $thumb->toText();
1217  // Ignore errors if requested
1218  if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
1219  $thumb = $handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $transformParams );
1220  }
1221  } elseif ( $this->repo && $thumb->hasFile() && !$thumb->fileIsSource() ) {
1222  // Copy the thumbnail from the file system into storage...
1223 
1224  $starttime = microtime( true );
1225 
1226  $disposition = $this->getThumbDisposition( $thumbName );
1227  $status = $this->repo->quickImport( $tmpThumbPath, $thumbPath, $disposition );
1228  if ( $status->isOK() ) {
1229  $thumb->setStoragePath( $thumbPath );
1230  } else {
1231  $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $transformParams, $flags );
1232  }
1233 
1234  $statTiming = microtime( true ) - $starttime;
1235  $stats->timing( 'media.thumbnail.generate.store', 1000 * $statTiming );
1236 
1237  // Give extensions a chance to do something with this thumbnail...
1238  Hooks::run( 'FileTransformed', [ $this, $thumb, $tmpThumbPath, $thumbPath ] );
1239  }
1240 
1241  return $thumb;
1242  }
1243 
1250  protected function generateBucketsIfNeeded( $params, $flags = 0 ) {
1251  if ( !$this->repo
1252  || !isset( $params['physicalWidth'] )
1253  || !isset( $params['physicalHeight'] )
1254  ) {
1255  return false;
1256  }
1257 
1258  $bucket = $this->getThumbnailBucket( $params['physicalWidth'] );
1259 
1260  if ( !$bucket || $bucket == $params['physicalWidth'] ) {
1261  return false;
1262  }
1263 
1264  $bucketPath = $this->getBucketThumbPath( $bucket );
1265 
1266  if ( $this->repo->fileExists( $bucketPath ) ) {
1267  return false;
1268  }
1269 
1270  $starttime = microtime( true );
1271 
1272  $params['physicalWidth'] = $bucket;
1273  $params['width'] = $bucket;
1274 
1275  $params = $this->getHandler()->sanitizeParamsForBucketing( $params );
1276 
1277  $tmpFile = $this->makeTransformTmpFile( $bucketPath );
1278 
1279  if ( !$tmpFile ) {
1280  return false;
1281  }
1282 
1283  $thumb = $this->generateAndSaveThumb( $tmpFile, $params, $flags );
1284 
1285  $buckettime = microtime( true ) - $starttime;
1286 
1287  if ( !$thumb || $thumb->isError() ) {
1288  return false;
1289  }
1290 
1291  $this->tmpBucketedThumbCache[$bucket] = $tmpFile->getPath();
1292  // For the caching to work, we need to make the tmp file survive as long as
1293  // this object exists
1294  $tmpFile->bind( $this );
1295 
1296  MediaWikiServices::getInstance()->getStatsdDataFactory()->timing(
1297  'media.thumbnail.generate.bucket', 1000 * $buckettime );
1298 
1299  return true;
1300  }
1301 
1307  public function getThumbnailSource( $params ) {
1308  if ( $this->repo
1309  && $this->getHandler()->supportsBucketing()
1310  && isset( $params['physicalWidth'] )
1311  && $bucket = $this->getThumbnailBucket( $params['physicalWidth'] )
1312  ) {
1313  if ( $this->getWidth() != 0 ) {
1314  $bucketHeight = round( $this->getHeight() * ( $bucket / $this->getWidth() ) );
1315  } else {
1316  $bucketHeight = 0;
1317  }
1318 
1319  // Try to avoid reading from storage if the file was generated by this script
1320  if ( isset( $this->tmpBucketedThumbCache[$bucket] ) ) {
1321  $tmpPath = $this->tmpBucketedThumbCache[$bucket];
1322 
1323  if ( file_exists( $tmpPath ) ) {
1324  return [
1325  'path' => $tmpPath,
1326  'width' => $bucket,
1327  'height' => $bucketHeight
1328  ];
1329  }
1330  }
1331 
1332  $bucketPath = $this->getBucketThumbPath( $bucket );
1333 
1334  if ( $this->repo->fileExists( $bucketPath ) ) {
1335  $fsFile = $this->repo->getLocalReference( $bucketPath );
1336 
1337  if ( $fsFile ) {
1338  return [
1339  'path' => $fsFile->getPath(),
1340  'width' => $bucket,
1341  'height' => $bucketHeight
1342  ];
1343  }
1344  }
1345  }
1346 
1347  // Thumbnailing a very large file could result in network saturation if
1348  // everyone does it at once.
1349  if ( $this->getSize() >= 1e7 ) { // 10MB
1350  $work = new PoolCounterWorkViaCallback( 'GetLocalFileCopy', sha1( $this->getName() ),
1351  [
1352  'doWork' => function () {
1353  return $this->getLocalRefPath();
1354  }
1355  ]
1356  );
1357  $srcPath = $work->execute();
1358  } else {
1359  $srcPath = $this->getLocalRefPath();
1360  }
1361 
1362  // Original file
1363  return [
1364  'path' => $srcPath,
1365  'width' => $this->getWidth(),
1366  'height' => $this->getHeight()
1367  ];
1368  }
1369 
1375  protected function getBucketThumbPath( $bucket ) {
1376  $thumbName = $this->getBucketThumbName( $bucket );
1377  return $this->getThumbPath( $thumbName );
1378  }
1379 
1385  protected function getBucketThumbName( $bucket ) {
1386  return $this->thumbName( [ 'physicalWidth' => $bucket ] );
1387  }
1388 
1394  protected function makeTransformTmpFile( $thumbPath ) {
1395  $thumbExt = FileBackend::extensionFromPath( $thumbPath );
1396  return MediaWikiServices::getInstance()->getTempFSFileFactory()
1397  ->newTempFSFile( 'transform_', $thumbExt );
1398  }
1399 
1405  public function getThumbDisposition( $thumbName, $dispositionType = 'inline' ) {
1406  $fileName = $this->name; // file name to suggest
1407  $thumbExt = FileBackend::extensionFromPath( $thumbName );
1408  if ( $thumbExt != '' && $thumbExt !== $this->getExtension() ) {
1409  $fileName .= ".$thumbExt";
1410  }
1411 
1412  return FileBackend::makeContentDisposition( $dispositionType, $fileName );
1413  }
1414 
1420  protected function migrateThumbFile( $thumbName ) {
1421  }
1422 
1429  public function getHandler() {
1430  if ( !isset( $this->handler ) ) {
1431  $this->handler = MediaHandler::getHandler( $this->getMimeType() );
1432  }
1433 
1434  return $this->handler;
1435  }
1436 
1442  public function iconThumb() {
1443  global $wgResourceBasePath, $IP;
1444  $assetsPath = "$wgResourceBasePath/resources/assets/file-type-icons/";
1445  $assetsDirectory = "$IP/resources/assets/file-type-icons/";
1446 
1447  $try = [ 'fileicon-' . $this->getExtension() . '.png', 'fileicon.png' ];
1448  foreach ( $try as $icon ) {
1449  if ( file_exists( $assetsDirectory . $icon ) ) { // always FS
1450  $params = [ 'width' => 120, 'height' => 120 ];
1451 
1452  return new ThumbnailImage( $this, $assetsPath . $icon, false, $params );
1453  }
1454  }
1455 
1456  return null;
1457  }
1458 
1464  public function getLastError() {
1465  return $this->lastError;
1466  }
1467 
1474  protected function getThumbnails() {
1475  return [];
1476  }
1477 
1485  public function purgeCache( $options = [] ) {
1486  }
1487 
1493  public function purgeDescription() {
1494  $title = $this->getTitle();
1495  if ( $title ) {
1497  $hcu = MediaWikiServices::getInstance()->getHtmlCacheUpdater();
1498  $hcu->purgeTitleUrls( $title, $hcu::PURGE_INTENT_TXROUND_REFLECTED );
1499  }
1500  }
1501 
1506  public function purgeEverything() {
1507  // Delete thumbnails and refresh file metadata cache
1508  $this->purgeCache();
1509  $this->purgeDescription();
1510  // Purge cache of all pages using this file
1511  $title = $this->getTitle();
1512  if ( $title ) {
1514  $title,
1515  'imagelinks',
1516  [ 'causeAction' => 'file-purge' ]
1517  );
1518  JobQueueGroup::singleton()->lazyPush( $job );
1519  }
1520  }
1521 
1533  public function getHistory( $limit = null, $start = null, $end = null, $inc = true ) {
1534  return [];
1535  }
1536 
1546  public function nextHistoryLine() {
1547  return false;
1548  }
1549 
1556  public function resetHistory() {
1557  }
1558 
1566  public function getHashPath() {
1567  if ( $this->hashPath === null ) {
1568  $this->assertRepoDefined();
1569  $this->hashPath = $this->repo->getHashPath( $this->getName() );
1570  }
1571 
1572  return $this->hashPath;
1573  }
1574 
1581  public function getRel() {
1582  return $this->getHashPath() . $this->getName();
1583  }
1584 
1592  public function getArchiveRel( $suffix = false ) {
1593  $path = 'archive/' . $this->getHashPath();
1594  if ( $suffix === false ) {
1595  $path = rtrim( $path, '/' );
1596  } else {
1597  $path .= $suffix;
1598  }
1599 
1600  return $path;
1601  }
1602 
1610  public function getThumbRel( $suffix = false ) {
1611  $path = $this->getRel();
1612  if ( $suffix !== false ) {
1613  $path .= '/' . $suffix;
1614  }
1615 
1616  return $path;
1617  }
1618 
1625  public function getUrlRel() {
1626  return $this->getHashPath() . rawurlencode( $this->getName() );
1627  }
1628 
1637  private function getArchiveThumbRel( $archiveName, $suffix = false ) {
1638  $path = $this->getArchiveRel( $archiveName );
1639  if ( $suffix !== false ) {
1640  $path .= '/' . $suffix;
1641  }
1642 
1643  return $path;
1644  }
1645 
1652  public function getArchivePath( $suffix = false ) {
1653  $this->assertRepoDefined();
1654 
1655  return $this->repo->getZonePath( 'public' ) . '/' . $this->getArchiveRel( $suffix );
1656  }
1657 
1665  public function getArchiveThumbPath( $archiveName, $suffix = false ) {
1666  $this->assertRepoDefined();
1667 
1668  return $this->repo->getZonePath( 'thumb' ) . '/' .
1669  $this->getArchiveThumbRel( $archiveName, $suffix );
1670  }
1671 
1678  public function getThumbPath( $suffix = false ) {
1679  $this->assertRepoDefined();
1680 
1681  return $this->repo->getZonePath( 'thumb' ) . '/' . $this->getThumbRel( $suffix );
1682  }
1683 
1690  public function getTranscodedPath( $suffix = false ) {
1691  $this->assertRepoDefined();
1692 
1693  return $this->repo->getZonePath( 'transcoded' ) . '/' . $this->getThumbRel( $suffix );
1694  }
1695 
1702  public function getArchiveUrl( $suffix = false ) {
1703  $this->assertRepoDefined();
1704  $ext = $this->getExtension();
1705  $path = $this->repo->getZoneUrl( 'public', $ext ) . '/archive/' . $this->getHashPath();
1706  if ( $suffix === false ) {
1707  $path = rtrim( $path, '/' );
1708  } else {
1709  $path .= rawurlencode( $suffix );
1710  }
1711 
1712  return $path;
1713  }
1714 
1722  public function getArchiveThumbUrl( $archiveName, $suffix = false ) {
1723  $this->assertRepoDefined();
1724  $ext = $this->getExtension();
1725  $path = $this->repo->getZoneUrl( 'thumb', $ext ) . '/archive/' .
1726  $this->getHashPath() . rawurlencode( $archiveName );
1727  if ( $suffix !== false ) {
1728  $path .= '/' . rawurlencode( $suffix );
1729  }
1730 
1731  return $path;
1732  }
1733 
1741  private function getZoneUrl( $zone, $suffix = false ) {
1742  $this->assertRepoDefined();
1743  $ext = $this->getExtension();
1744  $path = $this->repo->getZoneUrl( $zone, $ext ) . '/' . $this->getUrlRel();
1745  if ( $suffix !== false ) {
1746  $path .= '/' . rawurlencode( $suffix );
1747  }
1748 
1749  return $path;
1750  }
1751 
1758  public function getThumbUrl( $suffix = false ) {
1759  return $this->getZoneUrl( 'thumb', $suffix );
1760  }
1761 
1768  public function getTranscodedUrl( $suffix = false ) {
1769  return $this->getZoneUrl( 'transcoded', $suffix );
1770  }
1771 
1778  public function getVirtualUrl( $suffix = false ) {
1779  $this->assertRepoDefined();
1780  $path = $this->repo->getVirtualUrl() . '/public/' . $this->getUrlRel();
1781  if ( $suffix !== false ) {
1782  $path .= '/' . rawurlencode( $suffix );
1783  }
1784 
1785  return $path;
1786  }
1787 
1794  public function getArchiveVirtualUrl( $suffix = false ) {
1795  $this->assertRepoDefined();
1796  $path = $this->repo->getVirtualUrl() . '/public/archive/' . $this->getHashPath();
1797  if ( $suffix === false ) {
1798  $path = rtrim( $path, '/' );
1799  } else {
1800  $path .= rawurlencode( $suffix );
1801  }
1802 
1803  return $path;
1804  }
1805 
1812  public function getThumbVirtualUrl( $suffix = false ) {
1813  $this->assertRepoDefined();
1814  $path = $this->repo->getVirtualUrl() . '/thumb/' . $this->getUrlRel();
1815  if ( $suffix !== false ) {
1816  $path .= '/' . rawurlencode( $suffix );
1817  }
1818 
1819  return $path;
1820  }
1821 
1825  protected function isHashed() {
1826  $this->assertRepoDefined();
1827 
1828  return (bool)$this->repo->getHashLevels();
1829  }
1830 
1834  protected function readOnlyError() {
1835  throw new MWException( static::class . ': write operations are not supported' );
1836  }
1837 
1853  public function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '',
1854  $watch = false, $timestamp = false, User $user = null
1855  ) {
1856  $this->readOnlyError();
1857  }
1858 
1880  public function publish( $src, $flags = 0, array $options = [] ) {
1881  $this->readOnlyError();
1882  }
1883 
1888  public function formatMetadata( $context = false ) {
1889  if ( !$this->getHandler() ) {
1890  return false;
1891  }
1892 
1893  return $this->getHandler()->formatMetadata( $this, $context );
1894  }
1895 
1901  public function isLocal() {
1902  return $this->repo && $this->repo->isLocal();
1903  }
1904 
1910  public function getRepoName() {
1911  return $this->repo ? $this->repo->getName() : 'unknown';
1912  }
1913 
1919  public function getRepo() {
1920  return $this->repo;
1921  }
1922 
1929  public function isOld() {
1930  return false;
1931  }
1932 
1940  public function isDeleted( $field ) {
1941  return false;
1942  }
1943 
1949  public function getVisibility() {
1950  return 0;
1951  }
1952 
1958  public function wasDeleted() {
1959  $title = $this->getTitle();
1960 
1961  return $title && $title->isDeletedQuick();
1962  }
1963 
1976  public function move( $target ) {
1977  $this->readOnlyError();
1978  }
1979 
1997  public function delete( $reason, $suppress = false, $user = null ) {
1998  wfDeprecated( __METHOD__, '1.35' );
1999  $this->readOnlyError();
2000  }
2001 
2019  public function deleteFile( $reason, User $user, $suppress = false ) {
2020  $this->readOnlyError();
2021  }
2022 
2036  public function restore( $versions = [], $unsuppress = false ) {
2037  $this->readOnlyError();
2038  }
2039 
2047  public function isMultipage() {
2048  return $this->getHandler() && $this->handler->isMultiPage( $this );
2049  }
2050 
2057  public function pageCount() {
2058  if ( !isset( $this->pageCount ) ) {
2059  if ( $this->getHandler() && $this->handler->isMultiPage( $this ) ) {
2060  $this->pageCount = $this->handler->pageCount( $this );
2061  } else {
2062  $this->pageCount = false;
2063  }
2064  }
2065 
2066  return $this->pageCount;
2067  }
2068 
2078  public static function scaleHeight( $srcWidth, $srcHeight, $dstWidth ) {
2079  // Exact integer multiply followed by division
2080  if ( $srcWidth == 0 ) {
2081  return 0;
2082  } else {
2083  return (int)round( $srcHeight * $dstWidth / $srcWidth );
2084  }
2085  }
2086 
2097  protected function getImageSize( $filePath ) {
2098  if ( !$this->getHandler() ) {
2099  return false;
2100  }
2101 
2102  return $this->getHandler()->getImageSize( $this, $filePath );
2103  }
2104 
2111  public function getDescriptionUrl() {
2112  if ( $this->repo ) {
2113  return $this->repo->getDescriptionUrl( $this->getName() );
2114  } else {
2115  return false;
2116  }
2117  }
2118 
2125  public function getDescriptionText( Language $lang = null ) {
2126  global $wgLang;
2127 
2128  if ( !$this->repo || !$this->repo->fetchDescription ) {
2129  return false;
2130  }
2131 
2132  $lang = $lang ?? $wgLang;
2133 
2134  $renderUrl = $this->repo->getDescriptionRenderUrl( $this->getName(), $lang->getCode() );
2135  if ( $renderUrl ) {
2136  $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
2137  $key = $this->repo->getLocalCacheKey(
2138  'RemoteFileDescription',
2139  $lang->getCode(),
2140  md5( $this->getName() )
2141  );
2142  $fname = __METHOD__;
2143 
2144  return $cache->getWithSetCallback(
2145  $key,
2146  $this->repo->descriptionCacheExpiry ?: $cache::TTL_UNCACHEABLE,
2147  function ( $oldValue, &$ttl, array &$setOpts ) use ( $renderUrl, $fname ) {
2148  wfDebug( "Fetching shared description from $renderUrl\n" );
2149  $res = MediaWikiServices::getInstance()->getHttpRequestFactory()->
2150  get( $renderUrl, [], $fname );
2151  if ( !$res ) {
2152  $ttl = WANObjectCache::TTL_UNCACHEABLE;
2153  }
2154 
2155  return $res;
2156  }
2157  );
2158  }
2159 
2160  return false;
2161  }
2162 
2175  public function getDescription( $audience = self::FOR_PUBLIC, User $user = null ) {
2176  return null;
2177  }
2178 
2184  public function getTimestamp() {
2185  $this->assertRepoDefined();
2186 
2187  return $this->repo->getFileTimestamp( $this->getPath() );
2188  }
2189 
2197  public function getDescriptionTouched() {
2198  return false;
2199  }
2200 
2206  public function getSha1() {
2207  $this->assertRepoDefined();
2208 
2209  return $this->repo->getFileSha1( $this->getPath() );
2210  }
2211 
2217  public function getStorageKey() {
2218  $hash = $this->getSha1();
2219  if ( !$hash ) {
2220  return false;
2221  }
2222  $ext = $this->getExtension();
2223  $dotExt = $ext === '' ? '' : ".$ext";
2224 
2225  return $hash . $dotExt;
2226  }
2227 
2236  public function userCan( $field, User $user = null ) {
2237  return true;
2238  }
2239 
2244  public function getContentHeaders() {
2245  $handler = $this->getHandler();
2246  if ( $handler ) {
2247  $metadata = $this->getMetadata();
2248 
2249  if ( is_string( $metadata ) ) {
2250  $metadata = AtEase::quietCall( 'unserialize', $metadata );
2251  }
2252 
2253  if ( !is_array( $metadata ) ) {
2254  $metadata = [];
2255  }
2256 
2257  return $handler->getContentHeaders( $metadata );
2258  }
2259 
2260  return [];
2261  }
2262 
2266  public function getLongDesc() {
2267  $handler = $this->getHandler();
2268  if ( $handler ) {
2269  return $handler->getLongDesc( $this );
2270  } else {
2271  return MediaHandler::getGeneralLongDesc( $this );
2272  }
2273  }
2274 
2278  public function getShortDesc() {
2279  $handler = $this->getHandler();
2280  if ( $handler ) {
2281  return $handler->getShortDesc( $this );
2282  } else {
2283  return MediaHandler::getGeneralShortDesc( $this );
2284  }
2285  }
2286 
2290  public function getDimensionsString() {
2291  $handler = $this->getHandler();
2292  if ( $handler ) {
2293  return $handler->getDimensionsString( $this );
2294  } else {
2295  return '';
2296  }
2297  }
2298 
2302  public function getRedirected() {
2303  return $this->redirected;
2304  }
2305 
2309  protected function getRedirectedTitle() {
2310  if ( $this->redirected ) {
2311  if ( !$this->redirectTitle ) {
2312  $this->redirectTitle = Title::makeTitle( NS_FILE, $this->redirected );
2313  }
2314 
2315  return $this->redirectTitle;
2316  }
2317 
2318  return null;
2319  }
2320 
2325  public function redirectedFrom( $from ) {
2326  $this->redirected = $from;
2327  }
2328 
2332  public function isMissing() {
2333  return false;
2334  }
2335 
2340  public function isCacheable() {
2341  return true;
2342  }
2343 
2348  protected function assertRepoDefined() {
2349  if ( !( $this->repo instanceof $this->repoClass ) ) {
2350  throw new MWException( "A {$this->repoClass} object is not set for this File.\n" );
2351  }
2352  }
2353 
2358  protected function assertTitleDefined() {
2359  if ( !( $this->title instanceof Title ) ) {
2360  throw new MWException( "A Title object is not set for this File.\n" );
2361  }
2362  }
2363 
2368  public function isExpensiveToThumbnail() {
2369  $handler = $this->getHandler();
2370  return $handler ? $handler->isExpensiveToThumbnail( $this ) : false;
2371  }
2372 
2378  public function isTransformedLocally() {
2379  return true;
2380  }
2381 }
File\getExtension
getExtension()
Get the file extension, e.g.
Definition: File.php:321
File\getContentHeaders
getContentHeaders()
Definition: File.php:2244
File\THUMB_FULL_NAME
const THUMB_FULL_NAME
Definition: File.php:84
File\getDisplayWidthHeight
getDisplayWidthHeight( $maxWidth, $maxHeight, $page=1)
Get the width and height to display image at.
Definition: File.php:545
File\wasDeleted
wasDeleted()
Was this file ever deleted from the wiki?
Definition: File.php:1958
File\redirectedFrom
redirectedFrom( $from)
Definition: File.php:2325
File\getDescriptionTouched
getDescriptionTouched()
Returns the timestamp (in TS_MW format) of the last change of the description page.
Definition: File.php:2197
File\getPath
getPath()
Return the storage path to the file.
Definition: File.php:427
MediaTransformError
Basic media transform error class.
Definition: MediaTransformError.php:29
ThumbnailImage
Media transform output for images.
Definition: ThumbnailImage.php:29
File\checkExtensionCompatibility
static checkExtensionCompatibility(File $old, $new)
Checks if file extensions are compatible.
Definition: File.php:259
File\$repo
FileRepo LocalRepo ForeignAPIRepo bool $repo
Some member variables can be lazy-initialised using __get().
Definition: File.php:106
MediaHandler\getCommonMetaArray
getCommonMetaArray(File $file)
Get an array of standard (FormatMetadata type) metadata values.
Definition: MediaHandler.php:239
File\canAnimateThumbIfAppropriate
canAnimateThumbIfAppropriate()
Will the thumbnail be animated if one would expect it to be.
Definition: File.php:679
MediaHandler\normaliseParams
normaliseParams( $image, &$params)
Changes the parameter array as necessary, ready for transformation.
PROTO_CANONICAL
const PROTO_CANONICAL
Definition: Defines.php:212
File\getArchiveThumbPath
getArchiveThumbPath( $archiveName, $suffix=false)
Get the path of an archived file's thumbs, or a particular thumb if $suffix is specified.
Definition: File.php:1665
File\getHeight
getHeight( $page=1)
Return the height of the image.
Definition: File.php:487
File\DELETED_USER
const DELETED_USER
Definition: File.php:65
File\$tmpBucketedThumbCache
array $tmpBucketedThumbCache
Cache of tmp filepaths pointing to generated bucket thumbnails, keyed by width.
Definition: File.php:164
File\getDescriptionShortUrl
getDescriptionShortUrl()
Get short description URL for a files based on the page ID.
Definition: File.php:374
File\getBitDepth
getBitDepth()
Return the bit depth of the file Overridden by LocalFile STUB.
Definition: File.php:750
File\getUrlRel
getUrlRel()
Get urlencoded path of the file relative to the public zone root.
Definition: File.php:1625
File\migrateThumbFile
migrateThumbFile( $thumbName)
Hook into transform() to allow migration of thumbnail files STUB.
Definition: File.php:1420
File\isMultipage
isMultipage()
Returns 'true' if this file is a type which supports multiple pages, e.g.
Definition: File.php:2047
File\getFullUrl
getFullUrl()
Return a fully-qualified URL to the file.
Definition: File.php:385
File\getZoneUrl
getZoneUrl( $zone, $suffix=false)
Get the URL of the zone directory, or a particular file if $suffix is specified.
Definition: File.php:1741
File\DELETED_RESTRICTED
const DELETED_RESTRICTED
Definition: File.php:66
File\getMetadata
getMetadata()
Get handler-specific metadata Overridden by LocalFile, UnregisteredLocalFile STUB.
Definition: File.php:703
File\RAW
const RAW
Definition: File.php:81
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:144
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
File\getIsSafeFileUncached
getIsSafeFileUncached()
Uncached accessor.
Definition: File.php:872
File\$transformScript
string $transformScript
URL of transformscript (for example thumb.php)
Definition: File.php:147
File\getRel
getRel()
Get the path of the file relative to the public zone root.
Definition: File.php:1581
File\isExpensiveToThumbnail
isExpensiveToThumbnail()
True if creating thumbnails from the file is large or otherwise resource-intensive.
Definition: File.php:2368
File\isMissing
isMissing()
Definition: File.php:2332
File\getOriginalTitle
getOriginalTitle()
Return the title used to find this file.
Definition: File.php:345
File\$redirectTitle
Title $redirectTitle
Definition: File.php:150
MediaHandler\getShortDesc
getShortDesc( $file)
Short description.
Definition: MediaHandler.php:580
File\getLastError
getLastError()
Get last thumbnailing error.
Definition: File.php:1464
File\getTimestamp
getTimestamp()
Get the 14-character timestamp of the file upload.
Definition: File.php:2184
File\getSha1
getSha1()
Get the SHA-1 base 36 hash of the file.
Definition: File.php:2206
File\convertMetadataVersion
convertMetadataVersion( $metadata, $version)
get versioned metadata
Definition: File.php:731
File\getUser
getUser( $type='text')
Returns ID or name of user who uploaded the file STUB.
Definition: File.php:582
FileBackend\extensionFromPath
static extensionFromPath( $path, $case='lowercase')
Get the final extension from a storage or FS path.
Definition: FileBackend.php:1598
File\RENDER_FORCE
const RENDER_FORCE
Force rendering even if thumbnail already exist and using RENDER_NOW I.e.
Definition: File.php:74
File\getUrl
getUrl()
Return the URL of the file.
Definition: File.php:358
NS_FILE
const NS_FILE
Definition: Defines.php:75
File\compare
static compare(File $a, File $b)
Callback for usort() to do file sorts by name.
Definition: File.php:298
MediaHandler\getMatchedLanguage
getMatchedLanguage( $userPreferredLanguage, array $availableLanguages)
When overridden in a descendant class, returns a language code most suiting.
Definition: MediaHandler.php:787
File\getTranscodedUrl
getTranscodedUrl( $suffix=false)
Get the URL of the transcoded directory, or a particular file if $suffix is specified.
Definition: File.php:1768
File\getThumbnailSource
getThumbnailSource( $params)
Returns the most appropriate source image for the thumbnail, given a target thumbnail size.
Definition: File.php:1307
MEDIATYPE_UNKNOWN
const MEDIATYPE_UNKNOWN
Definition: defines.php:26
File\getWidth
getWidth( $page=1)
Return the width of the image.
Definition: File.php:473
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1198
File\recordUpload
recordUpload( $oldver, $desc, $license='', $copyStatus='', $source='', $watch=false, $timestamp=false, User $user=null)
Record a file upload in the upload log and the image table STUB Overridden by LocalFile.
Definition: File.php:1853
File\getMediaType
getMediaType()
Return the type of the media in the file.
Definition: File.php:782
File\restore
restore( $versions=[], $unsuppress=false)
Restore all or specified deleted revisions to the given file.
Definition: File.php:2036
File\getCanonicalUrl
getCanonicalUrl()
Definition: File.php:392
File\splitMime
static splitMime( $mime)
Split an internet media type into its two components; if not a two-part name, set the minor type to '...
Definition: File.php:283
File\isVisible
isVisible()
Returns true if file exists in the repository and can be included in a page.
Definition: File.php:951
PoolCounterWorkViaCallback
Convenience class for dealing with PoolCounters using callbacks.
Definition: PoolCounterWorkViaCallback.php:28
$wgThumbnailBuckets
$wgThumbnailBuckets
When defined, is an array of image widths used as buckets for thumbnail generation.
Definition: DefaultSettings.php:1560
MediaHandler\getLongDesc
getLongDesc( $file)
Long description.
Definition: MediaHandler.php:590
$res
$res
Definition: testCompression.php:57
IDBAccessObject
Interface for database access objects.
Definition: IDBAccessObject.php:55
File\$repoClass
string $repoClass
Required Repository class type.
Definition: File.php:161
File\getArchiveRel
getArchiveRel( $suffix=false)
Get the path of an archived file relative to the public zone root.
Definition: File.php:1592
File\isDeleted
isDeleted( $field)
Is this file a "deleted" file in a private archive? STUB.
Definition: File.php:1940
File\getVisibility
getVisibility()
Return the deletion bitfield STUB.
Definition: File.php:1949
HTMLCacheUpdateJob\newForBacklinks
static newForBacklinks(Title $title, $table, $params=[])
Definition: HTMLCacheUpdateJob.php:59
$wgThumbnailMinimumBucketDistance
$wgThumbnailMinimumBucketDistance
When using thumbnail buckets as defined above, this sets the minimum distance to the bucket above the...
Definition: DefaultSettings.php:1577
MediaHandler\supportsBucketing
supportsBucketing()
Returns whether or not this handler supports the chained generation of thumbnails according to bucket...
Definition: MediaHandler.php:836
File\FOR_PUBLIC
const FOR_PUBLIC
Definition: File.php:79
File\normalizeTitle
static normalizeTitle( $title, $exception=false)
Given a string or Title object return either a valid Title object with namespace NS_FILE or null.
Definition: File.php:194
MediaHandler\getAvailableLanguages
getAvailableLanguages(File $file)
Get list of languages file can be viewed in.
Definition: MediaHandler.php:774
File\exists
exists()
Returns true if file exists in the repository.
Definition: File.php:941
File\getThumbVirtualUrl
getThumbVirtualUrl( $suffix=false)
Get the virtual URL for a thumbnail file or directory.
Definition: File.php:1812
$wgThumbnailEpoch
$wgThumbnailEpoch
If rendered thumbnail files are older than this timestamp, they will be rerendered on demand as if th...
Definition: DefaultSettings.php:1339
File\upgradeRow
upgradeRow()
Upgrade the database row if there is one Called by ImagePage STUB.
Definition: File.php:273
FileRepo
Base class for file repositories.
Definition: FileRepo.php:41
wfAppendQuery
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
Definition: GlobalFunctions.php:439
File\$path
string $path
The storage path corresponding to one of the zones.
Definition: File.php:136
MediaWiki\MediaWikiServices\getInstance
static getInstance()
Returns the global default instance of the top level service locator.
Definition: MediaWikiServices.php:175
File\isCacheable
isCacheable()
Check if this file object is small and can be cached.
Definition: File.php:2340
File\$canRender
bool $canRender
Whether the output of transform() for this file is likely to be valid.
Definition: File.php:153
File\getBucketThumbName
getBucketThumbName( $bucket)
Returns the name of the thumb for a given bucket.
Definition: File.php:1385
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:61
MediaHandler\isExpensiveToThumbnail
isExpensiveToThumbnail( $file)
True if creating thumbnails from the file is large or otherwise resource-intensive.
Definition: MediaHandler.php:826
File\getMimeType
getMimeType()
Returns the MIME type of the file.
Definition: File.php:771
File\getDefaultRenderLanguage
getDefaultRenderLanguage()
In files that support multiple language, what is the default language to use if none specified.
Definition: File.php:660
File\$url
string $url
The URL corresponding to one of the four basic zones.
Definition: File.php:127
MWException
MediaWiki exception.
Definition: MWException.php:26
File\getLocalRefPath
getLocalRefPath()
Get an FS copy or original of this file and return the path.
Definition: File.php:443
File\DELETED_COMMENT
const DELETED_COMMENT
Definition: File.php:64
File\transformErrorOutput
transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags)
Return either a MediaTransformError or placeholder thumbnail (if $wgIgnoreImageErrors)
Definition: File.php:1078
File\getIsSafeFile
getIsSafeFile()
Accessor for __get()
Definition: File.php:863
$starttime
$starttime
Definition: api.php:44
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
Definition: GlobalFunctions.php:1030
File\$redirectedTitle
Title $redirectedTitle
Definition: File.php:118
File\getThumbPath
getThumbPath( $suffix=false)
Get the path of the thumbnail directory, or a particular file if $suffix is specified.
Definition: File.php:1678
File\pageCount
pageCount()
Returns the number of pages of a multipage document, or false for documents which aren't multipage do...
Definition: File.php:2057
File\nextHistoryLine
nextHistoryLine()
Return the history of this file, line by line.
Definition: File.php:1546
File\normalizeExtension
static normalizeExtension( $extension)
Normalize a file extension to the common form, making it lowercase and checking some synonyms,...
Definition: File.php:234
PoolCounterWork\execute
execute( $skipcache=false)
Get the result of the work (whatever it is), or the result of the error() function.
Definition: PoolCounterWork.php:108
File\getArchiveVirtualUrl
getArchiveVirtualUrl( $suffix=false)
Get the public zone virtual URL for an archived version source file.
Definition: File.php:1794
File\deleteFile
deleteFile( $reason, User $user, $suppress=false)
Delete all versions of the file.
Definition: File.php:2019
MediaHandler\canAnimateThumbnail
canAnimateThumbnail( $file)
If the material is animated, we can animate the thumbnail.
Definition: MediaHandler.php:381
$wgLang
$wgLang
Definition: Setup.php:774
File\purgeCache
purgeCache( $options=[])
Purge shared caches such as thumbnails and DB data caching STUB Overridden by LocalFile.
Definition: File.php:1485
File\getTransformScript
getTransformScript()
Definition: File.php:958
File\FOR_THIS_USER
const FOR_THIS_USER
Definition: File.php:80
Title\makeTitle
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:595
File\getArchiveThumbRel
getArchiveThumbRel( $archiveName, $suffix=false)
Get the path, relative to the thumbnail zone root, for an archived file's thumbs directory or a speci...
Definition: File.php:1637
File\getStorageKey
getStorageKey()
Get the deletion archive key, "<sha1>.<ext>".
Definition: File.php:2217
File\__construct
__construct( $title, $repo)
Call this constructor from child classes.
Definition: File.php:176
File\isHashed
isHashed()
Definition: File.php:1825
File\generateAndSaveThumb
generateAndSaveThumb( $tmpFile, $transformParams, $flags)
Generates a thumbnail according to the given parameters and saves it to storage.
Definition: File.php:1182
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:913
File\getCommonMetaArray
getCommonMetaArray()
Like getMetadata but returns a handler independent array of common values.
Definition: File.php:713
File\getThumbRel
getThumbRel( $suffix=false)
Get the path, relative to the thumbnail zone root, of the thumbnail directory or a particular file if...
Definition: File.php:1610
File\isTransformedLocally
isTransformedLocally()
Whether the thumbnails created on the same server as this code is running.
Definition: File.php:2378
MediaHandler\getDimensionsString
getDimensionsString( $file)
Shown in file history box on image description page.
Definition: MediaHandler.php:641
File\canRender
canRender()
Checks if the output of transform() for this file is likely to be valid.
Definition: File.php:798
File\$fsFile
FSFile bool $fsFile
False if undefined.
Definition: File.php:121
File\getRedirectedTitle
getRedirectedTitle()
Definition: File.php:2309
MediaHandler\convertMetadataVersion
convertMetadataVersion( $metadata, $version=1)
Convert metadata version.
Definition: MediaHandler.php:163
MediaHandler\getGeneralShortDesc
static getGeneralShortDesc( $file)
Used instead of getShortDesc if there is no handler registered for file.
Definition: MediaHandler.php:600
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:621
File\getAvailableLanguages
getAvailableLanguages()
Gives a (possibly empty) list of languages to render the file in.
Definition: File.php:625
File\iconThumb
iconThumb()
Get a ThumbnailImage representing a file type icon.
Definition: File.php:1442
File\purgeDescription
purgeDescription()
Purge the file description page, but don't go after pages using the file.
Definition: File.php:1493
File\isOld
isOld()
Returns true if the image is an old version STUB.
Definition: File.php:1929
File\$handler
MediaHandler $handler
Definition: File.php:124
NS_MEDIA
const NS_MEDIA
Definition: Defines.php:57
File\assertTitleDefined
assertTitleDefined()
Assert that $this->title is set to a Title.
Definition: File.php:2358
$wgIgnoreImageErrors
$wgIgnoreImageErrors
If set, inline scaled images will still produce "<img>" tags ready for output instead of showing an e...
Definition: DefaultSettings.php:1360
MediaHandler\getTransform
getTransform( $image, $dstPath, $dstUrl, $params)
Get a MediaTransformOutput object representing the transformed output.
Definition: MediaHandler.php:269
File\getHistory
getHistory( $limit=null, $start=null, $end=null, $inc=true)
Return a fragment of the history of file.
Definition: File.php:1533
File\generateThumbName
generateThumbName( $name, $params)
Generate a thumbnail file name from a name and specified parameters.
Definition: File.php:1017
File\formatMetadata
formatMetadata( $context=false)
Definition: File.php:1888
File\createThumb
createThumb( $width, $height=-1)
Create a thumbnail of the image having the specified width/height.
Definition: File.php:1056
File\$title
Title string bool $title
Definition: File.php:109
File\getDescriptionUrl
getDescriptionUrl()
Get the URL of the image description page.
Definition: File.php:2111
PROTO_RELATIVE
const PROTO_RELATIVE
Definition: Defines.php:210
File\getArchiveThumbUrl
getArchiveThumbUrl( $archiveName, $suffix=false)
Get the URL of the archived file's thumbs, or a particular thumb if $suffix is specified.
Definition: File.php:1722
File\getName
getName()
Return the name of this file.
Definition: File.php:307
File\getArchiveUrl
getArchiveUrl( $suffix=false)
Get the URL of the archive directory, or a particular file if $suffix is specified.
Definition: File.php:1702
File\getThumbDisposition
getThumbDisposition( $thumbName, $dispositionType='inline')
Definition: File.php:1405
FSFile
Class representing a non-directory file on the file system.
Definition: FSFile.php:32
MediaHandler\doTransform
doTransform( $image, $dstPath, $dstUrl, $params, $flags=0)
Get a MediaTransformOutput object representing the transformed output.
File\isSafeFile
isSafeFile()
Determines if this media file is in a format that is unlikely to contain viruses or malicious content...
Definition: File.php:850
File\$pageCount
int false $pageCount
Number of pages of a multipage document, or false for documents which aren't multipage documents.
Definition: File.php:144
File\getRepoName
getRepoName()
Returns the name of the repository.
Definition: File.php:1910
File\DELETE_SOURCE
const DELETE_SOURCE
Definition: File.php:76
$wgResourceBasePath
$wgResourceBasePath
The default 'remoteBasePath' value for instances of ResourceLoaderFileModule.
Definition: DefaultSettings.php:4056
File\publish
publish( $src, $flags=0, array $options=[])
Move or copy a file to its public location.
Definition: File.php:1880
File\$extension
string $extension
File extension.
Definition: File.php:130
File\getBucketThumbPath
getBucketThumbPath( $bucket)
Returns the repo path of the thumb for a given bucket.
Definition: File.php:1375
$context
$context
Definition: load.php:43
File\$hashPath
string $hashPath
Relative path including trailing slash.
Definition: File.php:139
File\scaleHeight
static scaleHeight( $srcWidth, $srcHeight, $dstWidth)
Calculate the height of a thumbnail using the source and destination width.
Definition: File.php:2078
File\RENDER_NOW
const RENDER_NOW
Force rendering in the current process.
Definition: File.php:69
File\transform
transform( $params, $flags=0)
Transform a media file.
Definition: File.php:1098
unserialize
unserialize( $serialized)
Definition: ApiMessageTrait.php:146
File\getTitle
getTitle()
Return the associated title object.
Definition: File.php:336
File\readOnlyError
readOnlyError()
Definition: File.php:1834
Title
Represents a title within MediaWiki.
Definition: Title.php:42
ForeignAPIRepo
A foreign repository with a remote MediaWiki with an API thingy.
Definition: ForeignAPIRepo.php:41
File\$isSafeFile
bool $isSafeFile
Whether this media file is in a format that is unlikely to contain viruses or malicious content.
Definition: File.php:158
JobQueueGroup\singleton
static singleton( $domain=false)
Definition: JobQueueGroup.php:70
File\getThumbnailBucket
getThumbnailBucket( $desiredWidth, $page=1)
Return the smallest bucket from $wgThumbnailBuckets which is at least $wgThumbnailMinimumBucketDistan...
Definition: File.php:500
MediaHandler\getContentHeaders
getContentHeaders( $metadata)
Get useful response headers for GET/HEAD requests for a file with the given metadata.
Definition: MediaHandler.php:931
$cache
$cache
Definition: mcc.php:33
File\move
move( $target)
Move file to the new title.
Definition: File.php:1976
File\assertRepoDefined
assertRepoDefined()
Assert that $this->repo is set to a valid FileRepo instance.
Definition: File.php:2348
File\getShortDesc
getShortDesc()
Definition: File.php:2278
$job
if(count( $args)< 1) $job
Definition: recompressTracked.php:50
File\getDescription
getDescription( $audience=self::FOR_PUBLIC, User $user=null)
Get description of file revision STUB.
Definition: File.php:2175
File\getLength
getLength()
Get the duration of a media file in seconds.
Definition: File.php:591
File\getLongDesc
getLongDesc()
Definition: File.php:2266
File\isLocal
isLocal()
Returns true if the file comes from the local file repository.
Definition: File.php:1901
File\getDescriptionText
getDescriptionText(Language $lang=null)
Get the HTML text of the description page, if available.
Definition: File.php:2125
MediaHandler\getHandler
static getHandler( $type)
Get a MediaHandler for a given MIME type from the instance cache.
Definition: MediaHandler.php:51
File\getCanRender
getCanRender()
Accessor for __get()
Definition: File.php:810
MediaHandler\isAnimatedImage
isAnimatedImage( $file)
The material is an image, and is animated.
Definition: MediaHandler.php:370
$source
$source
Definition: mwdoc-filter.php:34
MediaHandler\isVectorized
isVectorized( $file)
The material is vectorized and thus scaling is lossless.
Definition: MediaHandler.php:358
File\mustRender
mustRender()
Return true if the file is of a type that can't be directly rendered by typical browsers and needs to...
Definition: File.php:824
File\load
load( $flags=0)
Load any lazy-loaded file object fields from source.
Definition: File.php:931
Title\isDeletedQuick
isDeletedQuick()
Is there a version of this page in the deletion archive?
Definition: Title.php:3146
File\resetHistory
resetHistory()
Reset the history pointer to the first element of the history.
Definition: File.php:1556
MediaHandler\getScriptedTransform
getScriptedTransform( $image, $script, $params)
Get a MediaTransformOutput object representing an alternate of the transformed output which will call...
Definition: MediaHandler.php:255
$ext
if(!is_readable( $file)) $ext
Definition: router.php:48
File\getRedirected
getRedirected()
Definition: File.php:2302
File\$name
string $name
The name of a file from its title object.
Definition: File.php:133
File\DELETED_FILE
const DELETED_FILE
Definition: File.php:63
File\getMatchedLanguage
getMatchedLanguage( $userPreferredLanguage)
Get the language code from the available languages for this file that matches the language requested ...
Definition: File.php:641
MediaHandler\getGeneralLongDesc
static getGeneralLongDesc( $file)
Used instead of getLongDesc if there is no handler registered for file.
Definition: MediaHandler.php:612
File\getRepo
getRepo()
Returns the repository.
Definition: File.php:1919
File\allowInlineDisplay
allowInlineDisplay()
Alias for canRender()
Definition: File.php:833
Title\invalidateCache
invalidateCache( $purgeTime=null)
Updates page_touched for this page; called from LinksUpdate.php.
Definition: Title.php:4123
$mime
$mime
Definition: router.php:60
File\getThumbUrl
getThumbUrl( $suffix=false)
Get the URL of the thumbnail directory, or a particular file if $suffix is specified.
Definition: File.php:1758
File\isVectorized
isVectorized()
Return true if the file is vectorized.
Definition: File.php:605
File\getDimensionsString
getDimensionsString()
Definition: File.php:2290
File\getHandler
getHandler()
Get a MediaHandler instance for this file.
Definition: File.php:1429
File\__get
__get( $name)
Definition: File.php:215
$wgTrustedMediaFormats
$wgTrustedMediaFormats
list of trusted media-types and MIME types.
Definition: DefaultSettings.php:1080
File\userCan
userCan( $field, User $user=null)
Determine if the current user is allowed to view a particular field of this file, if it's marked as d...
Definition: File.php:2236
$IP
$IP
Definition: WebStart.php:49
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:54
File\generateBucketsIfNeeded
generateBucketsIfNeeded( $params, $flags=0)
Generates chained bucketed thumbnails if needed.
Definition: File.php:1250
File\thumbName
thumbName( $params, $flags=0)
Return the file name of a thumbnail with the specified parameters.
Definition: File.php:1002
File\$lastError
string $lastError
Text of last error.
Definition: File.php:112
File\$redirected
string $redirected
Main part of the title, with underscores (Title::getDBkey)
Definition: File.php:115
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:133
File\getImageSize
getImageSize( $filePath)
Get an image size array like that returned by getImageSize(), or false if it can't be determined.
Definition: File.php:2097
FSFile\getPath
getPath()
Returns the file system path.
Definition: FSFile.php:53
File\makeTransformTmpFile
makeTransformTmpFile( $thumbPath)
Creates a temp FS file with the same extension and the thumbnail.
Definition: File.php:1394
File\getArchivePath
getArchivePath( $suffix=false)
Get the path of the archived file.
Definition: File.php:1652
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:39
File\purgeEverything
purgeEverything()
Purge metadata and all affected pages when the file is created, deleted, or majorly updated.
Definition: File.php:1506
File\getUnscaledThumb
getUnscaledThumb( $handlerParams=[])
Get a ThumbnailImage which is the same size as the source.
Definition: File.php:979
File\getHashPath
getHashPath()
Get the filename hash component of the directory including trailing slash, e.g.
Definition: File.php:1566
File\isTrustedFile
isTrustedFile()
Returns true if the file is flagged as trusted.
Definition: File.php:916
LocalRepo
A repository that stores files in the local filesystem and registers them in the wiki's own database.
Definition: LocalRepo.php:37
File\getSize
getSize()
Return the size of the image file, in bytes Overridden by LocalFile, UnregisteredLocalFile STUB.
Definition: File.php:760
MediaHandler
Base media handler class.
Definition: MediaHandler.php:35
MediaHandler\getLength
getLength( $file)
If its an audio file, return the length of the file.
Definition: MediaHandler.php:817
wfExpandUrl
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
Definition: GlobalFunctions.php:491
File\getThumbnails
getThumbnails()
Get all thumbnail names previously generated for this file STUB Overridden by LocalFile.
Definition: File.php:1474
MediaHandler\getDefaultRenderLanguage
getDefaultRenderLanguage(File $file)
On file types that support renderings in multiple languages, which language is used by default if uns...
Definition: MediaHandler.php:803
File\getTranscodedPath
getTranscodedPath( $suffix=false)
Get the path of the transcoded directory, or a particular file if $suffix is specified.
Definition: File.php:1690
File\getViewURL
getViewURL()
Definition: File.php:399
File\getVirtualUrl
getVirtualUrl( $suffix=false)
Get the public zone virtual URL for a current version source file.
Definition: File.php:1778
$type
$type
Definition: testCompression.php:52
FileBackend\makeContentDisposition
static makeContentDisposition( $type, $filename='')
Build a Content-Disposition header value per RFC 6266.
Definition: FileBackend.php:1633