MediaWiki  master
File.php
Go to the documentation of this file.
1 <?php
10 
33 // @phan-file-suppress PhanTypeMissingReturn false positives
61 abstract class File implements IDBAccessObject {
62  // Bitfield values akin to the Revision deletion constants
63  const DELETED_FILE = 1;
64  const DELETED_COMMENT = 2;
65  const DELETED_USER = 4;
66  const DELETED_RESTRICTED = 8;
67 
69  const RENDER_NOW = 1;
74  const RENDER_FORCE = 2;
75 
76  const DELETE_SOURCE = 1;
77 
78  // Audience options for File::getDescription()
79  const FOR_PUBLIC = 1;
80  const FOR_THIS_USER = 2;
81  const RAW = 3;
82 
83  // Options for File::thumbName()
84  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  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  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  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  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  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  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  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  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 
542  public function getUser( $type = 'text' ) {
543  return null;
544  }
545 
551  public function getLength() {
552  $handler = $this->getHandler();
553  if ( $handler ) {
554  return $handler->getLength( $this );
555  } else {
556  return 0;
557  }
558  }
559 
565  public function isVectorized() {
566  $handler = $this->getHandler();
567  if ( $handler ) {
568  return $handler->isVectorized( $this );
569  } else {
570  return false;
571  }
572  }
573 
585  public function getAvailableLanguages() {
586  $handler = $this->getHandler();
587  if ( $handler ) {
588  return $handler->getAvailableLanguages( $this );
589  } else {
590  return [];
591  }
592  }
593 
601  public function getMatchedLanguage( $userPreferredLanguage ) {
602  $handler = $this->getHandler();
603  if ( $handler ) {
605  $userPreferredLanguage,
607  );
608  }
609 
610  return null;
611  }
612 
620  public function getDefaultRenderLanguage() {
621  $handler = $this->getHandler();
622  if ( $handler ) {
623  return $handler->getDefaultRenderLanguage( $this );
624  } else {
625  return null;
626  }
627  }
628 
639  public function canAnimateThumbIfAppropriate() {
640  $handler = $this->getHandler();
641  if ( !$handler ) {
642  // We cannot handle image whatsoever, thus
643  // one would not expect it to be animated
644  // so true.
645  return true;
646  }
647 
648  return !$this->allowInlineDisplay()
649  // Image is not animated, so one would
650  // not expect thumb to be
651  || !$handler->isAnimatedImage( $this )
652  // Image is animated, but thumbnail isn't.
653  // This is unexpected to the user.
654  || $handler->canAnimateThumbnail( $this );
655  }
656 
663  public function getMetadata() {
664  return false;
665  }
666 
673  public function getCommonMetaArray() {
674  $handler = $this->getHandler();
675 
676  if ( !$handler ) {
677  return false;
678  }
679 
680  return $handler->getCommonMetaArray( $this );
681  }
682 
691  public function convertMetadataVersion( $metadata, $version ) {
692  $handler = $this->getHandler();
693  if ( !is_array( $metadata ) ) {
694  // Just to make the return type consistent
695  $metadata = unserialize( $metadata );
696  }
697  if ( $handler ) {
698  return $handler->convertMetadataVersion( $metadata, $version );
699  } else {
700  return $metadata;
701  }
702  }
703 
710  public function getBitDepth() {
711  return 0;
712  }
713 
720  public function getSize() {
721  return false;
722  }
723 
731  function getMimeType() {
732  return 'unknown/unknown';
733  }
734 
742  function getMediaType() {
743  return MEDIATYPE_UNKNOWN;
744  }
745 
758  function canRender() {
759  if ( !isset( $this->canRender ) ) {
760  $this->canRender = $this->getHandler() && $this->handler->canRender( $this ) && $this->exists();
761  }
762 
763  return $this->canRender;
764  }
765 
770  protected function getCanRender() {
771  return $this->canRender();
772  }
773 
784  function mustRender() {
785  return $this->getHandler() && $this->handler->mustRender( $this );
786  }
787 
793  function allowInlineDisplay() {
794  return $this->canRender();
795  }
796 
810  function isSafeFile() {
811  if ( !isset( $this->isSafeFile ) ) {
812  $this->isSafeFile = $this->getIsSafeFileUncached();
813  }
814 
815  return $this->isSafeFile;
816  }
817 
823  protected function getIsSafeFile() {
824  return $this->isSafeFile();
825  }
826 
832  protected function getIsSafeFileUncached() {
833  global $wgTrustedMediaFormats;
834 
835  if ( $this->allowInlineDisplay() ) {
836  return true;
837  }
838  if ( $this->isTrustedFile() ) {
839  return true;
840  }
841 
842  $type = $this->getMediaType();
843  $mime = $this->getMimeType();
844  # wfDebug( "LocalFile::isSafeFile: type= $type, mime= $mime\n" );
845 
846  if ( !$type || $type === MEDIATYPE_UNKNOWN ) {
847  return false; # unknown type, not trusted
848  }
849  if ( in_array( $type, $wgTrustedMediaFormats ) ) {
850  return true;
851  }
852 
853  if ( $mime === "unknown/unknown" ) {
854  return false; # unknown type, not trusted
855  }
856  if ( in_array( $mime, $wgTrustedMediaFormats ) ) {
857  return true;
858  }
859 
860  return false;
861  }
862 
876  function isTrustedFile() {
877  # this could be implemented to check a flag in the database,
878  # look for signatures, etc
879  return false;
880  }
881 
891  public function load( $flags = 0 ) {
892  }
893 
901  public function exists() {
902  return $this->getPath() && $this->repo->fileExists( $this->path );
903  }
904 
911  public function isVisible() {
912  return $this->exists();
913  }
914 
918  function getTransformScript() {
919  if ( !isset( $this->transformScript ) ) {
920  $this->transformScript = false;
921  if ( $this->repo ) {
922  $script = $this->repo->getThumbScriptUrl();
923  if ( $script ) {
924  $this->transformScript = wfAppendQuery( $script, [ 'f' => $this->getName() ] );
925  }
926  }
927  }
928 
929  return $this->transformScript;
930  }
931 
939  function getUnscaledThumb( $handlerParams = [] ) {
940  $hp =& $handlerParams;
941  $page = $hp['page'] ?? false;
942  $width = $this->getWidth( $page );
943  if ( !$width ) {
944  return $this->iconThumb();
945  }
946  $hp['width'] = $width;
947  // be sure to ignore any height specification as well (T64258)
948  unset( $hp['height'] );
949 
950  return $this->transform( $hp );
951  }
952 
962  public function thumbName( $params, $flags = 0 ) {
963  $name = ( $this->repo && !( $flags & self::THUMB_FULL_NAME ) )
964  ? $this->repo->nameForThumb( $this->getName() )
965  : $this->getName();
966 
967  return $this->generateThumbName( $name, $params );
968  }
969 
977  public function generateThumbName( $name, $params ) {
978  if ( !$this->getHandler() ) {
979  return null;
980  }
981  $extension = $this->getExtension();
982  list( $thumbExt, ) = $this->getHandler()->getThumbType(
983  $extension, $this->getMimeType(), $params );
984  $thumbName = $this->getHandler()->makeParamString( $params );
985 
986  if ( $this->repo->supportsSha1URLs() ) {
987  $thumbName .= '-' . $this->getSha1() . '.' . $thumbExt;
988  } else {
989  $thumbName .= '-' . $name;
990 
991  if ( $thumbExt != $extension ) {
992  $thumbName .= ".$thumbExt";
993  }
994  }
995 
996  return $thumbName;
997  }
998 
1016  public function createThumb( $width, $height = -1 ) {
1017  $params = [ 'width' => $width ];
1018  if ( $height != -1 ) {
1019  $params['height'] = $height;
1020  }
1021  $thumb = $this->transform( $params );
1022  if ( !$thumb || $thumb->isError() ) {
1023  return '';
1024  }
1025 
1026  return $thumb->getUrl();
1027  }
1028 
1038  protected function transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ) {
1039  global $wgIgnoreImageErrors;
1040 
1041  $handler = $this->getHandler();
1042  if ( $handler && $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
1043  return $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
1044  } else {
1045  return new MediaTransformError( 'thumbnail_error',
1046  $params['width'], 0, wfMessage( 'thumbnail-dest-create' ) );
1047  }
1048  }
1049 
1058  function transform( $params, $flags = 0 ) {
1059  global $wgThumbnailEpoch;
1060 
1061  do {
1062  if ( !$this->canRender() ) {
1063  $thumb = $this->iconThumb();
1064  break; // not a bitmap or renderable image, don't try
1065  }
1066 
1067  // Get the descriptionUrl to embed it as comment into the thumbnail. T21791.
1068  $descriptionUrl = $this->getDescriptionUrl();
1069  if ( $descriptionUrl ) {
1070  $params['descriptionUrl'] = wfExpandUrl( $descriptionUrl, PROTO_CANONICAL );
1071  }
1072 
1073  $handler = $this->getHandler();
1074  $script = $this->getTransformScript();
1075  if ( $script && !( $flags & self::RENDER_NOW ) ) {
1076  // Use a script to transform on client request, if possible
1077  $thumb = $handler->getScriptedTransform( $this, $script, $params );
1078  if ( $thumb ) {
1079  break;
1080  }
1081  }
1082 
1083  $normalisedParams = $params;
1084  $handler->normaliseParams( $this, $normalisedParams );
1085 
1086  $thumbName = $this->thumbName( $normalisedParams );
1087  $thumbUrl = $this->getThumbUrl( $thumbName );
1088  $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path
1089 
1090  if ( $this->repo ) {
1091  // Defer rendering if a 404 handler is set up...
1092  if ( $this->repo->canTransformVia404() && !( $flags & self::RENDER_NOW ) ) {
1093  // XXX: Pass in the storage path even though we are not rendering anything
1094  // and the path is supposed to be an FS path. This is due to getScalerType()
1095  // getting called on the path and clobbering $thumb->getUrl() if it's false.
1096  $thumb = $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
1097  break;
1098  }
1099  // Check if an up-to-date thumbnail already exists...
1100  wfDebug( __METHOD__ . ": Doing stat for $thumbPath\n" );
1101  if ( !( $flags & self::RENDER_FORCE ) && $this->repo->fileExists( $thumbPath ) ) {
1102  $timestamp = $this->repo->getFileTimestamp( $thumbPath );
1103  if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) {
1104  // XXX: Pass in the storage path even though we are not rendering anything
1105  // and the path is supposed to be an FS path. This is due to getScalerType()
1106  // getting called on the path and clobbering $thumb->getUrl() if it's false.
1107  $thumb = $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
1108  $thumb->setStoragePath( $thumbPath );
1109  break;
1110  }
1111  } elseif ( $flags & self::RENDER_FORCE ) {
1112  wfDebug( __METHOD__ . " forcing rendering per flag File::RENDER_FORCE\n" );
1113  }
1114 
1115  // If the backend is ready-only, don't keep generating thumbnails
1116  // only to return transformation errors, just return the error now.
1117  if ( $this->repo->getReadOnlyReason() !== false ) {
1118  $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags );
1119  break;
1120  }
1121  }
1122 
1123  $tmpFile = $this->makeTransformTmpFile( $thumbPath );
1124 
1125  if ( !$tmpFile ) {
1126  $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags );
1127  } else {
1128  $thumb = $this->generateAndSaveThumb( $tmpFile, $params, $flags );
1129  }
1130  } while ( false );
1131 
1132  return is_object( $thumb ) ? $thumb : false;
1133  }
1134 
1142  public function generateAndSaveThumb( $tmpFile, $transformParams, $flags ) {
1143  global $wgIgnoreImageErrors;
1144 
1145  $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
1146 
1147  $handler = $this->getHandler();
1148 
1149  $normalisedParams = $transformParams;
1150  $handler->normaliseParams( $this, $normalisedParams );
1151 
1152  $thumbName = $this->thumbName( $normalisedParams );
1153  $thumbUrl = $this->getThumbUrl( $thumbName );
1154  $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path
1155 
1156  $tmpThumbPath = $tmpFile->getPath();
1157 
1158  if ( $handler->supportsBucketing() ) {
1159  $this->generateBucketsIfNeeded( $normalisedParams, $flags );
1160  }
1161 
1162  $starttime = microtime( true );
1163 
1164  // Actually render the thumbnail...
1165  $thumb = $handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $transformParams );
1166  $tmpFile->bind( $thumb ); // keep alive with $thumb
1167 
1168  $statTiming = microtime( true ) - $starttime;
1169  $stats->timing( 'media.thumbnail.generate.transform', 1000 * $statTiming );
1170 
1171  if ( !$thumb ) { // bad params?
1172  $thumb = false;
1173  } elseif ( $thumb->isError() ) { // transform error
1175  '@phan-var MediaTransformError $thumb';
1176  $this->lastError = $thumb->toText();
1177  // Ignore errors if requested
1178  if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
1179  $thumb = $handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $transformParams );
1180  }
1181  } elseif ( $this->repo && $thumb->hasFile() && !$thumb->fileIsSource() ) {
1182  // Copy the thumbnail from the file system into storage...
1183 
1184  $starttime = microtime( true );
1185 
1186  $disposition = $this->getThumbDisposition( $thumbName );
1187  $status = $this->repo->quickImport( $tmpThumbPath, $thumbPath, $disposition );
1188  if ( $status->isOK() ) {
1189  $thumb->setStoragePath( $thumbPath );
1190  } else {
1191  $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $transformParams, $flags );
1192  }
1193 
1194  $statTiming = microtime( true ) - $starttime;
1195  $stats->timing( 'media.thumbnail.generate.store', 1000 * $statTiming );
1196 
1197  // Give extensions a chance to do something with this thumbnail...
1198  Hooks::run( 'FileTransformed', [ $this, $thumb, $tmpThumbPath, $thumbPath ] );
1199  }
1200 
1201  return $thumb;
1202  }
1203 
1210  protected function generateBucketsIfNeeded( $params, $flags = 0 ) {
1211  if ( !$this->repo
1212  || !isset( $params['physicalWidth'] )
1213  || !isset( $params['physicalHeight'] )
1214  ) {
1215  return false;
1216  }
1217 
1218  $bucket = $this->getThumbnailBucket( $params['physicalWidth'] );
1219 
1220  if ( !$bucket || $bucket == $params['physicalWidth'] ) {
1221  return false;
1222  }
1223 
1224  $bucketPath = $this->getBucketThumbPath( $bucket );
1225 
1226  if ( $this->repo->fileExists( $bucketPath ) ) {
1227  return false;
1228  }
1229 
1230  $starttime = microtime( true );
1231 
1232  $params['physicalWidth'] = $bucket;
1233  $params['width'] = $bucket;
1234 
1235  $params = $this->getHandler()->sanitizeParamsForBucketing( $params );
1236 
1237  $tmpFile = $this->makeTransformTmpFile( $bucketPath );
1238 
1239  if ( !$tmpFile ) {
1240  return false;
1241  }
1242 
1243  $thumb = $this->generateAndSaveThumb( $tmpFile, $params, $flags );
1244 
1245  $buckettime = microtime( true ) - $starttime;
1246 
1247  if ( !$thumb || $thumb->isError() ) {
1248  return false;
1249  }
1250 
1251  $this->tmpBucketedThumbCache[$bucket] = $tmpFile->getPath();
1252  // For the caching to work, we need to make the tmp file survive as long as
1253  // this object exists
1254  $tmpFile->bind( $this );
1255 
1256  MediaWikiServices::getInstance()->getStatsdDataFactory()->timing(
1257  'media.thumbnail.generate.bucket', 1000 * $buckettime );
1258 
1259  return true;
1260  }
1261 
1267  public function getThumbnailSource( $params ) {
1268  if ( $this->repo
1269  && $this->getHandler()->supportsBucketing()
1270  && isset( $params['physicalWidth'] )
1271  && $bucket = $this->getThumbnailBucket( $params['physicalWidth'] )
1272  ) {
1273  if ( $this->getWidth() != 0 ) {
1274  $bucketHeight = round( $this->getHeight() * ( $bucket / $this->getWidth() ) );
1275  } else {
1276  $bucketHeight = 0;
1277  }
1278 
1279  // Try to avoid reading from storage if the file was generated by this script
1280  if ( isset( $this->tmpBucketedThumbCache[$bucket] ) ) {
1281  $tmpPath = $this->tmpBucketedThumbCache[$bucket];
1282 
1283  if ( file_exists( $tmpPath ) ) {
1284  return [
1285  'path' => $tmpPath,
1286  'width' => $bucket,
1287  'height' => $bucketHeight
1288  ];
1289  }
1290  }
1291 
1292  $bucketPath = $this->getBucketThumbPath( $bucket );
1293 
1294  if ( $this->repo->fileExists( $bucketPath ) ) {
1295  $fsFile = $this->repo->getLocalReference( $bucketPath );
1296 
1297  if ( $fsFile ) {
1298  return [
1299  'path' => $fsFile->getPath(),
1300  'width' => $bucket,
1301  'height' => $bucketHeight
1302  ];
1303  }
1304  }
1305  }
1306 
1307  // Thumbnailing a very large file could result in network saturation if
1308  // everyone does it at once.
1309  if ( $this->getSize() >= 1e7 ) { // 10MB
1310  $work = new PoolCounterWorkViaCallback( 'GetLocalFileCopy', sha1( $this->getName() ),
1311  [
1312  'doWork' => function () {
1313  return $this->getLocalRefPath();
1314  }
1315  ]
1316  );
1317  $srcPath = $work->execute();
1318  } else {
1319  $srcPath = $this->getLocalRefPath();
1320  }
1321 
1322  // Original file
1323  return [
1324  'path' => $srcPath,
1325  'width' => $this->getWidth(),
1326  'height' => $this->getHeight()
1327  ];
1328  }
1329 
1335  protected function getBucketThumbPath( $bucket ) {
1336  $thumbName = $this->getBucketThumbName( $bucket );
1337  return $this->getThumbPath( $thumbName );
1338  }
1339 
1345  protected function getBucketThumbName( $bucket ) {
1346  return $this->thumbName( [ 'physicalWidth' => $bucket ] );
1347  }
1348 
1354  protected function makeTransformTmpFile( $thumbPath ) {
1355  $thumbExt = FileBackend::extensionFromPath( $thumbPath );
1356  return MediaWikiServices::getInstance()->getTempFSFileFactory()
1357  ->newTempFSFile( 'transform_', $thumbExt );
1358  }
1359 
1365  function getThumbDisposition( $thumbName, $dispositionType = 'inline' ) {
1366  $fileName = $this->name; // file name to suggest
1367  $thumbExt = FileBackend::extensionFromPath( $thumbName );
1368  if ( $thumbExt != '' && $thumbExt !== $this->getExtension() ) {
1369  $fileName .= ".$thumbExt";
1370  }
1371 
1372  return FileBackend::makeContentDisposition( $dispositionType, $fileName );
1373  }
1374 
1381  function migrateThumbFile( $thumbName ) {
1382  }
1383 
1390  function getHandler() {
1391  if ( !isset( $this->handler ) ) {
1392  $this->handler = MediaHandler::getHandler( $this->getMimeType() );
1393  }
1394 
1395  return $this->handler;
1396  }
1397 
1403  function iconThumb() {
1404  global $wgResourceBasePath, $IP;
1405  $assetsPath = "$wgResourceBasePath/resources/assets/file-type-icons/";
1406  $assetsDirectory = "$IP/resources/assets/file-type-icons/";
1407 
1408  $try = [ 'fileicon-' . $this->getExtension() . '.png', 'fileicon.png' ];
1409  foreach ( $try as $icon ) {
1410  if ( file_exists( $assetsDirectory . $icon ) ) { // always FS
1411  $params = [ 'width' => 120, 'height' => 120 ];
1412 
1413  return new ThumbnailImage( $this, $assetsPath . $icon, false, $params );
1414  }
1415  }
1416 
1417  return null;
1418  }
1419 
1425  function getLastError() {
1426  return $this->lastError;
1427  }
1428 
1435  function getThumbnails() {
1436  return [];
1437  }
1438 
1446  function purgeCache( $options = [] ) {
1447  }
1448 
1454  function purgeDescription() {
1455  $title = $this->getTitle();
1456  if ( $title ) {
1458  $title->purgeSquid();
1459  }
1460  }
1461 
1466  function purgeEverything() {
1467  // Delete thumbnails and refresh file metadata cache
1468  $this->purgeCache();
1469  $this->purgeDescription();
1470  // Purge cache of all pages using this file
1471  $title = $this->getTitle();
1472  if ( $title ) {
1474  $title,
1475  'imagelinks',
1476  [ 'causeAction' => 'file-purge' ]
1477  );
1478  JobQueueGroup::singleton()->lazyPush( $job );
1479  }
1480  }
1481 
1493  function getHistory( $limit = null, $start = null, $end = null, $inc = true ) {
1494  return [];
1495  }
1496 
1506  public function nextHistoryLine() {
1507  return false;
1508  }
1509 
1516  public function resetHistory() {
1517  }
1518 
1526  function getHashPath() {
1527  if ( $this->hashPath === null ) {
1528  $this->assertRepoDefined();
1529  $this->hashPath = $this->repo->getHashPath( $this->getName() );
1530  }
1531 
1532  return $this->hashPath;
1533  }
1534 
1541  function getRel() {
1542  return $this->getHashPath() . $this->getName();
1543  }
1544 
1552  function getArchiveRel( $suffix = false ) {
1553  $path = 'archive/' . $this->getHashPath();
1554  if ( $suffix === false ) {
1555  $path = rtrim( $path, '/' );
1556  } else {
1557  $path .= $suffix;
1558  }
1559 
1560  return $path;
1561  }
1562 
1570  function getThumbRel( $suffix = false ) {
1571  $path = $this->getRel();
1572  if ( $suffix !== false ) {
1573  $path .= '/' . $suffix;
1574  }
1575 
1576  return $path;
1577  }
1578 
1585  function getUrlRel() {
1586  return $this->getHashPath() . rawurlencode( $this->getName() );
1587  }
1588 
1597  function getArchiveThumbRel( $archiveName, $suffix = false ) {
1598  $path = $this->getArchiveRel( $archiveName );
1599  if ( $suffix !== false ) {
1600  $path .= '/' . $suffix;
1601  }
1602 
1603  return $path;
1604  }
1605 
1612  function getArchivePath( $suffix = false ) {
1613  $this->assertRepoDefined();
1614 
1615  return $this->repo->getZonePath( 'public' ) . '/' . $this->getArchiveRel( $suffix );
1616  }
1617 
1625  function getArchiveThumbPath( $archiveName, $suffix = false ) {
1626  $this->assertRepoDefined();
1627 
1628  return $this->repo->getZonePath( 'thumb' ) . '/' .
1629  $this->getArchiveThumbRel( $archiveName, $suffix );
1630  }
1631 
1638  function getThumbPath( $suffix = false ) {
1639  $this->assertRepoDefined();
1640 
1641  return $this->repo->getZonePath( 'thumb' ) . '/' . $this->getThumbRel( $suffix );
1642  }
1643 
1650  function getTranscodedPath( $suffix = false ) {
1651  $this->assertRepoDefined();
1652 
1653  return $this->repo->getZonePath( 'transcoded' ) . '/' . $this->getThumbRel( $suffix );
1654  }
1655 
1662  function getArchiveUrl( $suffix = false ) {
1663  $this->assertRepoDefined();
1664  $ext = $this->getExtension();
1665  $path = $this->repo->getZoneUrl( 'public', $ext ) . '/archive/' . $this->getHashPath();
1666  if ( $suffix === false ) {
1667  $path = rtrim( $path, '/' );
1668  } else {
1669  $path .= rawurlencode( $suffix );
1670  }
1671 
1672  return $path;
1673  }
1674 
1682  function getArchiveThumbUrl( $archiveName, $suffix = false ) {
1683  $this->assertRepoDefined();
1684  $ext = $this->getExtension();
1685  $path = $this->repo->getZoneUrl( 'thumb', $ext ) . '/archive/' .
1686  $this->getHashPath() . rawurlencode( $archiveName );
1687  if ( $suffix !== false ) {
1688  $path .= '/' . rawurlencode( $suffix );
1689  }
1690 
1691  return $path;
1692  }
1693 
1701  function getZoneUrl( $zone, $suffix = false ) {
1702  $this->assertRepoDefined();
1703  $ext = $this->getExtension();
1704  $path = $this->repo->getZoneUrl( $zone, $ext ) . '/' . $this->getUrlRel();
1705  if ( $suffix !== false ) {
1706  $path .= '/' . rawurlencode( $suffix );
1707  }
1708 
1709  return $path;
1710  }
1711 
1718  function getThumbUrl( $suffix = false ) {
1719  return $this->getZoneUrl( 'thumb', $suffix );
1720  }
1721 
1728  function getTranscodedUrl( $suffix = false ) {
1729  return $this->getZoneUrl( 'transcoded', $suffix );
1730  }
1731 
1738  function getVirtualUrl( $suffix = false ) {
1739  $this->assertRepoDefined();
1740  $path = $this->repo->getVirtualUrl() . '/public/' . $this->getUrlRel();
1741  if ( $suffix !== false ) {
1742  $path .= '/' . rawurlencode( $suffix );
1743  }
1744 
1745  return $path;
1746  }
1747 
1754  function getArchiveVirtualUrl( $suffix = false ) {
1755  $this->assertRepoDefined();
1756  $path = $this->repo->getVirtualUrl() . '/public/archive/' . $this->getHashPath();
1757  if ( $suffix === false ) {
1758  $path = rtrim( $path, '/' );
1759  } else {
1760  $path .= rawurlencode( $suffix );
1761  }
1762 
1763  return $path;
1764  }
1765 
1772  function getThumbVirtualUrl( $suffix = false ) {
1773  $this->assertRepoDefined();
1774  $path = $this->repo->getVirtualUrl() . '/thumb/' . $this->getUrlRel();
1775  if ( $suffix !== false ) {
1776  $path .= '/' . rawurlencode( $suffix );
1777  }
1778 
1779  return $path;
1780  }
1781 
1785  function isHashed() {
1786  $this->assertRepoDefined();
1787 
1788  return (bool)$this->repo->getHashLevels();
1789  }
1790 
1794  function readOnlyError() {
1795  throw new MWException( static::class . ': write operations are not supported' );
1796  }
1797 
1813  function recordUpload( $oldver, $desc, $license = '', $copyStatus = '', $source = '',
1814  $watch = false, $timestamp = false, User $user = null
1815  ) {
1816  $this->readOnlyError();
1817  }
1818 
1840  function publish( $src, $flags = 0, array $options = [] ) {
1841  $this->readOnlyError();
1842  }
1843 
1848  function formatMetadata( $context = false ) {
1849  if ( !$this->getHandler() ) {
1850  return false;
1851  }
1852 
1853  return $this->getHandler()->formatMetadata( $this, $context );
1854  }
1855 
1861  function isLocal() {
1862  return $this->repo && $this->repo->isLocal();
1863  }
1864 
1870  function getRepoName() {
1871  return $this->repo ? $this->repo->getName() : 'unknown';
1872  }
1873 
1879  function getRepo() {
1880  return $this->repo;
1881  }
1882 
1889  function isOld() {
1890  return false;
1891  }
1892 
1900  function isDeleted( $field ) {
1901  return false;
1902  }
1903 
1909  function getVisibility() {
1910  return 0;
1911  }
1912 
1918  function wasDeleted() {
1919  $title = $this->getTitle();
1920 
1921  return $title && $title->isDeletedQuick();
1922  }
1923 
1936  function move( $target ) {
1937  $this->readOnlyError();
1938  }
1939 
1955  function delete( $reason, $suppress = false, $user = null ) {
1956  $this->readOnlyError();
1957  }
1958 
1972  function restore( $versions = [], $unsuppress = false ) {
1973  $this->readOnlyError();
1974  }
1975 
1983  function isMultipage() {
1984  return $this->getHandler() && $this->handler->isMultiPage( $this );
1985  }
1986 
1993  function pageCount() {
1994  if ( !isset( $this->pageCount ) ) {
1995  if ( $this->getHandler() && $this->handler->isMultiPage( $this ) ) {
1996  $this->pageCount = $this->handler->pageCount( $this );
1997  } else {
1998  $this->pageCount = false;
1999  }
2000  }
2001 
2002  return $this->pageCount;
2003  }
2004 
2014  static function scaleHeight( $srcWidth, $srcHeight, $dstWidth ) {
2015  // Exact integer multiply followed by division
2016  if ( $srcWidth == 0 ) {
2017  return 0;
2018  } else {
2019  return (int)round( $srcHeight * $dstWidth / $srcWidth );
2020  }
2021  }
2022 
2033  function getImageSize( $filePath ) {
2034  if ( !$this->getHandler() ) {
2035  return false;
2036  }
2037 
2038  return $this->getHandler()->getImageSize( $this, $filePath );
2039  }
2040 
2047  function getDescriptionUrl() {
2048  if ( $this->repo ) {
2049  return $this->repo->getDescriptionUrl( $this->getName() );
2050  } else {
2051  return false;
2052  }
2053  }
2054 
2061  function getDescriptionText( Language $lang = null ) {
2062  global $wgLang;
2063 
2064  if ( !$this->repo || !$this->repo->fetchDescription ) {
2065  return false;
2066  }
2067 
2068  $lang = $lang ?? $wgLang;
2069 
2070  $renderUrl = $this->repo->getDescriptionRenderUrl( $this->getName(), $lang->getCode() );
2071  if ( $renderUrl ) {
2072  $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
2073  $key = $this->repo->getLocalCacheKey(
2074  'RemoteFileDescription',
2075  $lang->getCode(),
2076  md5( $this->getName() )
2077  );
2078  $fname = __METHOD__;
2079 
2080  return $cache->getWithSetCallback(
2081  $key,
2082  $this->repo->descriptionCacheExpiry ?: $cache::TTL_UNCACHEABLE,
2083  function ( $oldValue, &$ttl, array &$setOpts ) use ( $renderUrl, $fname ) {
2084  wfDebug( "Fetching shared description from $renderUrl\n" );
2085  $res = MediaWikiServices::getInstance()->getHttpRequestFactory()->
2086  get( $renderUrl, [], $fname );
2087  if ( !$res ) {
2088  $ttl = WANObjectCache::TTL_UNCACHEABLE;
2089  }
2090 
2091  return $res;
2092  }
2093  );
2094  }
2095 
2096  return false;
2097  }
2098 
2111  function getDescription( $audience = self::FOR_PUBLIC, User $user = null ) {
2112  return null;
2113  }
2114 
2120  function getTimestamp() {
2121  $this->assertRepoDefined();
2122 
2123  return $this->repo->getFileTimestamp( $this->getPath() );
2124  }
2125 
2133  public function getDescriptionTouched() {
2134  return false;
2135  }
2136 
2142  function getSha1() {
2143  $this->assertRepoDefined();
2144 
2145  return $this->repo->getFileSha1( $this->getPath() );
2146  }
2147 
2153  function getStorageKey() {
2154  $hash = $this->getSha1();
2155  if ( !$hash ) {
2156  return false;
2157  }
2158  $ext = $this->getExtension();
2159  $dotExt = $ext === '' ? '' : ".$ext";
2160 
2161  return $hash . $dotExt;
2162  }
2163 
2172  function userCan( $field, User $user = null ) {
2173  return true;
2174  }
2175 
2180  function getContentHeaders() {
2181  $handler = $this->getHandler();
2182  if ( $handler ) {
2183  $metadata = $this->getMetadata();
2184 
2185  if ( is_string( $metadata ) ) {
2186  $metadata = AtEase::quietCall( 'unserialize', $metadata );
2187  }
2188 
2189  if ( !is_array( $metadata ) ) {
2190  $metadata = [];
2191  }
2192 
2193  return $handler->getContentHeaders( $metadata );
2194  }
2195 
2196  return [];
2197  }
2198 
2202  function getLongDesc() {
2203  $handler = $this->getHandler();
2204  if ( $handler ) {
2205  return $handler->getLongDesc( $this );
2206  } else {
2207  return MediaHandler::getGeneralLongDesc( $this );
2208  }
2209  }
2210 
2214  function getShortDesc() {
2215  $handler = $this->getHandler();
2216  if ( $handler ) {
2217  return $handler->getShortDesc( $this );
2218  } else {
2219  return MediaHandler::getGeneralShortDesc( $this );
2220  }
2221  }
2222 
2226  function getDimensionsString() {
2227  $handler = $this->getHandler();
2228  if ( $handler ) {
2229  return $handler->getDimensionsString( $this );
2230  } else {
2231  return '';
2232  }
2233  }
2234 
2238  function getRedirected() {
2239  return $this->redirected;
2240  }
2241 
2245  function getRedirectedTitle() {
2246  if ( $this->redirected ) {
2247  if ( !$this->redirectTitle ) {
2248  $this->redirectTitle = Title::makeTitle( NS_FILE, $this->redirected );
2249  }
2250 
2251  return $this->redirectTitle;
2252  }
2253 
2254  return null;
2255  }
2256 
2261  function redirectedFrom( $from ) {
2262  $this->redirected = $from;
2263  }
2264 
2268  function isMissing() {
2269  return false;
2270  }
2271 
2276  public function isCacheable() {
2277  return true;
2278  }
2279 
2284  protected function assertRepoDefined() {
2285  if ( !( $this->repo instanceof $this->repoClass ) ) {
2286  throw new MWException( "A {$this->repoClass} object is not set for this File.\n" );
2287  }
2288  }
2289 
2294  protected function assertTitleDefined() {
2295  if ( !( $this->title instanceof Title ) ) {
2296  throw new MWException( "A Title object is not set for this File.\n" );
2297  }
2298  }
2299 
2304  public function isExpensiveToThumbnail() {
2305  $handler = $this->getHandler();
2306  return $handler ? $handler->isExpensiveToThumbnail( $this ) : false;
2307  }
2308 
2314  public function isTransformedLocally() {
2315  return true;
2316  }
2317 }
convertMetadataVersion( $metadata, $version=1)
Convert metadata version.
getLocalRefPath()
Get an FS copy or original of this file and return the path.
Definition: File.php:443
Title $redirectedTitle
Definition: File.php:118
string false $pageCount
Number of pages of a multipage document, or false for documents which aren&#39;t multipage documents...
Definition: File.php:144
invalidateCache( $purgeTime=null)
Updates page_touched for this page; called from LinksUpdate.php.
Definition: Title.php:4298
const DELETED_COMMENT
Definition: File.php:64
transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags)
Return either a MediaTransformError or placeholder thumbnail (if $wgIgnoreImageErrors) ...
Definition: File.php:1038
const FOR_THIS_USER
Definition: File.php:80
getRepoName()
Returns the name of the repository.
Definition: File.php:1870
MediaHandler $handler
Definition: File.php:124
getMatchedLanguage( $userPreferredLanguage, array $availableLanguages)
When overridden in a descendant class, returns a language code most suiting.
nextHistoryLine()
Return the history of this file, line by line.
Definition: File.php:1506
getShortDesc( $file)
Short description.
$context
Definition: load.php:40
getHistory( $limit=null, $start=null, $end=null, $inc=true)
Return a fragment of the history of file.
Definition: File.php:1493
getPath()
Returns the file system path.
Definition: FSFile.php:53
assertTitleDefined()
Assert that $this->title is set to a Title.
Definition: File.php:2294
formatMetadata( $context=false)
Definition: File.php:1848
$IP
Definition: WebStart.php:41
getThumbRel( $suffix=false)
Get the path, relative to the thumbnail zone root, of the thumbnail directory or a particular file if...
Definition: File.php:1570
move( $target)
Move file to the new title.
Definition: File.php:1936
getTransformScript()
Definition: File.php:918
FSFile bool $fsFile
False if undefined.
Definition: File.php:121
getArchiveThumbUrl( $archiveName, $suffix=false)
Get the URL of the archived file&#39;s thumbs, or a particular thumb if $suffix is specified.
Definition: File.php:1682
getThumbDisposition( $thumbName, $dispositionType='inline')
Definition: File.php:1365
getRedirectedTitle()
Definition: File.php:2245
getShortDesc()
Definition: File.php:2214
getAvailableLanguages()
Gives a (possibly empty) list of languages to render the file in.
Definition: File.php:585
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
getTransform( $image, $dstPath, $dstUrl, $params)
Get a MediaTransformOutput object representing the transformed output.
const DELETE_SOURCE
Definition: File.php:76
iconThumb()
Get a ThumbnailImage representing a file type icon.
Definition: File.php:1403
if(!isset( $args[0])) $lang
isSafeFile()
Determines if this media file is in a format that is unlikely to contain viruses or malicious content...
Definition: File.php:810
__construct( $title, $repo)
Call this constructor from child classes.
Definition: File.php:176
string $extension
File extension.
Definition: File.php:130
getStorageKey()
Get the deletion archive key, "<sha1>.<ext>".
Definition: File.php:2153
static scaleHeight( $srcWidth, $srcHeight, $dstWidth)
Calculate the height of a thumbnail using the source and destination width.
Definition: File.php:2014
isExpensiveToThumbnail( $file)
True if creating thumbnails from the file is large or otherwise resource-intensive.
transform( $params, $flags=0)
Transform a media file.
Definition: File.php:1058
isHashed()
Definition: File.php:1785
getCommonMetaArray()
Like getMetadata but returns a handler independent array of common values.
Definition: File.php:673
$source
createThumb( $width, $height=-1)
Create a thumbnail of the image having the specified width/height.
Definition: File.php:1016
getDescriptionUrl()
Get the URL of the image description page.
Definition: File.php:2047
$wgThumbnailEpoch
If rendered thumbnail files are older than this timestamp, they will be rerendered on demand as if th...
getMatchedLanguage( $userPreferredLanguage)
Get the language code from the available languages for this file that matches the language requested ...
Definition: File.php:601
canRender()
Checks if the output of transform() for this file is likely to be valid.
Definition: File.php:758
assertRepoDefined()
Assert that $this->repo is set to a valid FileRepo instance.
Definition: File.php:2284
getName()
Return the name of this file.
Definition: File.php:307
string $name
The name of a file from its title object.
Definition: File.php:133
getRepo()
Returns the repository.
Definition: File.php:1879
__get( $name)
Definition: File.php:215
getArchiveUrl( $suffix=false)
Get the URL of the archive directory, or a particular file if $suffix is specified.
Definition: File.php:1662
static getInstance()
Returns the global default instance of the top level service locator.
isLocal()
Returns true if the file comes from the local file repository.
Definition: File.php:1861
static extensionFromPath( $path, $case='lowercase')
Get the final extension from a storage or FS path.
getDescription( $audience=self::FOR_PUBLIC, User $user=null)
Get description of file revision STUB.
Definition: File.php:2111
isOld()
Returns true if the image is an old version STUB.
Definition: File.php:1889
execute( $skipcache=false)
Get the result of the work (whatever it is), or the result of the error() function.
getBucketThumbPath( $bucket)
Returns the repo path of the thumb for a given bucket.
Definition: File.php:1335
getCanRender()
Accessor for __get()
Definition: File.php:770
const MEDIATYPE_UNKNOWN
Definition: defines.php:26
generateThumbName( $name, $params)
Generate a thumbnail file name from a name and specified parameters.
Definition: File.php:977
getTitle()
Return the associated title object.
Definition: File.php:336
Title string bool $title
Definition: File.php:109
getHashPath()
Get the filename hash component of the directory including trailing slash, e.g.
Definition: File.php:1526
makeTransformTmpFile( $thumbPath)
Creates a temp FS file with the same extension and the thumbnail.
Definition: File.php:1354
bool $isSafeFile
Whether this media file is in a format that is unlikely to contain viruses or malicious content...
Definition: File.php:158
static getGeneralShortDesc( $file)
Used instead of getShortDesc if there is no handler registered for file.
getThumbnailBucket( $desiredWidth, $page=1)
Return the smallest bucket from $wgThumbnailBuckets which is at least $wgThumbnailMinimumBucketDistan...
Definition: File.php:500
purgeEverything()
Purge metadata and all affected pages when the file is created, deleted, or majorly updated...
Definition: File.php:1466
load( $flags=0)
Load any lazy-loaded file object fields from source.
Definition: File.php:891
getRedirected()
Definition: File.php:2238
const DELETED_FILE
Definition: File.php:63
isVectorized( $file)
The material is vectorized and thus scaling is lossless.
getThumbnails()
Get all thumbnail names previously generated for this file STUB Overridden by LocalFile.
Definition: File.php:1435
getVirtualUrl( $suffix=false)
Get the public zone virtual URL for a current version source file.
Definition: File.php:1738
getDefaultRenderLanguage(File $file)
On file types that support renderings in multiple languages, which language is used by default if uns...
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
Definition: User.php:51
getLongDesc()
Definition: File.php:2202
getLength()
Get the duration of a media file in seconds.
Definition: File.php:551
getDescriptionText(Language $lang=null)
Get the HTML text of the description page, if available.
Definition: File.php:2061
string $hashPath
Relative path including trailing slash.
Definition: File.php:139
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
const THUMB_FULL_NAME
Definition: File.php:84
publish( $src, $flags=0, array $options=[])
Move or copy a file to its public location.
Definition: File.php:1840
getContentHeaders()
Definition: File.php:2180
getPath()
Return the storage path to the file.
Definition: File.php:427
const RENDER_NOW
Force rendering in the current process.
Definition: File.php:69
wasDeleted()
Was this file ever deleted from the wiki?
Definition: File.php:1918
Convenience class for dealing with PoolCounters using callbacks.
readOnlyError()
Definition: File.php:1794
$wgLang
Definition: Setup.php:858
mustRender()
Return true if the file is of a type that can&#39;t be directly rendered by typical browsers and needs to...
Definition: File.php:784
getUnscaledThumb( $handlerParams=[])
Get a ThumbnailImage which is the same size as the source.
Definition: File.php:939
isTrustedFile()
Returns true if the file is flagged as trusted.
Definition: File.php:876
isAnimatedImage( $file)
The material is an image, and is animated.
getSize()
Return the size of the image file, in bytes Overridden by LocalFile, UnregisteredLocalFile STUB...
Definition: File.php:720
getThumbUrl( $suffix=false)
Get the URL of the thumbnail directory, or a particular file if $suffix is specified.
Definition: File.php:1718
isVectorized()
Return true if the file is vectorized.
Definition: File.php:565
getDescriptionShortUrl()
Get short description URL for a files based on the page ID.
Definition: File.php:374
isMultipage()
Returns &#39;true&#39; if this file is a type which supports multiple pages, e.g.
Definition: File.php:1983
getHandler()
Get a MediaHandler instance for this file.
Definition: File.php:1390
thumbName( $params, $flags=0)
Return the file name of a thumbnail with the specified parameters.
Definition: File.php:962
static newForBacklinks(Title $title, $table, $params=[])
$wgThumbnailBuckets
When defined, is an array of image widths used as buckets for thumbnail generation.
const NS_MEDIA
Definition: Defines.php:48
generateBucketsIfNeeded( $params, $flags=0)
Generates chained bucketed thumbnails if needed.
Definition: File.php:1210
getRel()
Get the path of the file relative to the public zone root.
Definition: File.php:1541
userCan( $field, User $user=null)
Determine if the current user is allowed to view a particular field of this file, if it&#39;s marked as d...
Definition: File.php:2172
getMetadata()
Get handler-specific metadata Overridden by LocalFile, UnregisteredLocalFile STUB.
Definition: File.php:663
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
string $lastError
Text of last error.
Definition: File.php:112
Media transform output for images.
getImageSize( $filePath)
Get an image size array like that returned by getImageSize(), or false if it can&#39;t be determined...
Definition: File.php:2033
resetHistory()
Reset the history pointer to the first element of the history.
Definition: File.php:1516
canAnimateThumbIfAppropriate()
Will the thumbnail be animated if one would expect it to be.
Definition: File.php:639
isMissing()
Definition: File.php:2268
getLastError()
Get last thumbnailing error.
Definition: File.php:1425
$cache
Definition: mcc.php:33
allowInlineDisplay()
Alias for canRender()
Definition: File.php:793
$wgResourceBasePath
The default &#39;remoteBasePath&#39; value for instances of ResourceLoaderFileModule.
getAvailableLanguages(File $file)
Get list of languages file can be viewed in.
migrateThumbFile( $thumbName)
Hook into transform() to allow migration of thumbnail files STUB Overridden by LocalFile.
Definition: File.php:1381
array $tmpBucketedThumbCache
Cache of tmp filepaths pointing to generated bucket thumbnails, keyed by width.
Definition: File.php:164
unserialize( $serialized)
getViewURL()
Definition: File.php:399
getTranscodedPath( $suffix=false)
Get the path of the transcoded directory, or a particular file if $suffix is specified.
Definition: File.php:1650
getSha1()
Get the SHA-1 base 36 hash of the file.
Definition: File.php:2142
getDimensionsString()
Definition: File.php:2226
getFullUrl()
Return a fully-qualified URL to the file.
Definition: File.php:385
convertMetadataVersion( $metadata, $version)
get versioned metadata
Definition: File.php:691
getExtension()
Get the file extension, e.g.
Definition: File.php:321
string $redirected
Main part of the title, with underscores (Title::getDBkey)
Definition: File.php:115
const PROTO_RELATIVE
Definition: Defines.php:201
const NS_FILE
Definition: Defines.php:66
$wgThumbnailMinimumBucketDistance
When using thumbnail buckets as defined above, this sets the minimum distance to the bucket above the...
FileRepo LocalRepo ForeignAPIRepo bool $repo
Some member variables can be lazy-initialised using __get().
Definition: File.php:106
static compare(File $a, File $b)
Callback for usort() to do file sorts by name.
Definition: File.php:298
getMediaType()
Return the type of the media in the file.
Definition: File.php:742
getArchivePath( $suffix=false)
Get the path of the archived file.
Definition: File.php:1612
isVisible()
Returns true if file exists in the repository and can be included in a page.
Definition: File.php:911
getScriptedTransform( $image, $script, $params)
Get a MediaTransformOutput object representing an alternate of the transformed output which will call...
getUrlRel()
Get urlencoded path of the file relative to the public zone root.
Definition: File.php:1585
getBitDepth()
Return the bit depth of the file Overridden by LocalFile STUB.
Definition: File.php:710
const DELETED_USER
Definition: File.php:65
getDimensionsString( $file)
Shown in file history box on image description page.
const DELETED_RESTRICTED
Definition: File.php:66
getZoneUrl( $zone, $suffix=false)
Get the URL of the zone directory, or a particular file if $suffix is specified.
Definition: File.php:1701
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:610
getArchiveRel( $suffix=false)
Get the path of an archived file relative to the public zone root.
Definition: File.php:1552
string $transformScript
URL of transformscript (for example thumb.php)
Definition: File.php:147
isExpensiveToThumbnail()
True if creating thumbnails from the file is large or otherwise resource-intensive.
Definition: File.php:2304
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:584
getIsSafeFileUncached()
Uncached accessor.
Definition: File.php:832
redirectedFrom( $from)
Definition: File.php:2261
getDescriptionTouched()
Returns the timestamp (in TS_MW format) of the last change of the description page.
Definition: File.php:2133
canAnimateThumbnail( $file)
If the material is animated, we can animate the thumbnail.
static checkExtensionCompatibility(File $old, $new)
Checks if file extensions are compatible.
Definition: File.php:259
getArchiveThumbPath( $archiveName, $suffix=false)
Get the path of an archived file&#39;s thumbs, or a particular thumb if $suffix is specified.
Definition: File.php:1625
const PROTO_CANONICAL
Definition: Defines.php:203
restore( $versions=[], $unsuppress=false)
Restore all or specified deleted revisions to the given file.
Definition: File.php:1972
getHeight( $page=1)
Return the height of the image.
Definition: File.php:487
getContentHeaders( $metadata)
Get useful response headers for GET/HEAD requests for a file with the given metadata.
getTimestamp()
Get the 14-character timestamp of the file upload.
Definition: File.php:2120
getLength( $file)
If its an audio file, return the length of the file.
getDefaultRenderLanguage()
In files that support multiple language, what is the default language to use if none specified...
Definition: File.php:620
const RAW
Definition: File.php:81
string $url
The URL corresponding to one of the four basic zones.
Definition: File.php:127
getUser( $type='text')
Returns ID or name of user who uploaded the file STUB.
Definition: File.php:542
getVisibility()
Return the deletion bitfield STUB.
Definition: File.php:1909
if(count( $args)< 1) $job
exists()
Returns true if file exists in the repository.
Definition: File.php:901
getTranscodedUrl( $suffix=false)
Get the URL of the transcoded directory, or a particular file if $suffix is specified.
Definition: File.php:1728
getThumbVirtualUrl( $suffix=false)
Get the virtual URL for a thumbnail file or directory.
Definition: File.php:1772
getUrl()
Return the URL of the file.
Definition: File.php:358
normaliseParams( $image, &$params)
Changes the parameter array as necessary, ready for transformation.
getThumbnailSource( $params)
Returns the most appropriate source image for the thumbnail, given a target thumbnail size...
Definition: File.php:1267
static getGeneralLongDesc( $file)
Used instead of getLongDesc if there is no handler registered for file.
if(!is_readable( $file)) $ext
Definition: router.php:48
getOriginalTitle()
Return the title used to find this file.
Definition: File.php:345
Title $redirectTitle
Definition: File.php:150
isDeletedQuick()
Is there a version of this page in the deletion archive?
Definition: Title.php:3136
static splitMime( $mime)
Split an internet media type into its two components; if not a two-part name, set the minor type to &#39;...
Definition: File.php:283
getCanonicalUrl()
Definition: File.php:392
bool $canRender
Whether the output of transform() for this file is likely to be valid.
Definition: File.php:153
static singleton( $domain=false)
isCacheable()
Check if this file object is small and can be cached.
Definition: File.php:2276
getBucketThumbName( $bucket)
Returns the name of the thumb for a given bucket.
Definition: File.php:1345
doTransform( $image, $dstPath, $dstUrl, $params, $flags=0)
Get a MediaTransformOutput object representing the transformed output.
$wgTrustedMediaFormats
list of trusted media-types and MIME types.
getIsSafeFile()
Accessor for __get()
Definition: File.php:823
const FOR_PUBLIC
Definition: File.php:79
getWidth( $page=1)
Return the width of the image.
Definition: File.php:473
const RENDER_FORCE
Force rendering even if thumbnail already exist and using RENDER_NOW I.e.
Definition: File.php:74
pageCount()
Returns the number of pages of a multipage document, or false for documents which aren&#39;t multipage do...
Definition: File.php:1993
upgradeRow()
Upgrade the database row if there is one Called by ImagePage STUB.
Definition: File.php:273
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
getCommonMetaArray(File $file)
Get an array of standard (FormatMetadata type) metadata values.
getLongDesc( $file)
Long description.
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:1813
generateAndSaveThumb( $tmpFile, $transformParams, $flags)
Generates a thumbnail according to the given parameters and saves it to storage.
Definition: File.php:1142
string $path
The storage path corresponding to one of the zones.
Definition: File.php:136
getArchiveVirtualUrl( $suffix=false)
Get the public zone virtual URL for an archived version source file.
Definition: File.php:1754
static normalizeExtension( $extension)
Normalize a file extension to the common form, making it lowercase and checking some synonyms...
Definition: File.php:234
supportsBucketing()
Returns whether or not this handler supports the chained generation of thumbnails according to bucket...
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:61
static getHandler( $type)
Get a MediaHandler for a given MIME type from the instance cache.
$wgIgnoreImageErrors
If set, inline scaled images will still produce "<img>" tags ready for output instead of showing an e...
purgeCache( $options=[])
Purge shared caches such as thumbnails and DB data caching STUB Overridden by LocalFile.
Definition: File.php:1446
string $repoClass
Required Repository class type.
Definition: File.php:161
isTransformedLocally()
Whether the thumbnails created on the same server as this code is running.
Definition: File.php:2314
getMimeType()
Returns the MIME type of the file.
Definition: File.php:731
isDeleted( $field)
Is this file a "deleted" file in a private archive? STUB.
Definition: File.php:1900
static makeContentDisposition( $type, $filename='')
Build a Content-Disposition header value per RFC 6266.
purgeDescription()
Purge the file description page, but don&#39;t go after pages using the file.
Definition: File.php:1454
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
getThumbPath( $suffix=false)
Get the path of the thumbnail directory, or a particular file if $suffix is specified.
Definition: File.php:1638
Basic media transform error class.
purgeSquid()
Purge all applicable CDN URLs.
Definition: Title.php:3574
getArchiveThumbRel( $archiveName, $suffix=false)
Get the path, relative to the thumbnail zone root, for an archived file&#39;s thumbs directory or a speci...
Definition: File.php:1597
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
$starttime
Definition: api.php:38