MediaWiki  master
thumb.php
Go to the documentation of this file.
1 <?php
31 use Wikimedia\AtEase\AtEase;
32 
33 define( 'MW_NO_OUTPUT_COMPRESSION', 1 );
34 // T241340: thumb.php is included by thumb_handler.php which already defined
35 // MW_ENTRY_POINT to 'thumb_handler'
36 if ( !defined( 'MW_ENTRY_POINT' ) ) {
37  define( 'MW_ENTRY_POINT', 'thumb' );
38 }
39 require __DIR__ . '/includes/WebStart.php';
40 
41 wfThumbMain();
42 
43 function wfThumbMain() {
45 
46  // Don't use fancy MIME detection, just check the file extension for jpg/gif/png
48 
49  if ( defined( 'THUMB_HANDLER' ) ) {
50  // Called from thumb_handler.php via 404; extract params from the URI...
52  } else {
53  // Called directly, use $_GET params
54  wfStreamThumb( $wgRequest->getQueryValuesOnly() );
55  }
56 
57  $mediawiki = new MediaWiki();
58  $mediawiki->doPostOutputShutdown();
59 }
60 
66 function wfThumbHandle404() {
67  global $wgThumbPath;
68 
69  if ( $wgThumbPath ) {
71  } else {
72  // Determine the request path relative to the thumbnail zone base
73  $repo = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo();
74  $baseUrl = $repo->getZoneUrl( 'thumb' );
75  if ( substr( $baseUrl, 0, 1 ) === '/' ) {
76  $basePath = $baseUrl;
77  } else {
78  $basePath = parse_url( $baseUrl, PHP_URL_PATH );
79  }
80  $relPath = WebRequest::getRequestPathSuffix( $basePath );
81  }
82 
83  $params = wfExtractThumbRequestInfo( $relPath ); // basic wiki URL param extracting
84  if ( $params == null ) {
85  wfThumbError( 400, 'The specified thumbnail parameters are not recognized.' );
86  return;
87  }
88 
89  wfStreamThumb( $params ); // stream the thumbnail
90 }
91 
105 function wfStreamThumb( array $params ) {
106  global $wgVaryOnXFP;
107  $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
108 
109  $headers = []; // HTTP headers to send
110 
111  $fileName = $params['f'] ?? '';
112 
113  // Backwards compatibility parameters
114  if ( isset( $params['w'] ) ) {
115  $params['width'] = $params['w'];
116  unset( $params['w'] );
117  }
118  if ( isset( $params['width'] ) && substr( $params['width'], -2 ) == 'px' ) {
119  // strip the px (pixel) suffix, if found
120  $params['width'] = substr( $params['width'], 0, -2 );
121  }
122  if ( isset( $params['p'] ) ) {
123  $params['page'] = $params['p'];
124  }
125 
126  // Is this a thumb of an archived file?
127  $isOld = ( isset( $params['archived'] ) && $params['archived'] );
128  unset( $params['archived'] ); // handlers don't care
129 
130  // Is this a thumb of a temp file?
131  $isTemp = ( isset( $params['temp'] ) && $params['temp'] );
132  unset( $params['temp'] ); // handlers don't care
133 
134  // Some basic input validation
135  $fileName = strtr( $fileName, '\\/', '__' );
136  $localRepo = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo();
137 
138  // Actually fetch the image. Method depends on whether it is archived or not.
139  if ( $isTemp ) {
140  $repo = $localRepo->getTempRepo();
141  $img = new UnregisteredLocalFile( null, $repo,
142  # Temp files are hashed based on the name without the timestamp.
143  # The thumbnails will be hashed based on the entire name however.
144  # @todo fix this convention to actually be reasonable.
145  $repo->getZonePath( 'public' ) . '/' . $repo->getTempHashPath( $fileName ) . $fileName
146  );
147  } elseif ( $isOld ) {
148  // Format is <timestamp>!<name>
149  $bits = explode( '!', $fileName, 2 );
150  if ( count( $bits ) != 2 ) {
151  wfThumbError( 404, wfMessage( 'badtitletext' )->parse() );
152  return;
153  }
154  $title = Title::makeTitleSafe( NS_FILE, $bits[1] );
155  if ( !$title ) {
156  wfThumbError( 404, wfMessage( 'badtitletext' )->parse() );
157  return;
158  }
159  $img = $localRepo->newFromArchiveName( $title, $fileName );
160  } else {
161  $img = $localRepo->newFile( $fileName );
162  }
163 
164  // Check the source file title
165  if ( !$img ) {
166  wfThumbError( 404, wfMessage( 'badtitletext' )->parse() );
167  return;
168  }
169 
170  // Check permissions if there are read restrictions
171  $varyHeader = [];
172  if ( !in_array( 'read', $permissionManager->getGroupPermissions( [ '*' ] ), true ) ) {
173  $user = RequestContext::getMain()->getUser();
174  $imgTitle = $img->getTitle();
175 
176  if ( !$imgTitle || !$permissionManager->userCan( 'read', $user, $imgTitle ) ) {
177  wfThumbError( 403, 'Access denied. You do not have permission to access ' .
178  'the source file.' );
179  return;
180  }
181  $headers[] = 'Cache-Control: private';
182  $varyHeader[] = 'Cookie';
183  }
184 
185  // Check if the file is hidden
186  if ( $img->isDeleted( File::DELETED_FILE ) ) {
187  wfThumbErrorText( 404, "The source file '$fileName' does not exist." );
188  return;
189  }
190 
191  // Do rendering parameters extraction from thumbnail name.
192  if ( isset( $params['thumbName'] ) ) {
193  $params = wfExtractThumbParams( $img, $params );
194  }
195  if ( $params == null ) {
196  wfThumbError( 400, 'The specified thumbnail parameters are not recognized.' );
197  return;
198  }
199 
200  // Check the source file storage path
201  if ( !$img->exists() ) {
202  $redirectedLocation = false;
203  if ( !$isTemp ) {
204  // Check for file redirect
205  // Since redirects are associated with pages, not versions of files,
206  // we look for the most current version to see if its a redirect.
207  $possRedirFile = $localRepo->findFile( $img->getName() );
208  if ( $possRedirFile && $possRedirFile->getRedirected() !== null ) {
209  $redirTarget = $possRedirFile->getName();
210  $targetFile = $localRepo->newFile( Title::makeTitleSafe( NS_FILE, $redirTarget ) );
211  if ( $targetFile->exists() ) {
212  $newThumbName = $targetFile->thumbName( $params );
213  if ( $isOld ) {
215  $newThumbUrl = $targetFile->getArchiveThumbUrl(
216  $bits[0] . '!' . $targetFile->getName(), $newThumbName );
217  } else {
218  $newThumbUrl = $targetFile->getThumbUrl( $newThumbName );
219  }
220  $redirectedLocation = wfExpandUrl( $newThumbUrl, PROTO_CURRENT );
221  }
222  }
223  }
224 
225  if ( $redirectedLocation ) {
226  // File has been moved. Give redirect.
227  $response = RequestContext::getMain()->getRequest()->response();
228  $response->statusHeader( 302 );
229  $response->header( 'Location: ' . $redirectedLocation );
230  $response->header( 'Expires: ' .
231  gmdate( 'D, d M Y H:i:s', time() + 12 * 3600 ) . ' GMT' );
232  if ( $wgVaryOnXFP ) {
233  $varyHeader[] = 'X-Forwarded-Proto';
234  }
235  if ( count( $varyHeader ) ) {
236  $response->header( 'Vary: ' . implode( ', ', $varyHeader ) );
237  }
238  $response->header( 'Content-Length: 0' );
239  return;
240  }
241 
242  // If its not a redirect that has a target as a local file, give 404.
243  wfThumbErrorText( 404, "The source file '$fileName' does not exist." );
244  return;
245  } elseif ( $img->getPath() === false ) {
246  wfThumbErrorText( 400, "The source file '$fileName' is not locally accessible." );
247  return;
248  }
249 
250  // Check IMS against the source file
251  // This means that clients can keep a cached copy even after it has been deleted on the server
252  if ( !empty( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) ) {
253  // Fix IE brokenness
254  $imsString = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
255  // Calculate time
256  AtEase::suppressWarnings();
257  $imsUnix = strtotime( $imsString );
258  AtEase::restoreWarnings();
259  if ( wfTimestamp( TS_UNIX, $img->getTimestamp() ) <= $imsUnix ) {
260  HttpStatus::header( 304 );
261  return;
262  }
263  }
264 
265  $rel404 = $params['rel404'] ?? null;
266  unset( $params['r'] ); // ignore 'r' because we unconditionally pass File::RENDER
267  unset( $params['f'] ); // We're done with 'f' parameter.
268  unset( $params['rel404'] ); // moved to $rel404
269 
270  // Get the normalized thumbnail name from the parameters...
271  try {
272  $thumbName = $img->thumbName( $params );
273  if ( !strlen( $thumbName ) ) { // invalid params?
275  'Empty return from File::thumbName'
276  );
277  }
278  $thumbName2 = $img->thumbName( $params, File::THUMB_FULL_NAME ); // b/c; "long" style
280  wfThumbError(
281  400,
282  'The specified thumbnail parameters are not valid: ' . $e->getMessage()
283  );
284  return;
285  } catch ( MWException $e ) {
286  wfThumbError( 500, $e->getHTML(), 'Exception caught while extracting thumb name',
287  [ 'exception' => $e ] );
288  return;
289  }
290 
291  // For 404 handled thumbnails, we only use the base name of the URI
292  // for the thumb params and the parent directory for the source file name.
293  // Check that the zone relative path matches up so CDN caches won't pick
294  // up thumbs that would not be purged on source file deletion (T36231).
295  if ( $rel404 !== null ) { // thumbnail was handled via 404
296  if ( rawurldecode( $rel404 ) === $img->getThumbRel( $thumbName ) ) {
297  // Request for the canonical thumbnail name
298  } elseif ( rawurldecode( $rel404 ) === $img->getThumbRel( $thumbName2 ) ) {
299  // Request for the "long" thumbnail name; redirect to canonical name
300  $response = RequestContext::getMain()->getRequest()->response();
301  $response->statusHeader( 301 );
302  $response->header( 'Location: ' .
303  wfExpandUrl( $img->getThumbUrl( $thumbName ), PROTO_CURRENT ) );
304  $response->header( 'Expires: ' .
305  gmdate( 'D, d M Y H:i:s', time() + 7 * 86400 ) . ' GMT' );
306  if ( $wgVaryOnXFP ) {
307  $varyHeader[] = 'X-Forwarded-Proto';
308  }
309  if ( count( $varyHeader ) ) {
310  $response->header( 'Vary: ' . implode( ', ', $varyHeader ) );
311  }
312  return;
313  } else {
314  wfThumbErrorText( 404, "The given path of the specified thumbnail is incorrect;
315  expected '" . $img->getThumbRel( $thumbName ) . "' but got '" .
316  rawurldecode( $rel404 ) . "'." );
317  return;
318  }
319  }
320 
321  $dispositionType = isset( $params['download'] ) ? 'attachment' : 'inline';
322 
323  // Suggest a good name for users downloading this thumbnail
324  $headers[] =
325  "Content-Disposition: {$img->getThumbDisposition( $thumbName, $dispositionType )}";
326 
327  if ( count( $varyHeader ) ) {
328  $headers[] = 'Vary: ' . implode( ', ', $varyHeader );
329  }
330 
331  // Stream the file if it exists already...
332  $thumbPath = $img->getThumbPath( $thumbName );
333  if ( $img->getRepo()->fileExists( $thumbPath ) ) {
334  $starttime = microtime( true );
335  $status = $img->getRepo()->streamFileWithStatus( $thumbPath, $headers );
336  $streamtime = microtime( true ) - $starttime;
337 
338  if ( $status->isOK() ) {
339  MediaWikiServices::getInstance()->getStatsdDataFactory()->timing(
340  'media.thumbnail.stream', $streamtime
341  );
342  } else {
343  wfThumbError( 500, 'Could not stream the file', null, [ 'file' => $thumbName,
344  'path' => $thumbPath, 'error' => $status->getWikiText( false, false, 'en' ) ] );
345  }
346  return;
347  }
348 
349  $user = RequestContext::getMain()->getUser();
350  if ( !wfThumbIsStandard( $img, $params ) && $user->pingLimiter( 'renderfile-nonstandard' ) ) {
351  wfThumbError( 429, wfMessage( 'actionthrottledtext' )->parse() );
352  return;
353  } elseif ( $user->pingLimiter( 'renderfile' ) ) {
354  wfThumbError( 429, wfMessage( 'actionthrottledtext' )->parse() );
355  return;
356  }
357 
358  $thumbProxyUrl = $img->getRepo()->getThumbProxyUrl();
359 
360  if ( strlen( $thumbProxyUrl ) ) {
361  wfProxyThumbnailRequest( $img, $thumbName );
362  // No local fallback when in proxy mode
363  return;
364  } else {
365  // Generate the thumbnail locally
366  list( $thumb, $errorMsg ) = wfGenerateThumbnail( $img, $params, $thumbName, $thumbPath );
367  }
368 
371  // Check for thumbnail generation errors...
372  $msg = wfMessage( 'thumbnail_error' );
373  $errorCode = 500;
374 
375  if ( !$thumb ) {
376  $errorMsg = $errorMsg ?: $msg->rawParams( 'File::transform() returned false' )->escaped();
377  if ( $errorMsg instanceof MessageSpecifier &&
378  $errorMsg->getKey() === 'thumbnail_image-failure-limit'
379  ) {
380  $errorCode = 429;
381  }
382  } elseif ( $thumb->isError() ) {
383  $errorMsg = $thumb->getHtmlMsg();
384  $errorCode = $thumb->getHttpStatusCode();
385  } elseif ( !$thumb->hasFile() ) {
386  $errorMsg = $msg->rawParams( 'No path supplied in thumbnail object' )->escaped();
387  } elseif ( $thumb->fileIsSource() ) {
388  $errorMsg = $msg
389  ->rawParams( 'Image was not scaled, is the requested width bigger than the source?' )
390  ->escaped();
391  $errorCode = 400;
392  }
393 
394  if ( $errorMsg !== false ) {
395  wfThumbError( $errorCode, $errorMsg, null, [ 'file' => $thumbName, 'path' => $thumbPath ] );
396  } else {
397  // Stream the file if there were no errors
398  $status = $thumb->streamFileWithStatus( $headers );
399  if ( !$status->isOK() ) {
400  wfThumbError( 500, 'Could not stream the file', null, [
401  'file' => $thumbName, 'path' => $thumbPath,
402  'error' => $status->getWikiText( false, false, 'en' ) ] );
403  }
404  }
405 }
406 
413 function wfProxyThumbnailRequest( $img, $thumbName ) {
414  $thumbProxyUrl = $img->getRepo()->getThumbProxyUrl();
415 
416  // Instead of generating the thumbnail ourselves, we proxy the request to another service
417  $thumbProxiedUrl = $thumbProxyUrl . $img->getThumbRel( $thumbName );
418 
419  $req = MWHttpRequest::factory( $thumbProxiedUrl );
420  $secret = $img->getRepo()->getThumbProxySecret();
421 
422  // Pass a secret key shared with the proxied service if any
423  if ( strlen( $secret ) ) {
424  $req->setHeader( 'X-Swift-Secret', $secret );
425  }
426 
427  // Send request to proxied service
428  $status = $req->execute();
429 
431 
432  // Simply serve the response from the proxied service as-is
433  header( 'HTTP/1.1 ' . $req->getStatus() );
434 
435  $headers = $req->getResponseHeaders();
436 
437  foreach ( $headers as $key => $values ) {
438  foreach ( $values as $value ) {
439  header( $key . ': ' . $value, false );
440  }
441  }
442 
443  echo $req->getContent();
444 }
445 
455 function wfGenerateThumbnail( File $file, array $params, $thumbName, $thumbPath ) {
456  global $wgAttemptFailureEpoch;
457 
459  $key = $cache->makeKey(
460  'attempt-failures',
462  $file->getRepo()->getName(),
463  $file->getSha1(),
464  md5( $thumbName )
465  );
466 
467  // Check if this file keeps failing to render
468  if ( $cache->get( $key ) >= 4 ) {
469  return [ false, wfMessage( 'thumbnail_image-failure-limit', 4 ) ];
470  }
471 
472  $done = false;
473  // Record failures on PHP fatals in addition to caching exceptions
474  register_shutdown_function( static function () use ( $cache, &$done, $key ) {
475  if ( !$done ) { // transform() gave a fatal
476  // Randomize TTL to reduce stampedes
477  $cache->incrWithInit( $key, $cache::TTL_HOUR + mt_rand( 0, 300 ) );
478  }
479  } );
480 
481  $thumb = false;
482  $errorHtml = false;
483 
484  // guard thumbnail rendering with PoolCounter to avoid stampedes
485  // expensive files use a separate PoolCounter config so it is possible
486  // to set up a global limit on them
487  if ( $file->isExpensiveToThumbnail() ) {
488  $poolCounterType = 'FileRenderExpensive';
489  } else {
490  $poolCounterType = 'FileRender';
491  }
492 
493  // Thumbnail isn't already there, so create the new thumbnail...
494  try {
495  $work = new PoolCounterWorkViaCallback( $poolCounterType, sha1( $file->getName() ),
496  [
497  'doWork' => static function () use ( $file, $params ) {
498  return $file->transform( $params, File::RENDER_NOW );
499  },
500  'doCachedWork' => static function () use ( $file, $params, $thumbPath ) {
501  // If the worker that finished made this thumbnail then use it.
502  // Otherwise, it probably made a different thumbnail for this file.
503  return $file->getRepo()->fileExists( $thumbPath )
504  ? $file->transform( $params, File::RENDER_NOW )
505  : false; // retry once more in exclusive mode
506  },
507  'error' => static function ( Status $status ) {
508  return wfMessage( 'generic-pool-error' )->parse() . '<hr>' . $status->getHTML();
509  }
510  ]
511  );
512  $result = $work->execute();
513  if ( $result instanceof MediaTransformOutput ) {
514  $thumb = $result;
515  } elseif ( is_string( $result ) ) { // error
516  $errorHtml = $result;
517  }
518  } catch ( Exception $e ) {
519  // Tried to select a page on a non-paged file?
520  }
521 
523  $done = true; // no PHP fatal occurred
524 
525  if ( !$thumb || $thumb->isError() ) {
526  // Randomize TTL to reduce stampedes
527  $cache->incrWithInit( $key, $cache::TTL_HOUR + mt_rand( 0, 300 ) );
528  }
529 
530  return [ $thumb, $errorHtml ];
531 }
532 
552 function wfExtractThumbRequestInfo( $thumbRel ) {
553  $repo = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo();
554 
555  $hashDirReg = $subdirReg = '';
556  $hashLevels = $repo->getHashLevels();
557  for ( $i = 0; $i < $hashLevels; $i++ ) {
558  $subdirReg .= '[0-9a-f]';
559  $hashDirReg .= "$subdirReg/";
560  }
561 
562  // Check if this is a thumbnail of an original in the local file repo
563  if ( preg_match( "!^((archive/)?$hashDirReg([^/]*)/([^/]*))$!", $thumbRel, $m ) ) {
564  list( /*all*/, $rel, $archOrTemp, $filename, $thumbname ) = $m;
565  // Check if this is a thumbnail of an temp file in the local file repo
566  } elseif ( preg_match( "!^(temp/)($hashDirReg([^/]*)/([^/]*))$!", $thumbRel, $m ) ) {
567  list( /*all*/, $archOrTemp, $rel, $filename, $thumbname ) = $m;
568  } else {
569  return null; // not a valid looking thumbnail request
570  }
571 
572  $params = [ 'f' => $filename, 'rel404' => $rel ];
573  if ( $archOrTemp === 'archive/' ) {
574  $params['archived'] = 1;
575  } elseif ( $archOrTemp === 'temp/' ) {
576  $params['temp'] = 1;
577  }
578 
579  $params['thumbName'] = $thumbname;
580  return $params;
581 }
582 
591 function wfExtractThumbParams( $file, $params ) {
592  if ( !isset( $params['thumbName'] ) ) {
593  throw new InvalidArgumentException( "No thumbnail name passed to wfExtractThumbParams" );
594  }
595 
596  $thumbname = $params['thumbName'];
597  unset( $params['thumbName'] );
598 
599  // FIXME: Files in the temp zone don't set a MIME type, which means
600  // they don't have a handler. Which means we can't parse the param
601  // string. However, not a big issue as what good is a param string
602  // if you have no handler to make use of the param string and
603  // actually generate the thumbnail.
604  $handler = $file->getHandler();
605 
606  // Based on UploadStash::parseKey
607  $fileNamePos = strrpos( $thumbname, $params['f'] );
608  if ( $fileNamePos === false ) {
609  // Maybe using a short filename? (see FileRepo::nameForThumb)
610  $fileNamePos = strrpos( $thumbname, 'thumbnail' );
611  }
612 
613  if ( $handler && $fileNamePos !== false ) {
614  $paramString = substr( $thumbname, 0, $fileNamePos - 1 );
615  $extraParams = $handler->parseParamString( $paramString );
616  if ( $extraParams !== false ) {
617  return $params + $extraParams;
618  }
619  }
620 
621  // As a last ditch fallback, use the traditional common parameters
622  if ( preg_match( '!^(page(\d*)-)*(\d*)px-[^/]*$!', $thumbname, $matches ) ) {
623  list( /* all */, /* pagefull */, $pagenum, $size ) = $matches;
624  $params['width'] = $size;
625  if ( $pagenum ) {
626  $params['page'] = $pagenum;
627  }
628  return $params; // valid thumbnail URL
629  }
630  return null;
631 }
632 
640 function wfThumbErrorText( $status, $msgText ) {
641  wfThumbError( $status, htmlspecialchars( $msgText, ENT_NOQUOTES ) );
642 }
643 
654 function wfThumbError( $status, $msgHtml, $msgText = null, $context = [] ) {
655  global $wgShowHostnames;
656 
658 
659  if ( headers_sent() ) {
660  LoggerFactory::getInstance( 'thumbnail' )->error(
661  'Error after output had been started. Output may be corrupt or truncated. ' .
662  'Original error: ' . ( $msgText ?: $msgHtml ) . " (Status $status)",
663  $context
664  );
665  return;
666  }
667 
668  header( 'Cache-Control: no-cache' );
669  header( 'Content-Type: text/html; charset=utf-8' );
670  if ( $status == 400 || $status == 404 || $status == 429 ) {
671  HttpStatus::header( $status );
672  } elseif ( $status == 403 ) {
673  HttpStatus::header( 403 );
674  header( 'Vary: Cookie' );
675  } else {
676  LoggerFactory::getInstance( 'thumbnail' )->error( $msgText ?: $msgHtml, $context );
677  HttpStatus::header( 500 );
678  }
679  if ( $wgShowHostnames ) {
680  header( 'X-MW-Thumbnail-Renderer: ' . wfHostname() );
681  $url = htmlspecialchars(
682  $_SERVER['REQUEST_URI'] ?? '',
683  ENT_NOQUOTES
684  );
685  $hostname = htmlspecialchars( wfHostname(), ENT_NOQUOTES );
686  $debug = "<!-- $url -->\n<!-- $hostname -->\n";
687  } else {
688  $debug = '';
689  }
690  $content = <<<EOT
691 <!DOCTYPE html>
692 <html><head>
693 <meta charset="UTF-8" />
694 <title>Error generating thumbnail</title>
695 </head>
696 <body>
697 <h1>Error generating thumbnail</h1>
698 <p>
699 $msgHtml
700 </p>
701 $debug
702 </body>
703 </html>
704 
705 EOT;
706  header( 'Content-Length: ' . strlen( $content ) );
707  echo $content;
708 }
const NS_FILE
Definition: Defines.php:70
const PROTO_CURRENT
Definition: Defines.php:197
wfThumbIsStandard(File $file, array $params)
Returns true if these thumbnail parameters match one that MediaWiki requests from file description pa...
wfHostname()
Get host name of the current machine, for use in error reporting.
wfExpandUrl( $url, $defaultProto=PROTO_CURRENT)
Expand a potentially local URL to a fully-qualified URL.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
$matches
global $wgRequest
Definition: Setup.php:366
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:68
const RENDER_NOW
Force rendering in the current process.
Definition: File.php:78
const DELETED_FILE
Definition: File.php:72
const THUMB_FULL_NAME
Definition: File.php:93
static header( $code)
Output an HTTP status code header.
Definition: HttpStatus.php:96
MediaWiki exception.
Definition: MWException.php:29
getHTML()
Format an HTML message for the current exception object.
static factory( $url, array $options=null, $caller=__METHOD__)
Generate a new request object.
MediaWiki exception thrown by some methods when the transform parameter array is invalid.
Base class for the output of MediaHandler::doTransform() and File::transform().
static warnIfHeadersSent()
Log a warning message if headers have already been sent.
PSR-3 logger instance factory.
MediaWikiServices is the service locator for the application scope of MediaWiki.
The MediaWiki class is the helper class for the index.php entry point.
Definition: MediaWiki.php:38
static getLocalClusterInstance()
Get the main cluster-local cache object.
Convenience class for dealing with PoolCounters using callbacks.
execute( $skipcache=false)
Get the result of the work (whatever it is), or the result of the error() function.
static getMain()
Get the RequestContext object associated with the main request.
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: Status.php:44
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:664
File without associated database record.
static getRequestPathSuffix( $basePath)
If the request URL matches a given base path, extract the path part of the request URL after that bas...
Definition: WebRequest.php:238
$wgShowHostnames
Config variable stub for the ShowHostnames setting, for use by phpdoc and IDEs.
$wgThumbPath
Config variable stub for the ThumbPath setting, for use by phpdoc and IDEs.
$wgVaryOnXFP
Config variable stub for the VaryOnXFP setting, for use by phpdoc and IDEs.
$wgAttemptFailureEpoch
Config variable stub for the AttemptFailureEpoch setting, for use by phpdoc and IDEs.
$wgTrivialMimeDetection
Config variable stub for the TrivialMimeDetection setting, for use by phpdoc and IDEs.
$mediawiki
Definition: img_auth.php:48
getKey()
Returns the message key.
$debug
Definition: mcc.php:31
$cache
Definition: mcc.php:33
$content
Definition: router.php:76
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
wfThumbHandle404()
Handle a thumbnail request via thumbnail file URL.
Definition: thumb.php:66
wfThumbError( $status, $msgHtml, $msgText=null, $context=[])
Output a thumbnail generation error message.
Definition: thumb.php:654
wfStreamThumb(array $params)
Stream a thumbnail specified by parameters.
Definition: thumb.php:105
wfGenerateThumbnail(File $file, array $params, $thumbName, $thumbPath)
Actually try to generate a new thumbnail.
Definition: thumb.php:455
wfProxyThumbnailRequest( $img, $thumbName)
Proxies thumbnail request to a service that handles thumbnailing.
Definition: thumb.php:413
wfExtractThumbRequestInfo( $thumbRel)
Convert pathinfo type parameter, into normal request parameters.
Definition: thumb.php:552
wfThumbMain()
Definition: thumb.php:43
wfThumbErrorText( $status, $msgText)
Output a thumbnail generation error message.
Definition: thumb.php:640
wfExtractThumbParams( $file, $params)
Convert a thumbnail name (122px-foo.png) to parameters, using file handler.
Definition: thumb.php:591