Skip to content

magento/magento2#28239: resize command does not process hidden images #33452

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

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Command\Command;
use Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage;


/**
* Resizes product images according to theme view definitions.
Expand All @@ -30,6 +30,11 @@ class ImagesResizeCommand extends Command
*/
const ASYNC_RESIZE = 'async';

/**
* Do not process images marked as hidden from product page
*/
const SKIP_HIDDEN_IMAGES = 'skip_hidden_images';

/**
* @var ImageResizeScheduler
*/
Expand All @@ -51,31 +56,28 @@ class ImagesResizeCommand extends Command
private $progressBarFactory;

/**
* @var ProductImage
* @var bool
*/
private $productImage;
private $skipHiddenImages = false;

/**
* @param State $appState
* @param ImageResize $imageResize
* @param ImageResizeScheduler $imageResizeScheduler
* @param ProgressBarFactory $progressBarFactory
* @param ProductImage $productImage
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function __construct(
State $appState,
ImageResize $imageResize,
ImageResizeScheduler $imageResizeScheduler,
ProgressBarFactory $progressBarFactory,
ProductImage $productImage
ProgressBarFactory $progressBarFactory
) {
parent::__construct();
$this->appState = $appState;
$this->imageResize = $imageResize;
$this->imageResizeScheduler = $imageResizeScheduler;
$this->progressBarFactory = $progressBarFactory;
$this->productImage = $productImage;
}

/**
Expand All @@ -102,6 +104,12 @@ private function getOptionsList() : array
InputOption::VALUE_NONE,
'Resize image in asynchronous mode'
),
new InputOption(
self::SKIP_HIDDEN_IMAGES,
null,
InputOption::VALUE_NONE,
'Do not process images marked as hidden from product page'
),
];
}

Expand All @@ -112,6 +120,7 @@ private function getOptionsList() : array
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$this->skipHiddenImages = $input->getOption(self::SKIP_HIDDEN_IMAGES);
$result = $input->getOption(self::ASYNC_RESIZE) ?
$this->executeAsync($output) : $this->executeSync($output);

Expand All @@ -129,7 +138,7 @@ private function executeSync(OutputInterface $output): int
try {
$errors = [];
$this->appState->setAreaCode(Area::AREA_GLOBAL);
$generator = $this->imageResize->resizeFromThemes();
$generator = $this->imageResize->resizeFromThemes(null, $this->skipHiddenImages);

/** @var ProgressBar $progress */
$progress = $this->progressBarFactory->create(
Expand Down Expand Up @@ -194,7 +203,7 @@ private function executeAsync(OutputInterface $output): int
$progress = $this->progressBarFactory->create(
[
'output' => $output,
'max' => $this->productImage->getCountUsedProductImages()
'max' => $this->imageResize->getCountProductImages($this->skipHiddenImages)
]
);
$progress->setFormat(
Expand All @@ -205,7 +214,7 @@ private function executeAsync(OutputInterface $output): int
$progress->setOverwrite(false);
}

$productImages = $this->productImage->getUsedProductImages();
$productImages = $this->imageResize->getProductImages($this->skipHiddenImages);
foreach ($productImages as $image) {
$result = $this->imageResizeScheduler->schedule($image['filepath']);

Expand Down
27 changes: 24 additions & 3 deletions app/code/Magento/MediaStorage/Service/ImageResize.php
Original file line number Diff line number Diff line change
Expand Up @@ -171,17 +171,18 @@ public function resizeFromImageName(string $originalImageName)
* Create resized images of different sizes from themes.
*
* @param array|null $themes
* @param bool $skipHiddenImages
* @return Generator
* @throws NotFoundException
*/
public function resizeFromThemes(array $themes = null): Generator
public function resizeFromThemes(array $themes = null, bool $skipHiddenImages = false): Generator
{
$count = $this->productImage->getCountUsedProductImages();
$count = $this->getCountProductImages($skipHiddenImages);
if (!$count) {
throw new NotFoundException(__('Cannot resize images - product images not found'));
}

$productImages = $this->productImage->getUsedProductImages();
$productImages = $this->getProductImages($skipHiddenImages);
$viewImages = $this->getViewImages($themes ?? $this->getThemesInUse());

foreach ($productImages as $image) {
Expand Down Expand Up @@ -210,6 +211,26 @@ public function resizeFromThemes(array $themes = null): Generator
}
}

/**
* @param bool $skipHiddenImages
* @return int
*/
public function getCountProductImages(bool $skipHiddenImages = false): int
{
return $skipHiddenImages ?
$this->productImage->getCountUsedProductImages() : $this->productImage->getCountAllProductImages();
}

/**
* @param bool $skipHiddenImages
* @return Generator
*/
public function getProductImages(bool $skipHiddenImages = false): \Generator
{
return $skipHiddenImages ?
$this->productImage->getUsedProductImages() : $this->productImage->getAllProductImages();
}

/**
* Search the current theme.
*
Expand Down
114 changes: 97 additions & 17 deletions app/code/Magento/MediaStorage/Test/Unit/Service/ImageResizeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,33 @@ class ImageResizeTest extends TestCase
* @var string
*/
private $testfilepath;

/**
* @var string
*/
private $testImageHiddenFilename;

/**
* @var MockObject|StoreManagerInterface
*/
private $storeManager;

/**
* @var string
*/
private $testImageHiddenfilepath;

/**
* @inheritDoc
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function setUp(): void
{
$this->testfilename = "image.jpg";
$this->testImageHiddenFilename = "image_hidden.jpg";
$this->testfilepath = "/image.jpg";
$this->testImageHiddenfilepath = "/image_hidden.jpg";


$this->appStateMock = $this->createMock(State::class);
$this->imageConfigMock = $this->createMock(MediaConfig::class);
Expand Down Expand Up @@ -160,7 +174,7 @@ protected function setUp(): void

$this->assetImageMock->expects($this->any())
->method('getPath')
->willReturn($this->testfilepath);
->willReturnOnConsecutiveCalls($this->testfilepath, $this->testImageHiddenfilepath);
$this->assetImageFactoryMock->expects($this->any())
->method('create')
->willReturn($this->assetImageMock);
Expand All @@ -182,16 +196,15 @@ protected function setUp(): void

$this->imageConfigMock->expects($this->any())
->method('getMediaPath')
->with($this->testfilename)
->willReturn($this->testfilepath);
->withConsecutive([$this->testfilename], [$this->testImageHiddenFilename])
->willReturnOnConsecutiveCalls($this->testfilepath, $this->testImageHiddenfilepath);
$this->mediaDirectoryMock->expects($this->any())
->method('getAbsolutePath')
->with($this->testfilepath)
->willReturn($this->testfilepath);
->withConsecutive([$this->testfilepath], [$this->testImageHiddenfilepath])
->willReturnOnConsecutiveCalls($this->testfilepath, $this->testImageHiddenfilepath);
$this->mediaDirectoryMock->expects($this->any())
->method('getRelativePath')
->with($this->testfilepath)
->willReturn($this->testfilepath);
->willReturnOnConsecutiveCalls($this->testfilepath, $this->testImageHiddenfilepath);

$this->viewMock->expects($this->any())
->method('getMediaEntities')
Expand Down Expand Up @@ -248,7 +261,7 @@ public function testResizeFromThemesMediaStorageDatabase()
->willReturn(false);

$imageMock = $this->createMock(Image::class);
$this->imageFactoryMock->expects($this->once())
$this->imageFactoryMock->expects($this->any())
->method('create')
->willReturn($imageMock);

Expand All @@ -268,17 +281,17 @@ function () {

$this->mediaDirectoryMock->expects($this->any())
->method('isFile')
->with($this->testfilepath)
->withConsecutive([$this->testfilepath], [$this->testImageHiddenfilepath])
->willReturn(true);

$this->databaseMock->expects($this->once())
$this->databaseMock->expects($this->any())
->method('saveFileToFilesystem')
->with($this->testfilepath);
$this->databaseMock->expects($this->once())
->withConsecutive([$this->testfilepath], [$this->testImageHiddenfilepath]);
$this->databaseMock->expects($this->any())
->method('saveFile')
->with($this->testfilepath);
->withConsecutive([$this->testfilepath], [$this->testImageHiddenfilepath]);

$generator = $this->service->resizeFromThemes(['test-theme']);
$generator = $this->service->resizeFromThemes(['test-theme'], true);
while ($generator->valid()) {
$resizeInfo = $generator->key();
$this->assertEquals('image.jpg', $resizeInfo['filename']);
Expand All @@ -287,6 +300,73 @@ function () {
}
}

public function testResizeFromThemesHiddenImagesMediaStorageDatabase()
{
$this->databaseMock->expects($this->any())
->method('checkDbUsage')
->willReturn(true);
$this->databaseMock->expects($this->any())
->method('fileExists')
->willReturn(false);

$imageMock = $this->createMock(Image::class);
$this->imageFactoryMock->expects($this->any())
->method('create')
->willReturn($imageMock);

$this->productImageMock->expects($this->any())
->method('getCountUsedProductImages')
->willReturn(1);
$this->productImageMock->expects($this->any())
->method('getUsedProductImages')
->willReturnCallback(
function () {
$data = [[ 'filepath' => $this->testfilename ]];
foreach ($data as $e) {
yield $e;
}
}
);

$this->productImageMock->expects($this->any())
->method('getCountAllProductImages')
->willReturn(2);
$this->productImageMock->expects($this->any())
->method('getAllProductImages')
->willReturnCallback(
function () {
$data = [[ 'filepath' => $this->testfilename ], [ 'filepath' => $this->testImageHiddenFilename ]];
foreach ($data as $e) {
yield $e;
}
}
);

$this->mediaDirectoryMock->expects($this->any())
->method('isFile')
->withConsecutive([$this->testfilepath], [$this->testImageHiddenfilepath])
->willReturn(true);

$this->databaseMock->expects($this->any())
->method('saveFileToFilesystem')
->withConsecutive([$this->testfilepath], [$this->testImageHiddenfilepath]);
$this->databaseMock->expects($this->any())
->method('saveFile')
->withConsecutive([$this->testfilepath], [$this->testImageHiddenfilepath]);

$this->assertEquals(2, $this->service->getCountProductImages());
$this->assertEquals(1, $this->service->getCountProductImages(true));

$generator = $this->service->resizeFromThemes(['test-theme']);
while ($generator->valid()) {
$resizeInfo = $generator->key();
$this->assertContains($resizeInfo['filename'], [$this->testfilename, $this->testImageHiddenFilename]);
$this->assertEmpty($resizeInfo['error']);
$generator->next();
}

}

public function testResizeFromThemesUnsupportedImage()
{
$this->databaseMock->expects($this->any())
Expand All @@ -296,7 +376,7 @@ public function testResizeFromThemesUnsupportedImage()
->method('fileExists')
->willReturn(false);

$this->imageFactoryMock->expects($this->once())
$this->imageFactoryMock->expects($this->any())
->method('create')
->willThrowException(new \InvalidArgumentException('Unsupported image format.'));

Expand All @@ -316,10 +396,10 @@ function () {

$this->mediaDirectoryMock->expects($this->any())
->method('isFile')
->with($this->testfilepath)
->withConsecutive([$this->testfilepath], [$this->testImageHiddenfilepath])
->willReturn(true);

$generator = $this->service->resizeFromThemes(['test-theme']);
$generator = $this->service->resizeFromThemes(['test-theme'], true);
while ($generator->valid()) {
$resizeInfo = $generator->key();
$this->assertEquals('Unsupported image format.', $resizeInfo['error']);
Expand Down