Skip to content

Commit 88b200c

Browse files
ENGCOM-7234: Prevent resizing an image if it was already resized before #26801
- Merge Pull Request #26801 from hostep/magento2:fix-for-issue-26796 - Merged commits: 1. 38d1556 2. 801b4b3 3. 2d1a3c1
2 parents 176ba2b + 2d1a3c1 commit 88b200c

File tree

2 files changed

+120
-25
lines changed

2 files changed

+120
-25
lines changed

app/code/Magento/MediaStorage/Service/ImageResize.php

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,18 @@
1515
use Magento\Framework\App\ObjectManager;
1616
use Magento\Framework\Exception\NotFoundException;
1717
use Magento\Framework\Filesystem;
18+
use Magento\Framework\Filesystem\Directory\WriteInterface;
1819
use Magento\Framework\Image;
1920
use Magento\Framework\Image\Factory as ImageFactory;
2021
use Magento\Catalog\Model\Product\Media\ConfigInterface as MediaConfig;
2122
use Magento\Framework\App\State;
2223
use Magento\Framework\View\ConfigInterface as ViewConfig;
23-
use \Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage;
24+
use Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage;
2425
use Magento\Store\Model\StoreManagerInterface;
2526
use Magento\Theme\Model\Config\Customization as ThemeCustomizationConfig;
26-
use Magento\Theme\Model\ResourceModel\Theme\Collection;
27+
use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollection;
2728
use Magento\Framework\App\Filesystem\DirectoryList;
28-
use Magento\MediaStorage\Helper\File\Storage\Database;
29+
use Magento\MediaStorage\Helper\File\Storage\Database as FileStorageDatabase;
2930
use Magento\Theme\Model\Theme;
3031

3132
/**
@@ -76,24 +77,20 @@ class ImageResize
7677
private $themeCustomizationConfig;
7778

7879
/**
79-
* @var Collection
80+
* @var ThemeCollection
8081
*/
8182
private $themeCollection;
8283

8384
/**
84-
* @var Filesystem
85+
* @var WriteInterface
8586
*/
8687
private $mediaDirectory;
8788

8889
/**
89-
* @var Filesystem
90-
*/
91-
private $filesystem;
92-
93-
/**
94-
* @var Database
90+
* @var FileStorageDatabase
9591
*/
9692
private $fileStorageDatabase;
93+
9794
/**
9895
* @var StoreManagerInterface
9996
*/
@@ -108,9 +105,9 @@ class ImageResize
108105
* @param ViewConfig $viewConfig
109106
* @param AssertImageFactory $assertImageFactory
110107
* @param ThemeCustomizationConfig $themeCustomizationConfig
111-
* @param Collection $themeCollection
108+
* @param ThemeCollection $themeCollection
112109
* @param Filesystem $filesystem
113-
* @param Database $fileStorageDatabase
110+
* @param FileStorageDatabase $fileStorageDatabase
114111
* @param StoreManagerInterface $storeManager
115112
* @throws \Magento\Framework\Exception\FileSystemException
116113
* @internal param ProductImage $gallery
@@ -125,9 +122,9 @@ public function __construct(
125122
ViewConfig $viewConfig,
126123
AssertImageFactory $assertImageFactory,
127124
ThemeCustomizationConfig $themeCustomizationConfig,
128-
Collection $themeCollection,
125+
ThemeCollection $themeCollection,
129126
Filesystem $filesystem,
130-
Database $fileStorageDatabase = null,
127+
FileStorageDatabase $fileStorageDatabase = null,
131128
StoreManagerInterface $storeManager = null
132129
) {
133130
$this->appState = $appState;
@@ -140,9 +137,8 @@ public function __construct(
140137
$this->themeCustomizationConfig = $themeCustomizationConfig;
141138
$this->themeCollection = $themeCollection;
142139
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
143-
$this->filesystem = $filesystem;
144140
$this->fileStorageDatabase = $fileStorageDatabase ?:
145-
ObjectManager::getInstance()->get(Database::class);
141+
ObjectManager::getInstance()->get(FileStorageDatabase::class);
146142
$this->storeManager = $storeManager ?? ObjectManager::getInstance()->get(StoreManagerInterface::class);
147143
}
148144

@@ -294,7 +290,7 @@ private function makeImage(string $originalImagePath, array $imageParams): Image
294290
}
295291

