Skip to content

Commit

Permalink
ENGCOM-7234: Prevent resizing an image if it was already resized before
Browse files Browse the repository at this point in the history
  • Loading branch information
slavvka authored Apr 3, 2020
2 parents 1aca84b + 88b200c commit 3170d3a
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 25 deletions.
76 changes: 53 additions & 23 deletions app/code/Magento/MediaStorage/Service/ImageResize.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,18 @@
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\NotFoundException;
use Magento\Framework\Filesystem;
use Magento\Framework\Filesystem\Directory\WriteInterface;
use Magento\Framework\Image;
use Magento\Framework\Image\Factory as ImageFactory;
use Magento\Catalog\Model\Product\Media\ConfigInterface as MediaConfig;
use Magento\Framework\App\State;
use Magento\Framework\View\ConfigInterface as ViewConfig;
use \Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage;
use Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Theme\Model\Config\Customization as ThemeCustomizationConfig;
use Magento\Theme\Model\ResourceModel\Theme\Collection;
use Magento\Theme\Model\ResourceModel\Theme\Collection as ThemeCollection;
use Magento\Framework\App\Filesystem\DirectoryList;
use Magento\MediaStorage\Helper\File\Storage\Database;
use Magento\MediaStorage\Helper\File\Storage\Database as FileStorageDatabase;
use Magento\Theme\Model\Theme;

/**
Expand Down Expand Up @@ -76,24 +77,20 @@ class ImageResize
private $themeCustomizationConfig;

/**
* @var Collection
* @var ThemeCollection
*/
private $themeCollection;

/**
* @var Filesystem
* @var WriteInterface
*/
private $mediaDirectory;

/**
* @var Filesystem
*/
private $filesystem;

/**
* @var Database
* @var FileStorageDatabase
*/
private $fileStorageDatabase;

