Add deprecation notices to recent s/var/public/ property changes.
[lhc/web/wiklou.git] / thumb.php
index 707f1e2..59bf8dc 100644 (file)
--- a/thumb.php
+++ b/thumb.php
@@ -163,12 +163,6 @@ function wfStreamThumb( array $params ) {
                return;
        }
 
-       // Check if the file is hidden
-       if ( $img->isDeleted( File::DELETED_FILE ) ) {
-               wfThumbError( 404, "The source file '$fileName' does not exist." );
-               return;
-       }
-
        // Check permissions if there are read restrictions
        $varyHeader = array();
        if ( !in_array( 'read', User::getGroupPermissions( array( '*' ) ), true ) ) {
@@ -181,6 +175,12 @@ function wfStreamThumb( array $params ) {
                $varyHeader[] = 'Cookie';
        }
 
+       // Check if the file is hidden
+       if ( $img->isDeleted( File::DELETED_FILE ) ) {
+               wfThumbError( 404, "The source file '$fileName' does not exist." );
+               return;
+       }
+
        // Do rendering parameters extraction from thumbnail name.
        if ( isset( $params['thumbName'] ) ) {
                $params = wfExtractThumbParams( $img, $params );
@@ -327,7 +327,7 @@ function wfStreamThumb( array $params ) {
        }
 
        // Actually generate a new thumbnail
-       list( $thumb, $errorMsg ) = wfGenerateThumbnail( $img, $params, $thumbName );
+       list( $thumb, $errorMsg ) = wfGenerateThumbnail( $img, $params, $thumbName, $thumbPath );
 
        // Check for thumbnail generation errors...
        $msg = wfMessage( 'thumbnail_error' );
@@ -356,9 +356,10 @@ function wfStreamThumb( array $params ) {
  * @param File $file
  * @param array $params
  * @param string $thumbName
+ * @param string $thumbPath
  * @return array (MediaTransformOutput|bool, string|bool error message HTML)
  */
-function wfGenerateThumbnail( File $file, array $params, $thumbName ) {
+function wfGenerateThumbnail( File $file, array $params, $thumbName, $thumbPath ) {
        global $wgMemc, $wgAttemptFailureEpoch;
 
        $key = wfMemcKey( 'attempt-failures', $wgAttemptFailureEpoch,
@@ -374,7 +375,8 @@ function wfGenerateThumbnail( File $file, array $params, $thumbName ) {
        register_shutdown_function( function() use ( &$done, $key ) {
                if ( !$done ) { // transform() gave a fatal
                        global $wgMemc;
-                       $wgMemc->incrWithInit( $key, 3600 );
+                       // Randomize TTL to reduce stampedes
+                       $wgMemc->incrWithInit( $key, 3600 + mt_rand( 0, 300 ) );
                }
        } );
 
@@ -388,8 +390,12 @@ function wfGenerateThumbnail( File $file, array $params, $thumbName ) {
                                'doWork' => function() use ( $file, $params ) {
                                        return $file->transform( $params, File::RENDER_NOW );
                                },
-                               'getCachedWork' => function() use ( $file, $params ) {
-                                       return $file->transform( $params );
+                               'getCachedWork' => function() use ( $file, $params, $thumbPath ) {
+                                       // If the worker that finished made this thumbnail then use it.
+                                       // Otherwise, it probably made a different thumbnail for this file.
+                                       return $file->getRepo()->fileExists( $thumbPath )
+                                               ? $file->transform( $params, File::RENDER_NOW )
+                                               : false; // retry once more in exclusive mode
                                },
                                'fallback' => function() {
                                        return wfMessage( 'generic-pool-error' )->parse();
@@ -412,7 +418,8 @@ function wfGenerateThumbnail( File $file, array $params, $thumbName ) {
        $done = true; // no PHP fatal occured
 
        if ( !$thumb || $thumb->isError() ) {
-               $wgMemc->incrWithInit( $key, 3600 );
+               // Randomize TTL to reduce stampedes
+               $wgMemc->incrWithInit( $key, 3600 + mt_rand( 0, 300 ) );
        }
 
        return array( $thumb, $errorHtml );
@@ -423,29 +430,58 @@ function wfGenerateThumbnail( File $file, array $params, $thumbName ) {
  * links to on file description pages and possibly parser output.
  *
  * $params is considered non-standard if they involve a non-standard
- * width or any parameter aside from width and page number. The number
- * of possible files with standard parameters is far less than that of all
- * possible combinations; rate-limiting for them can thus be more generious.
+ * width or any non-default parameters aside from width and page number.
+ * The number of possible files with standard parameters is far less than
+ * that of all combinations; rate-limiting for them can thus be more generious.
  *
- * @param File $img
+ * @param File $file
  * @param array $params
  * @return bool
  */
-function wfThumbIsStandard( File $img, array $params ) {
+function wfThumbIsStandard( File $file, array $params ) {
        global $wgThumbLimits, $wgImageLimits;
-       // @TODO: use polymorphism with media handler here
-       if ( array_diff( array_keys( $params ), array( 'width', 'page' ) ) ) {
-               return false; // extra parameters present
+
+       $handler = $file->getHandler();
+       if ( !$handler || !isset( $params['width'] ) ) {
+               return false;
        }
-       if ( isset( $params['width'] ) ) {
-               $widths = $wgThumbLimits;
+
+       $basicParams = array();
+       if ( isset( $params['page'] ) ) {
+               $basicParams['page'] = $params['page'];
+       }
+
+       // Check if the width matches one of $wgThumbLimits
+       if ( in_array( $params['width'], $wgThumbLimits ) ) {
+               $normalParams = $basicParams + array( 'width' => $params['width'] );
+               // Append any default values to the map (e.g. "lossy", "lossless", ...)
+               $handler->normaliseParams( $file, $normalParams );
+       } else {
+               // If not, then check if the width matchs one of $wgImageLimits
+               $match = false;
                foreach ( $wgImageLimits as $pair ) {
-                       $widths[] = $pair[0];
+                       $normalParams = $basicParams + array( 'width' => $pair[0], 'height' => $pair[1] );
+                       // Decide whether the thumbnail should be scaled on width or height.
+                       // Also append any default values to the map (e.g. "lossy", "lossless", ...)
+                       $handler->normaliseParams( $file, $normalParams );
+                       // Check if this standard thumbnail size maps to the given width
+                       if ( $normalParams['width'] == $params['width'] ) {
+                               $match = true;
+                               break;
+                       }
+               }
+               if ( !$match ) {
+                       return false; // not standard for description pages
                }
-               if ( !in_array( $params['width'], $widths ) ) {
+       }
+
+       // Check that the given values for non-page, non-width, params are just defaults
+       foreach ( $params as $key => $value ) {
+               if ( !isset( $normalParams[$key] ) || $normalParams[$key] != $value ) {
                        return false;
                }
        }
+
        return true;
 }