Skip to content

Commit c782080

Browse files
author
Oleksandr Iegorov
committed
Merge branch 'MAGETWO-99311-2' of https://github.com/magento-tango/magento2ce into MC-22998
2 parents 67fe58f + 557e8fa commit c782080

File tree

10 files changed

+379
-17
lines changed

10 files changed

+379
-17
lines changed

app/code/Magento/MediaStorage/Console/Command/ImagesResizeCommand.php

Lines changed: 125 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,39 @@
88
namespace Magento\MediaStorage\Console\Command;
99

1010
use Magento\Framework\App\Area;
11-
use Magento\Framework\App\ObjectManager;
1211
use Magento\Framework\App\State;
13-
use Magento\Framework\ObjectManagerInterface;
12+
use Magento\Framework\Console\Cli;
1413
use Magento\MediaStorage\Service\ImageResize;
14+
use Magento\MediaStorage\Service\ImageResizeScheduler;
1515
use Symfony\Component\Console\Helper\ProgressBar;
1616
use Symfony\Component\Console\Helper\ProgressBarFactory;
1717
use Symfony\Component\Console\Input\InputInterface;
1818
use Symfony\Component\Console\Output\OutputInterface;
19+
use Symfony\Component\Console\Input\InputOption;
20+
use Symfony\Component\Console\Command\Command;
21+
use Magento\Catalog\Model\ResourceModel\Product\Image as ProductImage;
1922

