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