5
5
*/
6
6
namespace Magento \Catalog \Console \Command ;
7
7
8
+ use Magento \Catalog \Api \ProductRepositoryInterface ;
9
+ use Magento \Catalog \Model \Product \Image \CacheFactory ;
10
+ use Magento \Catalog \Model \ResourceModel \Product \CollectionFactory ;
11
+ use Magento \Catalog \Model \ResourceModel \Product \Image as ProductImage ;
12
+ use Magento \Framework \App \Area ;
13
+ use Magento \Framework \App \ObjectManager ;
14
+ use Magento \Framework \App \State ;
15
+ use Magento \Catalog \Helper \Image as ImageHelper ;
16
+ use Magento \Framework \Console \Cli ;
17
+ use Symfony \Component \Console \Command \Command ;
8
18
use Symfony \Component \Console \Input \InputInterface ;
9
19
use Symfony \Component \Console \Output \OutputInterface ;
20
+ use Magento \Framework \View \ConfigInterface as ViewConfig ;
21
+ use Magento \Theme \Model \ResourceModel \Theme \Collection as ThemeCollection ;
22
+ use Magento \Catalog \Model \Product \Image ;
23
+ use Magento \Catalog \Model \Product \ImageFactory as ProductImageFactory ;
24
+ use Symfony \Component \Console \Helper \ProgressBar ;
10
25
11
- class ImagesResizeCommand extends \Symfony \Component \Console \Command \Command
26
+ /**
27
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
28
+ */
29
+ class ImagesResizeCommand extends Command
12
30
{
13
31
/**
14
- * @var \Magento\Framework\App\ State
32
+ * @var State
15
33
*/
16
34
protected $ appState ;
17
35
18
36
/**
19
- * @var \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory
37
+ * @deprecated
38
+ * @var CollectionFactory
20
39
*/
21
40
protected $ productCollectionFactory ;
22
41
23
42
/**
24
- * @var \Magento\Catalog\Api\ProductRepositoryInterface
43
+ * @deprecated
44
+ * @var ProductRepositoryInterface
25
45
*/
26
46
protected $ productRepository ;
27
47
28
48
/**
29
- * @var \Magento\Catalog\Model\Product\Image\CacheFactory
49
+ * @deprecated
50
+ * @var CacheFactory
30
51
*/
31
52
protected $ imageCacheFactory ;
32
53
33
54
/**
34
- * @param \Magento\Framework\App\State $appState
35
- * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
36
- * @param \Magento\Catalog\Api\ProductRepositoryInterface $productRepository
37
- * @param \Magento\Catalog\Model\Product\Image\CacheFactory $imageCacheFactory
55
+ * @var ProductImage
56
+ */
57
+ private $ productImage ;
58
+
59
+ /**
60
+ * @var ViewConfig
61
+ */
62
+ private $ viewConfig ;
63
+
64
+ /**
65
+ * @var ThemeCollection
66
+ */
67
+ private $ themeCollection ;
68
+
69
+ /**
70
+ * @var ProductImageFactory
71
+ */
72
+ private $ productImageFactory ;
73
+
74
+ /**
75
+ * @param State $appState
76
+ * @param CollectionFactory $productCollectionFactory
77
+ * @param ProductRepositoryInterface $productRepository
78
+ * @param CacheFactory $imageCacheFactory
79
+ * @param ProductImage $productImage
80
+ * @param ViewConfig $viewConfig
81
+ * @param ThemeCollection $themeCollection
82
+ * @param ProductImageFactory $productImageFactory
38
83
*/
39
84
public function __construct (
40
- \Magento \Framework \App \State $ appState ,
41
- \Magento \Catalog \Model \ResourceModel \Product \CollectionFactory $ productCollectionFactory ,
42
- \Magento \Catalog \Api \ProductRepositoryInterface $ productRepository ,
43
- \Magento \Catalog \Model \Product \Image \CacheFactory $ imageCacheFactory
85
+ State $ appState ,
86
+ CollectionFactory $ productCollectionFactory ,
87
+ ProductRepositoryInterface $ productRepository ,
88
+ CacheFactory $ imageCacheFactory ,
89
+ ProductImage $ productImage = null ,
90
+ ViewConfig $ viewConfig = null ,
91
+ ThemeCollection $ themeCollection = null ,
92
+ ProductImageFactory $ productImageFactory = null
44
93
) {
45
94
$ this ->appState = $ appState ;
46
95
$ this ->productCollectionFactory = $ productCollectionFactory ;
47
96
$ this ->productRepository = $ productRepository ;
48
97
$ this ->imageCacheFactory = $ imageCacheFactory ;
98
+ $ this ->productImage = $ productImage ?: ObjectManager::getInstance ()->get (ProductImage::class);
99
+ $ this ->viewConfig = $ viewConfig ?: ObjectManager::getInstance ()->get (ViewConfig::class);
100
+ $ this ->themeCollection = $ themeCollection ?: ObjectManager::getInstance ()->get (ThemeCollection::class);
101
+ $ this ->productImageFactory = $ productImageFactory
102
+ ?: ObjectManager::getInstance ()->get (ProductImageFactory::class);
49
103
parent ::__construct ();
50
104
}
51
105
@@ -63,49 +117,122 @@ protected function configure()
63
117
*/
64
118
protected function execute (InputInterface $ input , OutputInterface $ output )
65
119
{
66
- $ this ->appState ->setAreaCode (\Magento \Framework \App \Area::AREA_GLOBAL );
67
-
68
- /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection */
69
- $ productCollection = $ this ->productCollectionFactory ->create ();
70
- $ productIds = $ productCollection ->getAllIds ();
71
- if (!count ($ productIds )) {
72
- $ output ->writeln ("<info>No product images to resize</info> " );
73
- return \Magento \Framework \Console \Cli::RETURN_SUCCESS ;
74
- }
120
+ $ this ->appState ->setAreaCode (Area::AREA_GLOBAL );
75
121
76
- $ errorMessage = '' ;
77
122
try {
78
- foreach ($ productIds as $ productId ) {
79
- try {
80
- /** @var \Magento\Catalog\Model\Product $product */
81
- $ product = $ this ->productRepository ->getById ($ productId );
82
- } catch (\Magento \Framework \Exception \NoSuchEntityException $ e ) {
83
- continue ;
84
- }
123
+ $ count = $ this ->productImage ->getCountAllProductImages ();
124
+ if (!$ count ) {
125
+ $ output ->writeln ("<info>No product images to resize</info> " );
126
+ return Cli::RETURN_SUCCESS ;
127
+ }
85
128
86
- try {
87
- /** @var \Magento\Catalog\Model\Product\Image\Cache $imageCache */
88
- $ imageCache = $ this ->imageCacheFactory ->create ();
89
- $ imageCache ->generate ($ product );
90
- } catch (\Magento \Framework \Exception \RuntimeException $ e ) {
91
- $ errorMessage = $ e ->getMessage ();
92
- }
129
+ $ productImages = $ this ->productImage ->getAllProductImages ();
130
+
131
+ $ themes = $ this ->themeCollection ->loadRegisteredThemes ();
132
+ $ viewImages = $ this ->getViewImages ($ themes ->getItems ());
133
+
134
+ $ progress = new ProgressBar ($ output , $ count );
135
+ $ progress ->setFormat (
136
+ "%current%/%max% [%bar%] %percent:3s%% %elapsed% %memory:6s% \t| <info>%message%</info> "
137
+ );
93
138
94
- $ output ->write (". " );
139
+ if ($ output ->getVerbosity () !== OutputInterface::VERBOSITY_NORMAL ) {
140
+ $ progress ->setOverwrite (false );
141
+ }
142
+
143
+ foreach ($ productImages as $ image ) {
144
+ $ originalImageName = $ image ['filepath ' ];
145
+
146
+ foreach ($ viewImages as $ viewImage ) {
147
+ $ image = $ this ->makeImage ($ originalImageName , $ viewImage );
148
+ $ image ->resize ();
149
+ $ image ->saveFile ();
150
+ }
151
+ $ progress ->setMessage ($ originalImageName );
152
+ $ progress ->advance ();
95
153
}
96
154
} catch (\Exception $ e ) {
97
155
$ output ->writeln ("<error> {$ e ->getMessage ()}</error> " );
98
156
// we must have an exit code higher than zero to indicate something was wrong
99
- return \ Magento \ Framework \ Console \ Cli::RETURN_FAILURE ;
157
+ return Cli::RETURN_FAILURE ;
100
158
}
101
159
102
160
$ output ->write ("\n" );
103
161
$ output ->writeln ("<info>Product images resized successfully.</info> " );
104
162
105
- if ($ errorMessage !== '' ) {
106
- $ output ->writeln ("<comment> {$ errorMessage }</comment> " );
163
+ return 0 ;
164
+ }
165
+
166
+ /**
167
+ * Make image
168
+ * @param string $originalImagePath
169
+ * @param array $imageParams
170
+ * @return Image
171
+ */
172
+ private function makeImage (string $ originalImagePath , array $ imageParams ): Image
173
+ {
174
+ $ image = $ this ->productImageFactory ->create ();
175
+
176
+ if (isset ($ imageParams ['height ' ])) {
177
+ $ image ->setHeight ($ imageParams ['height ' ]);
178
+ }
179
+ if (isset ($ imageParams ['width ' ])) {
180
+ $ image ->setWidth ($ imageParams ['width ' ]);
181
+ }
182
+ if (isset ($ imageParams ['aspect_ratio ' ])) {
183
+ $ image ->setKeepAspectRatio ($ imageParams ['aspect_ratio ' ]);
184
+ }
185
+ if (isset ($ imageParams ['frame ' ])) {
186
+ $ image ->setKeepFrame ($ imageParams ['frame ' ]);
187
+ }
188
+ if (isset ($ imageParams ['transparency ' ])) {
189
+ $ image ->setKeepTransparency ($ imageParams ['transparency ' ]);
190
+ }
191
+ if (isset ($ imageParams ['constrain ' ])) {
192
+ $ image ->setConstrainOnly ($ imageParams ['constrain ' ]);
193
+ }
194
+ if (isset ($ imageParams ['background ' ])) {
195
+ $ image ->setBackgroundColor ($ imageParams ['background ' ]);
107
196
}
108
197
109
- return 0 ;
198
+ $ image ->setDestinationSubdir ($ imageParams ['type ' ]);
199
+ $ image ->setBaseFile ($ originalImagePath );
200
+
201
+ return $ image ;
202
+ }
203
+
204
+ /**
205
+ * Get view images data from themes
206
+ * @param array $themes
207
+ * @return array
208
+ */
209
+ private function getViewImages (array $ themes ): array
210
+ {
211
+ $ viewImages = [];
212
+ foreach ($ themes as $ theme ) {
213
+ $ config = $ this ->viewConfig ->getViewConfig ([
214
+ 'area ' => Area::AREA_FRONTEND ,
215
+ 'themeModel ' => $ theme ,
216
+ ]);
217
+ $ images = $ config ->getMediaEntities ('Magento_Catalog ' , ImageHelper::MEDIA_TYPE_CONFIG_NODE );
218
+ foreach ($ images as $ imageId => $ imageData ) {
219
+ $ uniqIndex = $ this ->getUniqImageIndex ($ imageData );
220
+ $ imageData ['id ' ] = $ imageId ;
221
+ $ viewImages [$ uniqIndex ] = $ imageData ;
222
+ }
223
+ }
224
+ return $ viewImages ;
225
+ }
226
+
227
+ /**
228
+ * Get uniq image index
229
+ * @param array $imageData
230
+ * @return string
231
+ */
232
+ private function getUniqImageIndex (array $ imageData ): string
233
+ {
234
+ ksort ($ imageData );
235
+ unset($ imageData ['type ' ]);
236
+ return md5 (json_encode ($ imageData ));
110
237
}
111
238
}
0 commit comments