2023
/**
2124
* Resizes product images according to theme view definitions.
2225
*
2326
* @package Magento\MediaStorage\Console\Command
2427
*/
25-
class ImagesResizeCommand extends \Symfony\Component\Console\Command\Command
28+
class ImagesResizeCommand extends Command
2629
{
30+
/**
31+
* Asynchronous image resize mode
32+
*/
33+
const ASYNC_RESIZE = 'async';
34+
35+
/**
36+
* @var ImageResizeScheduler
37+
*/
38+
private $imageResizeScheduler;
39+
2740
/**
2841
* @var ImageResize
2942
*/
30-
private $resize;
43+
private $imageResize;
3144

3245
/**
3346
* @var State
@@ -39,24 +52,32 @@ class ImagesResizeCommand extends \Symfony\Component\Console\Command\Command
3952
*/
4053
private $progressBarFactory;
4154

55+
/**
56+
* @var ProductImage
57+
*/
58+
private $productImage;
59+
4260
/**
4361
* @param State $appState
44-
* @param ImageResize $resize
45-
* @param ObjectManagerInterface $objectManager
62+
* @param ImageResize $imageResize
63+
* @param ImageResizeScheduler $imageResizeScheduler
4664
* @param ProgressBarFactory $progressBarFactory
65+
* @param ProductImage $productImage
4766
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
4867
*/
4968
public function __construct(
5069
State $appState,
51-
ImageResize $resize,
52-
ObjectManagerInterface $objectManager,
53-
ProgressBarFactory $progressBarFactory = null
70+
ImageResize $imageResize,
71+
ImageResizeScheduler $imageResizeScheduler,
72+
ProgressBarFactory $progressBarFactory,
73+
ProductImage $productImage
5474
) {
5575
parent::__construct();
56-
$this->resize = $resize;
5776
$this->appState = $appState;
58-
$this->progressBarFactory = $progressBarFactory
59-
?: ObjectManager::getInstance()->get(ProgressBarFactory::class);
77+
$this->imageResize = $imageResize;
78+
$this->imageResizeScheduler = $imageResizeScheduler;
79+
$this->progressBarFactory = $progressBarFactory;
80+
$this->productImage = $productImage;
6081
}
6182

6283
/**
@@ -65,7 +86,25 @@ public function __construct(
6586
protected function configure()
6687
{
6788
$this->setName('catalog:images:resize')
68-
->setDescription('Creates resized product images');
89+
->setDescription('Creates resized product images')
90+
->setDefinition($this->getOptionsList());
91+
}
92+
93+
/**
94+
* Image resize command options list
95+
*
96+
* @return array
97+
*/
98+
private function getOptionsList() : array
99+
{
100+
return [
101+
new InputOption(
102+
self::ASYNC_RESIZE,
103+
'a',
104+
InputOption::VALUE_NONE,
105+
'Resize image in asynchronous mode'
106+
),
107+
];
69108
}
70109

71110
/**
@@ -74,11 +113,25 @@ protected function configure()
74113
* @param OutputInterface $output
75114
*/
76115
protected function execute(InputInterface $input, OutputInterface $output)
116+
{
117+
$result = $input->getOption(self::ASYNC_RESIZE) ?
118+
$this->executeAsync($output) : $this->executeSync($output);
119+
120+
return $result;
121+
}
122+
123+
/**
124+
* Run resize in synchronous mode
125+
*
126+
* @param OutputInterface $output
127+
* @return int
128+
*/
129+
private function executeSync(OutputInterface $output): int
77130
{
78131
try {
79132
$errors = [];
80133
$this->appState->setAreaCode(Area::AREA_GLOBAL);
81-
$generator = $this->resize->resizeFromThemes();
134+
$generator = $this->imageResize->resizeFromThemes();
82135

83136
/** @var ProgressBar $progress */
84137
$progress = $this->progressBarFactory->create(
@@ -111,7 +164,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
111164
} catch (\Exception $e) {
112165
$output->writeln("<error>{$e->getMessage()}</error>");
113166
// we must have an exit code higher than zero to indicate something was wrong
114-
return \Magento\Framework\Console\Cli::RETURN_FAILURE;
167+
return Cli::RETURN_FAILURE;
115168
}
116169

117170
$output->write(PHP_EOL);
@@ -124,6 +177,62 @@ protected function execute(InputInterface $input, OutputInterface $output)
124177
$output->writeln("<info>Product images resized successfully</info>");
125178
}
126179

127-
return \Magento\Framework\Console\Cli::RETURN_SUCCESS;
180+
return Cli::RETURN_SUCCESS;
181+
}
182+
183+
/**
184+
* Schedule asynchronous image resizing
185+
*
186+
* @param OutputInterface $output
187+
* @return int
188+
*/
189+
private function executeAsync(OutputInterface $output): int
190+
{
191+
try {
192+
$errors = [];
193+
$this->appState->setAreaCode(Area::AREA_GLOBAL);
194+
195+
/** @var ProgressBar $progress */
196+
$progress = $this->progressBarFactory->create(
197+
[
198+
'output' => $output,
199+
'max' => $this->productImage->getCountUsedProductImages()
200+
]
201+
);
202+
$progress->setFormat(
203+
"%current%/%max% [%bar%] %percent:3s%% %elapsed% %memory:6s% \t| <info>%message%</info>"
204+
);
205+
206+
if ($output->getVerbosity() !== OutputInterface::VERBOSITY_NORMAL) {
207+
$progress->setOverwrite(false);
208+
}
209+
210+
$productImages = $this->productImage->getUsedProductImages();
211+
foreach ($productImages as $image) {
212+
$result = $this->imageResizeScheduler->schedule($image['filepath']);
213+
214+
if (!$result) {
215+
$errors[$image['filepath']] = 'Error image scheduling: ' . $image['filepath'];
216+
}
217+
$progress->setMessage($image['filepath']);
218+
$progress->advance();
219+
}
220+
} catch (\Exception $e) {
221+
$output->writeln("<error>{$e->getMessage()}</error>");
222+
// we must have an exit code higher than zero to indicate something was wrong
223+
return Cli::RETURN_FAILURE;
224+
}
225+
226+
$output->write(PHP_EOL);
227+
if (count($errors)) {
228+
$output->writeln("<info>Product images resized with errors:</info>");
229+
foreach ($errors as $error) {
230+
$output->writeln("<error>{$error}</error>");
231+
}
232+
} else {
233+
$output->writeln("<info>Product images scheduled successfully</info>");
234+
}
235+
236+
return Cli::RETURN_SUCCESS;
128237
}
129238
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\MediaStorage\Model;
9+
10+
use Magento\AsynchronousOperations\Api\Data\OperationInterface;
11+
use Magento\Framework\Serialize\SerializerInterface;
12+
use Psr\Log\LoggerInterface;
13+
use Magento\MediaStorage\Service\ImageResize;
14+
use Magento\Framework\EntityManager\EntityManager;
15+
use Magento\Framework\Exception\NotFoundException;
16+
17+
/**
18+
* Consumer for image resize
19+
*/
20+
class ConsumerImageResize
21+
{
22+
/**
23+
* @var SerializerInterface
24+
*/
25+
private $serializer;
26+
27+
/**
28+
* @var LoggerInterface
29+
*/
30+
private $logger;
31+
32+
/**
33+
* @var ImageResize
34+
*/
35+
private $resize;
36+
37+
/**
38+
* @var EntityManager
39+
*/
40+
private $entityManager;
41+
42+
/**
43+
* @param ImageResize $resize
44+
* @param LoggerInterface $logger
45+
* @param SerializerInterface $serializer
46+
* @param EntityManager $entityManager
47+
*/
48+
public function __construct(
49+
ImageResize $resize,
50+
LoggerInterface $logger,
51+
SerializerInterface $serializer,
52+
EntityManager $entityManager
53+
) {
54+
$this->resize = $resize;
55+
$this->logger = $logger;
56+
$this->serializer = $serializer;
57+
$this->entityManager = $entityManager;
58+
}
59+
60+
/**
61+
* Image resize
62+
*
63+
* @param OperationInterface $operation
64+
* @return void
65+
* @throws \Exception
66+
*/
67+
public function process(OperationInterface $operation): void
68+
{
69+
try {
70+
$serializedData = $operation->getSerializedData();
71+
$data = $this->serializer->unserialize($serializedData);
72+
$this->resize->resizeFromImageName($data['filename']);
73+
} catch (NotFoundException $e) {
74+
$this->logger->critical($e->getMessage());
75+
$status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED;
76+
$errorCode = $e->getCode();
77+
$message = $e->getMessage();
78+
} catch (\Exception $e) {
79+
$this->logger->critical($e->getMessage());
80+
$status = OperationInterface::STATUS_TYPE_NOT_RETRIABLY_FAILED;
81+
$errorCode = $e->getCode();
82+
$message = __('Sorry, something went wrong during image resize. Please see log for details.');
83+
}
84+
85+
$operation->setStatus($status ?? OperationInterface::STATUS_TYPE_COMPLETE)
86+
->setErrorCode($errorCode ?? null)
87+
->setResultMessage($message ?? null);
88+
89+
$this->entityManager->save($operation);
90+
}
91+
}

0 commit comments

Comments
 (0)