From: Aaron Schulz Date: Thu, 5 Jan 2012 01:58:05 +0000 (+0000) Subject: In SpecialUploadStash: X-Git-Tag: 1.31.0-rc.0~25519 X-Git-Url: http://git.cyclocoop.org/%22%2C%20generer_url_ecrire%28?a=commitdiff_plain;h=5fdac785a3e0b19d70b6f2ab31ae7960133a29c4;p=lhc%2Fweb%2Fwiklou.git In SpecialUploadStash: * Updated outputLocallyScaledThumb() and outputLocalFile() to handle changes in r106752. In MediaTransformOutput: * Added a storage path field to the transformation output object and set it in File::maybeDoTransform(). In File: * Fixed maybeDoTransform() handling if repo member is not set and made it fully respect $wgIgnoreImageErrors. In BitmapHandler: * Don't set bogus path if TRANSFORM_LATER in doTransform() for deffered renderings. --- diff --git a/includes/filerepo/file/File.php b/includes/filerepo/file/File.php index 21f2f984cf..5476366aaf 100644 --- a/includes/filerepo/file/File.php +++ b/includes/filerepo/file/File.php @@ -757,63 +757,89 @@ abstract class File { global $wgIgnoreImageErrors, $wgThumbnailEpoch; $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path - if ( $this->repo && $this->repo->canTransformVia404() && !( $flags & self::RENDER_NOW ) ) { - wfDebug( __METHOD__ . " transformation deferred." ); - // XXX: Pass in the storage path even though we are not rendering anything - // and the path is supposed to be an FS path. This is due to getScalerType() - // getting called on the path and clobbering $thumb->getUrl() if it's false. - return $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params ); - } - - wfDebug( __METHOD__.": Doing stat for $thumbPath\n" ); - $this->migrateThumbFile( $thumbName ); - if ( $this->repo->fileExists( $thumbPath ) && !( $flags & self::RENDER_FORCE ) ) { - $timestamp = $this->repo->getFileTimestamp( $thumbPath ); - if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) { + if ( $this->repo ) { + // Defer rendering if a 404 handler is set up... + if ( $this->repo->canTransformVia404() && !( $flags & self::RENDER_NOW ) ) { + wfDebug( __METHOD__ . " transformation deferred." ); // XXX: Pass in the storage path even though we are not rendering anything // and the path is supposed to be an FS path. This is due to getScalerType() // getting called on the path and clobbering $thumb->getUrl() if it's false. return $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params ); } - } elseif ( $flags & self::RENDER_FORCE ) { - wfDebug( __METHOD__ . " forcing rendering per flag File::RENDER_FORCE\n" ); + // Clean up broken thumbnails as needed + $this->migrateThumbFile( $thumbName ); + // Check if an up-to-date thumbnail already exists... + wfDebug( __METHOD__.": Doing stat for $thumbPath\n" ); + if ( $this->repo->fileExists( $thumbPath ) && !( $flags & self::RENDER_FORCE ) ) { + $timestamp = $this->repo->getFileTimestamp( $thumbPath ); + if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) { + // XXX: Pass in the storage path even though we are not rendering anything + // and the path is supposed to be an FS path. This is due to getScalerType() + // getting called on the path and clobbering $thumb->getUrl() if it's false. + $thumb = $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params ); + $thumb->setStoragePath( $thumbPath ); + return $thumb; + } + } elseif ( $flags & self::RENDER_FORCE ) { + wfDebug( __METHOD__ . " forcing rendering per flag File::RENDER_FORCE\n" ); + } } // Create a temp FS file with the same extension and the thumbnail $thumbExt = FileBackend::extensionFromPath( $thumbPath ); $tmpFile = TempFSFile::factory( 'transform_', $thumbExt ); if ( !$tmpFile ) { - return new MediaTransformError( 'thumbnail_error', - $params['width'], 0, wfMsg( 'thumbnail-temp-create' ) ); + return $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ); } $tmpThumbPath = $tmpFile->getPath(); // path of 0-byte temp file - // Actually render the thumbnail + // Actually render the thumbnail... $thumb = $this->handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $params ); $tmpFile->bind( $thumb ); // keep alive with $thumb - // Ignore errors if requested - if ( !$thumb ) { + if ( !$thumb ) { // bad params? $thumb = null; - } elseif ( $thumb->isError() ) { + } elseif ( $thumb->isError() ) { // transform error $this->lastError = $thumb->toText(); + // Ignore errors if requested if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) { $thumb = $this->handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $params ); } } elseif ( $thumb->hasFile() && !$thumb->fileIsSource() ) { - // Copy any thumbnail from the FS into storage at $dstpath + // Copy the thumbnail from the file system into storage $status = $this->repo->store( $tmpThumbPath, 'thumb', $this->getThumbRel( $thumbName ), FileRepo::OVERWRITE | FileRepo::SKIP_LOCKING | FileRepo::ALLOW_STALE ); - if ( !$status->isOK() ) { - return new MediaTransformError( 'thumbnail_error', - $params['width'], 0, wfMsg( 'thumbnail-dest-create' ) ); + if ( $status->isOK() ) { + $thumb->setStoragePath( $thumbPath ); + } else { + $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ); } } return $thumb; } + /** + * Return either a MediaTransformError or placeholder thumbnail (if $wgIgnoreImageErrors) + * + * @param $thumbPath string Thumbnail storage path + * @param $thumbUrl string Thumbnail URL + * @param $params Array + * @param $flags integer + * @return MediaTransformOutput + */ + protected function transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ) { + global $wgIgnoreImageErrors; + + if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) { + return $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params ); + } else { + return new MediaTransformError( 'thumbnail_error', + $params['width'], 0, wfMsg( 'thumbnail-dest-create' ) ); + } + } + /** * Transform a media file * diff --git a/includes/media/Bitmap.php b/includes/media/Bitmap.php index 878ad58fb9..164f8643cc 100644 --- a/includes/media/Bitmap.php +++ b/includes/media/Bitmap.php @@ -154,7 +154,7 @@ class BitmapHandler extends ImageHandler { if ( $flags & self::TRANSFORM_LATER ) { wfDebug( __METHOD__ . ": Transforming later per flags.\n" ); return new ThumbnailImage( $image, $dstUrl, $scalerParams['clientWidth'], - $scalerParams['clientHeight'], $dstPath ); + $scalerParams['clientHeight'], false ); } # Try to make a target path for the thumbnail diff --git a/includes/media/MediaTransformOutput.php b/includes/media/MediaTransformOutput.php index f7c527086d..de6b1c0525 100644 --- a/includes/media/MediaTransformOutput.php +++ b/includes/media/MediaTransformOutput.php @@ -18,6 +18,7 @@ abstract class MediaTransformOutput { var $file; var $width, $height, $url, $page, $path; + protected $storagePath = false; /** * Get the width of the output box @@ -40,6 +41,21 @@ abstract class MediaTransformOutput { return $this->url; } + /** + * @return string|false The permanent thumbnail storage path + */ + public function getStoragePath() { + return $this->storagePath; + } + + /** + * @param $storagePath string The permanent storage path + * @return void + */ + public function setStoragePath( $storagePath ) { + $this->storagePath = $storagePath; + } + /** * Fetch HTML for this transform output * diff --git a/includes/specials/SpecialUploadStash.php b/includes/specials/SpecialUploadStash.php index 5d353f1c3f..121b6a44a5 100644 --- a/includes/specials/SpecialUploadStash.php +++ b/includes/specials/SpecialUploadStash.php @@ -166,14 +166,15 @@ class SpecialUploadStash extends UnlistedSpecialPage { } // we should have just generated it locally - if ( ! $thumbnailImage->getPath() ) { + if ( !$thumbnailImage->getStoragePath() ) { throw new UploadStashFileNotFoundException( "no local path for scaled item" ); } // now we should construct a File, so we can get mime and other such info in a standard way // n.b. mimetype may be different from original (ogx original -> jpeg thumb) - $thumbFile = new UnregisteredLocalFile( false, $this->stash->repo, $thumbnailImage->getPath(), false ); - if ( ! $thumbFile ) { + $thumbFile = new UnregisteredLocalFile( false, + $this->stash->repo, $thumbnailImage->getStoragePath(), false ); + if ( !$thumbFile ) { throw new UploadStashFileNotFoundException( "couldn't create local file object for thumbnail" ); } @@ -238,18 +239,17 @@ class SpecialUploadStash extends UnlistedSpecialPage { /** * Output HTTP response for file * Side effect: writes HTTP response to STDOUT. - * XXX could use wfStreamfile (in includes/Streamfile.php), but for consistency with outputContents() doing it this way. - * XXX is mimeType really enough, or do we need encoding for full Content-Type header? * * @param $file File object with a local path (e.g. UnregisteredLocalFile, LocalFile. Oddly these don't share an ancestor!) */ - private function outputLocalFile( $file ) { + private function outputLocalFile( File $file ) { if ( $file->getSize() > self::MAX_SERVE_BYTES ) { throw new SpecialUploadStashTooLargeException(); } - self::outputFileHeaders( $file->getMimeType(), $file->getSize() ); - readfile( $file->getPath() ); - return true; + return $file->getRepo()->streamFile( $file->getPath(), + array( 'Content-Transfer-Encoding: binary', + 'Expires: Sun, 17-Jan-2038 19:14:07 GMT' ) + ); } /**