88namespace Magento \MediaStorage \Console \Command ;
99
1010use Magento \Framework \App \Area ;
11- use Magento \Framework \App \ObjectManager ;
1211use Magento \Framework \App \State ;
13- use Magento \Framework \ObjectManagerInterface ;
12+ use Magento \Framework \Console \ Cli ;
1413use Magento \MediaStorage \Service \ImageResize ;
14+ use Magento \MediaStorage \Service \ImageResizeScheduler ;
1515use Symfony \Component \Console \Helper \ProgressBar ;
1616use Symfony \Component \Console \Helper \ProgressBarFactory ;
1717use Symfony \Component \Console \Input \InputInterface ;
1818use 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.
22- *
23- * @package Magento\MediaStorage\Console\Command
2425 */
25- class ImagesResizeCommand extends \ Symfony \ Component \ Console \ Command \ Command
26+ class ImagesResizeCommand extends Command
2627{
28+ /**
29+ * Asynchronous image resize mode
30+ */
31+ const ASYNC_RESIZE = 'async ' ;
32+
33+ /**
34+ * @var ImageResizeScheduler
35+ */
36+ private $ imageResizeScheduler ;
37+
2738 /**
2839 * @var ImageResize
2940 */
30- private $ resize ;
41+ private $ imageResize ;
3142
3243 /**
3344 * @var State
@@ -39,24 +50,32 @@ class ImagesResizeCommand extends \Symfony\Component\Console\Command\Command
3950 */
4051 private $ progressBarFactory ;
4152
53+ /**
54+ * @var ProductImage
55+ */
56+ private $ productImage ;
57+
4258 /**
4359 * @param State $appState
44- * @param ImageResize $resize
45- * @param ObjectManagerInterface $objectManager
60+ * @param ImageResize $imageResize
61+ * @param ImageResizeScheduler $imageResizeScheduler
4662 * @param ProgressBarFactory $progressBarFactory
63+ * @param ProductImage $productImage
4764 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
4865 */
4966 public function __construct (
5067 State $ appState ,
51- ImageResize $ resize ,
52- ObjectManagerInterface $ objectManager ,
53- ProgressBarFactory $ progressBarFactory = null
68+ ImageResize $ imageResize ,
69+ ImageResizeScheduler $ imageResizeScheduler ,
70+ ProgressBarFactory $ progressBarFactory ,
71+ ProductImage $ productImage
5472 ) {
5573 parent ::__construct ();
56- $ this ->resize = $ resize ;
5774 $ this ->appState = $ appState ;
58- $ this ->progressBarFactory = $ progressBarFactory
59- ?: ObjectManager::getInstance ()->get (ProgressBarFactory::class);
75+ $ this ->imageResize = $ imageResize ;
76+ $ this ->imageResizeScheduler = $ imageResizeScheduler ;
77+ $ this ->progressBarFactory = $ progressBarFactory ;
78+ $ this ->productImage = $ productImage ;
6079 }
6180
6281 /**
@@ -65,7 +84,25 @@ public function __construct(
6584 protected function configure ()
6685 {
6786 $ this ->setName ('catalog:images:resize ' )
68- ->setDescription ('Creates resized product images ' );
87+ ->setDescription ('Creates resized product images ' )
88+ ->setDefinition ($ this ->getOptionsList ());
89+ }
90+
91+ /**
92+ * Image resize command options list
93+ *
94+ * @return array
95+ */
96+ private function getOptionsList () : array
97+ {
98+ return [
99+ new InputOption (
100+ self ::ASYNC_RESIZE ,
101+ 'a ' ,
102+ InputOption::VALUE_NONE ,
103+ 'Resize image in asynchronous mode '
104+ ),
105+ ];
69106 }
70107
71108 /**
@@ -74,11 +111,25 @@ protected function configure()
74111 * @param OutputInterface $output
75112 */
76113 protected function execute (InputInterface $ input , OutputInterface $ output )
114+ {
115+ $ result = $ input ->getOption (self ::ASYNC_RESIZE ) ?
116+ $ this ->executeAsync ($ output ) : $ this ->executeSync ($ output );
117+
118+ return $ result ;
119+ }
120+
121+ /**
122+ * Run resize in synchronous mode
123+ *
124+ * @param OutputInterface $output
125+ * @return int
126+ */
127+ private function executeSync (OutputInterface $ output ): int
77128 {
78129 try {
79130 $ errors = [];
80131 $ this ->appState ->setAreaCode (Area::AREA_GLOBAL );
81- $ generator = $ this ->resize ->resizeFromThemes ();
132+ $ generator = $ this ->imageResize ->resizeFromThemes ();
82133
83134 /** @var ProgressBar $progress */
84135 $ progress = $ this ->progressBarFactory ->create (
@@ -111,7 +162,7 @@ protected function execute(InputInterface $input, OutputInterface $output)
111162 } catch (\Exception $ e ) {
112163 $ output ->writeln ("<error> {$ e ->getMessage ()}</error> " );
113164 // we must have an exit code higher than zero to indicate something was wrong
114- return \ Magento \ Framework \ Console \ Cli::RETURN_FAILURE ;
165+ return Cli::RETURN_FAILURE ;
115166 }
116167
117168 $ output ->write (PHP_EOL );
@@ -124,6 +175,62 @@ protected function execute(InputInterface $input, OutputInterface $output)
124175 $ output ->writeln ("<info>Product images resized successfully</info> " );
125176 }
126177
127- return \Magento \Framework \Console \Cli::RETURN_SUCCESS ;
178+ return Cli::RETURN_SUCCESS ;
179+ }
180+
181+ /**
182+ * Schedule asynchronous image resizing
183+ *
184+ * @param OutputInterface $output
185+ * @return int
186+ */
187+ private function executeAsync (OutputInterface $ output ): int
188+ {
189+ try {
190+ $ errors = [];
191+ $ this ->appState ->setAreaCode (Area::AREA_GLOBAL );
192+
193+ /** @var ProgressBar $progress */
194+ $ progress = $ this ->progressBarFactory ->create (
195+ [
196+ 'output ' => $ output ,
197+ 'max ' => $ this ->productImage ->getCountUsedProductImages ()
198+ ]
199+ );
200+ $ progress ->setFormat (
201+ "%current%/%max% [%bar%] %percent:3s%% %elapsed% %memory:6s% \t| <info>%message%</info> "
202+ );
203+
204+ if ($ output ->getVerbosity () !== OutputInterface::VERBOSITY_NORMAL ) {
205+ $ progress ->setOverwrite (false );
206+ }
207+
208+ $ productImages = $ this ->productImage ->getUsedProductImages ();
209+ foreach ($ productImages as $ image ) {
210+ $ result = $ this ->imageResizeScheduler ->schedule ($ image ['filepath ' ]);
211+
212+ if (!$ result ) {
213+ $ errors [$ image ['filepath ' ]] = 'Error image scheduling: ' . $ image ['filepath ' ];
214+ }
215+ $ progress ->setMessage ($ image ['filepath ' ]);
216+ $ progress ->advance ();
217+ }
218+ } catch (\Exception $ e ) {
219+ $ output ->writeln ("<error> {$ e ->getMessage ()}</error> " );
220+ // we must have an exit code higher than zero to indicate something was wrong
221+ return Cli::RETURN_FAILURE ;
222+ }
223+
224+ $ output ->write (PHP_EOL );
225+ if (count ($ errors )) {
226+ $ output ->writeln ("<info>Product images resized with errors:</info> " );
227+ foreach ($ errors as $ error ) {
228+ $ output ->writeln ("<error> {$ error }</error> " );
229+ }
230+ } else {
231+ $ output ->writeln ("<info>Product images scheduled successfully</info> " );
232+ }
233+
234+ return Cli::RETURN_SUCCESS ;
128235 }
129236}
0 commit comments