/**
* @var StoreManagerInterface
*/
Expand All @@ -108,9 +105,9 @@ class ImageResize
* @param ViewConfig $viewConfig
* @param AssertImageFactory $assertImageFactory
* @param ThemeCustomizationConfig $themeCustomizationConfig
* @param Collection $themeCollection
* @param ThemeCollection $themeCollection
* @param Filesystem $filesystem
* @param Database $fileStorageDatabase
* @param FileStorageDatabase $fileStorageDatabase
* @param StoreManagerInterface $storeManager
* @throws \Magento\Framework\Exception\FileSystemException
* @internal param ProductImage $gallery
Expand All @@ -125,9 +122,9 @@ public function __construct(
ViewConfig $viewConfig,
AssertImageFactory $assertImageFactory,
ThemeCustomizationConfig $themeCustomizationConfig,
Collection $themeCollection,
ThemeCollection $themeCollection,
Filesystem $filesystem,
Database $fileStorageDatabase = null,
FileStorageDatabase $fileStorageDatabase = null,
StoreManagerInterface $storeManager = null
) {
$this->appState = $appState;
Expand All @@ -140,9 +137,8 @@ public function __construct(
$this->themeCustomizationConfig = $themeCustomizationConfig;
$this->themeCollection = $themeCollection;
$this->mediaDirectory = $filesystem->getDirectoryWrite(DirectoryList::MEDIA);
$this->filesystem = $filesystem;
$this->fileStorageDatabase = $fileStorageDatabase ?:
ObjectManager::getInstance()->get(Database::class);
ObjectManager::getInstance()->get(FileStorageDatabase::class);
$this->storeManager = $storeManager ?? ObjectManager::getInstance()->get(StoreManagerInterface::class);
}

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

/**
* Resize image.
* Resize image if not already resized before
*
* @param array $imageParams
* @param string $originalImagePath
Expand All @@ -303,13 +299,48 @@ private function makeImage(string $originalImagePath, array $imageParams): Image
private function resize(array $imageParams, string $originalImagePath, string $originalImageName)
{
unset($imageParams['id']);
$image = $this->makeImage($originalImagePath, $imageParams);
$imageAsset = $this->assertImageFactory->create(
[
'miscParams' => $imageParams,
'filePath' => $originalImageName,
]
);
$imageAssetPath = $imageAsset->getPath();
$usingDbAsStorage = $this->fileStorageDatabase->checkDbUsage();
$mediaStorageFilename = $this->mediaDirectory->getRelativePath($imageAssetPath);

$alreadyResized = $usingDbAsStorage ?
$this->fileStorageDatabase->fileExists($mediaStorageFilename) :
$this->mediaDirectory->isFile($imageAssetPath);

if (!$alreadyResized) {
$this->generateResizedImage(
$imageParams,
$originalImagePath,
$imageAssetPath,
$usingDbAsStorage,
$mediaStorageFilename
);
}
}

/**
* Generate resized image
*
* @param array $imageParams
* @param string $originalImagePath
* @param string $imageAssetPath
* @param bool $usingDbAsStorage
* @param string $mediaStorageFilename
*/
private function generateResizedImage(
array $imageParams,
string $originalImagePath,
string $imageAssetPath,
bool $usingDbAsStorage,
string $mediaStorageFilename
) {
$image = $this->makeImage($originalImagePath, $imageParams);

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

$image->save($imageAsset->getPath());
$image->save($imageAssetPath);

if ($this->fileStorageDatabase->checkDbUsage()) {
$mediastoragefilename = $this->mediaDirectory->getRelativePath($imageAsset->getPath());
$this->fileStorageDatabase->saveFile($mediastoragefilename);
if ($usingDbAsStorage) {
$this->fileStorageDatabase->saveFile($mediaStorageFilename);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
use Magento\Framework\App\Filesystem\DirectoryList;

/**
* Class ImageResizeTest
*
* @SuppressWarnings(PHPMD.TooManyFields)
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
Expand Down Expand Up @@ -249,6 +247,9 @@ public function testResizeFromThemesMediaStorageDatabase()
$this->databaseMock->expects($this->any())
->method('checkDbUsage')
->will($this->returnValue(true));
$this->databaseMock->expects($this->any())
->method('fileExists')
->will($this->returnValue(false));

$this->productImageMock->expects($this->any())
->method('getCountUsedProductImages')
Expand Down Expand Up @@ -289,6 +290,9 @@ public function testResizeFromImageNameMediaStorageDatabase()
$this->databaseMock->expects($this->any())
->method('checkDbUsage')
->will($this->returnValue(true));
$this->databaseMock->expects($this->any())
->method('fileExists')
->will($this->returnValue(false));

$this->mediaDirectoryMock->expects($this->any())
->method('isFile')
Expand Down Expand Up @@ -318,4 +322,65 @@ public function testResizeFromImageNameMediaStorageDatabase()

$this->service->resizeFromImageName($this->testfilename);
}

public function testSkipResizingAlreadyResizedImageOnDisk()
{
$this->databaseMock->expects($this->any())
->method('checkDbUsage')
->will($this->returnValue(false));

$this->mediaDirectoryMock->expects($this->any())
->method('isFile')
->will($this->returnValue(true));

$this->themeCollectionMock->expects($this->any())
->method('loadRegisteredThemes')
->willReturn(
[ new DataObject(['id' => '0']) ]
);
$this->themeCustomizationConfigMock->expects($this->any())
->method('getStoresByThemes')
->willReturn(
['0' => []]
);

$this->imageFactoryMock->expects($this->never())
->method('create');

$this->service->resizeFromImageName($this->testfilename);
}

public function testSkipResizingAlreadyResizedImageInDatabase()
{
$this->databaseMock->expects($this->any())
->method('checkDbUsage')
->will($this->returnValue(true));
$this->databaseMock->expects($this->any())
->method('fileExists')
->will($this->returnValue(true));

$this->mediaDirectoryMock->expects($this->any())
->method('isFile')
->with($this->testfilepath)
->willReturnOnConsecutiveCalls(
$this->returnValue(false),
$this->returnValue(true)
);

$this->themeCollectionMock->expects($this->any())
->method('loadRegisteredThemes')
->willReturn(
[ new DataObject(['id' => '0']) ]
);
$this->themeCustomizationConfigMock->expects($this->any())
->method('getStoresByThemes')
->willReturn(
['0' => []]
);

$this->databaseMock->expects($this->never())
->method('saveFile');

$this->service->resizeFromImageName($this->testfilename);
}
}

0 comments on commit 3170d3a

Please sign in to comment.