1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace exchange\classes; |
4
|
|
|
|
5
|
|
|
use CI; |
6
|
|
|
use CMSFactory\ModuleSettings; |
7
|
|
|
use core\models\Route; |
8
|
|
|
use core\models\RouteQuery; |
9
|
|
|
use Exception; |
10
|
|
|
use MediaManager\Image; |
11
|
|
|
use MY_Controller; |
12
|
|
|
use Propel\Runtime\ActiveQuery\Criteria; |
13
|
|
|
use SimpleXMLElement; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* |
17
|
|
|
* @author kolia |
18
|
|
|
*/ |
19
|
|
|
class Products extends ExchangeBase |
20
|
|
|
{ |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* |
24
|
|
|
* @var array |
25
|
|
|
*/ |
26
|
|
|
private $additionalParentsCategories = []; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* |
30
|
|
|
* @var array |
31
|
|
|
*/ |
32
|
|
|
protected $compare_exIds = []; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* |
36
|
|
|
* @var array |
37
|
|
|
*/ |
38
|
|
|
protected $compare_properties = []; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* |
42
|
|
|
* @var array |
43
|
|
|
*/ |
44
|
|
|
protected $compare_urls = []; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* |
48
|
|
|
* @var array |
49
|
|
|
*/ |
50
|
|
|
private $existingProductsIds = []; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* |
54
|
|
|
* @var array |
55
|
|
|
*/ |
56
|
|
|
protected $i18nExisting = []; |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* |
60
|
|
|
* @var boolean |
61
|
|
|
*/ |
62
|
|
|
private $ignoreExistingDescriptions = false; |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* |
66
|
|
|
* @var |
67
|
|
|
*/ |
68
|
|
|
private $ignoreExistingProducts = false; |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* If product have images, then all |
72
|
|
|
* his old images need to be deleted |
73
|
|
|
* @var array |
74
|
|
|
*/ |
75
|
|
|
protected $imagesToDelete = []; |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @var array |
79
|
|
|
*/ |
80
|
|
|
protected $imagesToResize = []; |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* @var array |
84
|
|
|
*/ |
85
|
|
|
protected $imagesToResizeAdditional = []; |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* |
89
|
|
|
* @var DataCollector |
90
|
|
|
*/ |
91
|
|
|
protected $insertCollector; |
92
|
|
|
|
93
|
|
|
/** |
94
|
|
|
* Array of products main categories |
95
|
|
|
* @var array |
96
|
|
|
*/ |
97
|
|
|
private $parentCat = []; |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* |
101
|
|
|
* @var array |
102
|
|
|
*/ |
103
|
|
|
protected $productProCats = []; |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* In the xml there can be two different products with same names, this array |
107
|
|
|
* gathers just created product urls to prevent equal addresses |
108
|
|
|
* @var array |
109
|
|
|
*/ |
110
|
|
|
protected $productsNewUrls = []; |
111
|
|
|
|
112
|
|
|
/** |
113
|
|
|
* |
114
|
|
|
* @var array |
115
|
|
|
*/ |
116
|
|
|
protected $productss; |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* |
120
|
|
|
* @var boolean |
121
|
|
|
*/ |
122
|
|
|
protected $runResize = FALSE; |
123
|
|
|
|
124
|
|
|
/** |
125
|
|
|
* If products have 'ХарактеристикиТовара' run fix |
126
|
|
|
* @var bool |
127
|
|
|
*/ |
128
|
|
|
protected $runVariantsFix = false; |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Path of folder where xml and images stored |
132
|
|
|
* @var string |
133
|
|
|
*/ |
134
|
|
|
protected $tempDir; |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* |
138
|
|
|
* @var DataCollector |
139
|
|
|
*/ |
140
|
|
|
protected $updateCollector; |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* |
144
|
|
|
* @var VariantCharacteristics |
145
|
|
|
*/ |
146
|
|
|
private $variantCharacteristics; |
147
|
|
|
|
148
|
|
|
private $categoryUrls = []; |
149
|
|
|
|
150
|
|
|
protected function addProductsToUpperCategories() { |
151
|
|
|
|
152
|
|
|
$products = $this->db->select('shop_products.id, shop_category.full_path_ids') |
153
|
|
|
->join('shop_category', 'shop_category.id = shop_products.category_id') |
154
|
|
|
->get('shop_products') |
155
|
|
|
->result(); |
156
|
|
|
|
157
|
|
|
$insertData = []; |
158
|
|
|
foreach ($products as $product) { |
159
|
|
|
$path = unserialize($product->full_path_ids); |
160
|
|
|
foreach ($path as $fpi) { |
161
|
|
|
$newData = [ |
162
|
|
|
'category_id' => $fpi, |
163
|
|
|
'product_id' => $product->id, |
164
|
|
|
]; |
165
|
|
|
if ($this->isProductCategoriesRowNew($newData) == FALSE) { |
166
|
|
|
continue; |
167
|
|
|
} |
168
|
|
|
$insertData[] = $newData; |
169
|
|
|
} |
170
|
|
|
} |
171
|
|
|
$this->insertBatch('shop_product_categories', $insertData); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
protected function getUrls() { |
175
|
|
|
|
176
|
|
|
$productExIds = []; |
177
|
|
|
foreach ($this->products as $product) { |
|
|
|
|
178
|
|
|
if (!empty($product['external_id'])) { |
179
|
|
|
$productExIds[$product['external_id']] = $product['id']; |
180
|
|
|
} |
181
|
|
|
} |
182
|
|
|
return $productExIds; |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* |
187
|
|
|
*/ |
188
|
|
|
protected function import_() { |
189
|
|
|
|
190
|
|
|
$ignoreExisting = ModuleSettings::ofModule('exchange')->get('ignore_existing'); |
191
|
|
|
$this->ignoreExistingProducts = isset($ignoreExisting['products']); |
192
|
|
|
$this->ignoreExistingDescriptions = isset($ignoreExisting['description']); |
193
|
|
|
|
194
|
|
|
$this->insertCollector = new DataCollector(); |
195
|
|
|
$this->updateCollector = new DataCollector(); |
196
|
|
|
|
197
|
|
|
$storageFilePath = CI::$APP->config->item('characteristicsStorageFilePath'); |
198
|
|
|
$this->variantCharacteristics = new VariantCharacteristics($storageFilePath); |
199
|
|
|
|
200
|
|
|
$this->rememberOriginAdditionalParentsCats(); |
201
|
|
|
|
202
|
|
|
$this->getCompareData(); |
203
|
|
|
|
204
|
|
|
$this->processProducts1(); |
205
|
|
|
$this->insert1(); |
206
|
|
|
$this->processProducts23_Insert23(); |
207
|
|
|
|
208
|
|
|
if (!$this->ignoreExistingProducts) { |
209
|
|
|
$this->update(); |
210
|
|
|
} |
211
|
|
|
$this->rememberOriginAdditionalParentsCats(); |
212
|
|
|
|
213
|
|
|
$this->rebuildAdditionalParentsCats(); |
214
|
|
|
$this->runResize(); |
215
|
|
|
// $this->rebuildProductProperties(); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* |
220
|
|
|
*/ |
221
|
|
|
protected function rememberOriginAdditionalParentsCats() { |
222
|
|
|
|
223
|
|
|
$result = $this->db |
224
|
|
|
->select(['shop_products.id', 'shop_category.full_path_ids']) |
225
|
|
|
->join('shop_category', 'shop_category.id=shop_products.category_id') |
226
|
|
|
->get('shop_products'); |
227
|
|
|
|
228
|
|
|
if (!$result) { |
229
|
|
|
return; |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
$result = $result->result_array(); |
233
|
|
|
foreach ($result as $row) { |
234
|
|
|
$this->additionalParentsCategories[$row['id']] = unserialize($row['full_path_ids']); |
235
|
|
|
} |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
/** |
239
|
|
|
* Getting from base data of product for fast compare (external_ids, urls...) |
240
|
|
|
* @param integer $type if empty = all, |
241
|
|
|
* 1 - only external_ids, |
242
|
|
|
* 2 - only urls, |
243
|
|
|
* 3 - only properties |
244
|
|
|
*/ |
245
|
|
|
protected function getCompareData($type = NULL) { |
246
|
|
|
|
247
|
|
|
foreach ($this->products as $product) { |
|
|
|
|
248
|
|
|
// external ids of products |
249
|
|
|
if (!empty($product['external_id']) & ($type == NULL || (int) $type == 1)) { |
250
|
|
|
$this->compare_exIds[$product['external_id']] = $product['id']; |
251
|
|
|
} |
252
|
|
|
if ($type == NULL || (int) $type == 2) { |
253
|
|
|
$this->compare_urls[$product['url']] = $product['external_id']; |
254
|
|
|
} |
255
|
|
|
} |
256
|
|
|
if ($type == NULL || (int) $type == 3) { |
257
|
|
|
foreach ($this->properties as $property) { |
|
|
|
|
258
|
|
|
if (!empty($property['external_id'])) { |
259
|
|
|
$this->compare_properties[$property['external_id']] = $property; |
260
|
|
|
} |
261
|
|
|
} |
262
|
|
|
} |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
/** |
266
|
|
|
* Gather data for tables: |
267
|
|
|
* - `shop_products` (data will be ready) |
268
|
|
|
* - `shop_products_i18n` (after `shop_products`) |
269
|
|
|
* - `shop_product_variants` (after `shop_products`) |
270
|
|
|
* - `shop_product_variants_i18n` (after `shop_product_variants`) |
271
|
|
|
* - `shop_products_categories` (after `shop_products`) |
272
|
|
|
* - `shop_product_images` (after `shop_products`) |
273
|
|
|
* |
274
|
|
|
* P.S. For updating all data will be ready immediately, inserting need depends on the order |
275
|
|
|
* |
276
|
|
|
*/ |
277
|
|
|
protected function processProducts1() { |
278
|
|
|
|
279
|
|
|
$propertiesDataUpdate = []; |
280
|
|
|
$productPropDTDel = []; |
281
|
|
|
|
282
|
|
|
// for variants |
283
|
|
|
$productsUniqueExIds = []; |
284
|
|
|
|
285
|
|
|
// passing each product |
286
|
|
|
foreach ($this->importData as $product) { |
287
|
|
|
|
288
|
|
|
if (FALSE !== strpos((string) $product->Ид, '#')) { // this is variant of product |
289
|
|
|
$exId = array_shift(explode('#', (string) $product->Ид)); // getting product id |
|
|
|
|
290
|
|
|
$variantExId = (string) $product->Ид; |
291
|
|
|
} else { |
292
|
|
|
$exId = (string) $product->Ид; |
293
|
|
|
$variantExId = NULL; |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
// GETTING ALL DATA |
297
|
|
|
list($products, $i18n) = $this->pass1Helper_getProductData($product, $exId); |
298
|
|
|
|
299
|
|
|
$isNewProduct = !isset($this->compare_exIds[$products['external_id']]); |
300
|
|
|
$isNewVariant = $variantExId == null ? false : !isset($this->variantsIds[$variantExId]); |
|
|
|
|
301
|
|
|
|
302
|
|
|
list($variant, $variantI18n) = $this->pass1Helper_getVariantData($product, $isNewProduct); |
303
|
|
|
|
304
|
|
|
try { |
305
|
|
|
$categoryId = $this->pass1Helper_getCategoryData($product); |
306
|
|
|
$products['category_id'] = $categoryId; |
307
|
|
|
} catch (Exception $e) { |
308
|
|
|
continue; |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
list($additionalImages, $mainImage) = $this->pass1Helper_getImagesData($product, $exId); |
312
|
|
|
|
313
|
|
|
$this->imagesToResize[] = $mainImage; |
314
|
|
|
foreach ($additionalImages as $addImg) { |
315
|
|
|
$this->imagesToResizeAdditional[] = $addImg['image_name']; |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
if ($mainImage != NULL) { |
319
|
|
|
$variant['mainImage'] = $mainImage; |
320
|
|
|
} else { |
321
|
|
|
$variant['mainImage'] = ''; |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
list($shopProductPropertiesData, $brandId) = $this->pass1Helper_getPropertiesData($product, $categoryId); |
325
|
|
|
|
326
|
|
|
if ($brandId) { |
327
|
|
|
$products['brand_id'] = $brandId; |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
$url = translit_url((string) $product->Наименование); |
331
|
|
|
|
332
|
|
|
// splitting on new & existing products (by external_id) |
333
|
|
|
if ($isNewProduct) { // NEW |
334
|
|
|
// default variants values (without `product_id`) |
335
|
|
|
if (!$variantExId == NULL) { // this is variant of product |
336
|
|
|
$this->insertCollector->addData('shop_product_variants', $variant, $variantExId); |
337
|
|
|
$this->insertCollector->addData('shop_product_variants_i18n', $variantI18n, $variantExId); |
338
|
|
View Code Duplication |
if (!isset($productsUniqueExIds[$exId])) { |
339
|
|
|
$productsUniqueExIds[$exId] = 0; |
340
|
|
|
} else { |
341
|
|
|
$this->insertCollector->newPass(); |
342
|
|
|
$this->updateCollector->newPass(); |
343
|
|
|
continue; |
344
|
|
|
} |
345
|
|
|
} else { |
346
|
|
|
$this->insertCollector->addData('shop_product_variants', $variant, $exId); |
347
|
|
|
$this->insertCollector->addData('shop_product_variants_i18n', $variantI18n, $exId); |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
if (isset($this->compare_urls[$url])) { |
351
|
|
|
if ($this->compare_urls[$url] != $exId) { // add some number to url |
352
|
|
|
$i = 1; |
353
|
|
|
$url_ = $url; |
354
|
|
|
while (array_key_exists($url, $this->compare_urls)) { |
355
|
|
|
$url = $url_ . ++$i; |
356
|
|
|
} |
357
|
|
|
} |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
$products['url'] = $url; |
361
|
|
|
|
362
|
|
|
$this->compare_urls[$url] = $exId; |
363
|
|
|
|
364
|
|
|
$this->insertCollector->addData('shop_products', $products, $exId); |
365
|
|
|
$this->insertCollector->addData('shop_products_i18n', $i18n, $exId); |
366
|
|
|
|
367
|
|
|
$this->insertCollector->addData('shop_product_categories', ['category_id' => $products['category_id']], $exId); |
368
|
|
|
foreach ($shopProductPropertiesData as $propertyData) { |
369
|
|
|
$this->insertCollector->updateData('shop_product_properties_data', $propertyData, $exId); |
370
|
|
|
} |
371
|
|
|
if ($additionalImages != NULL) { |
372
|
|
|
$this->insertCollector->addData('shop_product_images', $additionalImages, $exId); |
373
|
|
|
} |
374
|
|
|
} else { // EXISTING |
375
|
|
|
$productId = $this->compare_exIds[$exId]; |
376
|
|
|
$this->existingProductsIds[] = $productId; |
377
|
|
|
$variant = array_merge($variant, ['product_id' => $productId]); |
378
|
|
|
|
379
|
|
|
if (isset($this->variantImages[$exId]) & empty($variant['mainImage'])) { |
|
|
|
|
380
|
|
|
$variant['mainImage'] = $this->variantImages[$exId]; |
|
|
|
|
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
// to not drop prices on update |
384
|
|
|
unset($variant['price_in_main']); |
385
|
|
|
unset($variant['price']); |
386
|
|
|
|
387
|
|
|
if (!$variantExId == NULL) { // this is variant of product |
388
|
|
|
if ($isNewVariant) { |
389
|
|
|
$this->insertCollector->addData('shop_product_variants', $variant, $variantExId); |
390
|
|
|
$this->insertCollector->addData('shop_product_variants_i18n', $variantI18n, $variantExId); |
391
|
|
|
} else { |
392
|
|
|
$this->updateCollector->addData('shop_product_variants', $variant, $variantExId); |
393
|
|
|
$this->updateCollector->addData('shop_product_variants_i18n', $variantI18n, $variantExId); |
394
|
|
|
} |
395
|
|
|
|
396
|
|
View Code Duplication |
if (!isset($productsUniqueExIds[$exId])) { |
397
|
|
|
$productsUniqueExIds[$exId] = 0; |
398
|
|
|
} else { |
399
|
|
|
$this->insertCollector->newPass(); |
400
|
|
|
$this->updateCollector->newPass(); |
401
|
|
|
continue; |
402
|
|
|
} |
403
|
|
|
} else { |
404
|
|
|
$this->updateCollector->addData('shop_product_variants', array_merge($variant, ['product_id' => $productId])); |
405
|
|
|
$this->updateCollector->addData('shop_product_variants_i18n', $variantI18n, $exId); |
406
|
|
|
} |
407
|
|
|
|
408
|
|
|
if (isset($products['category_id'])) { // will be updated by product_id |
409
|
|
|
$this->updateCollector->addData( |
410
|
|
|
'shop_product_categories', |
411
|
|
|
[ |
412
|
|
|
'product_id' => $productId, |
413
|
|
|
'category_id' => $products['category_id'], |
414
|
|
|
] |
415
|
|
|
); |
416
|
|
|
} |
417
|
|
|
$this->updateCollector->addData('shop_products', array_merge($products, ['id' => $productId, 'url' => $url])); |
418
|
|
|
$this->updateCollector->addData('shop_products_i18n', array_merge($i18n, ['id' => $productId])); |
419
|
|
|
|
420
|
|
|
foreach ($shopProductPropertiesData as $propertyData) { |
421
|
|
|
$propertiesDataUpdate[] = array_merge($propertyData, ['product_id' => $productId]); |
422
|
|
|
} |
423
|
|
|
$productPropDTDel[] = $productId; |
424
|
|
|
if ($additionalImages != NULL) { |
425
|
|
|
$countAddImg = count($additionalImages); |
426
|
|
|
for ($i = 0; $i < $countAddImg; $i++) { |
427
|
|
|
$additionalImages[$i]['product_id'] = $productId; |
428
|
|
|
} |
429
|
|
|
$this->updateCollector->addData('shop_product_images', $additionalImages); |
430
|
|
|
} |
431
|
|
|
} |
432
|
|
|
|
433
|
|
|
$this->insertCollector->newPass(); |
434
|
|
|
$this->updateCollector->newPass(); |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
if (!$this->ignoreExistingProducts and $productPropDTDel) { |
438
|
|
|
$this->db |
439
|
|
|
->where_in('product_id', $productPropDTDel) |
440
|
|
|
->delete('shop_product_properties_data'); |
441
|
|
|
|
442
|
|
|
$this->insertPropertiesData('shop_product_properties_data', $propertiesDataUpdate); |
443
|
|
|
} |
444
|
|
|
|
445
|
|
|
$this->variantCharacteristics->saveCharacteristics(); |
446
|
|
|
} |
447
|
|
|
|
448
|
|
|
/** |
449
|
|
|
* Method-helper for simplify processProducts1 method |
450
|
|
|
* @param SimpleXMLElement $product |
451
|
|
|
* @param string $exId |
452
|
|
|
* @return array |
|
|
|
|
453
|
|
|
*/ |
454
|
|
|
protected function pass1Helper_getProductData(SimpleXMLElement $product, $exId) { |
455
|
|
|
|
456
|
|
|
$products = [ |
457
|
|
|
'external_id' => $exId, |
458
|
|
|
'active' => (string) $product->Статус == 'Удален' ? 0 : 1, |
459
|
|
|
]; |
460
|
|
|
$i18n = [ |
461
|
|
|
'locale' => $this->locale, |
462
|
|
|
'name' => (string) $product->Наименование, |
463
|
|
|
]; |
464
|
|
|
|
465
|
|
|
$hasDescription = false; |
466
|
|
|
|
467
|
|
|
if (isset($product->Описание)) { |
468
|
|
|
$hasDescription = true; |
469
|
|
|
$description = (string) $product->Описание; |
470
|
|
|
} elseif (isset($product->ЗначенияРеквизитов->ЗначениеРеквизита->Наименование)) { |
471
|
|
|
foreach ($product->ЗначенияРеквизитов->ЗначениеРеквизита as $recVal) { |
472
|
|
|
if ((string) $recVal->Наименование == 'Полное наименование') { |
473
|
|
|
$hasDescription = true; |
474
|
|
|
$description = (string) $recVal->Значение; |
475
|
|
|
} |
476
|
|
|
} |
477
|
|
|
} |
478
|
|
|
|
479
|
|
|
if ($hasDescription) { |
480
|
|
|
$locale = MY_Controller::defaultLocale(); |
481
|
|
|
$res = $this->db |
482
|
|
|
->select('shop_products_i18n.short_description, shop_products_i18n.full_description') |
483
|
|
|
->from('shop_products') |
484
|
|
|
->where('external_id', $exId) |
485
|
|
|
->where('shop_products_i18n.locale', $locale) |
486
|
|
|
->join('shop_products_i18n', 'shop_products_i18n.id = shop_products.id') |
487
|
|
|
->get(); |
488
|
|
|
|
489
|
|
|
if ($res->num_rows() > 0) { |
490
|
|
|
$desc = $res->row_array(); |
491
|
|
|
$shortDescIsEmpty = ('' == $desc['short_description']); |
492
|
|
|
$FullDescIsEmpty = ('' == $desc['full_description']); |
493
|
|
|
} |
494
|
|
|
if ($this->ignoreExistingDescriptions) { |
495
|
|
|
$shortDescIsEmpty && $i18n['short_description'] = $description; |
496
|
|
|
$FullDescIsEmpty && $i18n['full_description'] = $description; |
497
|
|
|
} else { |
498
|
|
|
$i18n['short_description'] = $description; |
499
|
|
|
$i18n['full_description'] = $description; |
500
|
|
|
} |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
return [ |
504
|
|
|
$products, |
505
|
|
|
$i18n, |
506
|
|
|
]; |
507
|
|
|
} |
508
|
|
|
|
509
|
|
|
/** |
510
|
|
|
* Method-helper for simplify processProducts1 method |
511
|
|
|
* @param SimpleXMLElement $product |
512
|
|
|
* @param bool $isNew |
513
|
|
|
* @return array |
|
|
|
|
514
|
|
|
*/ |
515
|
|
|
protected function pass1Helper_getVariantData(SimpleXMLElement $product, $isNew = true) { |
516
|
|
|
|
517
|
|
|
$variant = [ |
518
|
|
|
'external_id' => (string) $product->Ид, |
519
|
|
|
'number' => (string) $product->Артикул, |
520
|
|
|
'currency' => $this->mainCurrencyId, |
|
|
|
|
521
|
|
|
]; |
522
|
|
|
|
523
|
|
|
//$name = (string) $product->Наименование; |
524
|
|
|
$name = ''; |
525
|
|
|
if (isset($product->ХарактеристикиТовара)) { |
526
|
|
|
foreach ($product->ХарактеристикиТовара->ХарактеристикаТовара as $value) { |
527
|
|
|
$chName = (string) $value->Наименование; |
528
|
|
|
$chValue = (string) $value->Значение; |
529
|
|
|
|
530
|
|
|
$name .= ' ' . $chValue; |
531
|
|
|
$this->variantCharacteristics->addCharacteristic($chName, $chValue); |
532
|
|
|
} |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
$variantI18n = [ |
536
|
|
|
'locale' => $this->locale, |
537
|
|
|
'name' => trim($name), |
538
|
|
|
]; |
539
|
|
|
|
540
|
|
|
if ($isNew) { |
541
|
|
|
$defaultVariantsValues = [ |
542
|
|
|
'price' => '0.00000', |
543
|
|
|
'stock' => 0, |
544
|
|
|
'position' => 0, |
545
|
|
|
'price_in_main' => '0.00000', |
546
|
|
|
]; |
547
|
|
|
} else { |
548
|
|
|
$defaultVariantsValues = []; |
549
|
|
|
} |
550
|
|
|
|
551
|
|
|
return [ |
552
|
|
|
array_merge($variant, $defaultVariantsValues), |
553
|
|
|
$variantI18n, |
554
|
|
|
]; |
555
|
|
|
} |
556
|
|
|
|
557
|
|
|
/** |
558
|
|
|
* Method-helper for simplify processProducts1 method |
559
|
|
|
* @param SimpleXMLElement $product |
560
|
|
|
* @return int |
561
|
|
|
* @throws Exception |
562
|
|
|
*/ |
563
|
|
|
protected function pass1Helper_getCategoryData(SimpleXMLElement $product) { |
564
|
|
|
|
565
|
|
|
$categoryId = NULL; |
|
|
|
|
566
|
|
|
if (isset($product->Группы)) { |
567
|
|
|
$categoryExId = (string) $product->Группы->Ид; |
568
|
|
|
$categoryId = Categories::getInstance()->categoryExists2($categoryExId, TRUE); |
569
|
|
|
if (!$categoryId) { |
570
|
|
|
throw new Exception(sprintf('Error! Product category with id [%s] not found in file', $categoryExId)); |
571
|
|
|
} |
572
|
|
|
} else { |
573
|
|
|
throw new Exception(sprintf('Error! Product "%s" category not found in file', $product->Наименование)); |
574
|
|
|
} |
575
|
|
|
|
576
|
|
|
return $categoryId; |
577
|
|
|
} |
578
|
|
|
|
579
|
|
|
/** |
580
|
|
|
* Method-helper for simplify processProducts1 method |
581
|
|
|
* @param SimpleXMLElement $product |
582
|
|
|
* @param string $exId |
583
|
|
|
* @return array |
584
|
|
|
*/ |
585
|
|
|
protected function pass1Helper_getImagesData(SimpleXMLElement $product, $exId) { |
586
|
|
|
|
587
|
|
|
$additionalImages = NULL; |
588
|
|
|
$mainImage = NULL; |
589
|
|
|
|
590
|
|
|
if (count($product->Картинка) > 1) { |
591
|
|
|
$this->imagesToDelete[$exId] = NULL; |
592
|
|
|
} |
593
|
|
|
$i = 0; |
594
|
|
|
foreach ((array) $product->Картинка as $image) { |
595
|
|
|
$path = (string) $image; |
596
|
|
|
$fileName = pathinfo($path, PATHINFO_BASENAME); |
597
|
|
|
if ($i == 0) { // main image |
598
|
|
|
if (file_exists($this->tempDir . $path) and !file_exists('./uploads/shop/products/origin/' . $fileName)) { |
599
|
|
|
$copied = copy($this->tempDir . $path, './uploads/shop/products/origin/' . $fileName); |
600
|
|
|
if ($copied != FALSE) { |
601
|
|
|
$mainImage = $fileName; |
602
|
|
|
} |
603
|
|
|
} elseif (file_exists('./uploads/shop/products/origin/' . $fileName)) { |
604
|
|
|
$mainImage = $fileName; |
605
|
|
|
} |
606
|
|
|
} else { // rest of images will be an additional |
607
|
|
|
if (file_exists($this->tempDir . $path) and !file_exists('./uploads/shop/products/origin/additional/' . $fileName)) { |
608
|
|
|
$copied = copy($this->tempDir . $path, './uploads/shop/products/origin/additional/' . $fileName); |
609
|
|
View Code Duplication |
if ($copied != FALSE) { |
610
|
|
|
$additionalImages[] = [ |
611
|
|
|
'position' => $i - 1, |
612
|
|
|
'image_name' => $fileName, |
613
|
|
|
]; |
614
|
|
|
} |
615
|
|
View Code Duplication |
} elseif (file_exists('./uploads/shop/products/origin/additional/' . $fileName)) { |
616
|
|
|
$additionalImages[] = [ |
617
|
|
|
'position' => $i - 1, |
618
|
|
|
'image_name' => $fileName, |
619
|
|
|
]; |
620
|
|
|
} |
621
|
|
|
} |
622
|
|
|
$i++; |
623
|
|
|
} |
624
|
|
|
|
625
|
|
|
return [ |
626
|
|
|
$additionalImages, |
627
|
|
|
$mainImage, |
628
|
|
|
]; |
629
|
|
|
} |
630
|
|
|
|
631
|
|
|
/** |
632
|
|
|
* Method-helper for simplify processProducts1 method |
633
|
|
|
* @param SimpleXMLElement $product |
634
|
|
|
* @param int $categoryId |
635
|
|
|
* @return array |
636
|
|
|
*/ |
637
|
|
|
protected function pass1Helper_getPropertiesData(SimpleXMLElement $product, $categoryId) { |
638
|
|
|
|
639
|
|
|
$brandIdentif = Properties::getInstance()->getBrandIdentif(); |
|
|
|
|
640
|
|
|
$brandId = ''; |
641
|
|
|
|
642
|
|
|
$shopProductPropertiesData = []; |
643
|
|
|
// processing properties of product |
644
|
|
|
if (isset($product->ЗначенияСвойств)) { |
645
|
|
|
foreach ($product->ЗначенияСвойств->ЗначенияСвойства as $property) { |
646
|
|
|
$propertyValue = (string) $property->Значение; |
647
|
|
|
if (empty($propertyValue)) { |
648
|
|
|
continue; |
649
|
|
|
} |
650
|
|
|
// check for "brand" |
651
|
|
|
$propertyExId = (string) $property->Ид; |
652
|
|
|
if ($propertyExId == $brandIdentif) { |
653
|
|
|
$brandId = Properties::getInstance()->getBrandIdByExId($propertyValue) ?: Properties::getInstance()->getBrandIdByName($propertyValue); |
|
|
|
|
654
|
|
|
continue; |
655
|
|
|
} |
656
|
|
|
|
657
|
|
|
if (!isset($this->compare_properties[$propertyExId])) { |
658
|
|
|
continue; |
659
|
|
|
} |
660
|
|
|
|
661
|
|
|
$propertyId = $this->compare_properties[$propertyExId]['id']; |
662
|
|
|
|
663
|
|
|
// if property is multiple, then correting value |
664
|
|
|
if (Properties::getInstance()->dictionaryProperties[$propertyExId]) { |
665
|
|
|
$propertyValue = Properties::getInstance()->dictionaryProperties[$propertyExId][$propertyValue]; |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
$shopProductPropertiesData[] = [ |
669
|
|
|
'property_id' => $propertyId, |
670
|
|
|
'value' => $propertyValue, |
671
|
|
|
'locale' => $this->locale, |
672
|
|
|
]; |
673
|
|
|
|
674
|
|
|
if ($categoryId != NULL) { |
675
|
|
|
$newRow = TRUE; |
676
|
|
|
foreach ($this->productProCats as $row) { |
677
|
|
|
if ($row['property_id'] == $propertyId & $row['category_id'] == $categoryId) { |
|
|
|
|
678
|
|
|
$newRow = FALSE; |
679
|
|
|
break; |
680
|
|
|
} |
681
|
|
|
} |
682
|
|
|
if ($newRow == TRUE) { |
683
|
|
|
$this->productProCats[] = [ |
684
|
|
|
'property_id' => $propertyId, |
685
|
|
|
'category_id' => $categoryId, |
686
|
|
|
]; // TODO: то тоже тре бде потім розібрати |
687
|
|
|
} |
688
|
|
|
} |
689
|
|
|
} |
690
|
|
|
} |
691
|
|
|
|
692
|
|
|
return [ |
693
|
|
|
$shopProductPropertiesData, |
694
|
|
|
$brandId, |
695
|
|
|
]; |
696
|
|
|
} |
697
|
|
|
|
698
|
|
|
// ------------------------------ HELPERS ------------------------------ |
699
|
|
|
|
700
|
|
|
/** |
701
|
|
|
* Inserting data into `shop_products` |
702
|
|
|
*/ |
703
|
|
|
protected function insert1() { |
704
|
|
|
|
705
|
|
|
$this->insertProducts($this->insertCollector->getData('shop_products')); |
706
|
|
|
$this->dataLoad->getNewData('products'); |
707
|
|
|
|
708
|
|
|
// properties-categories relations |
709
|
|
|
if (count($this->productProCats) > 0) { |
710
|
|
|
$epc = $this->db->get('shop_product_properties_categories')->result_array(); |
711
|
|
|
foreach ($this->productProCats as $key => $newRowData) { |
712
|
|
|
$newRowIsReallyNew = TRUE; |
713
|
|
|
foreach ($epc as $rowData) { |
714
|
|
|
if ($newRowData['property_id'] == $rowData['property_id'] & $newRowData['category_id'] == $rowData['category_id']) { |
|
|
|
|
715
|
|
|
unset($this->productProCats[$key]); |
716
|
|
|
$newRowIsReallyNew = FALSE; |
717
|
|
|
break; |
718
|
|
|
} |
719
|
|
|
} |
720
|
|
|
if ($newRowIsReallyNew == FALSE) { |
721
|
|
|
continue; |
722
|
|
|
} |
723
|
|
|
} |
724
|
|
|
$this->insertBatch('shop_product_properties_categories', $this->productProCats); |
725
|
|
|
} |
726
|
|
|
} |
727
|
|
|
|
728
|
|
|
private function insertProducts($data) { |
729
|
|
|
if (FALSE == (count($data) > 0)) { |
730
|
|
|
return; |
731
|
|
|
} |
732
|
|
|
|
733
|
|
|
foreach ($data as $value) { |
734
|
|
|
$routeUrl = $value['url']; |
735
|
|
|
unset($value['url']); |
736
|
|
|
$value['created'] = time(); |
737
|
|
|
$value['updated'] = time(); |
738
|
|
|
$this->db->set($value)->insert('shop_products'); |
739
|
|
|
|
740
|
|
|
$id = $this->db->insert_id(); |
741
|
|
|
|
742
|
|
|
$category_id = $value['category_id']; |
743
|
|
|
if (!array_key_exists($category_id, $this->categoryUrls)) { |
744
|
|
|
$parentRoute = RouteQuery::create()->filterByType(Route::TYPE_SHOP_CATEGORY) |
745
|
|
|
->findOneByEntityId($category_id); |
746
|
|
|
$this->categoryUrls[$category_id] = $parentRoute->getFullUrl(); |
747
|
|
|
} |
748
|
|
|
|
749
|
|
|
$parentUrl = $this->categoryUrls[$category_id]; |
750
|
|
|
|
751
|
|
|
$route = new Route(); |
752
|
|
|
$route->setType(Route::TYPE_PRODUCT) |
753
|
|
|
->setParentUrl($parentUrl) |
754
|
|
|
->setUrl($routeUrl) |
755
|
|
|
->setEntityId($id) |
756
|
|
|
->save(); |
757
|
|
|
|
758
|
|
|
$this->db->update('shop_products', ['route_id' => $route->getId()], ['id' => $id]); |
759
|
|
|
|
760
|
|
|
} |
761
|
|
|
|
762
|
|
|
$error = $this->db->_error_message(); |
763
|
|
|
|
764
|
|
|
if (!empty($error)) { |
765
|
|
|
throw new Exception('Error on inserting into `shop_products`: ' . $error); |
766
|
|
|
} |
767
|
|
|
// gathering statistics |
768
|
|
|
ExchangeBase::$stats[] = [ |
769
|
|
|
'query type' => 'insert', |
770
|
|
|
'table name' => 'shop_products', |
771
|
|
|
'affected rows' => count($data), |
772
|
|
|
]; |
773
|
|
|
} |
774
|
|
|
|
775
|
|
|
/** |
776
|
|
|
* Filling with product_id tables that need it, and inserting into other tables |
777
|
|
|
* @throws \Exception |
778
|
|
|
*/ |
779
|
|
|
protected function processProducts23_Insert23() { |
780
|
|
|
|
781
|
|
|
// process 2 (adding product_id to tables data) |
782
|
|
|
$products = &$this->insertCollector->getData('shop_products'); |
783
|
|
|
$productsI18n = &$this->insertCollector->getData('shop_products_i18n'); |
784
|
|
|
$variants = &$this->insertCollector->getData('shop_product_variants'); |
785
|
|
|
$propertiesData = &$this->insertCollector->getData('shop_product_properties_data'); |
786
|
|
|
$images = &$this->insertCollector->getData('shop_product_images'); |
787
|
|
|
$productCategories = &$this->insertCollector->getData('shop_product_categories'); |
788
|
|
|
$imagesToDelete = []; |
789
|
|
|
$propertiesData_ = []; |
790
|
|
|
$imagesForInsert = []; |
791
|
|
|
|
792
|
|
|
foreach ($this->productIds as $externalId => $productId) { |
|
|
|
|
793
|
|
|
if (FALSE == isset($products[$externalId])) { |
794
|
|
|
continue; |
795
|
|
|
} |
796
|
|
|
$productsI18n[$externalId]['id'] = $productId; |
797
|
|
|
if (isset($propertiesData[$externalId])) { |
798
|
|
|
foreach ($propertiesData[$externalId] as $oneProductPropData) { |
799
|
|
|
$propertiesData_[] = array_merge($oneProductPropData, ['product_id' => $productId]); |
800
|
|
|
} |
801
|
|
|
} |
802
|
|
|
if (isset($images[$externalId])) { |
803
|
|
|
$countImgs = count($images[$externalId]); |
804
|
|
|
for ($i = 0; $i < $countImgs; $i++) { |
805
|
|
|
$images[$externalId][$i]['product_id'] = $productId; |
806
|
|
|
$imagesForInsert[] = $images[$externalId][$i]; |
807
|
|
|
} |
808
|
|
|
} |
809
|
|
|
if (isset($this->imagesToDelete[$externalId])) { |
810
|
|
|
$imagesToDelete[] = $productId; |
811
|
|
|
} |
812
|
|
|
if (isset($productCategories[$externalId])) { |
813
|
|
|
$productCategories[$externalId]['product_id'] = $productId; |
814
|
|
|
if (FALSE == $this->isProductCategoriesRowNew($productCategories[$externalId])) { |
815
|
|
|
unset($productCategories[$externalId]); |
816
|
|
|
} |
817
|
|
|
} |
818
|
|
|
} |
819
|
|
|
$this->insertCollector->unsetData('shop_product_properties_data'); |
820
|
|
|
// insert 2 (inserting those which where needed product_id) |
821
|
|
|
$this->insertBatch('shop_products_i18n', $productsI18n); |
822
|
|
|
|
823
|
|
|
foreach ($variants as $variantExId => $variantData) { |
824
|
|
|
$productExId = array_shift(explode('#', $variantExId)); |
|
|
|
|
825
|
|
|
$variants[$variantExId]['product_id'] = $this->productIds[$productExId]; |
|
|
|
|
826
|
|
|
} |
827
|
|
|
|
828
|
|
|
$this->insertBatch('shop_product_variants', $variants); |
829
|
|
|
|
830
|
|
|
// adding shop_product_properties_data and shop_product_properties_data_i18n is not so ordinary... |
831
|
|
|
if (count($propertiesData_) > 0) { |
832
|
|
|
|
833
|
|
|
$data = $this->prepareProductPropertiesData($propertiesData_); |
834
|
|
|
$this->insertBatch('shop_product_properties_data', $data); |
835
|
|
|
} |
836
|
|
|
|
837
|
|
|
// inserting shop_product_categories |
838
|
|
|
$this->insertBatch('shop_product_categories', $productCategories); |
839
|
|
|
|
840
|
|
|
//process3 (variants) |
841
|
|
|
$variantsI18n = &$this->insertCollector->getData('shop_product_variants_i18n'); |
842
|
|
|
|
843
|
|
|
$variantsIds = $this->dataLoad->getNewData('variantsIds'); |
844
|
|
|
foreach ($variantsIds as $externalId => $variantId) { |
845
|
|
|
if (FALSE == isset($variantsI18n[$externalId])) { |
846
|
|
|
continue; |
847
|
|
|
} |
848
|
|
|
$variantsI18n[$externalId]['id'] = $variantId; |
849
|
|
|
} |
850
|
|
|
|
851
|
|
|
// insert 3 |
852
|
|
|
$this->insertBatch('shop_product_variants_i18n', $variantsI18n); |
853
|
|
|
|
854
|
|
|
// deleting additional images, inserting new |
855
|
|
|
if ($imagesToDelete) { |
856
|
|
|
$this->db->where_in('product_id', $imagesToDelete)->delete('shop_product_images'); |
857
|
|
|
} |
858
|
|
|
$this->insertBatch('shop_product_images', $imagesForInsert); |
859
|
|
|
} |
860
|
|
|
|
861
|
|
|
/** |
862
|
|
|
* |
863
|
|
|
* @param array $newRowData |
864
|
|
|
* @return boolean |
865
|
|
|
*/ |
866
|
|
|
protected function isProductCategoriesRowNew(array $newRowData) { |
867
|
|
|
|
868
|
|
|
if (!isset($this->existingRows)) { |
869
|
|
|
$this->existingRows = $this->db->get('shop_product_categories')->result_array(); |
|
|
|
|
870
|
|
|
} |
871
|
|
|
|
872
|
|
|
foreach ($this->existingRows as $existingRowData) { |
873
|
|
|
if ($existingRowData['product_id'] == $newRowData['product_id'] & $existingRowData['category_id'] == $newRowData['category_id']) { |
|
|
|
|
874
|
|
|
return FALSE; |
875
|
|
|
} |
876
|
|
|
} |
877
|
|
|
return TRUE; |
878
|
|
|
} |
879
|
|
|
|
880
|
|
|
/** |
881
|
|
|
* Update all |
882
|
|
|
* @throws \Exception |
883
|
|
|
*/ |
884
|
|
|
protected function update() { |
885
|
|
|
|
886
|
|
|
// update has only two "passes" - as we already got product_id |
887
|
|
|
$this->updateFromCollector('shop_products', 'id'); |
888
|
|
|
$this->updateFromCollector('shop_product_categories', 'product_id'); |
889
|
|
|
$this->updateFromCollector('shop_products_i18n', 'id'); |
890
|
|
|
//$this->updateFromCollector('shop_product_properties_data', 'product_id'); |
891
|
|
|
// $this->updateFromCollector('shop_product_images', 'product_id'); |
892
|
|
|
$this->updateFromCollector('shop_product_variants', 'external_id'); |
893
|
|
|
|
894
|
|
|
// get variants ids, and update variants_18n |
895
|
|
|
$variantsI18n = &$this->updateCollector->getData('shop_product_variants_i18n'); |
896
|
|
|
|
897
|
|
|
$this->dataLoad->getNewData('variantsIds'); |
898
|
|
|
foreach ($variantsI18n as $exId => $variantI18n) { |
899
|
|
|
$variantsI18n[$exId]['id'] = $this->variantsIds[$exId]; |
|
|
|
|
900
|
|
|
} |
901
|
|
|
|
902
|
|
|
$this->updateBatch('shop_product_variants_i18n', $variantsI18n, 'id'); |
903
|
|
|
|
904
|
|
|
$productsIdsWithImages = []; |
905
|
|
|
$additionalImages = []; |
906
|
|
|
$additionalImages_ = &$this->updateCollector->getData('shop_product_images'); |
907
|
|
|
$countAddImgs = count($additionalImages_); |
908
|
|
|
for ($i = 0; $i < $countAddImgs; $i++) { |
909
|
|
|
foreach ($additionalImages_[$i] as $addImgData) { |
910
|
|
|
$productsIdsWithImages[] = $addImgData['product_id']; |
911
|
|
|
} |
912
|
|
|
$additionalImages = array_merge($additionalImages, $additionalImages_[$i]); |
913
|
|
|
} |
914
|
|
|
if ($productsIdsWithImages) { |
915
|
|
|
$this->db |
916
|
|
|
->where_in('product_id', array_unique($productsIdsWithImages)) |
917
|
|
|
->delete('shop_product_images'); |
918
|
|
|
} |
919
|
|
|
|
920
|
|
|
$this->insertBatch('shop_product_images', $additionalImages); |
921
|
|
|
} |
922
|
|
|
|
923
|
|
|
/** |
924
|
|
|
* Helper-method for updating |
925
|
|
|
* @param string $tableName |
926
|
|
|
* @param string $compareField |
927
|
|
|
* @throws \Exception |
928
|
|
|
*/ |
929
|
|
|
protected function updateFromCollector($tableName, $compareField) { |
930
|
|
|
|
931
|
|
|
$this->updateBatch($tableName, $this->updateCollector->getData($tableName), $compareField); |
932
|
|
|
} |
933
|
|
|
|
934
|
|
|
// ----------------------- end of HELPERS ------------------------------ |
935
|
|
|
|
936
|
|
|
/** |
937
|
|
|
* Set shop categories for products |
938
|
|
|
* @throws Exception |
939
|
|
|
*/ |
940
|
|
|
public function rebuildAdditionalParentsCats() { |
941
|
|
|
|
942
|
|
|
$ids = []; |
943
|
|
|
|
944
|
|
|
foreach ($this->products as $products) { |
|
|
|
|
945
|
|
|
$ids[] = $products['id']; |
946
|
|
|
} |
947
|
|
|
|
948
|
|
|
$products = $this->db |
949
|
|
|
->select('shop_products.category_id, shop_products.id, shop_category.full_path_ids, shop_category.parent_id, shop_category.id as cat_id') |
950
|
|
|
->join('shop_category', 'shop_category.id = shop_products.category_id') |
951
|
|
|
->where_in('shop_products.id', $ids) |
952
|
|
|
->get('shop_products') |
953
|
|
|
->result(); |
954
|
|
|
|
955
|
|
|
foreach ($products as $p) { |
956
|
|
|
$this->parentCat[$p->id] = $p->category_id; |
957
|
|
|
} |
958
|
|
|
|
959
|
|
|
if ($this->ignoreExistingProducts) { |
960
|
|
|
// deleting only "path categories" data (parents) |
961
|
|
|
foreach ($this->additionalParentsCategories as $productId => $parentCategoriesIds) { |
962
|
|
|
|
963
|
|
|
array_push($parentCategoriesIds, $this->parentCat[$productId]); |
964
|
|
|
if ($parentCategoriesIds and in_array($productId, $ids)) { |
965
|
|
|
$this->db |
966
|
|
|
->where('product_id', $productId) |
967
|
|
|
->where_in('category_id', $parentCategoriesIds) |
968
|
|
|
->delete('shop_product_categories'); |
969
|
|
|
} |
970
|
|
|
} |
971
|
|
|
} else { |
972
|
|
|
$this->db->where_in('product_id', $ids)->delete('shop_product_categories'); |
973
|
|
|
} |
974
|
|
|
|
975
|
|
|
foreach ($products as $product) { |
976
|
|
|
$pathIds = unserialize($product->full_path_ids); |
977
|
|
|
|
978
|
|
|
array_push($pathIds, $product->cat_id); |
979
|
|
|
foreach ($pathIds as $categoryId) { |
980
|
|
|
$this->db->insert( |
981
|
|
|
'shop_product_categories', |
982
|
|
|
[ |
983
|
|
|
'category_id' => $categoryId, |
984
|
|
|
'product_id' => $product->id, |
985
|
|
|
] |
986
|
|
|
); |
987
|
|
|
} |
988
|
|
|
} |
989
|
|
|
} |
990
|
|
|
|
991
|
|
|
private function runResize() { |
992
|
|
|
|
993
|
|
|
if ($this->runResize) { |
994
|
|
|
Image::create() |
995
|
|
|
->resizeByName($this->imagesToResize) |
996
|
|
|
->resizeByNameAdditional(array_unique($this->imagesToResizeAdditional)); |
997
|
|
|
} |
998
|
|
|
} |
999
|
|
|
|
1000
|
|
|
protected function rebuildProductProperties() { |
1001
|
|
|
|
1002
|
|
|
$productTableProperties = $this->db->select('shop_product_properties_data.property_id, shop_product_property_value_i18n.value, shop_product_property_value_i18n.locale') |
1003
|
|
|
->from('shop_product_properties_data') |
1004
|
|
|
->join('shop_product_property_value', 'shop_product_properties_data.value_id = shop_product_property_value.id') |
1005
|
|
|
->join('shop_product_property_value_i18n', 'shop_product_property_value.id = shop_product_property_value_i18n.id') |
1006
|
|
|
->get()->result_array(); |
1007
|
|
|
|
1008
|
|
|
$propertiesTableValues = $this->db->select('id, data, locale')->get('shop_product_properties_i18n')->result_array(); |
1009
|
|
|
|
1010
|
|
|
// array: |
1011
|
|
|
// [property_id][array property_locales][array property_values] |
1012
|
|
|
|
1013
|
|
|
$productPropertiesOrdered = []; |
1014
|
|
|
|
1015
|
|
|
foreach ($productTableProperties as $one) { |
1016
|
|
|
if (!isset($productPropertiesOrdered[$one['property_id']])) { |
1017
|
|
|
$productPropertiesOrdered[$one['property_id']] = []; |
1018
|
|
|
} |
1019
|
|
|
if (!isset($productPropertiesOrdered[$one['property_id']][$one['locale']])) { |
1020
|
|
|
$productPropertiesOrdered[$one['property_id']][$one['locale']] = []; |
1021
|
|
|
} |
1022
|
|
|
if (!in_array($one['value'], $productPropertiesOrdered[$one['property_id']][$one['locale']], true)) { |
1023
|
|
|
array_push($productPropertiesOrdered[$one['property_id']][$one['locale']], $one['value']); |
1024
|
|
|
} |
1025
|
|
|
} |
1026
|
|
|
|
1027
|
|
|
foreach ($propertiesTableValues as $one) { |
1028
|
|
|
$id = $one['id']; |
1029
|
|
|
$locale = $one['locale']; |
1030
|
|
|
$insertData = []; |
1031
|
|
|
$res = true; |
1032
|
|
|
$error = false; |
1033
|
|
|
|
1034
|
|
|
if (array_key_exists($id, $productPropertiesOrdered) && array_key_exists($locale, $productPropertiesOrdered[$id])) { |
1035
|
|
|
$onePropertyValues = unserialize($one['data']) ?: []; |
1036
|
|
|
$insertData['data'] = serialize(array_unique(array_merge($onePropertyValues, $productPropertiesOrdered[$id][$locale]))); |
1037
|
|
|
$res = $res && $this->db->where('id', $id)->update('shop_product_properties_i18n', $insertData); |
|
|
|
|
1038
|
|
|
$error = $this->db->_error_message() ?: $error; |
|
|
|
|
1039
|
|
|
} |
1040
|
|
|
} |
1041
|
|
|
} |
1042
|
|
|
|
1043
|
|
|
/** |
1044
|
|
|
* @param bool $run_resize |
1045
|
|
|
* @return $this |
1046
|
|
|
*/ |
1047
|
|
|
public function setResize($run_resize = FALSE) { |
1048
|
|
|
|
1049
|
|
|
$this->runResize = $run_resize; |
1050
|
|
|
return $this; |
1051
|
|
|
} |
1052
|
|
|
|
1053
|
|
|
/** |
1054
|
|
|
* Setting temporary folder with import data. Mantadory! |
1055
|
|
|
* @param string $tempDir |
1056
|
|
|
* @return $this |
1057
|
|
|
*/ |
1058
|
|
|
public function setTempDir($tempDir) { |
1059
|
|
|
|
1060
|
|
|
$this->tempDir = $tempDir; |
1061
|
|
|
return $this; |
1062
|
|
|
} |
1063
|
|
|
|
1064
|
|
|
private function getPropertyValueIdOrCreate($propertyId, $value, $locale) { |
1065
|
|
|
$valueModel = \SPropertyValueQuery::create() |
1066
|
|
|
->joinWithI18n($locale, Criteria::INNER_JOIN) |
1067
|
|
|
->useI18nQuery($locale) |
1068
|
|
|
->filterByValue($value) |
1069
|
|
|
->endUse() |
1070
|
|
|
->filterByPropertyId($propertyId) |
1071
|
|
|
->findOne(); |
1072
|
|
|
|
1073
|
|
|
if (!$valueModel) { |
1074
|
|
|
$valueModel = new \SPropertyValue(); |
1075
|
|
|
$valueModel->setPropertyId($propertyId) |
1076
|
|
|
->setValue($value) |
1077
|
|
|
->setLocale($locale) |
1078
|
|
|
->save(); |
1079
|
|
|
|
1080
|
|
|
} |
1081
|
|
|
|
1082
|
|
|
return $valueModel->getId(); |
1083
|
|
|
} |
1084
|
|
|
|
1085
|
|
|
private function prepareProductPropertiesData($propertiesData) { |
1086
|
|
|
|
1087
|
|
|
$data = []; |
1088
|
|
|
foreach ($propertiesData as $key => $item) { |
1089
|
|
|
|
1090
|
|
|
$dataItem = [ |
1091
|
|
|
'property_id' => $item['property_id'], |
1092
|
|
|
'product_id' => $item['product_id'], |
1093
|
|
|
'value_id' => $this->getPropertyValueIdOrCreate($item['property_id'], $item['value'], $item['locale']), |
1094
|
|
|
|
1095
|
|
|
]; |
1096
|
|
|
$data[] = $dataItem; |
1097
|
|
|
} |
1098
|
|
|
|
1099
|
|
|
return $data; |
1100
|
|
|
} |
1101
|
|
|
|
1102
|
|
|
} |
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.
If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.