1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Stockbase\Integration\Cron; |
4
|
|
|
|
5
|
|
|
use Magento\Framework\ObjectManagerInterface; |
6
|
|
|
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollection; |
7
|
|
|
use Magento\Catalog\Model\Product as ProductModel; |
8
|
|
|
use Magento\Framework\Url as UrlHelper; |
9
|
|
|
use Magento\Framework\App\Filesystem\DirectoryList; |
10
|
|
|
use Magento\Framework\Filesystem\Io\File; |
11
|
|
|
use Psr\Log\LoggerInterface; |
12
|
|
|
use Stockbase\Integration\StockbaseApi\Client\StockbaseClientFactory; |
13
|
|
|
use Stockbase\Integration\Model\Config\StockbaseConfiguration; |
14
|
|
|
use Stockbase\Integration\Model\ResourceModel\StockItem as StockItemResource; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Stockbase images synchronization cron job. |
18
|
|
|
*/ |
19
|
|
|
class Images |
20
|
|
|
{ |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* @var LoggerInterface |
24
|
|
|
*/ |
25
|
|
|
private $logger; |
26
|
|
|
/** |
27
|
|
|
* @var StockbaseClientFactory |
28
|
|
|
*/ |
29
|
|
|
private $stockbaseClientFactory; |
30
|
|
|
/** |
31
|
|
|
* @var ObjectManagerInterface |
32
|
|
|
*/ |
33
|
|
|
private $objectManager; |
34
|
|
|
/** |
35
|
|
|
* @var StockbaseConfiguration |
36
|
|
|
*/ |
37
|
|
|
private $config; |
38
|
|
|
/** |
39
|
|
|
* @var ProductCollection |
40
|
|
|
*/ |
41
|
|
|
private $productCollection; |
42
|
|
|
/** |
43
|
|
|
* @var ProductModel |
44
|
|
|
*/ |
45
|
|
|
private $product; |
46
|
|
|
/** |
47
|
|
|
* @var UrlHelper |
48
|
|
|
*/ |
49
|
|
|
private $urlHelper; |
50
|
|
|
/** |
51
|
|
|
* Directory List |
52
|
|
|
* |
53
|
|
|
* @var DirectoryList |
54
|
|
|
*/ |
55
|
|
|
private $directoryList; |
56
|
|
|
/** |
57
|
|
|
* File interface |
58
|
|
|
* |
59
|
|
|
* @var File |
60
|
|
|
*/ |
61
|
|
|
private $file; |
62
|
|
|
/** |
63
|
|
|
* @var array |
64
|
|
|
*/ |
65
|
|
|
private $eans = array(); |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* Images constructor. |
69
|
|
|
* @param LoggerInterface $logger |
70
|
|
|
* @param ObjectManagerInterface $objectManager |
71
|
|
|
* @param StockbaseClientFactory $stockbaseClientFactory |
72
|
|
|
* @param StockbaseConfiguration $config |
73
|
|
|
* @param ProductCollection $productCollection |
74
|
|
|
* @param ProductModel $product |
75
|
|
|
* @param UrlHelper $urlHelper |
76
|
|
|
* @param DirectoryList $directoryList |
77
|
|
|
* @param File $file |
78
|
|
|
*/ |
79
|
|
|
public function __construct( |
80
|
|
|
LoggerInterface $logger, |
81
|
|
|
ObjectManagerInterface $objectManager, |
82
|
|
|
StockbaseClientFactory $stockbaseClientFactory, |
83
|
|
|
StockbaseConfiguration $config, |
84
|
|
|
ProductCollection $productCollection, |
85
|
|
|
ProductModel $product, |
86
|
|
|
UrlHelper $urlHelper, |
87
|
|
|
DirectoryList $directoryList, |
88
|
|
|
File $file |
89
|
|
|
) { |
90
|
|
|
$this->logger = $logger; |
91
|
|
|
$this->stockbaseClientFactory = $stockbaseClientFactory; |
92
|
|
|
$this->objectManager = $objectManager; |
93
|
|
|
$this->config = $config; |
94
|
|
|
$this->productCollection = $productCollection; |
95
|
|
|
$this->product = $product; |
96
|
|
|
$this->urlHelper = $urlHelper; |
97
|
|
|
$this->directoryList = $directoryList; |
98
|
|
|
$this->file = $file; |
99
|
|
|
} |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Executes the job. |
103
|
|
|
*/ |
104
|
|
|
public function execute() |
105
|
|
|
{ |
106
|
|
|
// validate configuration: |
107
|
|
|
if (!$this->config->isModuleEnabled() || !$this->config->isImagesSyncEnabled()) { |
108
|
|
|
return; |
109
|
|
|
} |
110
|
|
|
// start process: |
111
|
|
|
$this->logger->info('Synchronizing Stockbase images...'); |
112
|
|
|
// get processed eans: |
113
|
|
|
$processedEans = json_decode($this->getImagesEans()) ? : array(); |
114
|
|
|
// get all the eans: |
115
|
|
|
$eans = $this->getNotProcessedEans($processedEans); |
116
|
|
|
$this->logger->info('EANs to be processed: '.count($eans)); |
117
|
|
|
try { |
118
|
|
|
// if still need to process eans: |
119
|
|
|
if(count($eans) > 0) { |
120
|
|
|
$client = $this->stockbaseClientFactory->create(); |
121
|
|
|
$images = $client->getImages($eans); |
122
|
|
|
// validate returned images: |
123
|
|
|
if(is_array($images->{'Items'}) && count($images->{'Items'}) > 0) { |
124
|
|
|
// download and save the images locally: |
125
|
|
|
$this->saveImageForProduct($images->{'Items'}); |
126
|
|
|
// update the processed images configuration: |
127
|
|
|
$processedEans = array_merge($processedEans, $eans); |
128
|
|
|
$encodedEans = json_encode($processedEans); |
129
|
|
|
$this->saveImagesEans($encodedEans); |
130
|
|
|
$this->logger->info('New images synchronized.'); |
131
|
|
|
} |
132
|
|
|
} |
133
|
|
|
} catch (Exception $e) { |
|
|
|
|
134
|
|
|
$this->logger->info('Cron runImageImport error: '.$e->getMessage()); |
135
|
|
|
return false; |
136
|
|
|
} |
137
|
|
|
$this->logger->info('Stockbase images synchronization complete.'); |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* @return array |
142
|
|
|
*/ |
143
|
|
|
private function getNotProcessedEans($processedEans) |
144
|
|
|
{ |
145
|
|
|
// clean eans list: |
146
|
|
|
$this->eans = array(); |
147
|
|
|
// start process: |
148
|
|
|
$this->logger->info('Get All EANs process'); |
149
|
|
|
// get ean attribute: |
150
|
|
|
$attribute = $this->config->getEanFieldName(); |
151
|
|
|
// validate attribute: |
152
|
|
|
if($attribute) { |
153
|
|
|
// create collection and apply filters: |
154
|
|
|
$collection = $this->productCollection->create() |
155
|
|
|
->addAttributeToSelect($attribute) |
156
|
|
|
->addAttributeToSelect('stockbase_product') |
157
|
|
|
->addAttributeToFilter('stockbase_product', array('eq' => '1')) // stockbase product |
158
|
|
|
->addAttributeToFilter($attribute, array('notnull' => true, 'neq' => '')) // not null and not empty |
159
|
|
|
->addAttributeToFilter($attribute, array('nin' => $processedEans)) // not processed eans |
160
|
|
|
; |
161
|
|
|
// walk collection and save eans in the object: |
162
|
|
|
$collection->walk(array($this, 'getProductEan')); |
163
|
|
|
// log eans count: |
164
|
|
|
$this->logger->info('Found EANs: '.count($this->eans)); |
165
|
|
|
} else { |
166
|
|
|
// missing ean attribute: |
167
|
|
|
$this->logger->info('Please setup the EAN attribute.'); |
168
|
|
|
} |
169
|
|
|
return $this->eans; |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* @param $product |
174
|
|
|
*/ |
175
|
|
|
public function getProductEan($product) |
176
|
|
|
{ |
177
|
|
|
// get ean attribute: |
178
|
|
|
$attribute = $this->config->getEanFieldName(); |
179
|
|
|
// get ean: |
180
|
|
|
$ean = $product->getData($attribute); |
181
|
|
|
// if the ean is not empty: |
182
|
|
|
if ($ean) { |
183
|
|
|
// add the ean if this product has one: |
184
|
|
|
$this->eans[] = $ean; |
185
|
|
|
} |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Saves images array from stockbase for given $ean |
190
|
|
|
* |
191
|
|
|
* @param array $images |
192
|
|
|
* |
193
|
|
|
* @return bool |
194
|
|
|
*/ |
195
|
|
|
private function saveImageForProduct($images) |
196
|
|
|
{ |
197
|
|
|
$this->logger->info('Save images process:'); |
198
|
|
|
// get product model: |
199
|
|
|
$productModel = $this->product; |
200
|
|
|
// get ean attribute: |
201
|
|
|
$eanField = $this->config->getEanFieldName(); |
202
|
|
|
// loop images: |
203
|
|
|
foreach ($images as $image) { |
204
|
|
|
$this->logger->info('Image URL: '.$image->{'Url'}); |
205
|
|
|
// load product by ean: |
206
|
|
|
$product = $productModel->loadByAttribute($eanField, $image->EAN); |
207
|
|
|
// continue looping if we do not have product: |
208
|
|
|
if (!$product) { |
209
|
|
|
continue; |
210
|
|
|
} |
211
|
|
|
// get image from stockbase: |
212
|
|
|
$stockbaseImage = (string)$image->{'Url'}; |
213
|
|
|
// create temporal folder if it is not exists: |
214
|
|
|
$tmpDir = $this->getMediaDirTmpDir(); |
215
|
|
|
$this->file->checkAndCreateFolder($tmpDir); |
216
|
|
|
// get new file path: |
217
|
|
|
$newFileName = $tmpDir . baseName($image->{'Url'}); |
218
|
|
|
// read file from URL and copy it to the new destination: |
219
|
|
|
$result = $this->file->read($stockbaseImage, $newFileName); |
220
|
|
|
if ($result) { |
221
|
|
|
if ($product->getMediaGallery() == null) { |
222
|
|
|
$product->setMediaGallery(array('images' => array(), 'values' => array())); |
223
|
|
|
} |
224
|
|
|
// add saved file to the $product gallery: |
225
|
|
|
$product->addImageToMediaGallery( |
226
|
|
|
$newFileName, |
227
|
|
|
array('image', 'small_image', 'thumbnail'), |
228
|
|
|
false, |
229
|
|
|
false |
230
|
|
|
); |
231
|
|
|
// save product: |
232
|
|
|
$product->save(); |
233
|
|
|
$this->logger->info('Product saved.'); |
234
|
|
|
} else { |
235
|
|
|
$this->logger->info('Can not read the image: '.$stockbaseImage); |
236
|
|
|
} |
237
|
|
|
} |
238
|
|
|
return true; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
/** |
242
|
|
|
* Media directory name for the temporary file storage |
243
|
|
|
* pub/media/tmp |
244
|
|
|
* |
245
|
|
|
* @return string |
246
|
|
|
*/ |
247
|
|
|
private function getMediaDirTmpDir() |
248
|
|
|
{ |
249
|
|
|
return $this->directoryList->getPath(DirectoryList::MEDIA) . DIRECTORY_SEPARATOR . 'tmp'; |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* @return mixed |
254
|
|
|
*/ |
255
|
|
|
private function getImagesEans() |
256
|
|
|
{ |
257
|
|
|
return $this->config->getImagesEans(); |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* @param $eans |
262
|
|
|
*/ |
263
|
|
|
private function saveImagesEans($eans) |
264
|
|
|
{ |
265
|
|
|
$this->config->saveImagesEans($eans); |
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
} |
269
|
|
|
|
Scrutinizer analyzes your
composer.json
/composer.lock
file if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.