From 7b2ac5419dffd85b183b9d6adebb30f7a1075014 Mon Sep 17 00:00:00 2001 From: reliq Date: Mon, 8 Jul 2024 02:13:26 +0200 Subject: [PATCH] fix: read error in ImageDispenser --- src/Service/ImageDispenser.php | 33 ++++++++++----------- tests/Unit/Service/ImageDispenserTest.php | 36 +++++++++++------------ 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/Service/ImageDispenser.php b/src/Service/ImageDispenser.php index c1b2ccc..0fdac05 100644 --- a/src/Service/ImageDispenser.php +++ b/src/Service/ImageDispenser.php @@ -7,7 +7,6 @@ use Illuminate\Contracts\Filesystem\Factory as FilesystemManager; use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Contracts\Filesystem\Filesystem; -use Illuminate\Http\Request; use Illuminate\Http\Response; use Intervention\Image\Encoders\AutoEncoder; use Intervention\Image\Interfaces\ImageInterface; @@ -19,6 +18,7 @@ use ReliqArts\GuidedImage\Contract\ImageDispenser as ImageDispenserContract; use ReliqArts\GuidedImage\Contract\ImageManager; use ReliqArts\GuidedImage\Demand\Dummy; +use ReliqArts\GuidedImage\Demand\ExistingImage; use ReliqArts\GuidedImage\Demand\Resize; use ReliqArts\GuidedImage\Demand\Thumbnail; use RuntimeException; @@ -108,7 +108,7 @@ public function getResizedImage(Resize $demand) if ($this->cacheDisk->exists($cacheFilePath)) { $image = $this->makeImageWithEncoding($this->cacheDisk->path($cacheFilePath)); } else { - $image = $this->makeImageWithEncoding($this->getImageFullUrl($guidedImage)); + $image = $this->makeImageWithEncoding($this->getImageFullPath($guidedImage)); $sizingMethod = $demand->allowUpSizing() ? 'resize' : 'resizeDown'; if ($demand->maintainAspectRatio()) { $sizingMethod = $demand->allowUpSizing() ? 'scale' : 'scaleDown'; @@ -125,7 +125,7 @@ public function getResizedImage(Resize $demand) return new Response( $this->cacheDisk->get($cacheFilePath), self::RESPONSE_HTTP_OK, - $this->getImageHeaders($cacheFilePath, $demand->getRequest(), $image) ?: [] + $this->getImageHeaders($cacheFilePath, $demand, $image) ?: [] ); } catch (RuntimeException $exception) { return $this->handleRuntimeException($exception, $guidedImage); @@ -187,7 +187,7 @@ public function getImageThumbnail(Thumbnail $demand) } else { /** @var ImageInterface $image */ $image = $this->imageManager - ->read($this->getImageFullUrl($guidedImage)) + ->read($this->getImageFullPath($guidedImage)) ->{$method}( $width, $height @@ -203,7 +203,7 @@ public function getImageThumbnail(Thumbnail $demand) return new Response( $this->cacheDisk->get($cacheFilePath), self::RESPONSE_HTTP_OK, - $this->getImageHeaders($cacheFilePath, $demand->getRequest(), $image) ?: [] + $this->getImageHeaders($cacheFilePath, $demand, $image) ?: [] ); } catch (RuntimeException $exception) { return $this->handleRuntimeException($exception, $guidedImage); @@ -235,13 +235,15 @@ public function emptyCache(): bool * * @return array image headers */ - private function getImageHeaders(string $cacheFilePath, Request $request, ImageInterface $image): array + private function getImageHeaders(string $relativeCacheFilePath, ExistingImage $demand, ImageInterface $image): array { - $filePath = $image->origin()->filePath(); - $lastModified = $this->cacheDisk->lastModified($cacheFilePath); + $request = $demand->getRequest(); + $fullCacheFilePath = $this->cacheDisk->path($relativeCacheFilePath); + $lastModified = $this->cacheDisk->lastModified($relativeCacheFilePath); $modifiedSince = $request->header('If-Modified-Since', ''); $etagHeader = trim($request->header('If-None-Match', '')); - $etagFile = $this->fileHelper->hashFile($filePath); + $etagFile = $this->fileHelper->hashFile($fullCacheFilePath); + $originalImageRelativePath = $demand->getGuidedImage()->getUrl(true); // check if image hasn't changed if ($etagFile === $etagHeader || strtotime($modifiedSince) === $lastModified) { @@ -256,7 +258,7 @@ private function getImageHeaders(string $cacheFilePath, Request $request, ImageI $this->getDefaultHeaders(), [ 'Content-Type' => $image->origin()->mediaType(), - 'Content-Disposition' => sprintf('inline; filename=%s', basename($image->origin()->filePath())), + 'Content-Disposition' => sprintf('inline; filename=%s', basename($originalImageRelativePath)), 'Last-Modified' => date(DATE_RFC822, $lastModified), 'Etag' => $etagFile, ] @@ -307,12 +309,9 @@ private function makeImageWithEncoding(mixed $data): ImageInterface return $this->imageManager->read($encodedImage->toFilePointer()); } - /** - * @throws RuntimeException - */ - private function getImageFullUrl(GuidedImage $guidedImage): string + private function getImageFullPath(GuidedImage $guidedImage): string { - return $this->uploadDisk->url($guidedImage->getUrl(true)); + return $this->uploadDisk->path($guidedImage->getUrl(true)); } /** @@ -322,8 +321,8 @@ private function handleRuntimeException( RuntimeException $exception, GuidedImage $guidedImage ): BinaryFileResponse { - $errorMessage = 'Intervention image creation failed with NotReadableException;'; - $context = ['imageUrl' => $this->getImageFullUrl($guidedImage)]; + $errorMessage = 'Intervention image creation failed with RuntimeException;'; + $context = ['imageUrl' => $this->getImageFullPath($guidedImage)]; if (! $this->configProvider->isRawImageFallbackEnabled()) { $this->logger->error( diff --git a/tests/Unit/Service/ImageDispenserTest.php b/tests/Unit/Service/ImageDispenserTest.php index 112fae1..29f9f50 100644 --- a/tests/Unit/Service/ImageDispenserTest.php +++ b/tests/Unit/Service/ImageDispenserTest.php @@ -64,7 +64,7 @@ final class ImageDispenserTest extends TestCase private const IMAGE_NAME = 'my-image'; - private const IMAGE_URL = '//image_url'; + private const IMAGE_PATH = './image_path'; private const IMAGE_WIDTH = 100; @@ -186,8 +186,8 @@ protected function setUp(): void ->willReturn(self::LAST_MODIFIED); $uploadDisk - ->url(self::IMAGE_URL) - ->willReturn(self::IMAGE_URL); + ->path(self::IMAGE_PATH) + ->willReturn(self::IMAGE_PATH); $fileHelper ->hashFile(Argument::type('string')) @@ -202,7 +202,7 @@ protected function setUp(): void ->willReturn(self::IMAGE_NAME); $this->guidedImage ->getUrl(true) - ->willReturn(self::IMAGE_URL); + ->willReturn(self::IMAGE_PATH); $this->subject = new ImageDispenser( $configProvider->reveal(), @@ -278,7 +278,7 @@ public function testGetResizedImage(): void ->willReturn(false); $this->cacheDisk ->path($cacheFile) - ->shouldBeCalledTimes(1) + ->shouldBeCalledTimes(2) ->willReturn($cacheFile); $this->cacheDisk ->get($cacheFile) @@ -289,7 +289,7 @@ public function testGetResizedImage(): void ->read($cacheFile) ->shouldNotBeCalled(); $this->imageManager - ->read(Argument::in([self::IMAGE_URL, self::FOO_RESOURCE])) + ->read(Argument::in([self::IMAGE_PATH, self::FOO_RESOURCE])) ->shouldBeCalledTimes(2) ->willReturn($image); @@ -333,7 +333,7 @@ public function testGetResizedImageWhenImageInstanceIsExpected(): void ->read($cacheFile) ->shouldNotBeCalled(); $this->imageManager - ->read(Argument::in([self::IMAGE_URL, self::FOO_RESOURCE])) + ->read(Argument::in([self::IMAGE_PATH, self::FOO_RESOURCE])) ->shouldBeCalledTimes(2) ->willReturn($image); @@ -358,7 +358,7 @@ public function testGetResizedImageWhenCacheFileExists(): void ->willReturn(true); $this->cacheDisk ->path($cacheFile) - ->shouldBeCalledTimes(1) + ->shouldBeCalledTimes(2) ->willReturn($cacheFile); $this->cacheDisk ->get($cacheFile) @@ -370,7 +370,7 @@ public function testGetResizedImageWhenCacheFileExists(): void ->shouldBeCalledTimes(2) ->willReturn($image); $this->imageManager - ->read(self::IMAGE_URL) + ->read(self::IMAGE_PATH) ->shouldNotBeCalled(); $result = $this->subject->getResizedImage( @@ -420,14 +420,14 @@ public function testGetResizedWhenImageRetrievalFails(): void ->read($cacheFile) ->shouldNotBeCalled(); $this->imageManager - ->read(Argument::in([self::IMAGE_URL, self::FOO_RESOURCE])) + ->read(Argument::in([self::IMAGE_PATH, self::FOO_RESOURCE])) ->shouldBeCalledTimes(2) ->willReturn($image); $this->guidedImage ->getUrl() ->shouldBeCalledTimes(1) - ->willReturn(self::IMAGE_URL); + ->willReturn(self::IMAGE_PATH); $this->logger ->error( @@ -476,14 +476,14 @@ public function testGetImageThumbnail(): void ->willReturn($imageContent); $this->cacheDisk ->path($cacheFile) - ->shouldBeCalledTimes(1) + ->shouldBeCalledTimes(2) ->willReturn($cacheFile); $this->imageManager ->read($cacheFile) ->shouldNotBeCalled(); $this->imageManager - ->read(self::IMAGE_URL) + ->read(self::IMAGE_PATH) ->shouldBeCalledTimes(1) ->willReturn($image); @@ -527,7 +527,7 @@ public function testGetImageThumbnailWhenImageInstanceIsExpected(): void ->read($cacheFile) ->shouldNotBeCalled(); $this->imageManager - ->read(Argument::in([self::IMAGE_URL, self::FOO_RESOURCE])) + ->read(Argument::in([self::IMAGE_PATH, self::FOO_RESOURCE])) ->shouldBeCalledTimes(1) ->willReturn($image); @@ -569,7 +569,7 @@ public function testGetImageThumbnailWhenCacheFileExists(): void ->willReturn(true); $this->cacheDisk ->path($cacheFile) - ->shouldBeCalledTimes(1) + ->shouldBeCalledTimes(2) ->willReturn($cacheFile); $this->cacheDisk ->get($cacheFile) @@ -581,7 +581,7 @@ public function testGetImageThumbnailWhenCacheFileExists(): void ->shouldBeCalledTimes(2) ->willReturn($image); $this->imageManager - ->read(self::IMAGE_URL) + ->read(self::IMAGE_PATH) ->shouldNotBeCalled(); $result = $this->subject->getImageThumbnail( @@ -636,7 +636,7 @@ public function testGetImageThumbnailWhenDemandIsInvalid(): void ->read($cacheFile) ->shouldNotBeCalled(); $this->imageManager - ->read(self::IMAGE_URL) + ->read(self::IMAGE_PATH) ->shouldNotBeCalled(); $this->logger @@ -691,7 +691,7 @@ public function testGetImageThumbnailWhenImageRetrievalFails(): void ->read($cacheFile) ->shouldNotBeCalled(); $this->imageManager - ->read(self::IMAGE_URL) + ->read(self::IMAGE_PATH) ->shouldBeCalledTimes(1) ->willThrow(RuntimeException::class);