296292
/**
297-
* Resize image.
293+
* Resize image if not already resized before
298294
*
299295
* @param array $imageParams
300296
* @param string $originalImagePath
@@ -303,13 +299,48 @@ private function makeImage(string $originalImagePath, array $imageParams): Image
303299
private function resize(array $imageParams, string $originalImagePath, string $originalImageName)
304300
{
305301
unset($imageParams['id']);
306-
$image = $this->makeImage($originalImagePath, $imageParams);
307302
$imageAsset = $this->assertImageFactory->create(
308303
[
309304
'miscParams' => $imageParams,
310305
'filePath' => $originalImageName,
311306
]
312307
);
308+
$imageAssetPath = $imageAsset->getPath();
309+
$usingDbAsStorage = $this->fileStorageDatabase->checkDbUsage();
310+
$mediaStorageFilename = $this->mediaDirectory->getRelativePath($imageAssetPath);
311+
312+
$alreadyResized = $usingDbAsStorage ?
313+
$this->fileStorageDatabase->fileExists($mediaStorageFilename) :
314+
$this->mediaDirectory->isFile($imageAssetPath);
315+
316+
if (!$alreadyResized) {
317+
$this->generateResizedImage(
318+
$imageParams,
319+
$originalImagePath,
320+
$imageAssetPath,
321+
$usingDbAsStorage,
322+
$mediaStorageFilename
323+
);
324+
}
325+
}
326+
327+
/**
328+
* Generate resized image
329+
*
330+
* @param array $imageParams
331+
* @param string $originalImagePath
332+
* @param string $imageAssetPath
333+
* @param bool $usingDbAsStorage
334+
* @param string $mediaStorageFilename
335+
*/
336+
private function generateResizedImage(
337+
array $imageParams,
338+
string $originalImagePath,
339+
string $imageAssetPath,
340+
bool $usingDbAsStorage,
341+
string $mediaStorageFilename
342+
) {
343+
$image = $this->makeImage($originalImagePath, $imageParams);
313344

314345
if ($imageParams['image_width'] !== null && $imageParams['image_height'] !== null) {
315346
$image->resize($imageParams['image_width'], $imageParams['image_height']);
@@ -335,11 +366,10 @@ private function resize(array $imageParams, string $originalImagePath, string $o
335366
$image->watermark($this->getWatermarkFilePath($imageParams['watermark_file']));
336367
}
337368

338-
$image->save($imageAsset->getPath());
369+
$image->save($imageAssetPath);
339370

340-
if ($this->fileStorageDatabase->checkDbUsage()) {
341-
$mediastoragefilename = $this->mediaDirectory->getRelativePath($imageAsset->getPath());
342-
$this->fileStorageDatabase->saveFile($mediastoragefilename);
371+
if ($usingDbAsStorage) {
372+
$this->fileStorageDatabase->saveFile($mediaStorageFilename);
343373
}
344374
}
345375

app/code/Magento/MediaStorage/Test/Unit/Service/ImageResizeTest.php

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
use Magento\Framework\App\Filesystem\DirectoryList;
2525

2626
/**
27-
* Class ImageResizeTest
28-
*
2927
* @SuppressWarnings(PHPMD.TooManyFields)
3028
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
3129
*/
@@ -249,6 +247,9 @@ public function testResizeFromThemesMediaStorageDatabase()
249247
$this->databaseMock->expects($this->any())
250248
->method('checkDbUsage')
251249
->will($this->returnValue(true));
250+
$this->databaseMock->expects($this->any())
251+
->method('fileExists')
252+
->will($this->returnValue(false));
252253

253254
$this->productImageMock->expects($this->any())
254255
->method('getCountUsedProductImages')
@@ -289,6 +290,9 @@ public function testResizeFromImageNameMediaStorageDatabase()
289290
$this->databaseMock->expects($this->any())
290291
->method('checkDbUsage')
291292
->will($this->returnValue(true));
293+
$this->databaseMock->expects($this->any())
294+
->method('fileExists')
295+
->will($this->returnValue(false));
292296

293297
$this->mediaDirectoryMock->expects($this->any())
294298
->method('isFile')
@@ -318,4 +322,65 @@ public function testResizeFromImageNameMediaStorageDatabase()
318322

319323
$this->service->resizeFromImageName($this->testfilename);
320324
}
325+
326+
public function testSkipResizingAlreadyResizedImageOnDisk()
327+
{
328+
$this->databaseMock->expects($this->any())
329+
->method('checkDbUsage')
330+
->will($this->returnValue(false));
331+
332+
$this->mediaDirectoryMock->expects($this->any())
333+
->method('isFile')
334+
->will($this->returnValue(true));
335+
336+
$this->themeCollectionMock->expects($this->any())
337+
->method('loadRegisteredThemes')
338+
->willReturn(
339+
[ new DataObject(['id' => '0']) ]
340+
);
341+
$this->themeCustomizationConfigMock->expects($this->any())
342+
->method('getStoresByThemes')
343+
->willReturn(
344+
['0' => []]
345+
);
346+
347+
$this->imageFactoryMock->expects($this->never())
348+
->method('create');
349+
350+
$this->service->resizeFromImageName($this->testfilename);
351+
}
352+
353+
public function testSkipResizingAlreadyResizedImageInDatabase()
354+
{
355+
$this->databaseMock->expects($this->any())
356+
->method('checkDbUsage')
357+
->will($this->returnValue(true));
358+
$this->databaseMock->expects($this->any())
359+
->method('fileExists')
360+
->will($this->returnValue(true));
361+
362+
$this->mediaDirectoryMock->expects($this->any())
363+
->method('isFile')
364+
->with($this->testfilepath)
365+
->willReturnOnConsecutiveCalls(
366+
$this->returnValue(false),
367+
$this->returnValue(true)
368+
);
369+
370+
$this->themeCollectionMock->expects($this->any())
371+
->method('loadRegisteredThemes')
372+
->willReturn(
373+
[ new DataObject(['id' => '0']) ]
374+
);
375+
$this->themeCustomizationConfigMock->expects($this->any())
376+
->method('getStoresByThemes')
377+
->willReturn(
378+
['0' => []]
379+
);
380+
381+
$this->databaseMock->expects($this->never())
382+
->method('saveFile');
383+
384+
$this->service->resizeFromImageName($this->testfilename);
385+
}
321386
}

0 commit comments

Comments
 (0)