Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent resizing an image if it was already resized before #26801

Merged
merged 3 commits into from
Apr 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
}
}