From 9450dea107e9774d465efb9cf8073f4895e5a166 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Wed, 6 Mar 2024 18:24:58 +0200 Subject: [PATCH 01/21] OEVE-211 Create thumbnails of same type as original image is Signed-off-by: Anton Fedurtsya --- src/Image/Service/ThumbnailResource.php | 9 +++++++-- .../Image/Service/ThumbnailResourceTest.php | 19 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/Image/Service/ThumbnailResource.php b/src/Image/Service/ThumbnailResource.php index 945c407..e6c5e55 100644 --- a/src/Image/Service/ThumbnailResource.php +++ b/src/Image/Service/ThumbnailResource.php @@ -33,15 +33,20 @@ public function getThumbnailFileName( bool $crop ): string { return sprintf( - '%s_thumb_%d*%d%s%s', + '%s_thumb_%d*%d%s.%s', $this->getThumbnailFileHash($originalFileName), $thumbnailSize->getWidth(), $thumbnailSize->getHeight(), $crop ? '' : '_nocrop', - '.jpg' + $this->getExtensionFromFileName($originalFileName) ); } + protected function getExtensionFromFileName(string $fileName): string + { + return pathinfo($fileName, PATHINFO_EXTENSION); + } + public function getDefaultThumbnailSize(): ImageSizeInterface { return new ImageSize(width: self::THUMBNAIL_DEFAULT_SIZE, height: self::THUMBNAIL_DEFAULT_SIZE); diff --git a/tests/Unit/Image/Service/ThumbnailResourceTest.php b/tests/Unit/Image/Service/ThumbnailResourceTest.php index 546d48b..76f085e 100644 --- a/tests/Unit/Image/Service/ThumbnailResourceTest.php +++ b/tests/Unit/Image/Service/ThumbnailResourceTest.php @@ -20,35 +20,44 @@ class ThumbnailResourceTest extends TestCase { public static function getThumbnailFileNameDataProvider(): \Generator { - $fileName = 'filename.gif'; + $fileName = 'filename.jpg'; $fileNameHash = md5($fileName); - yield "regular 100x100 nocrop" => [ + yield "regular jpg 100x100 nocrop" => [ 'originalFileName' => $fileName, 'thumbnailSize' => new ImageSize(100, 100), 'crop' => true, 'expectedName' => $fileNameHash . '_thumb_100*100.jpg' ]; - yield "regular 100x100 crop" => [ + yield "regular jpg 100x100 crop" => [ 'originalFileName' => $fileName, 'thumbnailSize' => new ImageSize(100, 100), 'crop' => false, 'expectedName' => $fileNameHash . '_thumb_100*100_nocrop.jpg' ]; - yield "regular 200x50 nocrop" => [ + yield "regular jpg 200x50 nocrop" => [ 'originalFileName' => $fileName, 'thumbnailSize' => new ImageSize(200, 50), 'crop' => true, 'expectedName' => $fileNameHash . '_thumb_200*50.jpg' ]; - yield "regular 200x50 crop" => [ + yield "regular jpg 200x50 crop" => [ 'originalFileName' => $fileName, 'thumbnailSize' => new ImageSize(200, 50), 'crop' => false, 'expectedName' => $fileNameHash . '_thumb_200*50_nocrop.jpg' ]; + + $specialExtensionFileName = 'filename.xxx'; + $specialExtensionFileNameHash = md5($specialExtensionFileName); + yield "extension save check" => [ + 'originalFileName' => $specialExtensionFileName, + 'thumbnailSize' => new ImageSize(100, 100), + 'crop' => true, + 'expectedName' => $specialExtensionFileNameHash . '_thumb_100*100.xxx' + ]; } protected function getSut( From b09ebfc8fceacb751efe265b096d9deaa29ae1f0 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Wed, 6 Mar 2024 18:51:08 +0200 Subject: [PATCH 02/21] OEVE-211 Add copy method to FileSystem service Signed-off-by: Anton Fedurtsya --- src/Service/FileSystemService.php | 6 ++++ src/Service/FileSystemServiceInterface.php | 2 ++ tests/Unit/Service/FileSystemServiceTest.php | 32 ++++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/src/Service/FileSystemService.php b/src/Service/FileSystemService.php index b56b690..d4b4440 100644 --- a/src/Service/FileSystemService.php +++ b/src/Service/FileSystemService.php @@ -79,4 +79,10 @@ public function getMimeType(string $filePath): string { return is_file($filePath) ? (string)mime_content_type($filePath) : ''; } + + public function copy(string $originalFile, string $destinationFile): void + { + $fileSystem = new Filesystem(); + $fileSystem->copy($originalFile, $destinationFile); + } } diff --git a/src/Service/FileSystemServiceInterface.php b/src/Service/FileSystemServiceInterface.php index fe464d2..694c034 100644 --- a/src/Service/FileSystemServiceInterface.php +++ b/src/Service/FileSystemServiceInterface.php @@ -31,4 +31,6 @@ public function moveUploadedFile(string $from, string $to): void; public function getFileSize(string $filePath): int; public function getMimeType(string $filePath): string; + + public function copy(string $originalFile, string $destinationFile): void; } diff --git a/tests/Unit/Service/FileSystemServiceTest.php b/tests/Unit/Service/FileSystemServiceTest.php index 443ec33..f137bf7 100644 --- a/tests/Unit/Service/FileSystemServiceTest.php +++ b/tests/Unit/Service/FileSystemServiceTest.php @@ -200,6 +200,38 @@ public function testMoveFileToNotExistingDirectory(): void $this->assertTrue($root->hasChild('someFolder/movedFile1.txt')); } + public function testCopyFileWithCopy(): void + { + $root = vfsStream::setup('root', 0777, [ + 'file1.txt' => 'content1', + 'file2.txt' => 'content2', + 'someFolder' => [ + ] + ]); + + $sut = $this->getSut(); + + $sut->copy($root->url() . '/' . 'file1.txt', $root->url() . '/someFolder/' . 'copiedFile1.txt'); + + $this->assertTrue($root->hasChild('file1.txt')); + $this->assertTrue($root->hasChild('file2.txt')); + $this->assertTrue($root->hasChild('someFolder/copiedFile1.txt')); + } + + public function testCopyToNotExistingFolderCreatesFolder(): void + { + $root = vfsStream::setup('root', 0777, [ + 'file1.txt' => 'content1', + ]); + + $sut = $this->getSut(); + + $sut->copy($root->url() . '/' . 'file1.txt', $root->url() . '/someNewFolder/' . 'copiedFile1.txt'); + + $this->assertTrue($root->hasChild('file1.txt')); + $this->assertTrue($root->hasChild('someNewFolder/copiedFile1.txt')); + } + public function testGetFileSize(): void { $root = vfsStream::setup('root', 0777, [ From d069b861205c2cc1727b529dd0715150096dca90 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Thu, 7 Mar 2024 16:23:10 +0200 Subject: [PATCH 03/21] Do not import unnecessary demodata Signed-off-by: Anton Fedurtsya --- tests/Integration/IntegrationTestCase.php | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/tests/Integration/IntegrationTestCase.php b/tests/Integration/IntegrationTestCase.php index 7de94e1..3a4f7ab 100644 --- a/tests/Integration/IntegrationTestCase.php +++ b/tests/Integration/IntegrationTestCase.php @@ -7,28 +7,6 @@ namespace OxidEsales\MediaLibrary\Tests\Integration; -use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory; -use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface; -use OxidEsales\Facts\Facts; - class IntegrationTestCase extends \OxidEsales\EshopCommunity\Tests\Integration\IntegrationTestCase { - public function setUp(): void - { - $facts = new Facts(); - $container = ContainerFactory::getInstance()->getContainer(); - $connection = $container->get(QueryBuilderFactoryInterface::class) - ->create() - ->getConnection(); - - $testdata = file_get_contents( - __DIR__ . '/../fixtures/testdata_' - . strtolower($facts->getEdition()) . '.sql' - ); - if (trim($testdata)) { - $connection->executeStatement( - $testdata - ); - } - } } From 9fae7a5ddca9f1b63cfd818d2bf33491880aec23 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Thu, 7 Mar 2024 16:58:54 +0200 Subject: [PATCH 04/21] OEVE-211 Implement thumbnail generator aggregator Signed-off-by: Anton Fedurtsya --- src/Image/Exception/AggregatorInputType.php | 14 +++++ .../Service/ThumbnailGeneratorAggregate.php | 49 +++++++++++++++ .../ThumbnailGeneratorAggregateInterface.php | 22 +++++++ .../Service/ThumbnailGeneratorInterface.php | 2 + .../ThumbnailGeneratorIntervention.php | 5 ++ src/Image/Service/ThumbnailService.php | 8 +-- src/Image/Service/services.yaml | 10 ++- .../ThumbnailGeneratorAggregateTest.php | 22 +++++++ .../Unit/Image/Service/ImageResourceTest.php | 2 +- .../ThumbnailGeneratorAggregateTest.php | 63 +++++++++++++++++++ .../Image/Service/ThumbnailResourceTest.php | 2 +- .../Image/Service/ThumbnailServiceTest.php | 12 ++-- 12 files changed, 197 insertions(+), 14 deletions(-) create mode 100644 src/Image/Exception/AggregatorInputType.php create mode 100644 src/Image/Service/ThumbnailGeneratorAggregate.php create mode 100644 src/Image/Service/ThumbnailGeneratorAggregateInterface.php create mode 100644 tests/Integration/Image/Service/ThumbnailGeneratorAggregateTest.php create mode 100644 tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php diff --git a/src/Image/Exception/AggregatorInputType.php b/src/Image/Exception/AggregatorInputType.php new file mode 100644 index 0000000..a1d5717 --- /dev/null +++ b/src/Image/Exception/AggregatorInputType.php @@ -0,0 +1,14 @@ + $thumbnailGenerators + * @throws AggregatorInputType + */ + public function __construct( + protected iterable $thumbnailGenerators + ) { + foreach ($this->thumbnailGenerators as $oneGenerator) { + if (!$oneGenerator instanceof ThumbnailGeneratorInterface) { + throw new AggregatorInputType(); + } + } + } + + public function generateThumbnail( + string $sourcePath, + string $thumbnailPath, + ImageSizeInterface $thumbnailSize, + bool $isCropRequired, + ): void { + foreach($this->thumbnailGenerators as $oneGenerator) { + if ($oneGenerator->isOriginSupported($sourcePath)) { + $oneGenerator->generateThumbnail( + sourcePath: $sourcePath, + thumbnailPath: $thumbnailPath, + size: $thumbnailSize, + blCrop: $isCropRequired + ); + break; + } + } + } +} \ No newline at end of file diff --git a/src/Image/Service/ThumbnailGeneratorAggregateInterface.php b/src/Image/Service/ThumbnailGeneratorAggregateInterface.php new file mode 100644 index 0000000..c72ff4e --- /dev/null +++ b/src/Image/Service/ThumbnailGeneratorAggregateInterface.php @@ -0,0 +1,22 @@ +fileSystemService->ensureDirectory($thumbnailDirectoryPath); - $this->thumbnailGenerator->generateThumbnail( + $this->thumbnailGeneratorAggregate->generateThumbnail( sourcePath: Path::join($this->mediaResource->getPathToMediaFiles($folderName), $fileName), thumbnailPath: $thumbnailPath, - size: $imageSize ?? $this->thumbnailResource->getDefaultThumbnailSize(), - blCrop: $crop + thumbnailSize: $imageSize ?? $this->thumbnailResource->getDefaultThumbnailSize(), + isCropRequired: $crop ); } diff --git a/src/Image/Service/services.yaml b/src/Image/Service/services.yaml index 7a000be..1b9c3d4 100644 --- a/src/Image/Service/services.yaml +++ b/src/Image/Service/services.yaml @@ -8,9 +8,15 @@ services: arguments: $driver: 'Intervention\Image\Drivers\Gd\Driver' - OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorInterface: - class: OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention + OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorAggregateInterface: + class: OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorAggregate public: true + arguments: + $thumbnailGenerators: + - '@OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention' + + OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention: + class: OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention OxidEsales\MediaLibrary\Image\Service\ThumbnailResourceInterface: class: OxidEsales\MediaLibrary\Image\Service\ThumbnailResource diff --git a/tests/Integration/Image/Service/ThumbnailGeneratorAggregateTest.php b/tests/Integration/Image/Service/ThumbnailGeneratorAggregateTest.php new file mode 100644 index 0000000..9b91359 --- /dev/null +++ b/tests/Integration/Image/Service/ThumbnailGeneratorAggregateTest.php @@ -0,0 +1,22 @@ +get(ThumbnailGeneratorAggregateInterface::class); + $this->assertInstanceOf(ThumbnailGeneratorAggregateInterface::class, $sut); + } +} diff --git a/tests/Unit/Image/Service/ImageResourceTest.php b/tests/Unit/Image/Service/ImageResourceTest.php index f0866a8..6d290eb 100644 --- a/tests/Unit/Image/Service/ImageResourceTest.php +++ b/tests/Unit/Image/Service/ImageResourceTest.php @@ -5,7 +5,7 @@ * See LICENSE file for license details. */ -namespace Image\Service; +namespace OxidEsales\MediaLibrary\Tests\Unit\Image\Service; use OxidEsales\Eshop\Core\Config; use OxidEsales\MediaLibrary\Media\DataType\Media; diff --git a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php new file mode 100644 index 0000000..6d51817 --- /dev/null +++ b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php @@ -0,0 +1,63 @@ +expectException(AggregatorInputType::class); + new ThumbnailGeneratorAggregate([new \stdClass()]); + } + + public function testConstructorWorks(): void + { + $filePath = uniqid(); + $thumbnailPath = uniqid(); + $thumbnailSize = $this->createStub(ImageSize::class); + $isCropRequired = (bool)random_int(0, 1); + + $generatorSpyWrong = $this->createMock(ThumbnailGeneratorInterface::class); + $generatorSpyWrong->method('isOriginSupported')->with($filePath)->willReturn(false); + $generatorSpyWrong->expects($this->never())->method('generateThumbnail'); + + $generatorSpyExpected = $this->createMock(ThumbnailGeneratorInterface::class); + $generatorSpyExpected->method('isOriginSupported')->with($filePath)->willReturn(true); + $generatorSpyExpected->expects($this->once()) + ->method('generateThumbnail') + ->with($filePath, $thumbnailPath, $thumbnailSize, $isCropRequired); + + $generatorSpyAfterExpectedNotCalled = $this->createMock(ThumbnailGeneratorInterface::class); + $generatorSpyAfterExpectedNotCalled->method('isOriginSupported')->with($filePath)->willReturn(true); + $generatorSpyAfterExpectedNotCalled->expects($this->never())->method('generateThumbnail'); + + $sut = new ThumbnailGeneratorAggregate([ + $generatorSpyWrong, + $generatorSpyExpected, + $generatorSpyAfterExpectedNotCalled + ]); + + $sut->generateThumbnail( + sourcePath: $filePath, + thumbnailPath: $thumbnailPath, + thumbnailSize: $thumbnailSize, + isCropRequired: $isCropRequired + ); + } +} \ No newline at end of file diff --git a/tests/Unit/Image/Service/ThumbnailResourceTest.php b/tests/Unit/Image/Service/ThumbnailResourceTest.php index 76f085e..f6f279e 100644 --- a/tests/Unit/Image/Service/ThumbnailResourceTest.php +++ b/tests/Unit/Image/Service/ThumbnailResourceTest.php @@ -5,7 +5,7 @@ * See LICENSE file for license details. */ -namespace Image\Service; +namespace OxidEsales\MediaLibrary\Tests\Unit\Image\Service; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; diff --git a/tests/Unit/Image/Service/ThumbnailServiceTest.php b/tests/Unit/Image/Service/ThumbnailServiceTest.php index 2e39d2e..050f9a7 100644 --- a/tests/Unit/Image/Service/ThumbnailServiceTest.php +++ b/tests/Unit/Image/Service/ThumbnailServiceTest.php @@ -5,11 +5,11 @@ * See LICENSE file for license details. */ -namespace Image\Service; +namespace OxidEsales\MediaLibrary\Tests\Unit\Image\Service; use org\bovigo\vfs\vfsStream; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; -use OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorInterface; +use OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorAggregateInterface; use OxidEsales\MediaLibrary\Image\Service\ThumbnailResourceInterface; use OxidEsales\MediaLibrary\Image\Service\ThumbnailService; use OxidEsales\MediaLibrary\Media\DataType\MediaInterface; @@ -52,7 +52,7 @@ public function testGetThumbnailUrlTriggerDefaultThumbnailCreation(): void $sut = $this->getSut( thumbnailResource: $thumbnailResourceMock = $this->createMock(ThumbnailResourceInterface::class), fileSystemService: $fileSystemSpy = $this->createMock(FileSystemServiceInterface::class), - thumbnailGenerator: $thumbnailGeneratorSpy = $this->createMock(ThumbnailGeneratorInterface::class), + thumbnailGeneratorAggregate: $thumbnailGeneratorAggregateSpy = $this->createMock(ThumbnailGeneratorAggregateInterface::class), imageResource: $imageResourceMock = $this->createMock(MediaResourceInterface::class), ); @@ -74,7 +74,7 @@ public function testGetThumbnailUrlTriggerDefaultThumbnailCreation(): void $imageResourceMock->method('getPathToMediaFiles')->with($folderName)->willReturn($originalFolder); $fileSystemSpy->expects($this->once())->method('ensureDirectory')->with($thumbnailFolder); - $thumbnailGeneratorSpy->expects($this->once())->method('generateThumbnail') + $thumbnailGeneratorAggregateSpy->expects($this->once())->method('generateThumbnail') ->with( $originalFolder . '/' . $fileName, $thumbnailFolder . '/' . $thumbnailFileName, @@ -89,13 +89,13 @@ public function testGetThumbnailUrlTriggerDefaultThumbnailCreation(): void public function getSut( ThumbnailResourceInterface $thumbnailResource = null, FileSystemServiceInterface $fileSystemService = null, - ThumbnailGeneratorInterface $thumbnailGenerator = null, + ThumbnailGeneratorAggregateInterface $thumbnailGeneratorAggregate = null, MediaResourceInterface $imageResource = null, ): ThumbnailService { return new ThumbnailService( thumbnailResource: $thumbnailResource ?? $this->createStub(ThumbnailResourceInterface::class), fileSystemService: $fileSystemService ?? $this->createStub(FileSystemServiceInterface::class), - thumbnailGenerator: $thumbnailGenerator ?? $this->createStub(ThumbnailGeneratorInterface::class), + thumbnailGeneratorAggregate: $thumbnailGeneratorAggregate ?? $this->createStub(ThumbnailGeneratorAggregateInterface::class), mediaResource: $imageResource ?? $this->createStub(MediaResourceInterface::class), ); } From 7fc3e7bb1ca91789cbcb108a386535dae5703432 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Thu, 7 Mar 2024 17:15:41 +0200 Subject: [PATCH 05/21] OEVE-211 Improve Intervention thumbnail generator test Signed-off-by: Anton Fedurtsya --- .../ThumbnailGeneratorInterventionTest.php | 102 +++++++++--------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/tests/Integration/Image/Service/ThumbnailGeneratorInterventionTest.php b/tests/Integration/Image/Service/ThumbnailGeneratorInterventionTest.php index 405ab04..bd69b55 100644 --- a/tests/Integration/Image/Service/ThumbnailGeneratorInterventionTest.php +++ b/tests/Integration/Image/Service/ThumbnailGeneratorInterventionTest.php @@ -11,21 +11,14 @@ use Intervention\Image\ImageManager; use org\bovigo\vfs\vfsStream; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; -use OxidEsales\MediaLibrary\Tests\Integration\IntegrationTestCase; use OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention; +use OxidEsales\MediaLibrary\Tests\Integration\IntegrationTestCase; /** * @covers \OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention */ class ThumbnailGeneratorInterventionTest extends IntegrationTestCase { - private $vfsRootUrl; - public function setUp(): void - { - $this->vfsRootUrl = vfsStream::setup()->url(); - parent::setUp(); - } - /** * @dataProvider getThumbnailDataProvider */ @@ -37,15 +30,17 @@ public function testGenerateThumbnail( $expectedThumbnailHeight, $cropThumbnail ): void { + $rootPath = vfsStream::setup()->url(); + $imageManager = new ImageManager(new Driver()); - $thumbnailGenerator = new ThumbnailGeneratorIntervention($imageManager); + $sut = new ThumbnailGeneratorIntervention($imageManager); - $sourcePath = $this->vfsRootUrl . '/source.jpg'; + $sourcePath = $rootPath . '/source.jpg'; $img = $imageManager->create($sourceWidth, $sourceHeight); $img->save($sourcePath); - $thumbnailPath = $this->vfsRootUrl . '/thumbnail.jpg'; - $thumbnailGenerator->generateThumbnail( + $thumbnailPath = $rootPath . '/thumbnail.jpg'; + $sut->generateThumbnail( $sourcePath, $thumbnailPath, new ImageSize($thumbnailSize, $thumbnailSize), @@ -59,58 +54,65 @@ public function testGenerateThumbnail( self::assertSame($expectedThumbnailHeight, $resultThumbnailImage->height()); } - - public static function getThumbnailDataProvider() + public static function getThumbnailDataProvider(): array { return [ 'cropped_thumbnail_of_size_800x800_when_bigger_source_size_landscape' => [ - 'sourceWidth' => 950, - 'sourceHeight' => 900, - 'thumbnailSize' => 800, - 'expectedThumbnailWidth' => 800, - 'expectedThumbnailHeight' => 800, - 'cropThumbnail' => true, + 'sourceWidth' => 950, + 'sourceHeight' => 900, + 'thumbnailSize' => 800, + 'expectedThumbnailWidth' => 800, + 'expectedThumbnailHeight' => 800, + 'cropThumbnail' => true, ], 'cropped_thumbnail_of_size_500x500_when_smaller_source_size_landscape' => [ - 'sourceWidth' => 600, - 'sourceHeight' => 500, - 'thumbnailSize' => 800, - 'expectedThumbnailWidth' => 500, - 'expectedThumbnailHeight' => 500, - 'cropThumbnail' => true, + 'sourceWidth' => 600, + 'sourceHeight' => 500, + 'thumbnailSize' => 800, + 'expectedThumbnailWidth' => 500, + 'expectedThumbnailHeight' => 500, + 'cropThumbnail' => true, ], 'no_cropped_thumbnail_of_size_800x500_when_bigger_source_size_landscape' => [ - 'sourceWidth' => 800, - 'sourceHeight' => 500, - 'thumbnailSize' => 800, - 'expectedThumbnailWidth' => 800, - 'expectedThumbnailHeight' => 500, - 'cropThumbnail' => false, + 'sourceWidth' => 800, + 'sourceHeight' => 500, + 'thumbnailSize' => 800, + 'expectedThumbnailWidth' => 800, + 'expectedThumbnailHeight' => 500, + 'cropThumbnail' => false, ], 'no_cropped_thumbnail_of_size_200x300_when_bigger_source_size_potrait' => [ - 'sourceWidth' => 1000, - 'sourceHeight' => 1500, - 'thumbnailSize' => 300, - 'expectedThumbnailWidth' => 200, - 'expectedThumbnailHeight' => 300, - 'cropThumbnail' => false, + 'sourceWidth' => 1000, + 'sourceHeight' => 1500, + 'thumbnailSize' => 300, + 'expectedThumbnailWidth' => 200, + 'expectedThumbnailHeight' => 300, + 'cropThumbnail' => false, ], 'no_cropped_thumbnail_of_size_500x100_when_smaller_source_size_landscape' => [ - 'sourceWidth' => 500, - 'sourceHeight' => 100, - 'thumbnailSize' => 800, - 'expectedThumbnailWidth' => 500, - 'expectedThumbnailHeight' => 100, - 'cropThumbnail' => false, + 'sourceWidth' => 500, + 'sourceHeight' => 100, + 'thumbnailSize' => 800, + 'expectedThumbnailWidth' => 500, + 'expectedThumbnailHeight' => 100, + 'cropThumbnail' => false, ], 'no_cropped_thumbnail_of_size_500x100_when_smaller_source_size_potrait' => [ - 'sourceWidth' => 100, - 'sourceHeight' => 150, - 'thumbnailSize' => 300, - 'expectedThumbnailWidth' => 100, - 'expectedThumbnailHeight' => 150, - 'cropThumbnail' => false, + 'sourceWidth' => 100, + 'sourceHeight' => 150, + 'thumbnailSize' => 300, + 'expectedThumbnailWidth' => 100, + 'expectedThumbnailHeight' => 150, + 'cropThumbnail' => false, ], ]; } + + public function testIsOriginSupported(): void + { + $imageManager = new ImageManager(new Driver()); + $sut = new ThumbnailGeneratorIntervention($imageManager); + + $this->assertTrue($sut->isOriginSupported('anything')); + } } From 129a3bc12be5ca84ffcbbaac3cd6e9a40b877867 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Thu, 7 Mar 2024 17:23:30 +0200 Subject: [PATCH 06/21] OEVE-211 Extract thumbnail generators to separate namespace Signed-off-by: Anton Fedurtsya --- src/Image/Service/ThumbnailGeneratorAggregate.php | 1 + src/Image/Service/services.yaml | 6 +++--- .../Intervention.php} | 4 ++-- .../ThumbnailGeneratorInterface.php | 2 +- .../InterventionTest.php} | 12 ++++++------ .../Service/ThumbnailGeneratorAggregateTest.php | 2 +- 6 files changed, 14 insertions(+), 13 deletions(-) rename src/Image/{Service/ThumbnailGeneratorIntervention.php => ThumbnailGenerator/Intervention.php} (89%) rename src/Image/{Service => ThumbnailGenerator}/ThumbnailGeneratorInterface.php (88%) rename tests/Integration/Image/{Service/ThumbnailGeneratorInterventionTest.php => ThumbnailGenerator/InterventionTest.php} (90%) diff --git a/src/Image/Service/ThumbnailGeneratorAggregate.php b/src/Image/Service/ThumbnailGeneratorAggregate.php index b064441..83a57e3 100644 --- a/src/Image/Service/ThumbnailGeneratorAggregate.php +++ b/src/Image/Service/ThumbnailGeneratorAggregate.php @@ -11,6 +11,7 @@ use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; use OxidEsales\MediaLibrary\Image\Exception\AggregatorInputType; +use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\ThumbnailGeneratorInterface; class ThumbnailGeneratorAggregate implements ThumbnailGeneratorAggregateInterface { diff --git a/src/Image/Service/services.yaml b/src/Image/Service/services.yaml index 1b9c3d4..149c835 100644 --- a/src/Image/Service/services.yaml +++ b/src/Image/Service/services.yaml @@ -13,10 +13,10 @@ services: public: true arguments: $thumbnailGenerators: - - '@OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention' + - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention' - OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention: - class: OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention + OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention: + class: OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention OxidEsales\MediaLibrary\Image\Service\ThumbnailResourceInterface: class: OxidEsales\MediaLibrary\Image\Service\ThumbnailResource diff --git a/src/Image/Service/ThumbnailGeneratorIntervention.php b/src/Image/ThumbnailGenerator/Intervention.php similarity index 89% rename from src/Image/Service/ThumbnailGeneratorIntervention.php rename to src/Image/ThumbnailGenerator/Intervention.php index c1f1e14..e4930ab 100644 --- a/src/Image/Service/ThumbnailGeneratorIntervention.php +++ b/src/Image/ThumbnailGenerator/Intervention.php @@ -7,12 +7,12 @@ declare(strict_types=1); -namespace OxidEsales\MediaLibrary\Image\Service; +namespace OxidEsales\MediaLibrary\Image\ThumbnailGenerator; use Intervention\Image\ImageManager; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; -class ThumbnailGeneratorIntervention implements ThumbnailGeneratorInterface +class Intervention implements ThumbnailGeneratorInterface { public function __construct(private readonly ImageManager $imageManager) { diff --git a/src/Image/Service/ThumbnailGeneratorInterface.php b/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php similarity index 88% rename from src/Image/Service/ThumbnailGeneratorInterface.php rename to src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php index af0ee71..ef225ec 100644 --- a/src/Image/Service/ThumbnailGeneratorInterface.php +++ b/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php @@ -7,7 +7,7 @@ declare(strict_types=1); -namespace OxidEsales\MediaLibrary\Image\Service; +namespace OxidEsales\MediaLibrary\Image\ThumbnailGenerator; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; diff --git a/tests/Integration/Image/Service/ThumbnailGeneratorInterventionTest.php b/tests/Integration/Image/ThumbnailGenerator/InterventionTest.php similarity index 90% rename from tests/Integration/Image/Service/ThumbnailGeneratorInterventionTest.php rename to tests/Integration/Image/ThumbnailGenerator/InterventionTest.php index bd69b55..d15a56e 100644 --- a/tests/Integration/Image/Service/ThumbnailGeneratorInterventionTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/InterventionTest.php @@ -5,19 +5,19 @@ * See LICENSE file for license details. */ -namespace OxidEsales\MediaLibrary\Tests\Integration\Image\Service; +namespace OxidEsales\MediaLibrary\Tests\Integration\Image\ThumbnailGenerator; use Intervention\Image\Drivers\Gd\Driver; use Intervention\Image\ImageManager; use org\bovigo\vfs\vfsStream; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; -use OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention; +use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention; use OxidEsales\MediaLibrary\Tests\Integration\IntegrationTestCase; /** - * @covers \OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorIntervention + * @covers \OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention */ -class ThumbnailGeneratorInterventionTest extends IntegrationTestCase +class InterventionTest extends IntegrationTestCase { /** * @dataProvider getThumbnailDataProvider @@ -33,7 +33,7 @@ public function testGenerateThumbnail( $rootPath = vfsStream::setup()->url(); $imageManager = new ImageManager(new Driver()); - $sut = new ThumbnailGeneratorIntervention($imageManager); + $sut = new Intervention($imageManager); $sourcePath = $rootPath . '/source.jpg'; $img = $imageManager->create($sourceWidth, $sourceHeight); @@ -111,7 +111,7 @@ public static function getThumbnailDataProvider(): array public function testIsOriginSupported(): void { $imageManager = new ImageManager(new Driver()); - $sut = new ThumbnailGeneratorIntervention($imageManager); + $sut = new Intervention($imageManager); $this->assertTrue($sut->isOriginSupported('anything')); } diff --git a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php index 6d51817..bf2e4f8 100644 --- a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php +++ b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php @@ -12,7 +12,7 @@ use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; use OxidEsales\MediaLibrary\Image\Exception\AggregatorInputType; use OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorAggregate; -use OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorInterface; +use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\ThumbnailGeneratorInterface; use PHPUnit\Framework\TestCase; /** From 51cb66e79a83d332ab9b76397db0ec07df64f2e7 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Thu, 7 Mar 2024 17:39:13 +0200 Subject: [PATCH 07/21] OEVE-211 Extract thumbnail generators initializations Signed-off-by: Anton Fedurtsya --- services.yaml | 1 + src/Image/Service/ThumbnailGeneratorAggregate.php | 4 ++-- src/Image/Service/services.yaml | 8 -------- src/Image/ThumbnailGenerator/services.yaml | 13 +++++++++++++ .../Service/ThumbnailGeneratorAggregateTest.php | 2 +- tests/Unit/Image/Service/ThumbnailServiceTest.php | 6 +++--- 6 files changed, 20 insertions(+), 14 deletions(-) create mode 100644 src/Image/ThumbnailGenerator/services.yaml diff --git a/services.yaml b/services.yaml index 4702ad1..19fa62a 100644 --- a/services.yaml +++ b/services.yaml @@ -1,6 +1,7 @@ imports: - { resource: src/Breadcrumb/services.yaml } - { resource: src/Image/Service/services.yaml } + - { resource: src/Image/ThumbnailGenerator/services.yaml } - { resource: src/Language/Core/services.yaml } - { resource: src/Media/services.yaml } - { resource: src/Transput/services.yaml } diff --git a/src/Image/Service/ThumbnailGeneratorAggregate.php b/src/Image/Service/ThumbnailGeneratorAggregate.php index 83a57e3..be9fd25 100644 --- a/src/Image/Service/ThumbnailGeneratorAggregate.php +++ b/src/Image/Service/ThumbnailGeneratorAggregate.php @@ -35,7 +35,7 @@ public function generateThumbnail( ImageSizeInterface $thumbnailSize, bool $isCropRequired, ): void { - foreach($this->thumbnailGenerators as $oneGenerator) { + foreach ($this->thumbnailGenerators as $oneGenerator) { if ($oneGenerator->isOriginSupported($sourcePath)) { $oneGenerator->generateThumbnail( sourcePath: $sourcePath, @@ -47,4 +47,4 @@ public function generateThumbnail( } } } -} \ No newline at end of file +} diff --git a/src/Image/Service/services.yaml b/src/Image/Service/services.yaml index 149c835..07a5427 100644 --- a/src/Image/Service/services.yaml +++ b/src/Image/Service/services.yaml @@ -3,11 +3,6 @@ services: autowire: true public: false - Intervention\Image\ImageManager: - class: Intervention\Image\ImageManager - arguments: - $driver: 'Intervention\Image\Drivers\Gd\Driver' - OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorAggregateInterface: class: OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorAggregate public: true @@ -15,9 +10,6 @@ services: $thumbnailGenerators: - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention' - OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention: - class: OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention - OxidEsales\MediaLibrary\Image\Service\ThumbnailResourceInterface: class: OxidEsales\MediaLibrary\Image\Service\ThumbnailResource public: true diff --git a/src/Image/ThumbnailGenerator/services.yaml b/src/Image/ThumbnailGenerator/services.yaml new file mode 100644 index 0000000..b8d4503 --- /dev/null +++ b/src/Image/ThumbnailGenerator/services.yaml @@ -0,0 +1,13 @@ +services: + _defaults: + autowire: true + public: false + bind: + Intervention\Image\ImageManager: '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\InterventionImageManager' + + OxidEsales\MediaLibrary\Image\ThumbnailGenerator\InterventionImageManager: + class: Intervention\Image\ImageManager + arguments: + $driver: 'Intervention\Image\Drivers\Gd\Driver' + + OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention: ~ \ No newline at end of file diff --git a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php index bf2e4f8..917cf0f 100644 --- a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php +++ b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php @@ -60,4 +60,4 @@ public function testConstructorWorks(): void isCropRequired: $isCropRequired ); } -} \ No newline at end of file +} diff --git a/tests/Unit/Image/Service/ThumbnailServiceTest.php b/tests/Unit/Image/Service/ThumbnailServiceTest.php index 050f9a7..aeee291 100644 --- a/tests/Unit/Image/Service/ThumbnailServiceTest.php +++ b/tests/Unit/Image/Service/ThumbnailServiceTest.php @@ -52,7 +52,7 @@ public function testGetThumbnailUrlTriggerDefaultThumbnailCreation(): void $sut = $this->getSut( thumbnailResource: $thumbnailResourceMock = $this->createMock(ThumbnailResourceInterface::class), fileSystemService: $fileSystemSpy = $this->createMock(FileSystemServiceInterface::class), - thumbnailGeneratorAggregate: $thumbnailGeneratorAggregateSpy = $this->createMock(ThumbnailGeneratorAggregateInterface::class), + tgAgt: $thumbnailGeneratorAggregateSpy = $this->createMock(ThumbnailGeneratorAggregateInterface::class), imageResource: $imageResourceMock = $this->createMock(MediaResourceInterface::class), ); @@ -89,13 +89,13 @@ public function testGetThumbnailUrlTriggerDefaultThumbnailCreation(): void public function getSut( ThumbnailResourceInterface $thumbnailResource = null, FileSystemServiceInterface $fileSystemService = null, - ThumbnailGeneratorAggregateInterface $thumbnailGeneratorAggregate = null, + ThumbnailGeneratorAggregateInterface $tgAgt = null, MediaResourceInterface $imageResource = null, ): ThumbnailService { return new ThumbnailService( thumbnailResource: $thumbnailResource ?? $this->createStub(ThumbnailResourceInterface::class), fileSystemService: $fileSystemService ?? $this->createStub(FileSystemServiceInterface::class), - thumbnailGeneratorAggregate: $thumbnailGeneratorAggregate ?? $this->createStub(ThumbnailGeneratorAggregateInterface::class), + thumbnailGeneratorAggregate: $tgAgt ?? $this->createStub(ThumbnailGeneratorAggregateInterface::class), mediaResource: $imageResource ?? $this->createStub(MediaResourceInterface::class), ); } From 2c59fabd2c54591095ee41cfc0c7761609a86d40 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Thu, 7 Mar 2024 18:56:18 +0200 Subject: [PATCH 08/21] OEVE-211 Add svg thumbnail handler Signed-off-by: Anton Fedurtsya --- src/Image/Service/services.yaml | 1 + src/Image/ThumbnailGenerator/Svg.php | 36 ++++++++++++ src/Image/ThumbnailGenerator/services.yaml | 4 +- .../Image/ThumbnailGenerator/SvgTest.php | 56 +++++++++++++++++++ 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/Image/ThumbnailGenerator/Svg.php create mode 100644 tests/Integration/Image/ThumbnailGenerator/SvgTest.php diff --git a/src/Image/Service/services.yaml b/src/Image/Service/services.yaml index 07a5427..84fcd58 100644 --- a/src/Image/Service/services.yaml +++ b/src/Image/Service/services.yaml @@ -8,6 +8,7 @@ services: public: true arguments: $thumbnailGenerators: + - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Svg' - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention' OxidEsales\MediaLibrary\Image\Service\ThumbnailResourceInterface: diff --git a/src/Image/ThumbnailGenerator/Svg.php b/src/Image/ThumbnailGenerator/Svg.php new file mode 100644 index 0000000..ede912e --- /dev/null +++ b/src/Image/ThumbnailGenerator/Svg.php @@ -0,0 +1,36 @@ +fileSystemService->copy($sourcePath, $thumbnailPath); + } +} diff --git a/src/Image/ThumbnailGenerator/services.yaml b/src/Image/ThumbnailGenerator/services.yaml index b8d4503..dbe38af 100644 --- a/src/Image/ThumbnailGenerator/services.yaml +++ b/src/Image/ThumbnailGenerator/services.yaml @@ -10,4 +10,6 @@ services: arguments: $driver: 'Intervention\Image\Drivers\Gd\Driver' - OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention: ~ \ No newline at end of file + OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention: ~ + + OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Svg: ~ \ No newline at end of file diff --git a/tests/Integration/Image/ThumbnailGenerator/SvgTest.php b/tests/Integration/Image/ThumbnailGenerator/SvgTest.php new file mode 100644 index 0000000..cfa7d89 --- /dev/null +++ b/tests/Integration/Image/ThumbnailGenerator/SvgTest.php @@ -0,0 +1,56 @@ +getSut( + fileSystemService: $fileSystemSpy = $this->createMock(FileSystemServiceInterface::class) + ); + + $filePath = uniqid(); + $thumbPath = uniqid(); + + $fileSystemSpy->expects($this->once())->method('copy')->with($filePath, $thumbPath); + + $sut->generateThumbnail( + sourcePath: $filePath, + thumbnailPath: $thumbPath, + size: $this->createStub(ImageSizeInterface::class), + blCrop: (bool)random_int(0, 1) + ); + } + + public function testIsOriginSupported(): void + { + $sut = $this->getSut(); + $this->assertTrue($sut->isOriginSupported('xxx/someSvgPath.svg')); + $this->assertTrue($sut->isOriginSupported('xxx/someSvgPath.SVG')); + $this->assertFalse($sut->isOriginSupported('yyy/someOther.doc')); + $this->assertFalse($sut->isOriginSupported('yyy/someOther.gif')); + $this->assertFalse($sut->isOriginSupported('yyy/someOther.jpg')); + } + + public function getSut( + FileSystemServiceInterface $fileSystemService = null + ): Svg { + return new Svg( + fileSystemService: $fileSystemService ?? $this->createStub(FileSystemServiceInterface::class) + ); + } +} From 9213e1cf9c09a250de5efe0cb8228042445f6310 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 10:55:42 +0200 Subject: [PATCH 09/21] OEVE-211 Run intervention thumbnail preparation only for supported file types Signed-off-by: Anton Fedurtsya --- src/Image/ThumbnailGenerator/Intervention.php | 3 +- .../ThumbnailGenerator/InterventionTest.php | 69 ++++++++++++++++++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/Image/ThumbnailGenerator/Intervention.php b/src/Image/ThumbnailGenerator/Intervention.php index e4930ab..49528c3 100644 --- a/src/Image/ThumbnailGenerator/Intervention.php +++ b/src/Image/ThumbnailGenerator/Intervention.php @@ -20,7 +20,8 @@ public function __construct(private readonly ImageManager $imageManager) public function isOriginSupported(string $sourcePath): bool { - return true; + $extension = strtolower(pathinfo($sourcePath, PATHINFO_EXTENSION)); + return in_array($extension, ['jpg', 'jpeg', 'webp', 'gif', 'png', 'avif', 'bmp']); } public function generateThumbnail( diff --git a/tests/Integration/Image/ThumbnailGenerator/InterventionTest.php b/tests/Integration/Image/ThumbnailGenerator/InterventionTest.php index d15a56e..4db6b2f 100644 --- a/tests/Integration/Image/ThumbnailGenerator/InterventionTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/InterventionTest.php @@ -108,11 +108,76 @@ public static function getThumbnailDataProvider(): array ]; } - public function testIsOriginSupported(): void + /** @dataProvider fileTypesDataProvider */ + public function testIsOriginSupported(string $filePath, bool $expectedResult): void { $imageManager = new ImageManager(new Driver()); $sut = new Intervention($imageManager); - $this->assertTrue($sut->isOriginSupported('anything')); + $this->assertSame($expectedResult, $sut->isOriginSupported($filePath)); + $this->assertSame($expectedResult, $sut->isOriginSupported(strtoupper($filePath))); + } + + public static function fileTypesDataProvider(): \Generator + { + yield "jpg" => [ + 'filePath' => 'someFileName.jpg', + 'expectedResult' => true, + ]; + + yield "jpeg" => [ + 'filePath' => 'someFileName.jpeg', + 'expectedResult' => true, + ]; + + yield "webp" => [ + 'filePath' => 'someFileName.webp', + 'expectedResult' => true, + ]; + + yield "gif" => [ + 'filePath' => 'someFileName.gif', + 'expectedResult' => true, + ]; + + yield "png" => [ + 'filePath' => 'someFileName.png', + 'expectedResult' => true, + ]; + + yield "avif" => [ + 'filePath' => 'someFileName.avif', + 'expectedResult' => true, + ]; + + yield "bmp" => [ + 'filePath' => 'someFileName.bmp', + 'expectedResult' => true, + ]; + + yield "tiff" => [ + 'filePath' => 'someFileName.tiff', + 'expectedResult' => false, + ]; + + yield "heic" => [ + 'filePath' => 'someFileName.heic', + 'expectedResult' => false, + ]; + + yield "mp3" => [ + 'filePath' => 'someFileName.mp3', + 'expectedResult' => false, + ]; + + yield "doc" => [ + 'filePath' => 'someFileName.doc', + 'expectedResult' => false, + ]; + + yield "svg" => [ + 'filePath' => 'someFileName.svg', + 'expectedResult' => false, + ]; } } From 6b5c65979c2b8b22584cc48f01257c0b644043ed Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 11:23:14 +0200 Subject: [PATCH 10/21] OEVE-211 Add default driver for thumbnail generation This one does nothing at the moment, but will allow unsupported by other drivers formats to not explode Signed-off-by: Anton Fedurtsya --- .../Exception/NoSupportedDriversForSource.php | 14 ++++++++++ .../Service/ThumbnailGeneratorAggregate.php | 26 +++++++++++------ src/Image/Service/services.yaml | 1 + .../ThumbnailGenerator/DefaultDriver.php | 28 +++++++++++++++++++ src/Image/ThumbnailGenerator/services.yaml | 4 ++- .../ThumbnailGeneratorAggregateTest.php | 14 ++++++++++ .../Image/ThumbnailGenerator/DefaultTest.php | 22 +++++++++++++++ 7 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 src/Image/Exception/NoSupportedDriversForSource.php create mode 100644 src/Image/ThumbnailGenerator/DefaultDriver.php create mode 100644 tests/Unit/Image/ThumbnailGenerator/DefaultTest.php diff --git a/src/Image/Exception/NoSupportedDriversForSource.php b/src/Image/Exception/NoSupportedDriversForSource.php new file mode 100644 index 0000000..11c927e --- /dev/null +++ b/src/Image/Exception/NoSupportedDriversForSource.php @@ -0,0 +1,14 @@ +thumbnailGenerators as $oneGenerator) { - if ($oneGenerator->isOriginSupported($sourcePath)) { - $oneGenerator->generateThumbnail( - sourcePath: $sourcePath, - thumbnailPath: $thumbnailPath, - size: $thumbnailSize, - blCrop: $isCropRequired - ); - break; + $thumbnailGenerator = $this->getSupportedGenerator($sourcePath); + $thumbnailGenerator->generateThumbnail( + sourcePath: $sourcePath, + thumbnailPath: $thumbnailPath, + size: $thumbnailSize, + blCrop: $isCropRequired + ); + } + + protected function getSupportedGenerator(string $sourcePath): ThumbnailGeneratorInterface + { + foreach($this->thumbnailGenerators as $oneDriver) { + if ($oneDriver->isOriginSupported($sourcePath)) { + return $oneDriver; } } + + throw new NoSupportedDriversForSource(); } } diff --git a/src/Image/Service/services.yaml b/src/Image/Service/services.yaml index 84fcd58..baf19c7 100644 --- a/src/Image/Service/services.yaml +++ b/src/Image/Service/services.yaml @@ -10,6 +10,7 @@ services: $thumbnailGenerators: - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Svg' - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention' + - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver' OxidEsales\MediaLibrary\Image\Service\ThumbnailResourceInterface: class: OxidEsales\MediaLibrary\Image\Service\ThumbnailResource diff --git a/src/Image/ThumbnailGenerator/DefaultDriver.php b/src/Image/ThumbnailGenerator/DefaultDriver.php new file mode 100644 index 0000000..8ed9660 --- /dev/null +++ b/src/Image/ThumbnailGenerator/DefaultDriver.php @@ -0,0 +1,28 @@ +expectException(NoSupportedDriversForSource::class); + $sut->generateThumbnail( + sourcePath: uniqid(), + thumbnailPath: uniqid(), + thumbnailSize: $this->createStub(ImageSize::class), + isCropRequired: (bool)random_int(0, 1), + ); + } } diff --git a/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php b/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php new file mode 100644 index 0000000..e90312e --- /dev/null +++ b/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php @@ -0,0 +1,22 @@ +assertTrue($sut->isOriginSupported(uniqid())); + } +} \ No newline at end of file From f7744f107ab5448f46ec9134dda617bba048511a Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 11:26:18 +0200 Subject: [PATCH 11/21] OEVE-211 Add "Driver" to thumbnail generation handler class names Without any word, the name is too missleading. Signed-off-by: Anton Fedurtsya --- src/Image/Service/services.yaml | 4 ++-- .../{Intervention.php => InterventionDriver.php} | 2 +- .../ThumbnailGenerator/{Svg.php => SvgDriver.php} | 2 +- src/Image/ThumbnailGenerator/services.yaml | 4 ++-- ...InterventionTest.php => InterventionDriverTest.php} | 10 +++++----- .../{SvgTest.php => SvgDriverTest.php} | 10 +++++----- tests/Unit/Image/ThumbnailGenerator/DefaultTest.php | 3 +++ 7 files changed, 19 insertions(+), 16 deletions(-) rename src/Image/ThumbnailGenerator/{Intervention.php => InterventionDriver.php} (95%) rename src/Image/ThumbnailGenerator/{Svg.php => SvgDriver.php} (94%) rename tests/Integration/Image/ThumbnailGenerator/{InterventionTest.php => InterventionDriverTest.php} (96%) rename tests/Integration/Image/ThumbnailGenerator/{SvgTest.php => SvgDriverTest.php} (90%) diff --git a/src/Image/Service/services.yaml b/src/Image/Service/services.yaml index baf19c7..110931b 100644 --- a/src/Image/Service/services.yaml +++ b/src/Image/Service/services.yaml @@ -8,8 +8,8 @@ services: public: true arguments: $thumbnailGenerators: - - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Svg' - - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention' + - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\SvgDriver' + - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\InterventionDriver' - '@OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver' OxidEsales\MediaLibrary\Image\Service\ThumbnailResourceInterface: diff --git a/src/Image/ThumbnailGenerator/Intervention.php b/src/Image/ThumbnailGenerator/InterventionDriver.php similarity index 95% rename from src/Image/ThumbnailGenerator/Intervention.php rename to src/Image/ThumbnailGenerator/InterventionDriver.php index 49528c3..22545f6 100644 --- a/src/Image/ThumbnailGenerator/Intervention.php +++ b/src/Image/ThumbnailGenerator/InterventionDriver.php @@ -12,7 +12,7 @@ use Intervention\Image\ImageManager; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; -class Intervention implements ThumbnailGeneratorInterface +class InterventionDriver implements ThumbnailGeneratorInterface { public function __construct(private readonly ImageManager $imageManager) { diff --git a/src/Image/ThumbnailGenerator/Svg.php b/src/Image/ThumbnailGenerator/SvgDriver.php similarity index 94% rename from src/Image/ThumbnailGenerator/Svg.php rename to src/Image/ThumbnailGenerator/SvgDriver.php index ede912e..9edaa85 100644 --- a/src/Image/ThumbnailGenerator/Svg.php +++ b/src/Image/ThumbnailGenerator/SvgDriver.php @@ -12,7 +12,7 @@ use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; use OxidEsales\MediaLibrary\Service\FileSystemServiceInterface; -class Svg implements ThumbnailGeneratorInterface +class SvgDriver implements ThumbnailGeneratorInterface { public function __construct( protected FileSystemServiceInterface $fileSystemService diff --git a/src/Image/ThumbnailGenerator/services.yaml b/src/Image/ThumbnailGenerator/services.yaml index 5294e65..6fa5550 100644 --- a/src/Image/ThumbnailGenerator/services.yaml +++ b/src/Image/ThumbnailGenerator/services.yaml @@ -10,8 +10,8 @@ services: arguments: $driver: 'Intervention\Image\Drivers\Gd\Driver' - OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention: ~ + OxidEsales\MediaLibrary\Image\ThumbnailGenerator\InterventionDriver: ~ - OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Svg: ~ + OxidEsales\MediaLibrary\Image\ThumbnailGenerator\SvgDriver: ~ OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver: ~ \ No newline at end of file diff --git a/tests/Integration/Image/ThumbnailGenerator/InterventionTest.php b/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php similarity index 96% rename from tests/Integration/Image/ThumbnailGenerator/InterventionTest.php rename to tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php index 4db6b2f..7eb5841 100644 --- a/tests/Integration/Image/ThumbnailGenerator/InterventionTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php @@ -11,13 +11,13 @@ use Intervention\Image\ImageManager; use org\bovigo\vfs\vfsStream; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; -use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention; +use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\InterventionDriver; use OxidEsales\MediaLibrary\Tests\Integration\IntegrationTestCase; /** - * @covers \OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Intervention + * @covers \OxidEsales\MediaLibrary\Image\ThumbnailGenerator\InterventionDriver */ -class InterventionTest extends IntegrationTestCase +class InterventionDriverTest extends IntegrationTestCase { /** * @dataProvider getThumbnailDataProvider @@ -33,7 +33,7 @@ public function testGenerateThumbnail( $rootPath = vfsStream::setup()->url(); $imageManager = new ImageManager(new Driver()); - $sut = new Intervention($imageManager); + $sut = new InterventionDriver($imageManager); $sourcePath = $rootPath . '/source.jpg'; $img = $imageManager->create($sourceWidth, $sourceHeight); @@ -112,7 +112,7 @@ public static function getThumbnailDataProvider(): array public function testIsOriginSupported(string $filePath, bool $expectedResult): void { $imageManager = new ImageManager(new Driver()); - $sut = new Intervention($imageManager); + $sut = new InterventionDriver($imageManager); $this->assertSame($expectedResult, $sut->isOriginSupported($filePath)); $this->assertSame($expectedResult, $sut->isOriginSupported(strtoupper($filePath))); diff --git a/tests/Integration/Image/ThumbnailGenerator/SvgTest.php b/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php similarity index 90% rename from tests/Integration/Image/ThumbnailGenerator/SvgTest.php rename to tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php index cfa7d89..7cbd9b6 100644 --- a/tests/Integration/Image/ThumbnailGenerator/SvgTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php @@ -8,14 +8,14 @@ namespace Image\ThumbnailGenerator; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; -use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Svg; +use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\SvgDriver; use OxidEsales\MediaLibrary\Service\FileSystemServiceInterface; use OxidEsales\MediaLibrary\Tests\Integration\IntegrationTestCase; /** - * @covers \OxidEsales\MediaLibrary\Image\ThumbnailGenerator\Svg + * @covers \OxidEsales\MediaLibrary\Image\ThumbnailGenerator\SvgDriver */ -class SvgTest extends IntegrationTestCase +class SvgDriverTest extends IntegrationTestCase { public function testGenerateThumbnail(): void { @@ -48,8 +48,8 @@ public function testIsOriginSupported(): void public function getSut( FileSystemServiceInterface $fileSystemService = null - ): Svg { - return new Svg( + ): SvgDriver { + return new SvgDriver( fileSystemService: $fileSystemService ?? $this->createStub(FileSystemServiceInterface::class) ); } diff --git a/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php b/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php index e90312e..298c2b2 100644 --- a/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php +++ b/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php @@ -12,6 +12,9 @@ use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver; use PHPUnit\Framework\TestCase; +/** + * @covers \OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver + */ class DefaultTest extends TestCase { public function testIsOriginSupportedAlwaysReturnTrue(): void From aff3c0b70bc520e285a39edb9109a721f3dd2329 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 13:53:09 +0200 Subject: [PATCH 12/21] OEVE-211 Add getThumbnailFileName method to thumbnail generators As every generator handles thumbnail question differently, so should be with thumbnail names as well Signed-off-by: Anton Fedurtsya --- .../ThumbnailGenerator/DefaultDriver.php | 8 +++ .../ThumbnailGenerator/InterventionDriver.php | 25 ++++++++ src/Image/ThumbnailGenerator/SvgDriver.php | 16 +++++ .../ThumbnailGeneratorInterface.php | 6 ++ .../InterventionDriverTest.php | 63 +++++++++++++++++++ .../ThumbnailGenerator/SvgDriverTest.php | 28 +++++++++ .../Image/ThumbnailGenerator/DefaultTest.php | 14 +++++ 7 files changed, 160 insertions(+) diff --git a/src/Image/ThumbnailGenerator/DefaultDriver.php b/src/Image/ThumbnailGenerator/DefaultDriver.php index 8ed9660..5f4d203 100644 --- a/src/Image/ThumbnailGenerator/DefaultDriver.php +++ b/src/Image/ThumbnailGenerator/DefaultDriver.php @@ -25,4 +25,12 @@ public function generateThumbnail( bool $blCrop, ): void { } + + public function getThumbnailFileName( + string $originalFileName, + ImageSizeInterface $thumbnailSize, + bool $isCropRequired + ): string { + return 'default.jpg'; + } } \ No newline at end of file diff --git a/src/Image/ThumbnailGenerator/InterventionDriver.php b/src/Image/ThumbnailGenerator/InterventionDriver.php index 22545f6..38a641a 100644 --- a/src/Image/ThumbnailGenerator/InterventionDriver.php +++ b/src/Image/ThumbnailGenerator/InterventionDriver.php @@ -47,4 +47,29 @@ public function generateThumbnail( } $image->save($thumbnailPath); } + + public function getThumbnailFileName( + string $originalFileName, + ImageSizeInterface $thumbnailSize, + bool $isCropRequired + ): string { + return sprintf( + '%s_thumb_%d*%d%s.%s', + $this->getThumbnailFileHash($originalFileName), + $thumbnailSize->getWidth(), + $thumbnailSize->getHeight(), + $isCropRequired ? '' : '_nocrop', + $this->getExtensionFromFileName($originalFileName) + ); + } + + private function getThumbnailFileHash(string $originalFilename): string + { + return md5($originalFilename); + } + + protected function getExtensionFromFileName(string $fileName): string + { + return pathinfo($fileName, PATHINFO_EXTENSION); + } } diff --git a/src/Image/ThumbnailGenerator/SvgDriver.php b/src/Image/ThumbnailGenerator/SvgDriver.php index 9edaa85..40460ea 100644 --- a/src/Image/ThumbnailGenerator/SvgDriver.php +++ b/src/Image/ThumbnailGenerator/SvgDriver.php @@ -33,4 +33,20 @@ public function generateThumbnail( ): void { $this->fileSystemService->copy($sourcePath, $thumbnailPath); } + + public function getThumbnailFileName( + string $originalFileName, + ImageSizeInterface $thumbnailSize, + bool $isCropRequired + ): string { + return sprintf( + '%s.svg', + $this->getThumbnailFileHash($originalFileName), + ); + } + + private function getThumbnailFileHash(string $originalFilename): string + { + return md5($originalFilename); + } } diff --git a/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php b/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php index ef225ec..7c7ec56 100644 --- a/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php +++ b/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php @@ -15,6 +15,12 @@ interface ThumbnailGeneratorInterface { public function isOriginSupported(string $sourcePath): bool; + public function getThumbnailFileName( + string $originalFileName, + ImageSizeInterface $thumbnailSize, + bool $isCropRequired + ): string; + public function generateThumbnail( string $sourcePath, string $thumbnailPath, diff --git a/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php b/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php index 7eb5841..7c191ad 100644 --- a/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php @@ -11,6 +11,8 @@ use Intervention\Image\ImageManager; use org\bovigo\vfs\vfsStream; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; +use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; +use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver; use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\InterventionDriver; use OxidEsales\MediaLibrary\Tests\Integration\IntegrationTestCase; @@ -180,4 +182,65 @@ public static function fileTypesDataProvider(): \Generator 'expectedResult' => false, ]; } + + /** @dataProvider getThumbnailFileNameDataProvider */ + public function testGetThumbnailFileName( + string $originalFileName, + ImageSizeInterface $thumbnailSize, + bool $crop, + string $expectedName + ): void { + $imageManager = new ImageManager(new Driver()); + $sut = new InterventionDriver($imageManager); + + $result = $sut->getThumbnailFileName( + originalFileName: $originalFileName, + thumbnailSize: $thumbnailSize, + isCropRequired: $crop + ); + + $this->assertSame($expectedName, $result); + } + + public static function getThumbnailFileNameDataProvider(): \Generator + { + $fileName = 'filename.jpg'; + $fileNameHash = md5($fileName); + yield "regular jpg 100x100 nocrop" => [ + 'originalFileName' => $fileName, + 'thumbnailSize' => new ImageSize(100, 100), + 'crop' => true, + 'expectedName' => $fileNameHash . '_thumb_100*100.jpg' + ]; + + yield "regular jpg 100x100 crop" => [ + 'originalFileName' => $fileName, + 'thumbnailSize' => new ImageSize(100, 100), + 'crop' => false, + 'expectedName' => $fileNameHash . '_thumb_100*100_nocrop.jpg' + ]; + + yield "regular jpg 200x50 nocrop" => [ + 'originalFileName' => $fileName, + 'thumbnailSize' => new ImageSize(200, 50), + 'crop' => true, + 'expectedName' => $fileNameHash . '_thumb_200*50.jpg' + ]; + + yield "regular jpg 200x50 crop" => [ + 'originalFileName' => $fileName, + 'thumbnailSize' => new ImageSize(200, 50), + 'crop' => false, + 'expectedName' => $fileNameHash . '_thumb_200*50_nocrop.jpg' + ]; + + $specialExtensionFileName = 'filename.xxx'; + $specialExtensionFileNameHash = md5($specialExtensionFileName); + yield "extension save check" => [ + 'originalFileName' => $specialExtensionFileName, + 'thumbnailSize' => new ImageSize(100, 100), + 'crop' => true, + 'expectedName' => $specialExtensionFileNameHash . '_thumb_100*100.xxx' + ]; + } } diff --git a/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php b/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php index 7cbd9b6..28e105e 100644 --- a/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php @@ -7,6 +7,7 @@ namespace Image\ThumbnailGenerator; +use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\SvgDriver; use OxidEsales\MediaLibrary\Service\FileSystemServiceInterface; @@ -46,6 +47,33 @@ public function testIsOriginSupported(): void $this->assertFalse($sut->isOriginSupported('yyy/someOther.jpg')); } + /** @dataProvider getThumbnailFileNameDataProvider */ + public function testGetThumbnailFileName( + string $originalFileName, + string $expectedName + ): void { + $sut = $this->getSut(); + + $result = $sut->getThumbnailFileName( + originalFileName: $originalFileName, + thumbnailSize: $this->createStub(ImageSizeInterface::class), + isCropRequired: (bool)random_int(0, 1) + ); + + $this->assertSame($expectedName, $result); + } + + public static function getThumbnailFileNameDataProvider(): \Generator + { + $fileName = 'SomeFileName.SVG'; + $fileNameHash = md5($fileName); + + yield "regular svg" => [ + 'originalFileName' => $fileName, + 'expectedName' => $fileNameHash . '.svg' + ]; + } + public function getSut( FileSystemServiceInterface $fileSystemService = null ): SvgDriver { diff --git a/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php b/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php index 298c2b2..a6f2935 100644 --- a/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php +++ b/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php @@ -9,6 +9,7 @@ namespace OxidEsales\MediaLibrary\Tests\Unit\Image\ThumbnailGenerator; +use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver; use PHPUnit\Framework\TestCase; @@ -22,4 +23,17 @@ public function testIsOriginSupportedAlwaysReturnTrue(): void $sut = new DefaultDriver(); $this->assertTrue($sut->isOriginSupported(uniqid())); } + + public function testGetThumbnailFileNameReturnsDefaultValue(): void + { + $sut = new DefaultDriver(); + $this->assertSame( + 'default.jpg', + $sut->getThumbnailFileName( + originalFileName: uniqid(), + thumbnailSize: $this->createStub(ImageSizeInterface::class), + isCropRequired: (bool)random_int(0, 1) + ) + ); + } } \ No newline at end of file From 324eb92da6624ae27179a40134a391512649d6e7 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 14:21:08 +0200 Subject: [PATCH 13/21] OEVE-211 Add getThumbnailsGlob method to thumbnail generators As every generator handles thumbnail question differently, so should be with thumbnail removal as well Signed-off-by: Anton Fedurtsya --- src/Image/ThumbnailGenerator/DefaultDriver.php | 5 +++++ src/Image/ThumbnailGenerator/InterventionDriver.php | 5 +++++ src/Image/ThumbnailGenerator/SvgDriver.php | 5 +++++ .../ThumbnailGeneratorInterface.php | 2 ++ .../ThumbnailGenerator/InterventionDriverTest.php | 9 +++++++++ .../Image/ThumbnailGenerator/SvgDriverTest.php | 9 +++++++++ .../{DefaultTest.php => DefaultDriverTest.php} | 11 ++++++++++- 7 files changed, 45 insertions(+), 1 deletion(-) rename tests/Unit/Image/ThumbnailGenerator/{DefaultTest.php => DefaultDriverTest.php} (80%) diff --git a/src/Image/ThumbnailGenerator/DefaultDriver.php b/src/Image/ThumbnailGenerator/DefaultDriver.php index 5f4d203..0cdb13a 100644 --- a/src/Image/ThumbnailGenerator/DefaultDriver.php +++ b/src/Image/ThumbnailGenerator/DefaultDriver.php @@ -33,4 +33,9 @@ public function getThumbnailFileName( ): string { return 'default.jpg'; } + + public function getThumbnailsGlob(string $originalFilename): string + { + return 'default.jpg'; + } } \ No newline at end of file diff --git a/src/Image/ThumbnailGenerator/InterventionDriver.php b/src/Image/ThumbnailGenerator/InterventionDriver.php index 38a641a..87ac535 100644 --- a/src/Image/ThumbnailGenerator/InterventionDriver.php +++ b/src/Image/ThumbnailGenerator/InterventionDriver.php @@ -72,4 +72,9 @@ protected function getExtensionFromFileName(string $fileName): string { return pathinfo($fileName, PATHINFO_EXTENSION); } + + public function getThumbnailsGlob(string $originalFilename): string + { + return $this->getThumbnailFileHash($originalFilename) . '*.*'; + } } diff --git a/src/Image/ThumbnailGenerator/SvgDriver.php b/src/Image/ThumbnailGenerator/SvgDriver.php index 40460ea..9810fef 100644 --- a/src/Image/ThumbnailGenerator/SvgDriver.php +++ b/src/Image/ThumbnailGenerator/SvgDriver.php @@ -49,4 +49,9 @@ private function getThumbnailFileHash(string $originalFilename): string { return md5($originalFilename); } + + public function getThumbnailsGlob(string $originalFilename): string + { + return $this->getThumbnailFileHash($originalFilename) . '.svg'; + } } diff --git a/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php b/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php index 7c7ec56..e6a802d 100644 --- a/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php +++ b/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php @@ -27,4 +27,6 @@ public function generateThumbnail( ImageSizeInterface $size, bool $blCrop, ): void; + + public function getThumbnailsGlob(string $originalFilename): string; } diff --git a/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php b/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php index 7c191ad..b13afcf 100644 --- a/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php @@ -243,4 +243,13 @@ public static function getThumbnailFileNameDataProvider(): \Generator 'expectedName' => $specialExtensionFileNameHash . '_thumb_100*100.xxx' ]; } + + public function testGetThumbnailsGlob(): void + { + $imageManager = new ImageManager(new Driver()); + $sut = new InterventionDriver($imageManager); + + $originalFilename = 'someExampleFilename.txt'; + $this->assertSame('8910f1d8c070ff09e13d4977fc339a29*.*', $sut->getThumbnailsGlob($originalFilename)); + } } diff --git a/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php b/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php index 28e105e..3a749b3 100644 --- a/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php @@ -9,6 +9,7 @@ use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; +use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver; use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\SvgDriver; use OxidEsales\MediaLibrary\Service\FileSystemServiceInterface; use OxidEsales\MediaLibrary\Tests\Integration\IntegrationTestCase; @@ -74,6 +75,14 @@ public static function getThumbnailFileNameDataProvider(): \Generator ]; } + public function testGetThumbnailsGlob(): void + { + $sut = $this->getSut(); + + $originalFilename = 'someExampleFilename.svg'; + $this->assertSame('5a1040df467f3ceae2623aa5918f542a.svg', $sut->getThumbnailsGlob($originalFilename)); + } + public function getSut( FileSystemServiceInterface $fileSystemService = null ): SvgDriver { diff --git a/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php b/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php similarity index 80% rename from tests/Unit/Image/ThumbnailGenerator/DefaultTest.php rename to tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php index a6f2935..0778b06 100644 --- a/tests/Unit/Image/ThumbnailGenerator/DefaultTest.php +++ b/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php @@ -16,7 +16,7 @@ /** * @covers \OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver */ -class DefaultTest extends TestCase +class DefaultDriverTest extends TestCase { public function testIsOriginSupportedAlwaysReturnTrue(): void { @@ -36,4 +36,13 @@ public function testGetThumbnailFileNameReturnsDefaultValue(): void ) ); } + + public function testGetThumbnailsGlob(): void + { + $sut = new DefaultDriver(); + $this->assertSame( + 'default.jpg', + $sut->getThumbnailsGlob(uniqid()) + ); + } } \ No newline at end of file From 315837ae64242f5eee3b74582806c6c94939067d Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 14:30:38 +0200 Subject: [PATCH 14/21] OEVE-211 Make getSupportedGenerator publicly available Signed-off-by: Anton Fedurtsya --- .../Service/ThumbnailGeneratorAggregate.php | 2 +- .../ThumbnailGeneratorAggregateInterface.php | 3 +++ .../ThumbnailGeneratorAggregateTest.php | 24 ++++++++++++++++++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/Image/Service/ThumbnailGeneratorAggregate.php b/src/Image/Service/ThumbnailGeneratorAggregate.php index 81e171d..2416ad7 100644 --- a/src/Image/Service/ThumbnailGeneratorAggregate.php +++ b/src/Image/Service/ThumbnailGeneratorAggregate.php @@ -45,7 +45,7 @@ public function generateThumbnail( ); } - protected function getSupportedGenerator(string $sourcePath): ThumbnailGeneratorInterface + public function getSupportedGenerator(string $sourcePath): ThumbnailGeneratorInterface { foreach($this->thumbnailGenerators as $oneDriver) { if ($oneDriver->isOriginSupported($sourcePath)) { diff --git a/src/Image/Service/ThumbnailGeneratorAggregateInterface.php b/src/Image/Service/ThumbnailGeneratorAggregateInterface.php index c72ff4e..6a1f714 100644 --- a/src/Image/Service/ThumbnailGeneratorAggregateInterface.php +++ b/src/Image/Service/ThumbnailGeneratorAggregateInterface.php @@ -10,6 +10,7 @@ namespace OxidEsales\MediaLibrary\Image\Service; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; +use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\ThumbnailGeneratorInterface; interface ThumbnailGeneratorAggregateInterface { @@ -19,4 +20,6 @@ public function generateThumbnail( ImageSizeInterface $thumbnailSize, bool $isCropRequired, ): void; + + public function getSupportedGenerator(string $sourcePath): ThumbnailGeneratorInterface; } diff --git a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php index ee49f7d..0ba8b1f 100644 --- a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php +++ b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php @@ -27,7 +27,7 @@ public function testConstructorDoesNotAcceptWrongType(): void new ThumbnailGeneratorAggregate([new \stdClass()]); } - public function testConstructorWorks(): void + public function testGenerateThumbnailCalledOnCorrectGenerator(): void { $filePath = uniqid(); $thumbnailPath = uniqid(); @@ -62,6 +62,28 @@ public function testConstructorWorks(): void ); } + public function testGetSupportedThumbnailGenerator(): void + { + $filePath = uniqid(); + + $wrongGeneratorStub = $this->createMock(ThumbnailGeneratorInterface::class); + $wrongGeneratorStub->method('isOriginSupported')->with($filePath)->willReturn(false); + + $expectedGeneratorStub = $this->createMock(ThumbnailGeneratorInterface::class); + $expectedGeneratorStub->method('isOriginSupported')->with($filePath)->willReturn(true); + + $supportedButLowerPriorityGeneratorStub = $this->createMock(ThumbnailGeneratorInterface::class); + $supportedButLowerPriorityGeneratorStub->method('isOriginSupported')->with($filePath)->willReturn(true); + + $sut = new ThumbnailGeneratorAggregate([ + $wrongGeneratorStub, + $expectedGeneratorStub, + $supportedButLowerPriorityGeneratorStub + ]); + + $this->assertSame($expectedGeneratorStub, $sut->getSupportedGenerator($filePath)); + } + public function testNoSupportedDriversExceptionCase(): void { $sut = new ThumbnailGeneratorAggregate([]); From 5c2dc0d58af5b469d80a85af37a6fffcf2096da0 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 14:45:47 +0200 Subject: [PATCH 15/21] OEVE-211 Fix naming issues in the ThumbnailGeneratorInterface Signed-off-by: Anton Fedurtsya --- .../ThumbnailGenerator/DefaultDriver.php | 4 +-- .../ThumbnailGenerator/InterventionDriver.php | 10 +++--- src/Image/ThumbnailGenerator/SvgDriver.php | 4 +-- .../ThumbnailGeneratorInterface.php | 4 +-- .../InterventionDriverTest.php | 9 +++-- .../ThumbnailGenerator/SvgDriverTest.php | 4 +-- .../ThumbnailGeneratorAggregateTest.php | 35 ------------------- 7 files changed, 17 insertions(+), 53 deletions(-) diff --git a/src/Image/ThumbnailGenerator/DefaultDriver.php b/src/Image/ThumbnailGenerator/DefaultDriver.php index 0cdb13a..d1b83d3 100644 --- a/src/Image/ThumbnailGenerator/DefaultDriver.php +++ b/src/Image/ThumbnailGenerator/DefaultDriver.php @@ -21,8 +21,8 @@ public function isOriginSupported(string $sourcePath): bool public function generateThumbnail( string $sourcePath, string $thumbnailPath, - ImageSizeInterface $size, - bool $blCrop, + ImageSizeInterface $thumbnailSize, + bool $isCropRequired, ): void { } diff --git a/src/Image/ThumbnailGenerator/InterventionDriver.php b/src/Image/ThumbnailGenerator/InterventionDriver.php index 87ac535..1f75962 100644 --- a/src/Image/ThumbnailGenerator/InterventionDriver.php +++ b/src/Image/ThumbnailGenerator/InterventionDriver.php @@ -27,14 +27,14 @@ public function isOriginSupported(string $sourcePath): bool public function generateThumbnail( string $sourcePath, string $thumbnailPath, - ImageSizeInterface $size, - bool $blCrop, + ImageSizeInterface $thumbnailSize, + bool $isCropRequired, ): void { - $thumbnailWidth = $size->getWidth(); - $thumbnailHeight = $size->getHeight(); + $thumbnailWidth = $thumbnailSize->getWidth(); + $thumbnailHeight = $thumbnailSize->getHeight(); $image = $this->imageManager->read($sourcePath); - if ($blCrop) { + if ($isCropRequired) { $image->coverDown( width: $thumbnailWidth, height: $thumbnailHeight diff --git a/src/Image/ThumbnailGenerator/SvgDriver.php b/src/Image/ThumbnailGenerator/SvgDriver.php index 9810fef..8ad66a7 100644 --- a/src/Image/ThumbnailGenerator/SvgDriver.php +++ b/src/Image/ThumbnailGenerator/SvgDriver.php @@ -28,8 +28,8 @@ public function isOriginSupported(string $sourcePath): bool public function generateThumbnail( string $sourcePath, string $thumbnailPath, - ImageSizeInterface $size, - bool $blCrop, + ImageSizeInterface $thumbnailSize, + bool $isCropRequired, ): void { $this->fileSystemService->copy($sourcePath, $thumbnailPath); } diff --git a/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php b/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php index e6a802d..220e443 100644 --- a/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php +++ b/src/Image/ThumbnailGenerator/ThumbnailGeneratorInterface.php @@ -24,8 +24,8 @@ public function getThumbnailFileName( public function generateThumbnail( string $sourcePath, string $thumbnailPath, - ImageSizeInterface $size, - bool $blCrop, + ImageSizeInterface $thumbnailSize, + bool $isCropRequired, ): void; public function getThumbnailsGlob(string $originalFilename): string; diff --git a/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php b/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php index b13afcf..d9f07a7 100644 --- a/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/InterventionDriverTest.php @@ -12,7 +12,6 @@ use org\bovigo\vfs\vfsStream; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSize; use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; -use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\DefaultDriver; use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\InterventionDriver; use OxidEsales\MediaLibrary\Tests\Integration\IntegrationTestCase; @@ -43,10 +42,10 @@ public function testGenerateThumbnail( $thumbnailPath = $rootPath . '/thumbnail.jpg'; $sut->generateThumbnail( - $sourcePath, - $thumbnailPath, - new ImageSize($thumbnailSize, $thumbnailSize), - $cropThumbnail + sourcePath: $sourcePath, + thumbnailPath: $thumbnailPath, + thumbnailSize: new ImageSize($thumbnailSize, $thumbnailSize), + isCropRequired: $cropThumbnail ); self::assertFileExists($thumbnailPath); diff --git a/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php b/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php index 3a749b3..23bc02b 100644 --- a/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php +++ b/tests/Integration/Image/ThumbnailGenerator/SvgDriverTest.php @@ -33,8 +33,8 @@ public function testGenerateThumbnail(): void $sut->generateThumbnail( sourcePath: $filePath, thumbnailPath: $thumbPath, - size: $this->createStub(ImageSizeInterface::class), - blCrop: (bool)random_int(0, 1) + thumbnailSize: $this->createStub(ImageSizeInterface::class), + isCropRequired: (bool)random_int(0, 1) ); } diff --git a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php index 0ba8b1f..5ec14ce 100644 --- a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php +++ b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php @@ -27,41 +27,6 @@ public function testConstructorDoesNotAcceptWrongType(): void new ThumbnailGeneratorAggregate([new \stdClass()]); } - public function testGenerateThumbnailCalledOnCorrectGenerator(): void - { - $filePath = uniqid(); - $thumbnailPath = uniqid(); - $thumbnailSize = $this->createStub(ImageSize::class); - $isCropRequired = (bool)random_int(0, 1); - - $generatorSpyWrong = $this->createMock(ThumbnailGeneratorInterface::class); - $generatorSpyWrong->method('isOriginSupported')->with($filePath)->willReturn(false); - $generatorSpyWrong->expects($this->never())->method('generateThumbnail'); - - $generatorSpyExpected = $this->createMock(ThumbnailGeneratorInterface::class); - $generatorSpyExpected->method('isOriginSupported')->with($filePath)->willReturn(true); - $generatorSpyExpected->expects($this->once()) - ->method('generateThumbnail') - ->with($filePath, $thumbnailPath, $thumbnailSize, $isCropRequired); - - $generatorSpyAfterExpectedNotCalled = $this->createMock(ThumbnailGeneratorInterface::class); - $generatorSpyAfterExpectedNotCalled->method('isOriginSupported')->with($filePath)->willReturn(true); - $generatorSpyAfterExpectedNotCalled->expects($this->never())->method('generateThumbnail'); - - $sut = new ThumbnailGeneratorAggregate([ - $generatorSpyWrong, - $generatorSpyExpected, - $generatorSpyAfterExpectedNotCalled - ]); - - $sut->generateThumbnail( - sourcePath: $filePath, - thumbnailPath: $thumbnailPath, - thumbnailSize: $thumbnailSize, - isCropRequired: $isCropRequired - ); - } - public function testGetSupportedThumbnailGenerator(): void { $filePath = uniqid(); From d2aaedbb217690383bc4a869d3e5c8d8bc73d494 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 14:56:14 +0200 Subject: [PATCH 16/21] OEVE-211 Get thumbnail name and trigger thumbnail generator from driver Signed-off-by: Anton Fedurtsya --- .../Service/ThumbnailGeneratorAggregate.php | 15 ---------- .../ThumbnailGeneratorAggregateInterface.php | 8 ------ src/Image/Service/ThumbnailService.php | 8 ++++-- .../ThumbnailGeneratorAggregateTest.php | 7 +---- .../Image/Service/ThumbnailServiceTest.php | 28 +++++++++++-------- 5 files changed, 23 insertions(+), 43 deletions(-) diff --git a/src/Image/Service/ThumbnailGeneratorAggregate.php b/src/Image/Service/ThumbnailGeneratorAggregate.php index 2416ad7..71e8ddd 100644 --- a/src/Image/Service/ThumbnailGeneratorAggregate.php +++ b/src/Image/Service/ThumbnailGeneratorAggregate.php @@ -30,21 +30,6 @@ public function __construct( } } - public function generateThumbnail( - string $sourcePath, - string $thumbnailPath, - ImageSizeInterface $thumbnailSize, - bool $isCropRequired, - ): void { - $thumbnailGenerator = $this->getSupportedGenerator($sourcePath); - $thumbnailGenerator->generateThumbnail( - sourcePath: $sourcePath, - thumbnailPath: $thumbnailPath, - size: $thumbnailSize, - blCrop: $isCropRequired - ); - } - public function getSupportedGenerator(string $sourcePath): ThumbnailGeneratorInterface { foreach($this->thumbnailGenerators as $oneDriver) { diff --git a/src/Image/Service/ThumbnailGeneratorAggregateInterface.php b/src/Image/Service/ThumbnailGeneratorAggregateInterface.php index 6a1f714..9b14cf7 100644 --- a/src/Image/Service/ThumbnailGeneratorAggregateInterface.php +++ b/src/Image/Service/ThumbnailGeneratorAggregateInterface.php @@ -9,17 +9,9 @@ namespace OxidEsales\MediaLibrary\Image\Service; -use OxidEsales\MediaLibrary\Image\DataTransfer\ImageSizeInterface; use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\ThumbnailGeneratorInterface; interface ThumbnailGeneratorAggregateInterface { - public function generateThumbnail( - string $sourcePath, - string $thumbnailPath, - ImageSizeInterface $thumbnailSize, - bool $isCropRequired, - ): void; - public function getSupportedGenerator(string $sourcePath): ThumbnailGeneratorInterface; } diff --git a/src/Image/Service/ThumbnailService.php b/src/Image/Service/ThumbnailService.php index 5cd8195..1167a57 100644 --- a/src/Image/Service/ThumbnailService.php +++ b/src/Image/Service/ThumbnailService.php @@ -39,17 +39,19 @@ public function ensureAndGetThumbnailUrl( ImageSizeInterface $imageSize = null, bool $crop = true ): string { - $thumbnailFileName = $this->thumbnailResource->getThumbnailFileName( + $thumbnailGenerator = $this->thumbnailGeneratorAggregate->getSupportedGenerator($fileName); + + $thumbnailFileName = $thumbnailGenerator->getThumbnailFileName( originalFileName: $fileName, thumbnailSize: $imageSize ?? $this->thumbnailResource->getDefaultThumbnailSize(), - crop: $crop + isCropRequired: $crop ); $thumbnailDirectoryPath = $this->thumbnailResource->getPathToThumbnailFiles($folderName); $thumbnailPath = Path::join($thumbnailDirectoryPath, $thumbnailFileName); if (!is_file($thumbnailPath)) { $this->fileSystemService->ensureDirectory($thumbnailDirectoryPath); - $this->thumbnailGeneratorAggregate->generateThumbnail( + $thumbnailGenerator->generateThumbnail( sourcePath: Path::join($this->mediaResource->getPathToMediaFiles($folderName), $fileName), thumbnailPath: $thumbnailPath, thumbnailSize: $imageSize ?? $this->thumbnailResource->getDefaultThumbnailSize(), diff --git a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php index 5ec14ce..8306052 100644 --- a/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php +++ b/tests/Unit/Image/Service/ThumbnailGeneratorAggregateTest.php @@ -54,11 +54,6 @@ public function testNoSupportedDriversExceptionCase(): void $sut = new ThumbnailGeneratorAggregate([]); $this->expectException(NoSupportedDriversForSource::class); - $sut->generateThumbnail( - sourcePath: uniqid(), - thumbnailPath: uniqid(), - thumbnailSize: $this->createStub(ImageSize::class), - isCropRequired: (bool)random_int(0, 1), - ); + $sut->getSupportedGenerator(uniqid()); } } diff --git a/tests/Unit/Image/Service/ThumbnailServiceTest.php b/tests/Unit/Image/Service/ThumbnailServiceTest.php index aeee291..429ece4 100644 --- a/tests/Unit/Image/Service/ThumbnailServiceTest.php +++ b/tests/Unit/Image/Service/ThumbnailServiceTest.php @@ -12,6 +12,7 @@ use OxidEsales\MediaLibrary\Image\Service\ThumbnailGeneratorAggregateInterface; use OxidEsales\MediaLibrary\Image\Service\ThumbnailResourceInterface; use OxidEsales\MediaLibrary\Image\Service\ThumbnailService; +use OxidEsales\MediaLibrary\Image\ThumbnailGenerator\ThumbnailGeneratorInterface; use OxidEsales\MediaLibrary\Media\DataType\MediaInterface; use OxidEsales\MediaLibrary\Media\Service\MediaResourceInterface; use OxidEsales\MediaLibrary\Service\FileSystemServiceInterface; @@ -52,34 +53,39 @@ public function testGetThumbnailUrlTriggerDefaultThumbnailCreation(): void $sut = $this->getSut( thumbnailResource: $thumbnailResourceMock = $this->createMock(ThumbnailResourceInterface::class), fileSystemService: $fileSystemSpy = $this->createMock(FileSystemServiceInterface::class), - tgAgt: $thumbnailGeneratorAggregateSpy = $this->createMock(ThumbnailGeneratorAggregateInterface::class), - imageResource: $imageResourceMock = $this->createMock(MediaResourceInterface::class), + tgAgt: $thumbnailGeneratorAggregateStub = $this->createMock(ThumbnailGeneratorAggregateInterface::class), + imageResource: $mediaResourceMock = $this->createMock(MediaResourceInterface::class), ); $folderName = 'someFolderName'; $fileName = 'someFileName'; $thumbnailFileName = 'someThumbnailName'; - $sizeStub = new ImageSize(100, 100); + $defaultSizeStub = new ImageSize(100, 100); $thumbnailFolder = $vfsRootPath . '/thumbs'; $thumbnailUrlFolder = 'someUrlToThumbFolder'; + $defaultCropFlag = true; + $thumbnailResourceMock->method('getUrlToThumbnailFiles')->with($folderName)->willReturn($thumbnailUrlFolder); $thumbnailResourceMock->method('getPathToThumbnailFiles')->with($folderName)->willReturn($thumbnailFolder); - $thumbnailResourceMock->method('getDefaultThumbnailSize')->willReturn($sizeStub); - $thumbnailResourceMock->method('getThumbnailFileName') - ->with($fileName, $sizeStub, true) - ->willReturn($thumbnailFileName); + $thumbnailResourceMock->method('getDefaultThumbnailSize')->willReturn($defaultSizeStub); $originalFolder = 'originalFolder'; - $imageResourceMock->method('getPathToMediaFiles')->with($folderName)->willReturn($originalFolder); + $mediaResourceMock->method('getPathToMediaFiles')->with($folderName)->willReturn($originalFolder); $fileSystemSpy->expects($this->once())->method('ensureDirectory')->with($thumbnailFolder); - $thumbnailGeneratorAggregateSpy->expects($this->once())->method('generateThumbnail') + + $thumbnailGeneratorSpy = $this->createMock(ThumbnailGeneratorInterface::class); + $thumbnailGeneratorAggregateStub->method('getSupportedGenerator')->willReturn($thumbnailGeneratorSpy); + $thumbnailGeneratorSpy->method('getThumbnailFileName') + ->with($fileName, $defaultSizeStub, $defaultCropFlag) + ->willReturn($thumbnailFileName); + $thumbnailGeneratorSpy->expects($this->once())->method('generateThumbnail') ->with( $originalFolder . '/' . $fileName, $thumbnailFolder . '/' . $thumbnailFileName, - $sizeStub, - true + $defaultSizeStub, + $defaultCropFlag ); $expectedUrl = $thumbnailUrlFolder . '/' . $thumbnailFileName; From 1252ca19b90ad8ee7a182e98b51474b97b63e53b Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 15:01:50 +0200 Subject: [PATCH 17/21] OEVE-211 Remove outdated getThumbnailFileName from ThumbnailResource Signed-off-by: Anton Fedurtsya --- src/Image/Service/ThumbnailResource.php | 20 ------- .../Service/ThumbnailResourceInterface.php | 6 -- .../Image/Service/ThumbnailResourceTest.php | 60 ------------------- 3 files changed, 86 deletions(-) diff --git a/src/Image/Service/ThumbnailResource.php b/src/Image/Service/ThumbnailResource.php index e6c5e55..56ada3a 100644 --- a/src/Image/Service/ThumbnailResource.php +++ b/src/Image/Service/ThumbnailResource.php @@ -27,26 +27,6 @@ private function getThumbnailFileHash(string $originalFilename): string return md5($originalFilename); } - public function getThumbnailFileName( - string $originalFileName, - ImageSizeInterface $thumbnailSize, - bool $crop - ): string { - return sprintf( - '%s_thumb_%d*%d%s.%s', - $this->getThumbnailFileHash($originalFileName), - $thumbnailSize->getWidth(), - $thumbnailSize->getHeight(), - $crop ? '' : '_nocrop', - $this->getExtensionFromFileName($originalFileName) - ); - } - - protected function getExtensionFromFileName(string $fileName): string - { - return pathinfo($fileName, PATHINFO_EXTENSION); - } - public function getDefaultThumbnailSize(): ImageSizeInterface { return new ImageSize(width: self::THUMBNAIL_DEFAULT_SIZE, height: self::THUMBNAIL_DEFAULT_SIZE); diff --git a/src/Image/Service/ThumbnailResourceInterface.php b/src/Image/Service/ThumbnailResourceInterface.php index 23a4261..f726740 100644 --- a/src/Image/Service/ThumbnailResourceInterface.php +++ b/src/Image/Service/ThumbnailResourceInterface.php @@ -14,12 +14,6 @@ interface ThumbnailResourceInterface { - public function getThumbnailFileName( - string $originalFileName, - ImageSizeInterface $thumbnailSize, - bool $crop - ): string; - public function getDefaultThumbnailSize(): ImageSizeInterface; public function getPathToThumbnailFiles(string $folderName): string; diff --git a/tests/Unit/Image/Service/ThumbnailResourceTest.php b/tests/Unit/Image/Service/ThumbnailResourceTest.php index f6f279e..7d53d96 100644 --- a/tests/Unit/Image/Service/ThumbnailResourceTest.php +++ b/tests/Unit/Image/Service/ThumbnailResourceTest.php @@ -18,48 +18,6 @@ */ class ThumbnailResourceTest extends TestCase { - public static function getThumbnailFileNameDataProvider(): \Generator - { - $fileName = 'filename.jpg'; - $fileNameHash = md5($fileName); - yield "regular jpg 100x100 nocrop" => [ - 'originalFileName' => $fileName, - 'thumbnailSize' => new ImageSize(100, 100), - 'crop' => true, - 'expectedName' => $fileNameHash . '_thumb_100*100.jpg' - ]; - - yield "regular jpg 100x100 crop" => [ - 'originalFileName' => $fileName, - 'thumbnailSize' => new ImageSize(100, 100), - 'crop' => false, - 'expectedName' => $fileNameHash . '_thumb_100*100_nocrop.jpg' - ]; - - yield "regular jpg 200x50 nocrop" => [ - 'originalFileName' => $fileName, - 'thumbnailSize' => new ImageSize(200, 50), - 'crop' => true, - 'expectedName' => $fileNameHash . '_thumb_200*50.jpg' - ]; - - yield "regular jpg 200x50 crop" => [ - 'originalFileName' => $fileName, - 'thumbnailSize' => new ImageSize(200, 50), - 'crop' => false, - 'expectedName' => $fileNameHash . '_thumb_200*50_nocrop.jpg' - ]; - - $specialExtensionFileName = 'filename.xxx'; - $specialExtensionFileNameHash = md5($specialExtensionFileName); - yield "extension save check" => [ - 'originalFileName' => $specialExtensionFileName, - 'thumbnailSize' => new ImageSize(100, 100), - 'crop' => true, - 'expectedName' => $specialExtensionFileNameHash . '_thumb_100*100.xxx' - ]; - } - protected function getSut( MediaResourceInterface $imageResource = null, ) { @@ -68,24 +26,6 @@ protected function getSut( ); } - /** @dataProvider getThumbnailFileNameDataProvider */ - public function testGetThumbnailFileName( - string $originalFileName, - ImageSizeInterface $thumbnailSize, - bool $crop, - string $expectedName - ): void { - $sut = $this->getSut(); - - $result = $sut->getThumbnailFileName( - originalFileName: $originalFileName, - thumbnailSize: $thumbnailSize, - crop: $crop - ); - - $this->assertSame($expectedName, $result); - } - public function testGetThumbnailsGlob(): void { $sut = $this->getSut(); From c95dd9b521be99cade64ea601b51a21c0b240291 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 15:23:03 +0200 Subject: [PATCH 18/21] OEVE-211 Remove outdated getThumbnailsGlob from ThumbnailResource Signed-off-by: Anton Fedurtsya --- src/Image/Service/ThumbnailResource.php | 5 ----- src/Image/Service/ThumbnailResourceInterface.php | 2 -- src/Image/Service/ThumbnailService.php | 4 +++- tests/Unit/Image/Service/ThumbnailResourceTest.php | 8 -------- tests/Unit/Image/Service/ThumbnailServiceTest.php | 6 +++++- 5 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/Image/Service/ThumbnailResource.php b/src/Image/Service/ThumbnailResource.php index 56ada3a..ba97e53 100644 --- a/src/Image/Service/ThumbnailResource.php +++ b/src/Image/Service/ThumbnailResource.php @@ -47,9 +47,4 @@ public function getUrlToThumbnailFiles(string $folderName = ''): string self::THUMBNAIL_DIRECTORY ); } - - public function getThumbnailsGlob(string $originalFilename): string - { - return $this->getThumbnailFileHash($originalFilename) . '*.*'; - } } diff --git a/src/Image/Service/ThumbnailResourceInterface.php b/src/Image/Service/ThumbnailResourceInterface.php index f726740..6679806 100644 --- a/src/Image/Service/ThumbnailResourceInterface.php +++ b/src/Image/Service/ThumbnailResourceInterface.php @@ -19,6 +19,4 @@ public function getDefaultThumbnailSize(): ImageSizeInterface; public function getPathToThumbnailFiles(string $folderName): string; public function getUrlToThumbnailFiles(string $folderName): string; - - public function getThumbnailsGlob(string $originalFilename): string; } diff --git a/src/Image/Service/ThumbnailService.php b/src/Image/Service/ThumbnailService.php index 1167a57..ea5cf59 100644 --- a/src/Image/Service/ThumbnailService.php +++ b/src/Image/Service/ThumbnailService.php @@ -27,9 +27,11 @@ public function __construct( public function deleteMediaThumbnails(MediaInterface $media): void { + $thumbnailGenerator = $this->thumbnailGeneratorAggregate->getSupportedGenerator($media->getFileName()); + $this->fileSystemService->deleteByGlob( inPath: $this->thumbnailResource->getPathToThumbnailFiles($media->getFolderName()), - globTargetToDelete: $this->thumbnailResource->getThumbnailsGlob($media->getFileName()) + globTargetToDelete: $thumbnailGenerator->getThumbnailsGlob($media->getFileName()) ); } diff --git a/tests/Unit/Image/Service/ThumbnailResourceTest.php b/tests/Unit/Image/Service/ThumbnailResourceTest.php index 7d53d96..c726e83 100644 --- a/tests/Unit/Image/Service/ThumbnailResourceTest.php +++ b/tests/Unit/Image/Service/ThumbnailResourceTest.php @@ -26,14 +26,6 @@ protected function getSut( ); } - public function testGetThumbnailsGlob(): void - { - $sut = $this->getSut(); - - $originalFilename = 'someExampleFilename.txt'; - $this->assertSame('8910f1d8c070ff09e13d4977fc339a29*.*', $sut->getThumbnailsGlob($originalFilename)); - } - public function testGetDefaultThumbnailSize(): void { $sut = $this->getSut(); diff --git a/tests/Unit/Image/Service/ThumbnailServiceTest.php b/tests/Unit/Image/Service/ThumbnailServiceTest.php index 429ece4..d601c36 100644 --- a/tests/Unit/Image/Service/ThumbnailServiceTest.php +++ b/tests/Unit/Image/Service/ThumbnailServiceTest.php @@ -28,6 +28,7 @@ public function testDeleteMediaThumbnailsTriggersFilesystemDeleteByGlob(): void $sut = $this->getSut( thumbnailResource: $thumbnailResourceStub = $this->createStub(ThumbnailResourceInterface::class), fileSystemService: $fileSystemServiceSpy = $this->createMock(FileSystemServiceInterface::class), + tgAgt: $thumbnailGeneratorAggregateStub = $this->createMock(ThumbnailGeneratorAggregateInterface::class), ); $mediaFileName = uniqid(); @@ -38,9 +39,12 @@ public function testDeleteMediaThumbnailsTriggersFilesystemDeleteByGlob(): void $thumbGlob = 'exampleThumbGlob'; $thumbPath = 'exampleThumbPath'; - $thumbnailResourceStub->method('getThumbnailsGlob')->with($mediaFileName)->willReturn($thumbGlob); $thumbnailResourceStub->method('getPathToThumbnailFiles')->with($mediaFolderName)->willReturn($thumbPath); + $thumbnailGeneratorStub = $this->createMock(ThumbnailGeneratorInterface::class); + $thumbnailGeneratorAggregateStub->method('getSupportedGenerator')->willReturn($thumbnailGeneratorStub); + $thumbnailGeneratorStub->method('getThumbnailsGlob')->with($mediaFileName)->willReturn($thumbGlob); + $fileSystemServiceSpy->expects($this->once())->method('deleteByGlob')->with($thumbPath, $thumbGlob); $sut->deleteMediaThumbnails($mediaStub); From af8bfd5953f71cb9f0071662f1e693569462ffef Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 15:26:20 +0200 Subject: [PATCH 19/21] OEVE-211 Remove unused getThumbnailFileHash leftover Signed-off-by: Anton Fedurtsya --- src/Image/Service/ThumbnailResource.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Image/Service/ThumbnailResource.php b/src/Image/Service/ThumbnailResource.php index ba97e53..934f003 100644 --- a/src/Image/Service/ThumbnailResource.php +++ b/src/Image/Service/ThumbnailResource.php @@ -22,11 +22,6 @@ public function __construct( ) { } - private function getThumbnailFileHash(string $originalFilename): string - { - return md5($originalFilename); - } - public function getDefaultThumbnailSize(): ImageSizeInterface { return new ImageSize(width: self::THUMBNAIL_DEFAULT_SIZE, height: self::THUMBNAIL_DEFAULT_SIZE); From 480f8aa137d5b38e36e3a0a813de5a380a1d0716 Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 15:26:34 +0200 Subject: [PATCH 20/21] OEVE-211 Fix coding standard issues Signed-off-by: Anton Fedurtsya --- src/Image/Exception/NoSupportedDriversForSource.php | 2 +- src/Image/Service/ThumbnailGeneratorAggregate.php | 2 +- src/Image/ThumbnailGenerator/DefaultDriver.php | 2 +- tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Image/Exception/NoSupportedDriversForSource.php b/src/Image/Exception/NoSupportedDriversForSource.php index 11c927e..7009b2b 100644 --- a/src/Image/Exception/NoSupportedDriversForSource.php +++ b/src/Image/Exception/NoSupportedDriversForSource.php @@ -11,4 +11,4 @@ class NoSupportedDriversForSource extends \Exception { -} \ No newline at end of file +} diff --git a/src/Image/Service/ThumbnailGeneratorAggregate.php b/src/Image/Service/ThumbnailGeneratorAggregate.php index 71e8ddd..68ca616 100644 --- a/src/Image/Service/ThumbnailGeneratorAggregate.php +++ b/src/Image/Service/ThumbnailGeneratorAggregate.php @@ -32,7 +32,7 @@ public function __construct( public function getSupportedGenerator(string $sourcePath): ThumbnailGeneratorInterface { - foreach($this->thumbnailGenerators as $oneDriver) { + foreach ($this->thumbnailGenerators as $oneDriver) { if ($oneDriver->isOriginSupported($sourcePath)) { return $oneDriver; } diff --git a/src/Image/ThumbnailGenerator/DefaultDriver.php b/src/Image/ThumbnailGenerator/DefaultDriver.php index d1b83d3..069cca2 100644 --- a/src/Image/ThumbnailGenerator/DefaultDriver.php +++ b/src/Image/ThumbnailGenerator/DefaultDriver.php @@ -38,4 +38,4 @@ public function getThumbnailsGlob(string $originalFilename): string { return 'default.jpg'; } -} \ No newline at end of file +} diff --git a/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php b/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php index 0778b06..c3798cf 100644 --- a/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php +++ b/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php @@ -45,4 +45,4 @@ public function testGetThumbnailsGlob(): void $sut->getThumbnailsGlob(uniqid()) ); } -} \ No newline at end of file +} From 0513b6a3d712b3bd19c7779230c0c2545b12c28d Mon Sep 17 00:00:00 2001 From: Anton Fedurtsya Date: Fri, 8 Mar 2024 17:24:07 +0200 Subject: [PATCH 21/21] OEVE-211 Add temporary solution for file types without thumbnails Signed-off-by: Anton Fedurtsya --- assets/out/src/img/default.svg | 1 + src/Image/ThumbnailGenerator/DefaultDriver.php | 5 +++-- tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 assets/out/src/img/default.svg diff --git a/assets/out/src/img/default.svg b/assets/out/src/img/default.svg new file mode 100644 index 0000000..512a476 --- /dev/null +++ b/assets/out/src/img/default.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Image/ThumbnailGenerator/DefaultDriver.php b/src/Image/ThumbnailGenerator/DefaultDriver.php index 069cca2..8a1f17f 100644 --- a/src/Image/ThumbnailGenerator/DefaultDriver.php +++ b/src/Image/ThumbnailGenerator/DefaultDriver.php @@ -24,6 +24,7 @@ public function generateThumbnail( ImageSizeInterface $thumbnailSize, bool $isCropRequired, ): void { + copy(__DIR__ . '/../../../assets/out/src/img/default.svg', $thumbnailPath); } public function getThumbnailFileName( @@ -31,11 +32,11 @@ public function getThumbnailFileName( ImageSizeInterface $thumbnailSize, bool $isCropRequired ): string { - return 'default.jpg'; + return 'default.svg'; } public function getThumbnailsGlob(string $originalFilename): string { - return 'default.jpg'; + return 'default.svg'; } } diff --git a/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php b/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php index c3798cf..908fdd4 100644 --- a/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php +++ b/tests/Unit/Image/ThumbnailGenerator/DefaultDriverTest.php @@ -28,7 +28,7 @@ public function testGetThumbnailFileNameReturnsDefaultValue(): void { $sut = new DefaultDriver(); $this->assertSame( - 'default.jpg', + 'default.svg', $sut->getThumbnailFileName( originalFileName: uniqid(), thumbnailSize: $this->createStub(ImageSizeInterface::class), @@ -41,7 +41,7 @@ public function testGetThumbnailsGlob(): void { $sut = new DefaultDriver(); $this->assertSame( - 'default.jpg', + 'default.svg', $sut->getThumbnailsGlob(uniqid()) ); }