MediaWiki  master
File.php
Go to the documentation of this file.
1 <?php
8 use MediaWiki\HookContainer\ProtectedHookAccessorTrait;
10 use Wikimedia\AtEase\AtEase;
11 
34 // @phan-file-suppress PhanTypeMissingReturn false positives
63 abstract class File implements IDBAccessObject {
64  use ProtectedHookAccessorTrait;
65 
66  // Bitfield values akin to the Revision deletion constants
67  public const DELETED_FILE = 1;
68  public const DELETED_COMMENT = 2;
69  public const DELETED_USER = 4;
70  public const DELETED_RESTRICTED = 8;
71 
73  public const RENDER_NOW = 1;
78  public const RENDER_FORCE = 2;
79 
80  public const DELETE_SOURCE = 1;
81 
82  // Audience options for File::getDescription()
83  public const FOR_PUBLIC = 1;
84  public const FOR_THIS_USER = 2;
85  public const RAW = 3;
86 
87  // Options for File::thumbName()
88  public const THUMB_FULL_NAME = 1;
89 
110  public $repo;
111 
113  protected $title;
114 
116  protected $lastError;
117 
119  protected $redirected;
120 
122  protected $redirectedTitle;
123 
125  protected $fsFile;
126 
128  protected $handler;
129 
131  protected $url;
132 
134  protected $extension;
135 
137  protected $name;
138 
140  protected $path;
141 
143  protected $hashPath;
144 
148  protected $pageCount;
149 
151  protected $transformScript;
152 
154  protected $redirectTitle;
155 
157  protected $canRender;
158 
162  protected $isSafeFile;
163 
165  protected $repoClass = FileRepo::class;
166 
168  protected $tmpBucketedThumbCache = [];
169 
181  public function __construct( $title, $repo ) {
182  // Some subclasses do not use $title, but set name/title some other way
183  if ( $title !== false ) {
184  $title = self::normalizeTitle( $title, 'exception' );
185  }
186  $this->title = $title;
187  $this->repo = $repo;
188  }
189 
199  public static function normalizeTitle( $title, $exception = false ) {
200  $ret = $title;
201  if ( $ret instanceof Title ) {
202  # Normalize NS_MEDIA -> NS_FILE
203  if ( $ret->getNamespace() === NS_MEDIA ) {
204  $ret = Title::makeTitleSafe( NS_FILE, $ret->getDBkey() );
205  # Sanity check the title namespace
206  } elseif ( $ret->getNamespace() !== NS_FILE ) {
207  $ret = null;
208  }
209  } else {
210  # Convert strings to Title objects
211  $ret = Title::makeTitleSafe( NS_FILE, (string)$ret );
212  }
213  if ( !$ret && $exception !== false ) {
214  throw new MWException( "`$title` is not a valid file title." );
215  }
216 
217  return $ret;
218  }
219 
220  public function __get( $name ) {
221  $function = [ $this, 'get' . ucfirst( $name ) ];
222  if ( !is_callable( $function ) ) {
223  return null;
224  } else {
225  $this->$name = $function();
226 
227  return $this->$name;
228  }
229  }
230 
239  public static function normalizeExtension( $extension ) {
240  $lower = strtolower( $extension );
241  $squish = [
242  'htm' => 'html',
243  'jpeg' => 'jpg',
244  'mpeg' => 'mpg',
245  'tiff' => 'tif',
246  'ogv' => 'ogg' ];
247  if ( isset( $squish[$lower] ) ) {
248  return $squish[$lower];
249  } elseif ( preg_match( '/^[0-9a-z]+$/', $lower ) ) {
250  return $lower;
251  } else {
252  return '';
253  }
254  }
255 
264  public static function checkExtensionCompatibility( File $old, $new ) {
265  $oldMime = $old->getMimeType();
266  $n = strrpos( $new, '.' );
267  $newExt = self::normalizeExtension( $n ? substr( $new, $n + 1 ) : '' );
268  $mimeMagic = MediaWiki\MediaWikiServices::getInstance()->getMimeAnalyzer();
269 
270  return $mimeMagic->isMatchingExtension( $newExt, $oldMime );
271  }
272 
280  public function upgradeRow() {
281  }
282 
290  public static function splitMime( $mime ) {
291  if ( strpos( $mime, '/' ) !== false ) {
292  return explode( '/', $mime, 2 );
293  } else {
294  return [ $mime, 'unknown' ];
295  }
296  }
297 
305  public static function compare( File $a, File $b ) {
306  return strcmp( $a->getName(), $b->getName() );
307  }
308 
315  public function getName() {
316  if ( $this->name === null ) {
317  $this->assertRepoDefined();
318  $this->name = $this->repo->getNameFromTitle( $this->title );
319  }
320 
321  return $this->name;
322  }
323 
330  public function getExtension() {
331  if ( !isset( $this->extension ) ) {
332  $n = strrpos( $this->getName(), '.' );
333  $this->extension = self::normalizeExtension(
334  $n ? substr( $this->getName(), $n + 1 ) : '' );
335  }
336 
337  return $this->extension;
338  }
339 
345  public function getTitle() {
346  return $this->title;
347  }
348 
354  public function getOriginalTitle() {
355  if ( $this->redirected ) {
356  return $this->getRedirectedTitle();
357  }
358 
359  return $this->title;
360  }
361 
368  public function getUrl() {
369  if ( !isset( $this->url ) ) {
370  $this->assertRepoDefined();
371  $ext = $this->getExtension();
372  $this->url = $this->repo->getZoneUrl( 'public', $ext ) . '/' . $this->getUrlRel();
373  }
374 
375  return $this->url;
376  }
377 
385  public function getDescriptionShortUrl() {
386  return null;
387  }
388 
397  public function getFullUrl() {
398  return wfExpandUrl( $this->getUrl(), PROTO_RELATIVE );
399  }
400 
405  public function getCanonicalUrl() {
406  return wfExpandUrl( $this->getUrl(), PROTO_CANONICAL );
407  }
408 
412  public function getViewURL() {
413  if ( $this->mustRender() ) {
414  if ( $this->canRender() ) {
415  return $this->createThumb( $this->getWidth() );
416  } else {
417  wfDebug( __METHOD__ . ': supposed to render ' . $this->getName() .
418  ' (' . $this->getMimeType() . "), but can't!" );
419 
420  return $this->getUrl(); # hm... return NULL?
421  }
422  } else {
423  return $this->getUrl();
424  }
425  }
426 
441  public function getPath() {
442  if ( !isset( $this->path ) ) {
443  $this->assertRepoDefined();
444  $this->path = $this->repo->getZonePath( 'public' ) . '/' . $this->getRel();
445  }
446 
447  return $this->path;
448  }
449 
457  public function getLocalRefPath() {
458  $this->assertRepoDefined();
459  if ( !isset( $this->fsFile ) ) {
460  $starttime = microtime( true );
461  $this->fsFile = $this->repo->getLocalReference( $this->getPath() );
462 
463  $statTiming = microtime( true ) - $starttime;
464  MediaWikiServices::getInstance()->getStatsdDataFactory()->timing(
465  'media.thumbnail.generate.fetchoriginal', 1000 * $statTiming );
466 
467  if ( !$this->fsFile ) {
468  $this->fsFile = false; // null => false; cache negative hits
469  }
470  }
471 
472  return ( $this->fsFile )
473  ? $this->fsFile->getPath()
474  : false;
475  }
476 
488  public function getWidth( $page = 1 ) {
489  return false;
490  }
491 
503  public function getHeight( $page = 1 ) {
504  return false;
505  }
506 
516  public function getThumbnailBucket( $desiredWidth, $page = 1 ) {
518 
519  $imageWidth = $this->getWidth( $page );
520 
521  if ( $imageWidth === false ) {
522  return false;
523  }
524 
525  if ( $desiredWidth > $imageWidth ) {
526  return false;
527  }
528 
529  if ( !$wgThumbnailBuckets ) {
530  return false;
531  }
532 
533  $sortedBuckets = $wgThumbnailBuckets;
534 
535  sort( $sortedBuckets );
536 
537  foreach ( $sortedBuckets as $bucket ) {
538  if ( $bucket >= $imageWidth ) {
539  return false;
540  }
541 
542  if ( $bucket - $wgThumbnailMinimumBucketDistance > $desiredWidth ) {
543  return $bucket;
544  }
545  }
546 
547  // Image is bigger than any available bucket
548  return false;
549  }
550 
561  public function getDisplayWidthHeight( $maxWidth, $maxHeight, $page = 1 ) {
562  if ( !$maxWidth || !$maxHeight ) {
563  // should never happen
564  throw new MWException( 'Using a choice from $wgImageLimits that is 0x0' );
565  }
566 
567  $width = $this->getWidth( $page );
568  $height = $this->getHeight( $page );
569  if ( !$width || !$height ) {
570  return [ 0, 0 ];
571  }
572 
573  // Calculate the thumbnail size.
574  if ( $width <= $maxWidth && $height <= $maxHeight ) {
575  // Vectorized image, do nothing.
576  } elseif ( $width / $height >= $maxWidth / $maxHeight ) {
577  # The limiting factor is the width, not the height.
578  $height = round( $height * $maxWidth / $width );
579  $width = $maxWidth;
580  // Note that $height <= $maxHeight now.
581  } else {
582  $newwidth = floor( $width * $maxHeight / $height );
583  $height = round( $height * $newwidth / $width );
584  $width = $newwidth;
585  // Note that $height <= $maxHeight now, but might not be identical
586  // because of rounding.
587  }
588  return [ $width, $height ];
589  }
590 
599  public function getUser( $type = 'text' ) {
600  return null;
601  }
602 
609  public function getLength() {
610  $handler = $this->getHandler();
611  if ( $handler ) {
612  return $handler->getLength( $this );
613  } else {
614  return 0;
615  }
616  }
617 
623  public function isVectorized() {
624  $handler = $this->getHandler();
625  if ( $handler ) {
626  return $handler->isVectorized( $this );
627  } else {
628  return false;
629  }
630  }
631 
643  public function getAvailableLanguages() {
644  $handler = $this->getHandler();
645  if ( $handler ) {
646  return $handler->getAvailableLanguages( $this );
647  } else {
648  return [];
649  }
650  }
651 
659  public function getMatchedLanguage( $userPreferredLanguage ) {
660  $handler = $this->getHandler();
661  if ( $handler ) {
663  $userPreferredLanguage,
665  );
666  }
667 
668  return null;
669  }
670 
678  public function getDefaultRenderLanguage() {
679  $handler = $this->getHandler();
680  if ( $handler ) {
681  return $handler->getDefaultRenderLanguage( $this );
682  } else {
683  return null;
684  }
685  }
686 
697  public function canAnimateThumbIfAppropriate() {
698  $handler = $this->getHandler();
699  if ( !$handler ) {
700  // We cannot handle image whatsoever, thus
701  // one would not expect it to be animated
702  // so true.
703  return true;
704  }
705 
706  return !$this->allowInlineDisplay()
707  // Image is not animated, so one would
708  // not expect thumb to be
709  || !$handler->isAnimatedImage( $this )
710  // Image is animated, but thumbnail isn't.
711  // This is unexpected to the user.
712  || $handler->canAnimateThumbnail( $this );
713  }
714 
722  public function getMetadata() {
723  return false;
724  }
725 
732  public function getCommonMetaArray() {
733  $handler = $this->getHandler();
734 
735  if ( !$handler ) {
736  return false;
737  }
738 
739  return $handler->getCommonMetaArray( $this );
740  }
741 
750  public function convertMetadataVersion( $metadata, $version ) {
751  $handler = $this->getHandler();
752  if ( !is_array( $metadata ) ) {
753  // Just to make the return type consistent
754  $metadata = unserialize( $metadata );
755  }
756  if ( $handler ) {
757  return $handler->convertMetadataVersion( $metadata, $version );
758  } else {
759  return $metadata;
760  }
761  }
762 
770  public function getBitDepth() {
771  return 0;
772  }
773 
781  public function getSize() {
782  return false;
783  }
784 
793  public function getMimeType() {
794  return 'unknown/unknown';
795  }
796 
805  public function getMediaType() {
806  return MEDIATYPE_UNKNOWN;
807  }
808 
821  public function canRender() {
822  if ( !isset( $this->canRender ) ) {
823  $this->canRender = $this->getHandler() && $this->handler->canRender( $this ) && $this->exists();
824  }
825 
826  return $this->canRender;
827  }
828 
833  protected function getCanRender() {
834  return $this->canRender();
835  }
836 
848  public function mustRender() {
849  return $this->getHandler() && $this->handler->mustRender( $this );
850  }
851 
857  public function allowInlineDisplay() {
858  return $this->canRender();
859  }
860 
874  public function isSafeFile() {
875  if ( !isset( $this->isSafeFile ) ) {
876  $this->isSafeFile = $this->getIsSafeFileUncached();
877  }
878 
879  return $this->isSafeFile;
880  }
881 
887  protected function getIsSafeFile() {
888  return $this->isSafeFile();
889  }
890 
896  protected function getIsSafeFileUncached() {
897  global $wgTrustedMediaFormats;
898 
899  if ( $this->allowInlineDisplay() ) {
900  return true;
901  }
902  if ( $this->isTrustedFile() ) {
903  return true;
904  }
905 
906  $type = $this->getMediaType();
907  $mime = $this->getMimeType();
908 
909  if ( !$type || $type === MEDIATYPE_UNKNOWN ) {
910  return false; # unknown type, not trusted
911  }
912  if ( in_array( $type, $wgTrustedMediaFormats ) ) {
913  return true;
914  }
915 
916  if ( $mime === "unknown/unknown" ) {
917  return false; # unknown type, not trusted
918  }
919  if ( in_array( $mime, $wgTrustedMediaFormats ) ) {
920  return true;
921  }
922 
923  return false;
924  }
925 
939  protected function isTrustedFile() {
940  # this could be implemented to check a flag in the database,
941  # look for signatures, etc
942  return false;
943  }
944 
955  public function load( $flags = 0 ) {
956  }
957 
966  public function exists() {
967  return $this->getPath() && $this->repo->fileExists( $this->path );
968  }
969 
977  public function isVisible() {
978  return $this->exists();
979  }
980 
984  private function getTransformScript() {
985  if ( !isset( $this->transformScript ) ) {
986  $this->transformScript = false;
987  if ( $this->repo ) {
988  $script = $this->repo->getThumbScriptUrl();
989  if ( $script ) {
990  $this->transformScript = wfAppendQuery( $script, [ 'f' => $this->getName() ] );
991  }
992  }
993  }
994 
995  return $this->transformScript;
996  }
997 
1005  public function getUnscaledThumb( $handlerParams = [] ) {
1006  $hp =& $handlerParams;
1007  $page = $hp['page'] ?? false;
1008  $width = $this->getWidth( $page );
1009  if ( !$width ) {
1010  return $this->iconThumb();
1011  }
1012  $hp['width'] = $width;
1013  // be sure to ignore any height specification as well (T64258)
1014  unset( $hp['height'] );
1015 
1016  return $this->transform( $hp );
1017  }
1018 
1029  public function thumbName( $params, $flags = 0 ) {
1030  $name = ( $this->repo && !( $flags & self::THUMB_FULL_NAME ) )
1031  ? $this->repo->nameForThumb( $this->getName() )
1032  : $this->getName();
1033 
1034  return $this->generateThumbName( $name, $params );
1035  }
1036 
1045  public function generateThumbName( $name, $params ) {
1046  if ( !$this->getHandler() ) {
1047  return null;
1048  }
1049  $extension = $this->getExtension();
1050  list( $thumbExt, ) = $this->getHandler()->getThumbType(
1051  $extension, $this->getMimeType(), $params );
1052  $thumbName = $this->getHandler()->makeParamString( $params );
1053 
1054  if ( $this->repo->supportsSha1URLs() ) {
1055  $thumbName .= '-' . $this->getSha1() . '.' . $thumbExt;
1056  } else {
1057  $thumbName .= '-' . $name;
1058 
1059  if ( $thumbExt != $extension ) {
1060  $thumbName .= ".$thumbExt";
1061  }
1062  }
1063 
1064  return $thumbName;
1065  }
1066 
1084  public function createThumb( $width, $height = -1 ) {
1085  $params = [ 'width' => $width ];
1086  if ( $height != -1 ) {
1087  $params['height'] = $height;
1088  }
1089  $thumb = $this->transform( $params );
1090  if ( !$thumb || $thumb->isError() ) {
1091  return '';
1092  }
1093 
1094  return $thumb->getUrl();
1095  }
1096 
1106  protected function transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ) {
1107  global $wgIgnoreImageErrors;
1108 
1109  $handler = $this->getHandler();
1110  if ( $handler && $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
1111  return $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
1112  } else {
1113  return new MediaTransformError( 'thumbnail_error',
1114  $params['width'], 0, wfMessage( 'thumbnail-dest-create' ) );
1115  }
1116  }
1117 
1127  public function transform( $params, $flags = 0 ) {
1128  global $wgThumbnailEpoch;
1129 
1130  do {
1131  if ( !$this->canRender() ) {
1132  $thumb = $this->iconThumb();
1133  break; // not a bitmap or renderable image, don't try
1134  }
1135 
1136  // Get the descriptionUrl to embed it as comment into the thumbnail. T21791.
1137  $descriptionUrl = $this->getDescriptionUrl();
1138  if ( $descriptionUrl ) {
1139  $params['descriptionUrl'] = wfExpandUrl( $descriptionUrl, PROTO_CANONICAL );
1140  }
1141 
1142  $handler = $this->getHandler();
1143  $script = $this->getTransformScript();
1144  if ( $script && !( $flags & self::RENDER_NOW ) ) {
1145  // Use a script to transform on client request, if possible
1146  $thumb = $handler->getScriptedTransform( $this, $script, $params );
1147  if ( $thumb ) {
1148  break;
1149  }
1150  }
1151 
1152  $normalisedParams = $params;
1153  $handler->normaliseParams( $this, $normalisedParams );
1154 
1155  $thumbName = $this->thumbName( $normalisedParams );
1156  $thumbUrl = $this->getThumbUrl( $thumbName );
1157  $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path
1158 
1159  if ( $this->repo ) {
1160  // Defer rendering if a 404 handler is set up...
1161  if ( $this->repo->canTransformVia404() && !( $flags & self::RENDER_NOW ) ) {
1162  // XXX: Pass in the storage path even though we are not rendering anything
1163  // and the path is supposed to be an FS path. This is due to getScalerType()
1164  // getting called on the path and clobbering $thumb->getUrl() if it's false.
1165  $thumb = $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
1166  break;
1167  }
1168  // Check if an up-to-date thumbnail already exists...
1169  wfDebug( __METHOD__ . ": Doing stat for $thumbPath" );
1170  if ( !( $flags & self::RENDER_FORCE ) && $this->repo->fileExists( $thumbPath ) ) {
1171  $timestamp = $this->repo->getFileTimestamp( $thumbPath );
1172  if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) {
1173  // XXX: Pass in the storage path even though we are not rendering anything
1174  // and the path is supposed to be an FS path. This is due to getScalerType()
1175  // getting called on the path and clobbering $thumb->getUrl() if it's false.
1176  $thumb = $handler->getTransform( $this, $thumbPath, $thumbUrl, $params );
1177  $thumb->setStoragePath( $thumbPath );
1178  break;
1179  }
1180  } elseif ( $flags & self::RENDER_FORCE ) {
1181  wfDebug( __METHOD__ . " forcing rendering per flag File::RENDER_FORCE" );
1182  }
1183 
1184  // If the backend is ready-only, don't keep generating thumbnails
1185  // only to return transformation errors, just return the error now.
1186  if ( $this->repo->getReadOnlyReason() !== false ) {
1187  $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags );
1188  break;
1189  }
1190  }
1191 
1192  $tmpFile = $this->makeTransformTmpFile( $thumbPath );
1193 
1194  if ( !$tmpFile ) {
1195  $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags );
1196  } else {
1197  $thumb = $this->generateAndSaveThumb( $tmpFile, $params, $flags );
1198  }
1199  } while ( false );
1200 
1201  return is_object( $thumb ) ? $thumb : false;
1202  }
1203 
1211  public function generateAndSaveThumb( $tmpFile, $transformParams, $flags ) {
1212  global $wgIgnoreImageErrors;
1213 
1214  $stats = MediaWikiServices::getInstance()->getStatsdDataFactory();
1215 
1216  $handler = $this->getHandler();
1217 
1218  $normalisedParams = $transformParams;
1219  $handler->normaliseParams( $this, $normalisedParams );
1220 
1221  $thumbName = $this->thumbName( $normalisedParams );
1222  $thumbUrl = $this->getThumbUrl( $thumbName );
1223  $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path
1224 
1225  $tmpThumbPath = $tmpFile->getPath();
1226 
1227  if ( $handler->supportsBucketing() ) {
1228  $this->generateBucketsIfNeeded( $normalisedParams, $flags );
1229  }
1230 
1231  $starttime = microtime( true );
1232 
1233  // Actually render the thumbnail...
1234  $thumb = $handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $transformParams );
1235  $tmpFile->bind( $thumb ); // keep alive with $thumb
1236 
1237  $statTiming = microtime( true ) - $starttime;
1238  $stats->timing( 'media.thumbnail.generate.transform', 1000 * $statTiming );
1239 
1240  if ( !$thumb ) { // bad params?
1241  $thumb = false;
1242  } elseif ( $thumb->isError() ) { // transform error
1244  '@phan-var MediaTransformError $thumb';
1245  $this->lastError = $thumb->toText();
1246  // Ignore errors if requested
1247  if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) {
1248  $thumb = $handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $transformParams );
1249  }
1250  } elseif ( $this->repo && $thumb->hasFile() && !$thumb->fileIsSource() ) {
1251  // Copy the thumbnail from the file system into storage...
1252 
1253  $starttime = microtime( true );
1254 
1255  $disposition = $this->getThumbDisposition( $thumbName );
1256  $status = $this->repo->quickImport( $tmpThumbPath, $thumbPath, $disposition );
1257  if ( $status->isOK() ) {
1258  $thumb->setStoragePath( $thumbPath );
1259  } else {
1260  $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $transformParams, $flags );
1261  }
1262 
1263  $statTiming = microtime( true ) - $starttime;
1264  $stats->timing( 'media.thumbnail.generate.store', 1000 * $statTiming );
1265 
1266  // Give extensions a chance to do something with this thumbnail...
1267  $this->getHookRunner()->onFileTransformed( $this, $thumb, $tmpThumbPath, $thumbPath );
1268  }
1269 
1270  return $thumb;
1271  }
1272 
1279  protected function generateBucketsIfNeeded( $params, $flags = 0 ) {
1280  if ( !$this->repo
1281  || !isset( $params['physicalWidth'] )
1282  || !isset( $params['physicalHeight'] )
1283  ) {
1284  return false;
1285  }
1286 
1287  $bucket = $this->getThumbnailBucket( $params['physicalWidth'] );
1288 
1289  if ( !$bucket || $bucket == $params['physicalWidth'] ) {
1290  return false;
1291  }
1292 
1293  $bucketPath = $this->getBucketThumbPath( $bucket );
1294 
1295  if ( $this->repo->fileExists( $bucketPath ) ) {
1296  return false;
1297  }
1298 
1299  $starttime = microtime( true );
1300 
1301  $params['physicalWidth'] = $bucket;
1302  $params['width'] = $bucket;
1303 
1304  $params = $this->getHandler()->sanitizeParamsForBucketing( $params );
1305 
1306  $tmpFile = $this->makeTransformTmpFile( $bucketPath );
1307 
1308  if ( !$tmpFile ) {
1309  return false;
1310  }
1311 
1312  $thumb = $this->generateAndSaveThumb( $tmpFile, $params, $flags );
1313 
1314  $buckettime = microtime( true ) - $starttime;
1315 
1316  if ( !$thumb || $thumb->isError() ) {
1317  return false;
1318  }
1319 
1320  $this->tmpBucketedThumbCache[$bucket] = $tmpFile->getPath();
1321  // For the caching to work, we need to make the tmp file survive as long as
1322  // this object exists
1323  $tmpFile->bind( $this );
1324 
1325  MediaWikiServices::getInstance()->getStatsdDataFactory()->timing(
1326  'media.thumbnail.generate.bucket', 1000 * $buckettime );
1327 
1328  return true;
1329  }
1330 
1336  public function getThumbnailSource( $params ) {
1337  if ( $this->repo
1338  && $this->getHandler()->supportsBucketing()
1339  && isset( $params['physicalWidth'] )
1340  && $bucket = $this->getThumbnailBucket( $params['physicalWidth'] )
1341  ) {
1342  if ( $this->getWidth() != 0 ) {
1343  $bucketHeight = round( $this->getHeight() * ( $bucket / $this->getWidth() ) );
1344  } else {
1345  $bucketHeight = 0;
1346  }
1347 
1348  // Try to avoid reading from storage if the file was generated by this script
1349  if ( isset( $this->tmpBucketedThumbCache[$bucket] ) ) {
1350  $tmpPath = $this->tmpBucketedThumbCache[$bucket];
1351 
1352  if ( file_exists( $tmpPath ) ) {
1353  return [
1354  'path' => $tmpPath,
1355  'width' => $bucket,
1356  'height' => $bucketHeight
1357  ];
1358  }
1359  }
1360 
1361  $bucketPath = $this->getBucketThumbPath( $bucket );
1362 
1363  if ( $this->repo->fileExists( $bucketPath ) ) {
1364  $fsFile = $this->repo->getLocalReference( $bucketPath );
1365 
1366  if ( $fsFile ) {
1367  return [
1368  'path' => $fsFile->getPath(),
1369  'width' => $bucket,
1370  'height' => $bucketHeight
1371  ];
1372  }
1373  }
1374  }
1375 
1376  // Thumbnailing a very large file could result in network saturation if
1377  // everyone does it at once.
1378  if ( $this->getSize() >= 1e7 ) { // 10MB
1379  $work = new PoolCounterWorkViaCallback( 'GetLocalFileCopy', sha1( $this->getName() ),
1380  [
1381  'doWork' => function () {
1382  return $this->getLocalRefPath();
1383  }
1384  ]
1385  );
1386  $srcPath = $work->execute();
1387  } else {
1388  $srcPath = $this->getLocalRefPath();
1389  }
1390 
1391  // Original file
1392  return [
1393  'path' => $srcPath,
1394  'width' => $this->getWidth(),
1395  'height' => $this->getHeight()
1396  ];
1397  }
1398 
1404  protected function getBucketThumbPath( $bucket ) {
1405  $thumbName = $this->getBucketThumbName( $bucket );
1406  return $this->getThumbPath( $thumbName );
1407  }
1408 
1414  protected function getBucketThumbName( $bucket ) {
1415  return $this->thumbName( [ 'physicalWidth' => $bucket ] );
1416  }
1417 
1423  protected function makeTransformTmpFile( $thumbPath ) {
1424  $thumbExt = FileBackend::extensionFromPath( $thumbPath );
1425  return MediaWikiServices::getInstance()->getTempFSFileFactory()
1426  ->newTempFSFile( 'transform_', $thumbExt );
1427  }
1428 
1434  public function getThumbDisposition( $thumbName, $dispositionType = 'inline' ) {
1435  $fileName = $this->name; // file name to suggest
1436  $thumbExt = FileBackend::extensionFromPath( $thumbName );
1437  if ( $thumbExt != '' && $thumbExt !== $this->getExtension() ) {
1438  $fileName .= ".$thumbExt";
1439  }
1440 
1441  return FileBackend::makeContentDisposition( $dispositionType, $fileName );
1442  }
1443 
1450  protected function migrateThumbFile( $thumbName ) {
1451  }
1452 
1459  public function getHandler() {
1460  if ( !isset( $this->handler ) ) {
1461  $this->handler = MediaHandler::getHandler( $this->getMimeType() );
1462  }
1463 
1464  return $this->handler;
1465  }
1466 
1472  public function iconThumb() {
1473  global $wgResourceBasePath, $IP;
1474  $assetsPath = "$wgResourceBasePath/resources/assets/file-type-icons/";
1475  $assetsDirectory = "$IP/resources/assets/file-type-icons/";
1476 
1477  $try = [ 'fileicon-' . $this->getExtension() . '.png', 'fileicon.png' ];
1478  foreach ( $try as $icon ) {
1479  if ( file_exists( $assetsDirectory . $icon ) ) { // always FS
1480  $params = [ 'width' => 120, 'height' => 120 ];
1481 
1482  return new ThumbnailImage( $this, $assetsPath . $icon, false, $params );
1483  }
1484  }
1485 
1486  return null;
1487  }
1488 
1494  public function getLastError() {
1495  return $this->lastError;
1496  }
1497 
1505  protected function getThumbnails() {
1506  return [];
1507  }
1508 
1517  public function purgeCache( $options = [] ) {
1518  }
1519 
1525  public function purgeDescription() {
1526  $title = $this->getTitle();
1527  if ( $title ) {
1529  $hcu = MediaWikiServices::getInstance()->getHtmlCacheUpdater();
1530  $hcu->purgeTitleUrls( $title, $hcu::PURGE_INTENT_TXROUND_REFLECTED );
1531  }
1532  }
1533 
1538  public function purgeEverything() {
1539  // Delete thumbnails and refresh file metadata cache
1540  $this->purgeCache();
1541  $this->purgeDescription();
1542  // Purge cache of all pages using this file
1543  $title = $this->getTitle();
1544  if ( $title ) {
1546  $title,
1547  'imagelinks',
1548  [ 'causeAction' => 'file-purge' ]
1549  );
1550  JobQueueGroup::singleton()->lazyPush( $job );
1551  }
1552  }
1553 
1566  public function getHistory( $limit = null, $start = null, $end = null, $inc = true ) {
1567  return [];
1568  }
1569 
1580  public function nextHistoryLine() {
1581  return false;
1582  }
1583 
1591  public function resetHistory() {
1592  }
1593 
1601  public function getHashPath() {
1602  if ( $this->hashPath === null ) {
1603  $this->assertRepoDefined();
1604  $this->hashPath = $this->repo->getHashPath( $this->getName() );
1605  }
1606 
1607  return $this->hashPath;
1608  }
1609 
1617  public function getRel() {
1618  return $this->getHashPath() . $this->getName();
1619  }
1620 
1629  public function getArchiveRel( $suffix = false ) {
1630  $path = 'archive/' . $this->getHashPath();
1631  if ( $suffix === false ) {
1632  $path = rtrim( $path, '/' );
1633  } else {
1634  $path .= $suffix;
1635  }
1636 
1637  return $path;
1638  }
1639 
1648  public function getThumbRel( $suffix = false ) {
1649  $path = $this->getRel();
1650  if ( $suffix !== false ) {
1651  $path .= '/' . $suffix;
1652  }
1653 
1654  return $path;
1655  }
1656 
1664  public function getUrlRel() {
1665  return $this->getHashPath() . rawurlencode( $this->getName() );
1666  }
1667 
1676  private function getArchiveThumbRel( $archiveName, $suffix = false ) {
1677  $path = $this->getArchiveRel( $archiveName );
1678  if ( $suffix !== false ) {
1679  $path .= '/' . $suffix;
1680  }
1681 
1682  return $path;
1683  }
1684 
1691  public function getArchivePath( $suffix = false ) {
1692  $this->assertRepoDefined();
1693 
1694  return $this->repo->getZonePath( 'public' ) . '/' . $this->getArchiveRel( $suffix );
1695  }
1696 
1704  public function getArchiveThumbPath( $archiveName, $suffix = false ) {
1705  $this->assertRepoDefined();
1706 
1707  return $this->repo->getZonePath( 'thumb' ) . '/' .
1708  $this->getArchiveThumbRel( $archiveName, $suffix );
1709  }
1710 
1718  public function getThumbPath( $suffix = false ) {
1719  $this->assertRepoDefined();
1720 
1721  return $this->repo->getZonePath( 'thumb' ) . '/' . $this->getThumbRel( $suffix );
1722  }
1723 
1730  public function getTranscodedPath( $suffix = false ) {
1731  $this->assertRepoDefined();
1732 
1733  return $this->repo->getZonePath( 'transcoded' ) . '/' . $this->getThumbRel( $suffix );
1734  }
1735 
1743  public function getArchiveUrl( $suffix = false ) {
1744  $this->assertRepoDefined();
1745  $ext = $this->getExtension();
1746  $path = $this->repo->getZoneUrl( 'public', $ext ) . '/archive/' . $this->getHashPath();
1747  if ( $suffix === false ) {
1748  $path = rtrim( $path, '/' );
1749  } else {
1750  $path .= rawurlencode( $suffix );
1751  }
1752 
1753  return $path;
1754  }
1755 
1764  public function getArchiveThumbUrl( $archiveName, $suffix = false ) {
1765  $this->assertRepoDefined();
1766  $ext = $this->getExtension();
1767  $path = $this->repo->getZoneUrl( 'thumb', $ext ) . '/archive/' .
1768  $this->getHashPath() . rawurlencode( $archiveName );
1769  if ( $suffix !== false ) {
1770  $path .= '/' . rawurlencode( $suffix );
1771  }
1772 
1773  return $path;
1774  }
1775 
1783  private function getZoneUrl( $zone, $suffix = false ) {
1784  $this->assertRepoDefined();
1785  $ext = $this->getExtension();
1786  $path = $this->repo->getZoneUrl( $zone, $ext ) . '/' . $this->getUrlRel();
1787  if ( $suffix !== false ) {
1788  $path .= '/' . rawurlencode( $suffix );
1789  }
1790 
1791  return $path;
1792  }
1793 
1801  public function getThumbUrl( $suffix = false ) {
1802  return $this->getZoneUrl( 'thumb', $suffix );
1803  }
1804 
1811  public function getTranscodedUrl( $suffix = false ) {
1812  return $this->getZoneUrl( 'transcoded', $suffix );
1813  }
1814 
1822  public function getVirtualUrl( $suffix = false ) {
1823  $this->assertRepoDefined();
1824  $path = $this->repo->getVirtualUrl() . '/public/' . $this->getUrlRel();
1825  if ( $suffix !== false ) {
1826  $path .= '/' . rawurlencode( $suffix );
1827  }
1828 
1829  return $path;
1830  }
1831 
1839  public function getArchiveVirtualUrl( $suffix = false ) {
1840  $this->assertRepoDefined();
1841  $path = $this->repo->getVirtualUrl() . '/public/archive/' . $this->getHashPath();
1842  if ( $suffix === false ) {
1843  $path = rtrim( $path, '/' );
1844  } else {
1845  $path .= rawurlencode( $suffix );
1846  }
1847 
1848  return $path;
1849  }
1850 
1858  public function getThumbVirtualUrl( $suffix = false ) {
1859  $this->assertRepoDefined();
1860  $path = $this->repo->getVirtualUrl() . '/thumb/' . $this->getUrlRel();
1861  if ( $suffix !== false ) {
1862  $path .= '/' . rawurlencode( $suffix );
1863  }
1864 
1865  return $path;
1866  }
1867 
1871  protected function isHashed() {
1872  $this->assertRepoDefined();
1873 
1874  return (bool)$this->repo->getHashLevels();
1875  }
1876 
1880  protected function readOnlyError() {
1881  throw new MWException( static::class . ': write operations are not supported' );
1882  }
1883 
1906  public function publish( $src, $flags = 0, array $options = [] ) {
1907  $this->readOnlyError();
1908  }
1909 
1914  public function formatMetadata( $context = false ) {
1915  if ( !$this->getHandler() ) {
1916  return false;
1917  }
1918 
1919  return $this->getHandler()->formatMetadata( $this, $context );
1920  }
1921 
1927  public function isLocal() {
1928  return $this->repo && $this->repo->isLocal();
1929  }
1930 
1936  public function getRepoName() {
1937  return $this->repo ? $this->repo->getName() : 'unknown';
1938  }
1939 
1946  public function getRepo() {
1947  return $this->repo;
1948  }
1949 
1957  public function isOld() {
1958  return false;
1959  }
1960 
1969  public function isDeleted( $field ) {
1970  return false;
1971  }
1972 
1979  public function getVisibility() {
1980  return 0;
1981  }
1982 
1988  public function wasDeleted() {
1989  $title = $this->getTitle();
1990 
1991  return $title && $title->isDeletedQuick();
1992  }
1993 
2007  public function move( $target ) {
2008  $this->readOnlyError();
2009  }
2010 
2029  public function deleteFile( $reason, User $user, $suppress = false ) {
2030  $this->readOnlyError();
2031  }
2032 
2047  public function restore( $versions = [], $unsuppress = false ) {
2048  $this->readOnlyError();
2049  }
2050 
2059  public function isMultipage() {
2060  return $this->getHandler() && $this->handler->isMultiPage( $this );
2061  }
2062 
2070  public function pageCount() {
2071  if ( !isset( $this->pageCount ) ) {
2072  if ( $this->getHandler() && $this->handler->isMultiPage( $this ) ) {
2073  $this->pageCount = $this->handler->pageCount( $this );
2074  } else {
2075  $this->pageCount = false;
2076  }
2077  }
2078 
2079  return $this->pageCount;
2080  }
2081 
2091  public static function scaleHeight( $srcWidth, $srcHeight, $dstWidth ) {
2092  // Exact integer multiply followed by division
2093  if ( $srcWidth == 0 ) {
2094  return 0;
2095  } else {
2096  return (int)round( $srcHeight * $dstWidth / $srcWidth );
2097  }
2098  }
2099 
2111  protected function getImageSize( $filePath ) {
2112  if ( !$this->getHandler() ) {
2113  return false;
2114  }
2115 
2116  return $this->getHandler()->getImageSize( $this, $filePath );
2117  }
2118 
2126  public function getDescriptionUrl() {
2127  if ( $this->repo ) {
2128  return $this->repo->getDescriptionUrl( $this->getName() );
2129  } else {
2130  return false;
2131  }
2132  }
2133 
2141  public function getDescriptionText( Language $lang = null ) {
2142  global $wgLang;
2143 
2144  if ( !$this->repo || !$this->repo->fetchDescription ) {
2145  return false;
2146  }
2147 
2148  $lang = $lang ?? $wgLang;
2149 
2150  $renderUrl = $this->repo->getDescriptionRenderUrl( $this->getName(), $lang->getCode() );
2151  if ( $renderUrl ) {
2152  $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
2153  $key = $this->repo->getLocalCacheKey(
2154  'RemoteFileDescription',
2155  $lang->getCode(),
2156  md5( $this->getName() )
2157  );
2158  $fname = __METHOD__;
2159 
2160  return $cache->getWithSetCallback(
2161  $key,
2162  $this->repo->descriptionCacheExpiry ?: $cache::TTL_UNCACHEABLE,
2163  function ( $oldValue, &$ttl, array &$setOpts ) use ( $renderUrl, $fname ) {
2164  wfDebug( "Fetching shared description from $renderUrl" );
2165  $res = MediaWikiServices::getInstance()->getHttpRequestFactory()->
2166  get( $renderUrl, [], $fname );
2167  if ( !$res ) {
2168  $ttl = WANObjectCache::TTL_UNCACHEABLE;
2169  }
2170 
2171  return $res;
2172  }
2173  );
2174  }
2175 
2176  return false;
2177  }
2178 
2192  public function getDescription( $audience = self::FOR_PUBLIC, User $user = null ) {
2193  return null;
2194  }
2195 
2202  public function getTimestamp() {
2203  $this->assertRepoDefined();
2204 
2205  return $this->repo->getFileTimestamp( $this->getPath() );
2206  }
2207 
2216  public function getDescriptionTouched() {
2217  return false;
2218  }
2219 
2226  public function getSha1() {
2227  $this->assertRepoDefined();
2228 
2229  return $this->repo->getFileSha1( $this->getPath() );
2230  }
2231 
2237  public function getStorageKey() {
2238  $hash = $this->getSha1();
2239  if ( !$hash ) {
2240  return false;
2241  }
2242  $ext = $this->getExtension();
2243  $dotExt = $ext === '' ? '' : ".$ext";
2244 
2245  return $hash . $dotExt;
2246  }
2247 
2257  public function userCan( $field, User $user ) {
2258  return true;
2259  }
2260 
2265  public function getContentHeaders() {
2266  $handler = $this->getHandler();
2267  if ( $handler ) {
2268  $metadata = $this->getMetadata();
2269 
2270  if ( is_string( $metadata ) ) {
2271  $metadata = AtEase::quietCall( 'unserialize', $metadata );
2272  }
2273 
2274  if ( !is_array( $metadata ) ) {
2275  $metadata = [];
2276  }
2277 
2278  return $handler->getContentHeaders( $metadata );
2279  }
2280 
2281  return [];
2282  }
2283 
2287  public function getLongDesc() {
2288  $handler = $this->getHandler();
2289  if ( $handler ) {
2290  return $handler->getLongDesc( $this );
2291  } else {
2292  return MediaHandler::getGeneralLongDesc( $this );
2293  }
2294  }
2295 
2299  public function getShortDesc() {
2300  $handler = $this->getHandler();
2301  if ( $handler ) {
2302  return $handler->getShortDesc( $this );
2303  } else {
2304  return MediaHandler::getGeneralShortDesc( $this );
2305  }
2306  }
2307 
2311  public function getDimensionsString() {
2312  $handler = $this->getHandler();
2313  if ( $handler ) {
2314  return $handler->getDimensionsString( $this );
2315  } else {
2316  return '';
2317  }
2318  }
2319 
2323  public function getRedirected() {
2324  return $this->redirected;
2325  }
2326 
2330  protected function getRedirectedTitle() {
2331  if ( $this->redirected ) {
2332  if ( !$this->redirectTitle ) {
2333  $this->redirectTitle = Title::makeTitle( NS_FILE, $this->redirected );
2334  }
2335 
2336  return $this->redirectTitle;
2337  }
2338 
2339  return null;
2340  }
2341 
2346  public function redirectedFrom( $from ) {
2347  $this->redirected = $from;
2348  }
2349 
2354  public function isMissing() {
2355  return false;
2356  }
2357 
2363  public function isCacheable() {
2364  return true;
2365  }
2366 
2371  protected function assertRepoDefined() {
2372  if ( !( $this->repo instanceof $this->repoClass ) ) {
2373  throw new MWException( "A {$this->repoClass} object is not set for this File.\n" );
2374  }
2375  }
2376 
2381  protected function assertTitleDefined() {
2382  if ( !( $this->title instanceof Title ) ) {
2383  throw new MWException( "A Title object is not set for this File.\n" );
2384  }
2385  }
2386 
2391  public function isExpensiveToThumbnail() {
2392  $handler = $this->getHandler();
2393  return $handler ? $handler->isExpensiveToThumbnail( $this ) : false;
2394  }
2395 
2402  public function isTransformedLocally() {
2403  return true;
2404  }
2405 }
File\getExtension
getExtension()
Get the file extension, e.g.
Definition: File.php:330
File\getContentHeaders
getContentHeaders()
Definition: File.php:2265
File\THUMB_FULL_NAME
const THUMB_FULL_NAME
Definition: File.php:88
File\getDisplayWidthHeight
getDisplayWidthHeight( $maxWidth, $maxHeight, $page=1)
Get the width and height to display image at.
Definition: File.php:561
File\wasDeleted
wasDeleted()
Was this file ever deleted from the wiki?
Definition: File.php:1988
File\redirectedFrom
redirectedFrom( $from)
Definition: File.php:2346
File\getDescriptionTouched
getDescriptionTouched()
Returns the timestamp (in TS_MW format) of the last change of the description page.
Definition: File.php:2216
File\getPath
getPath()
Return the storage path to the file.
Definition: File.php:441
MediaTransformError
Basic media transform error class.
Definition: MediaTransformError.php:31
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:264
File\$repo
FileRepo LocalRepo ForeignAPIRepo bool $repo
Some member variables can be lazy-initialised using __get().
Definition: File.php:110
MediaHandler\getCommonMetaArray
getCommonMetaArray(File $file)
Get an array of standard (FormatMetadata type) metadata values.
Definition: MediaHandler.php:250
File\canAnimateThumbIfAppropriate
canAnimateThumbIfAppropriate()
Will the thumbnail be animated if one would expect it to be.
Definition: File.php:697
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:1704
File\getHeight
getHeight( $page=1)
Return the height of the image.
Definition: File.php:503
File\DELETED_USER
const DELETED_USER
Definition: File.php:69
File\$tmpBucketedThumbCache
array $tmpBucketedThumbCache
Cache of tmp filepaths pointing to generated bucket thumbnails, keyed by width.
Definition: File.php:168
File\getDescriptionShortUrl
getDescriptionShortUrl()
Get short description URL for a files based on the page ID Stable to override.
Definition: File.php:385
File\getBitDepth
getBitDepth()
Return the bit depth of the file Overridden by LocalFile STUB Stable to override.
Definition: File.php:770
File\getUrlRel
getUrlRel()
Get urlencoded path of the file relative to the public zone root.
Definition: File.php:1664
File\migrateThumbFile
migrateThumbFile( $thumbName)
Hook into transform() to allow migration of thumbnail files STUB Stable to override.
Definition: File.php:1450
File\userCan
userCan( $field, User $user)
Determine if the current user is allowed to view a particular field of this file, if it's marked as d...
Definition: File.php:2257
File\isMultipage
isMultipage()
Returns 'true' if this file is a type which supports multiple pages, e.g.
Definition: File.php:2059
File\getFullUrl
getFullUrl()
Return a fully-qualified URL to the file.
Definition: File.php:397
File\getZoneUrl
getZoneUrl( $zone, $suffix=false)
Get the URL of the zone directory, or a particular file if $suffix is specified.
Definition: File.php:1783
File\DELETED_RESTRICTED
const DELETED_RESTRICTED
Definition: File.php:70
File\getMetadata
getMetadata()
Get handler-specific metadata Overridden by LocalFile, UnregisteredLocalFile STUB Stable to override.
Definition: File.php:722
File\RAW
const RAW
Definition: File.php:85
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:163
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
File\getIsSafeFileUncached
getIsSafeFileUncached()
Uncached accessor.
Definition: File.php:896
File\$transformScript
string $transformScript
URL of transformscript (for example thumb.php)
Definition: File.php:151
File\getRel
getRel()
Get the path of the file relative to the public zone root.
Definition: File.php:1617
File\isExpensiveToThumbnail
isExpensiveToThumbnail()
True if creating thumbnails from the file is large or otherwise resource-intensive.
Definition: File.php:2391
File\isMissing
isMissing()
Stable to override.
Definition: File.php:2354
File\getOriginalTitle
getOriginalTitle()
Return the title used to find this file.
Definition: File.php:354
File\$redirectTitle
Title $redirectTitle
Definition: File.php:154
MediaHandler\getShortDesc
getShortDesc( $file)
Short description.
Definition: MediaHandler.php:628
File\getLastError
getLastError()
Get last thumbnailing error.
Definition: File.php:1494
File\getTimestamp
getTimestamp()
Get the 14-character timestamp of the file upload.
Definition: File.php:2202
File\getSha1
getSha1()
Get the SHA-1 base 36 hash of the file.
Definition: File.php:2226
File\convertMetadataVersion
convertMetadataVersion( $metadata, $version)
get versioned metadata
Definition: File.php:750
File\getUser
getUser( $type='text')
Returns ID or name of user who uploaded the file STUB.
Definition: File.php:599
FileBackend\extensionFromPath
static extensionFromPath( $path, $case='lowercase')
Get the final extension from a storage or FS path.
Definition: FileBackend.php:1602
File\RENDER_FORCE
const RENDER_FORCE
Force rendering even if thumbnail already exist and using RENDER_NOW I.e.
Definition: File.php:78
File\getUrl
getUrl()
Return the URL of the file Stable to override.
Definition: File.php:368
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:305
MediaHandler\getMatchedLanguage
getMatchedLanguage( $userPreferredLanguage, array $availableLanguages)
When overridden in a descendant class, returns a language code most suiting.
Definition: MediaHandler.php:854
File\getTranscodedUrl
getTranscodedUrl( $suffix=false)
Get the URL of the transcoded directory, or a particular file if $suffix is specified.
Definition: File.php:1811
File\getThumbnailSource
getThumbnailSource( $params)
Returns the most appropriate source image for the thumbnail, given a target thumbnail size.
Definition: File.php:1336
MEDIATYPE_UNKNOWN
const MEDIATYPE_UNKNOWN
Definition: defines.php:26
File\getWidth
getWidth( $page=1)
Return the width of the image.
Definition: File.php:488
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1220
File\getMediaType
getMediaType()
Return the type of the media in the file.
Definition: File.php:805
File\restore
restore( $versions=[], $unsuppress=false)
Restore all or specified deleted revisions to the given file.
Definition: File.php:2047
File\getCanonicalUrl
getCanonicalUrl()
Stable to override.
Definition: File.php:405
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:290
File\isVisible
isVisible()
Returns true if file exists in the repository and can be included in a page.
Definition: File.php:977
PoolCounterWorkViaCallback
Convenience class for dealing with PoolCounters using callbacks.
Definition: PoolCounterWorkViaCallback.php:31
$wgThumbnailBuckets
$wgThumbnailBuckets
When defined, is an array of image widths used as buckets for thumbnail generation.
Definition: DefaultSettings.php:1579
MediaHandler\getLongDesc
getLongDesc( $file)
Long description.
Definition: MediaHandler.php:640
$res
$res
Definition: testCompression.php:57
IDBAccessObject
Interface for database access objects.
Definition: IDBAccessObject.php:57
File\$repoClass
string $repoClass
Required Repository class type.
Definition: File.php:165
File\getArchiveRel
getArchiveRel( $suffix=false)
Get the path of an archived file relative to the public zone root Stable to override.
Definition: File.php:1629
File\isDeleted
isDeleted( $field)
Is this file a "deleted" file in a private archive? STUB.
Definition: File.php:1969
File\getVisibility
getVisibility()
Return the deletion bitfield STUB Stable to override.
Definition: File.php:1979
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:1596
MediaHandler\supportsBucketing
supportsBucketing()
Returns whether or not this handler supports the chained generation of thumbnails according to bucket...
Definition: MediaHandler.php:911
File\FOR_PUBLIC
const FOR_PUBLIC
Definition: File.php:83
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:199
MediaHandler\getAvailableLanguages
getAvailableLanguages(File $file)
Get list of languages file can be viewed in.
Definition: MediaHandler.php:839
File\exists
exists()
Returns true if file exists in the repository.
Definition: File.php:966
File\getThumbVirtualUrl
getThumbVirtualUrl( $suffix=false)
Get the virtual URL for a thumbnail file or directory Stable to override.
Definition: File.php:1858
$wgThumbnailEpoch
$wgThumbnailEpoch
If rendered thumbnail files are older than this timestamp, they will be rerendered on demand as if th...
Definition: DefaultSettings.php:1358
File\upgradeRow
upgradeRow()
Upgrade the database row if there is one Called by ImagePage STUB.
Definition: File.php:280
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:438
File\$path
string $path
The storage path corresponding to one of the zones.
Definition: File.php:140
MediaWiki\MediaWikiServices\getInstance
static getInstance()
Returns the global default instance of the top level service locator.
Definition: MediaWikiServices.php:195
File\isCacheable
isCacheable()
Check if this file object is small and can be cached Stable to override.
Definition: File.php:2363
File\$canRender
bool $canRender
Whether the output of transform() for this file is likely to be valid.
Definition: File.php:157
File\getBucketThumbName
getBucketThumbName( $bucket)
Returns the name of the thumb for a given bucket.
Definition: File.php:1414
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:63
MediaHandler\isExpensiveToThumbnail
isExpensiveToThumbnail( $file)
True if creating thumbnails from the file is large or otherwise resource-intensive.
Definition: MediaHandler.php:899
File\getMimeType
getMimeType()
Returns the MIME type of the file.
Definition: File.php:793
File\getDefaultRenderLanguage
getDefaultRenderLanguage()
In files that support multiple language, what is the default language to use if none specified.
Definition: File.php:678
File\$url
string $url
The URL corresponding to one of the four basic zones.
Definition: File.php:131
MWException
MediaWiki exception.
Definition: MWException.php:29
File\getLocalRefPath
getLocalRefPath()
Get an FS copy or original of this file and return the path.
Definition: File.php:457
File\DELETED_COMMENT
const DELETED_COMMENT
Definition: File.php:68
File\transformErrorOutput
transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags)
Return either a MediaTransformError or placeholder thumbnail (if $wgIgnoreImageErrors)
Definition: File.php:1106
File\getIsSafeFile
getIsSafeFile()
Accessor for __get()
Definition: File.php:887
File\$redirectedTitle
Title $redirectedTitle
Definition: File.php:122
File\getThumbPath
getThumbPath( $suffix=false)
Get the path of the thumbnail directory, or a particular file if $suffix is specified Stable to overr...
Definition: File.php:1718
File\pageCount
pageCount()
Returns the number of pages of a multipage document, or false for documents which aren't multipage do...
Definition: File.php:2070
File\nextHistoryLine
nextHistoryLine()
Return the history of this file, line by line.
Definition: File.php:1580
File\normalizeExtension
static normalizeExtension( $extension)
Normalize a file extension to the common form, making it lowercase and checking some synonyms,...
Definition: File.php:239
PoolCounterWork\execute
execute( $skipcache=false)
Get the result of the work (whatever it is), or the result of the error() function.
Definition: PoolCounterWork.php:127
File\getArchiveVirtualUrl
getArchiveVirtualUrl( $suffix=false)
Get the public zone virtual URL for an archived version source file Stable to override.
Definition: File.php:1839
File\deleteFile
deleteFile( $reason, User $user, $suppress=false)
Delete all versions of the file.
Definition: File.php:2029
MediaHandler\canAnimateThumbnail
canAnimateThumbnail( $file)
If the material is animated, we can animate the thumbnail.
Definition: MediaHandler.php:415
$wgLang
$wgLang
Definition: Setup.php:776
File\purgeCache
purgeCache( $options=[])
Purge shared caches such as thumbnails and DB data caching STUB Overridden by LocalFile Stable to ove...
Definition: File.php:1517
File\getTransformScript
getTransformScript()
Definition: File.php:984
File\FOR_THIS_USER
const FOR_THIS_USER
Definition: File.php:84
Title\makeTitle
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:591
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:1676
File\getStorageKey
getStorageKey()
Get the deletion archive key, "<sha1>.<ext>".
Definition: File.php:2237
File\__construct
__construct( $title, $repo)
Call this constructor from child classes.
Definition: File.php:181
File\isHashed
isHashed()
Definition: File.php:1871
File\generateAndSaveThumb
generateAndSaveThumb( $tmpFile, $transformParams, $flags)
Generates a thumbnail according to the given parameters and saves it to storage.
Definition: File.php:1211
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:910
File\getCommonMetaArray
getCommonMetaArray()
Like getMetadata but returns a handler independent array of common values.
Definition: File.php:732
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:1648
File\isTransformedLocally
isTransformedLocally()
Whether the thumbnails created on the same server as this code is running.
Definition: File.php:2402
MediaHandler\getDimensionsString
getDimensionsString( $file)
Shown in file history box on image description page.
Definition: MediaHandler.php:693
File\canRender
canRender()
Checks if the output of transform() for this file is likely to be valid.
Definition: File.php:821
File\$fsFile
FSFile bool $fsFile
False if undefined.
Definition: File.php:125
File\getRedirectedTitle
getRedirectedTitle()
Definition: File.php:2330
MediaHandler\convertMetadataVersion
convertMetadataVersion( $metadata, $version=1)
Convert metadata version.
Definition: MediaHandler.php:169
MediaHandler\getGeneralShortDesc
static getGeneralShortDesc( $file)
Used instead of getShortDesc if there is no handler registered for file.
Definition: MediaHandler.php:650
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:617
File\getAvailableLanguages
getAvailableLanguages()
Gives a (possibly empty) list of languages to render the file in.
Definition: File.php:643
File\iconThumb
iconThumb()
Get a ThumbnailImage representing a file type icon.
Definition: File.php:1472
File\purgeDescription
purgeDescription()
Purge the file description page, but don't go after pages using the file.
Definition: File.php:1525
File\isOld
isOld()
Returns true if the image is an old version STUB.
Definition: File.php:1957
File\$handler
MediaHandler $handler
Definition: File.php:128
NS_MEDIA
const NS_MEDIA
Definition: Defines.php:57
File\assertTitleDefined
assertTitleDefined()
Assert that $this->title is set to a Title.
Definition: File.php:2381
$wgIgnoreImageErrors
$wgIgnoreImageErrors
If set, inline scaled images will still produce "<img>" tags ready for output instead of showing an e...
Definition: DefaultSettings.php:1379
MediaHandler\getTransform
getTransform( $image, $dstPath, $dstUrl, $params)
Get a MediaTransformOutput object representing the transformed output.
Definition: MediaHandler.php:285
File\getHistory
getHistory( $limit=null, $start=null, $end=null, $inc=true)
Return a fragment of the history of file.
Definition: File.php:1566
File\generateThumbName
generateThumbName( $name, $params)
Generate a thumbnail file name from a name and specified parameters Stable to override.
Definition: File.php:1045
File\formatMetadata
formatMetadata( $context=false)
Definition: File.php:1914
File\createThumb
createThumb( $width, $height=-1)
Create a thumbnail of the image having the specified width/height.
Definition: File.php:1084
File\$title
Title string bool $title
Definition: File.php:113
File\getDescriptionUrl
getDescriptionUrl()
Get the URL of the image description page.
Definition: File.php:2126
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 Stable to ov...
Definition: File.php:1764
File\getName
getName()
Return the name of this file.
Definition: File.php:315
File\getArchiveUrl
getArchiveUrl( $suffix=false)
Get the URL of the archive directory, or a particular file if $suffix is specified Stable to override...
Definition: File.php:1743
File\getThumbDisposition
getThumbDisposition( $thumbName, $dispositionType='inline')
Definition: File.php:1434
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:874
File\$pageCount
int false $pageCount
Number of pages of a multipage document, or false for documents which aren't multipage documents.
Definition: File.php:148
File\getRepoName
getRepoName()
Returns the name of the repository.
Definition: File.php:1936
File\DELETE_SOURCE
const DELETE_SOURCE
Definition: File.php:80
$wgResourceBasePath
$wgResourceBasePath
The default 'remoteBasePath' value for instances of ResourceLoaderFileModule.
Definition: DefaultSettings.php:4095
File\publish
publish( $src, $flags=0, array $options=[])
Move or copy a file to its public location.
Definition: File.php:1906
File\$extension
string $extension
File extension.
Definition: File.php:134
File\getBucketThumbPath
getBucketThumbPath( $bucket)
Returns the repo path of the thumb for a given bucket.
Definition: File.php:1404
File\$hashPath
string $hashPath
Relative path including trailing slash.
Definition: File.php:143
File\scaleHeight
static scaleHeight( $srcWidth, $srcHeight, $dstWidth)
Calculate the height of a thumbnail using the source and destination width.
Definition: File.php:2091
File\RENDER_NOW
const RENDER_NOW
Force rendering in the current process.
Definition: File.php:73
File\transform
transform( $params, $flags=0)
Transform a media file Stable to override.
Definition: File.php:1127
unserialize
unserialize( $serialized)
Definition: ApiMessageTrait.php:146
File\getTitle
getTitle()
Return the associated title object.
Definition: File.php:345
File\readOnlyError
readOnlyError()
Definition: File.php:1880
Title
Represents a title within MediaWiki.
Definition: Title.php:41
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:162
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:516
MediaHandler\getContentHeaders
getContentHeaders( $metadata)
Get useful response headers for GET/HEAD requests for a file with the given metadata Stable to overri...
Definition: MediaHandler.php:1011
$cache
$cache
Definition: mcc.php:33
File\move
move( $target)
Move file to the new title.
Definition: File.php:2007
File\assertRepoDefined
assertRepoDefined()
Assert that $this->repo is set to a valid FileRepo instance.
Definition: File.php:2371
File\getShortDesc
getShortDesc()
Definition: File.php:2299
$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:2192
File\getLength
getLength()
Get the duration of a media file in seconds.
Definition: File.php:609
File\getLongDesc
getLongDesc()
Definition: File.php:2287
File\isLocal
isLocal()
Returns true if the file comes from the local file repository.
Definition: File.php:1927
File\getDescriptionText
getDescriptionText(Language $lang=null)
Get the HTML text of the description page, if available Stable to override.
Definition: File.php:2141
MediaHandler\getHandler
static getHandler( $type)
Get a MediaHandler for a given MIME type from the instance cache.
Definition: MediaHandler.php:53
File\getCanRender
getCanRender()
Accessor for __get()
Definition: File.php:833
MediaHandler\isAnimatedImage
isAnimatedImage( $file)
The material is an image, and is animated.
Definition: MediaHandler.php:402
MediaHandler\isVectorized
isVectorized( $file)
The material is vectorized and thus scaling is lossless.
Definition: MediaHandler.php:388
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:848
File\load
load( $flags=0)
Load any lazy-loaded file object fields from source.
Definition: File.php:955
Title\isDeletedQuick
isDeletedQuick()
Is there a version of this page in the deletion archive?
Definition: Title.php:3093
File\resetHistory
resetHistory()
Reset the history pointer to the first element of the history.
Definition: File.php:1591
MediaHandler\getScriptedTransform
getScriptedTransform( $image, $script, $params)
Get a MediaTransformOutput object representing an alternate of the transformed output which will call...
Definition: MediaHandler.php:269
$ext
if(!is_readable( $file)) $ext
Definition: router.php:48
File\getRedirected
getRedirected()
Definition: File.php:2323
File\$name
string $name
The name of a file from its title object.
Definition: File.php:137
File\DELETED_FILE
const DELETED_FILE
Definition: File.php:67
File\getMatchedLanguage
getMatchedLanguage( $userPreferredLanguage)
Get the language code from the available languages for this file that matches the language requested ...
Definition: File.php:659
MediaHandler\getGeneralLongDesc
static getGeneralLongDesc( $file)
Used instead of getLongDesc if there is no handler registered for file.
Definition: MediaHandler.php:662
File\getRepo
getRepo()
Returns the repository Stable to override.
Definition: File.php:1946
File\allowInlineDisplay
allowInlineDisplay()
Alias for canRender()
Definition: File.php:857
Title\invalidateCache
invalidateCache( $purgeTime=null)
Updates page_touched for this page; called from LinksUpdate.php.
Definition: Title.php:4072
$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 Stable to overri...
Definition: File.php:1801
File\isVectorized
isVectorized()
Return true if the file is vectorized.
Definition: File.php:623
File\getDimensionsString
getDimensionsString()
Definition: File.php:2311
File\getHandler
getHandler()
Get a MediaHandler instance for this file.
Definition: File.php:1459
File\__get
__get( $name)
Definition: File.php:220
$wgTrustedMediaFormats
$wgTrustedMediaFormats
list of trusted media-types and MIME types.
Definition: DefaultSettings.php:1097
$IP
$IP
Definition: WebStart.php:49
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:56
File\generateBucketsIfNeeded
generateBucketsIfNeeded( $params, $flags=0)
Generates chained bucketed thumbnails if needed.
Definition: File.php:1279
File\thumbName
thumbName( $params, $flags=0)
Return the file name of a thumbnail with the specified parameters.
Definition: File.php:1029
File\$lastError
string $lastError
Text of last error.
Definition: File.php:116
File\$redirected
string $redirected
Main part of the title, with underscores (Title::getDBkey)
Definition: File.php:119
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:2111
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:1423
File\getArchivePath
getArchivePath( $suffix=false)
Get the path of the archived file.
Definition: File.php:1691
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:41
File\purgeEverything
purgeEverything()
Purge metadata and all affected pages when the file is created, deleted, or majorly updated.
Definition: File.php:1538
File\getUnscaledThumb
getUnscaledThumb( $handlerParams=[])
Get a ThumbnailImage which is the same size as the source.
Definition: File.php:1005
File\getHashPath
getHashPath()
Get the filename hash component of the directory including trailing slash, e.g.
Definition: File.php:1601
File\isTrustedFile
isTrustedFile()
Returns true if the file is flagged as trusted.
Definition: File.php:939
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 Stabl...
Definition: File.php:781
MediaHandler
Base media handler class.
Definition: MediaHandler.php:37
MediaHandler\getLength
getLength( $file)
If its an audio file, return the length of the file.
Definition: MediaHandler.php:888
wfExpandUrl
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
Definition: GlobalFunctions.php:490
File\getThumbnails
getThumbnails()
Get all thumbnail names previously generated for this file STUB Overridden by LocalFile Stable to ove...
Definition: File.php:1505
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:872
File\getTranscodedPath
getTranscodedPath( $suffix=false)
Get the path of the transcoded directory, or a particular file if $suffix is specified.
Definition: File.php:1730
File\getViewURL
getViewURL()
Definition: File.php:412
File\getVirtualUrl
getVirtualUrl( $suffix=false)
Get the public zone virtual URL for a current version source file Stable to override.
Definition: File.php:1822
$type
$type
Definition: testCompression.php:52
FileBackend\makeContentDisposition
static makeContentDisposition( $type, $filename='')
Build a Content-Disposition header value per RFC 6266.
Definition: FileBackend.php:1637