GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

XmlFileReader::createProduct()   F
last analyzed

Complexity

Conditions 29
Paths 173

Size

Total Lines 117

Duplication

Lines 14
Ratio 11.97 %

Importance

Changes 0
Metric Value
dl 14
loc 117
rs 2.8466
c 0
b 0
f 0
cc 29
nc 173
nop 2

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace app\modules\data\components\commerceml;
4
5
use app\components\Helper;
6
use app\modules\data\models\CommercemlGuid;
7
use app\modules\shop\models\Category;
8
use app\models\BaseObject;
9
use app\models\ObjectPropertyGroup;
10
use app\models\ObjectStaticValues;
11
use app\modules\shop\models\CategoryGroup;
12
use app\modules\shop\models\Product;
13
use app\models\Property;
14
use app\models\PropertyStaticValues;
15
use app\properties\AbstractPropertyEavModel;
16
17
class XmlFileReader
18
{
19
    protected $filename = null;
20
    /** @var \XMLReader|null $xml */
21
    protected $xml = null;
22
23
    protected $categoryCache = [];
24
    protected $rootCategoryCache = 1;
25
    static protected $propertiesCache = [];
26
    protected $productCache = [];
27
    /** @var \app\models\BaseObject|null $objectProduct */
28
    protected $objectProduct = null;
29
30
    const NODE_CLASSIFICATOR = 'Классификатор';
31
    const NODE_CATALOG = 'Каталог';
32
    const NODE_PAKET_PREDLOZHENIY = 'ПакетПредложений';
33
    const NODE_SVOISTVA = 'Свойства';
34
    const NODE_SVOISTVO = 'Свойство';
35
    const NODE_GRUPPY = 'Группы';
36
    const NODE_GRUPPA = 'Группа';
37
    const NODE_TOVARY = 'Товары';
38
    const NODE_TOVAR = 'Товар';
39
    const NODE_ZNACHENIYA_SVOISTV = 'ЗначенияСвойств';
40
    const NODE_PREDLOZHENIYA = 'Предложения';
41
    const NODE_PREDLOZHENIE = 'Предложение';
42
    const ELEMENT_ID = 'Ид';
43
    const ELEMENT_NAIMENOVANIE = 'Наименование';
44
    const ELEMENT_OPISANIE = 'Описание';
45
    const ELEMENT_ARTIKUL = 'Артикул';
46
    const ELEMENT_BAZOVAYA_EDENICA = 'БазоваяЕдиница';
47
    const ELEMENT_ZNACHENIE_SVOISTVA = 'ЗначенияСвойства';
48
    const ELEMENT_ZNACHENIE = 'Значение';
49
    const ELEMENT_KOLICHESTVO = 'Количество';
50
    const ELEMENT_CENY = 'Цены';
51
    const ELEMENT_CENA = 'Цена';
52
    const ELEMENT_CENA_ZA_EDENICU = 'ЦенаЗаЕдиницу';
53
54
    const FILETYPE_IMPORT = 1;
55
    const FILETYPE_OFFERS = 2;
56
57
    function __construct($filename)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
58
    {
59
        if (is_file($filename)) {
60
            $this->filename = $filename;
61
            $xml = new \XMLReader();
62
            if (false !== $xml->open($filename)) {
63
                $this->xml = $xml;
64
65
                $rootCategory = Category::findOne(['parent_id' => 0]);
66
                if (empty($rootCategory)) {
67
                    if (null === $rootCategory = Category::createEmptyCategory(0, null, 'Каталог')) {
68
                        $this->xml->close();
69
                        $this->xml = null;
70
                    }
71
                    $this->rootCategoryCache = $rootCategory->id;
72
                } else {
73
                    $this->rootCategoryCache = $rootCategory->id;
74
                }
75
76
                if (empty(static::$propertiesCache)) {
77
                    static::$propertiesCache = array_reduce(CommercemlGuid::find([['>', 'model_id', 0], ['type' => 'PROPERTY']])->all(),
0 ignored issues
show
Documentation Bug introduced by
It seems like array_reduce(\app\module...rn $result; }, array()) of type * is incompatible with the declared type array of property $propertiesCache.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
78
                        function ($result, $item) {
79
                            $result[$item['guid']] = $item->property;
80
                            return $result;
81
                        }, []);
82
                }
83
                $product = \Yii::$container->get(Product::class);
84
                $this->objectProduct = BaseObject::getForClass(get_class($product));
85
            }
86
        }
87
    }
88
89
    /**
90
     *
91
     */
92
    function __destruct()
93
    {
94
        if (null !== $this->xml) {
95
            $this->xml->close();
96
        }
97
    }
98
99
    /**
100
     * Try to guess file "structure" for ordering multiple incoming files
101
     * @return int|null
102
     */
103
    public function fileType()
104
    {
105
        if (null === $this->xml) {
106
            return null;
107
        }
108
        $xml = $this->xml;
109
110
        while ($xml->read()) {
111
            if (\XMLReader::ELEMENT === $xml->nodeType && 1 === $xml->depth) {
112
                if (static::NODE_PAKET_PREDLOZHENIY === $xml->name) {
113
                    return static::FILETYPE_OFFERS;
114
                } else if (static::NODE_CATALOG === $xml->name) {
115
                    return static::FILETYPE_IMPORT;
116
                }
117
                $xml->next();
118
            }
119
        }
120
121
        return null;
122
    }
123
124
    /**
125
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
126
     */
127
    public function getProperties()
128
    {
129
        if (null === $this->xml) {
130
            return [];
131
        }
132
        $xml = $this->xml;
133
134
        while ($xml->read()) {
135
            if (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_CLASSIFICATOR === $xml->name) {
136
                while ($xml->read()) {
137
                    if (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_SVOISTVA === $xml->name) {
138
                        return $this->parseSvoistva();
139
                    }
140
                }
141
                break;
142
            }
143
        }
144
    }
145
146
    /**
147
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
148
     */
149
    public function parseSvoistva()
150
    {
151
        if (null === $this->xml) {
152
            return [];
153
        }
154
        $xml = $this->xml;
155
156
        $result = [];
157
        while ($xml->read()) {
158
            if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_SVOISTVA === $xml->name) {
159
                return $result;
160
            } else if (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_SVOISTVO === $xml->name) {
161
                $item = [];
162
                while ($xml->read()) {
163
                    if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_SVOISTVO === $xml->name) {
164
                        if (!empty($item)) {
165
                            $result[] = $item;
166
                        }
167
                        break;
168
                    } elseif (\XMLReader::ELEMENT === $xml->nodeType && in_array($xml->name, [static::ELEMENT_ID, static::ELEMENT_NAIMENOVANIE])) {
169
                        $_name = $xml->name;
170
                        $_value = $this->getElementText($_name);
171
                        if (!empty($_value)) {
172
                            $item[$_name] = $_value;
173
                        }
174
                    }
175
                }
176
            }
177
        }
178
    }
179
180
    /**
181
     * @return array|bool
182
     */
183 View Code Duplication
    public function parseProduct()
184
    {
185
        if (null === $this->xml) {
186
            return [];
187
        }
188
        $xml = $this->xml;
189
190
        while ($xml->read()) {
191
            if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_TOVARY === $xml->name) {
192
                return true;
193
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_TOVAR === $xml->name) {
194
                $this->createProduct($this->parseTovar());
195
            }
196
        }
197
    }
198
199
    /**
200
     * @return array
201
     */
202
    public function parseTovar()
203
    {
204
        if (null === $this->xml) {
205
            return [];
206
        }
207
        $xml = $this->xml;
208
        $depthProduct = $xml->depth;
209
        $result = [];
210
211
        $subElements = [
212
            static::ELEMENT_ID,
213
            static::ELEMENT_NAIMENOVANIE,
214
            static::ELEMENT_ARTIKUL,
215
            static::ELEMENT_BAZOVAYA_EDENICA,
216
            static::ELEMENT_OPISANIE,
217
        ];
218
219
        while ($xml->read()) {
220
            // Достигли окончания Товара
221
            if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_TOVAR === $xml->name) {
222
                return $result;
223
            // Получаем значения для элементов
224
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && in_array($xml->name, $subElements) && (1 === ($xml->depth - $depthProduct))) {
225
                $_name = $xml->name;
226
                $_value = $this->getElementText($_name);
227
                if (!empty($_value)) {
228
                    $result[$_name] = $_value;
229
                }
230
            // Достигли начала блока Свойств
231
            } elseif(\XMLReader::ELEMENT === $xml->nodeType && static::NODE_ZNACHENIYA_SVOISTV === $xml->name) {
232
                $result['properties'] = [];
233
            // Получаем значения для Свойства
234
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::ELEMENT_ZNACHENIE_SVOISTVA === $xml->name) {
235
                $_temp = [];
236
                while ($xml->read()) {
237
                    if (\XMLReader::END_ELEMENT === $xml->nodeType && static::ELEMENT_ZNACHENIE_SVOISTVA === $xml->name) {
238
                        if (isset($_temp[static::ELEMENT_ID]) && isset($_temp[static::ELEMENT_ZNACHENIE])) {
239
                            $result['properties'][$_temp[static::ELEMENT_ID]] = $_temp[static::ELEMENT_ZNACHENIE];
240
                        }
241
                        break;
242
                    } elseif (\XMLReader::ELEMENT === $xml->nodeType && in_array($xml->name, [static::ELEMENT_ID, static::ELEMENT_ZNACHENIE])) {
243
                        $_name = $xml->name;
244
                        if (null !== $_value = $this->getElementText($_name)) {
245
                            $_temp[$_name] = $_value;
246
                        }
247
                    }
248
                }
249
            // Получаем привязки к Категориям
250 View Code Duplication
            } elseif(\XMLReader::ELEMENT === $xml->nodeType && static::NODE_GRUPPY === $xml->name) {
251
                $result['categories'] = [];
252
                while ($xml->read()) {
253
                    if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_GRUPPY === $xml->name) {
254
                        break;
255
                    } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::ELEMENT_ID === $xml->name) {
256
                        if (null !== $_value = $this->getElementText($xml->name)) {
257
                            $result['categories'][] = $_value;
258
                        }
259
                    }
260
                }
261
            }
262
        }
263
264
        return $result;
265
    }
266
267
    public function parseGruppa($parent)
268
    {
269
        if (null === $this->xml) {
270
            return [];
271
        }
272
        $xml = $this->xml;
273
274
        $result = [];
275
        $lastParent = $parent;
276
277
        while ($xml->read()) {
278
            if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_GRUPPY === $xml->name) {
279
                return $result;
280
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_GRUPPY === $xml->name) {
281
                if (!empty($item)) {
282
                    $result[] = $lastParent = $this->createCategory($item, $parent);
283
                }
284
                $result = array_merge($result, $this->parseGruppa($lastParent));
285
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_GRUPPA === $xml->name) {
286
                $item = [];
287
                $lastParent = $parent;
288
            } elseif (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_GRUPPA === $xml->name) {
289
                if (!empty($item)) {
290
                    $result[] = $this->createCategory($item, $parent);
291
                }
292
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && in_array($xml->name, [static::ELEMENT_ID, static::ELEMENT_NAIMENOVANIE])) {
293
                $_name = $xml->name;
294
                if (null !== $_value = $this->getElementText($_name)) {
295
                    $item[$_name] = $_value;
0 ignored issues
show
Bug introduced by
The variable $item does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
296
                }
297
            }
298
        }
299
    }
300
301 View Code Duplication
    public function parseOffers()
302
    {
303
        if (null === $this->xml) {
304
            return [];
305
        }
306
        $xml = $this->xml;
307
308
        while ($xml->read()) {
309
            if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_PREDLOZHENIYA === $xml->name) {
310
                return true;
311
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_PREDLOZHENIE === $xml->name) {
312
                $this->createProduct($this->parsePredlozhenie(), false);
313
            }
314
        }
315
    }
316
317
    public function parsePredlozhenie()
318
    {
319
        if (null === $this->xml) {
320
            return [];
321
        }
322
        $xml = $this->xml;
323
        $result = [];
324
325
        while ($xml->read()) {
326
            if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_PREDLOZHENIE === $xml->name) {
327
                break;
328
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && in_array($xml->name, [static::ELEMENT_ID, static::ELEMENT_KOLICHESTVO, static::ELEMENT_NAIMENOVANIE])) {
329
                $_name = $xml->name;
330
                if (null !== $_value = $this->getElementText($_name)) {
331
                    $result[$_name] = $_value;
332
                }
333 View Code Duplication
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::ELEMENT_CENY === $xml->name) {
334
                $result['price'] = [];
335
                while ($xml->read()) {
336
                    if (\XMLReader::END_ELEMENT === $xml->nodeType && static::ELEMENT_CENY === $xml->name) {
337
                        break;
338
                    } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::ELEMENT_CENA_ZA_EDENICU === $xml->name) {
339
                        $_name = $xml->name;
340
                        if (null !== $_value = $this->getElementText($_name)) {
341
                            $result['price'][] = $_value;
342
                        }
343
                    }
344
                }
345
            }
346
        }
347
348
        return $result;
349
    }
350
351
    public function parse()
352
    {
353
        if (null === $this->xml) {
354
            return [];
355
        }
356
        $xml = $this->xml;
357
358
        $result = [];
359
360
        while ($xml->read()) {
361
            // Разбор Классификатора
362
            if (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_CLASSIFICATOR === $xml->name) {
363 View Code Duplication
                while ($xml->read()) {
364
                    if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_CLASSIFICATOR === $xml->name) {
365
                        break;
366
                    } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_GRUPPY === $xml->name) {
367
                        $result['categories'] = $this->parseGruppa($this->rootCategoryCache);
368
                    }
369
                }
370
            // Разбор Каталога
371
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_CATALOG === $xml->name) {
372 View Code Duplication
                while ($xml->read()) {
373
                    if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_CATALOG === $xml->name) {
374
                        break;
375
                    } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_TOVARY === $xml->name) {
376
                        $this->parseProduct();
377
                    }
378
                }
379
            // Разбор Предложений
380
            } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_PAKET_PREDLOZHENIY === $xml->name) {
381 View Code Duplication
                while ($xml->read()) {
382
                    if (\XMLReader::END_ELEMENT === $xml->nodeType && static::NODE_PAKET_PREDLOZHENIY === $xml->name) {
383
                        break;
384
                    } elseif (\XMLReader::ELEMENT === $xml->nodeType && static::NODE_PREDLOZHENIYA === $xml->name) {
385
                        $this->parseOffers();
386
                    }
387
                }
388
            }
389
        }
390
    }
391
392
    /**
393
     * @param array $item
394
     * @param int $parentId
395
     * @return int
396
     */
397
    protected function createCategory($item, $parentId)
398
    {
399
        if (empty($item) || empty($item[static::ELEMENT_ID]) || empty($item[static::ELEMENT_NAIMENOVANIE])) {
400
            return $parentId;
401
        }
402
        $result = $parentId;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
403
404
        if (isset($this->categoryCache[$item[static::ELEMENT_ID]])) {
405
            $result = $this->categoryCache[$item[static::ELEMENT_ID]];
406
        } else {
407
            $guid = CommercemlGuid::findOne(['guid' => $item[static::ELEMENT_ID]]);
408
409
            if (empty($guid)) {
410
                $guid = new CommercemlGuid();
411
                    $guid->guid = $item[static::ELEMENT_ID];
412
                    $guid->name = $item[static::ELEMENT_NAIMENOVANIE];
413
                    $guid->type = 'CATEGORY';
414
                    $guid->model_id = 1;
415
416
                $category = Category::findOne(['slug' => Helper::createSlug($item[static::ELEMENT_NAIMENOVANIE]), 'parent_id' => $parentId]);
417
                if (empty($category)) {
418
                    if (null !== $category = Category::createEmptyCategory($parentId, null, $item[static::ELEMENT_NAIMENOVANIE])) {
419
                        $guid->model_id = $category->id;
420
                    }
421
                } else {
422
                    $guid->model_id = $category->id;
423
                }
424
                $guid->save();
425
                $guid->refresh();
426
427
                $result = $this->categoryCache[$item[static::ELEMENT_ID]] = $guid->model_id;
428
            } else {
429
                $result = $this->categoryCache[$item[static::ELEMENT_ID]] = $guid->model_id;
430
            }
431
        }
432
433
        return $result;
434
    }
435
436
    protected function createProduct($item = [], $createNotExists = true)
437
    {
438
        if (empty($item) || !isset($item[static::ELEMENT_ID]) || !isset($item[static::ELEMENT_NAIMENOVANIE])) {
439
            return false;
440
        }
441
442
        $guid = CommercemlGuid::findOne(['guid' => $item[static::ELEMENT_ID], 'type' => 'PRODUCT']);
443
        if (empty($guid) && $createNotExists) {
444
            $category = !empty($item['categories']) ? array_shift($item['categories']) : null;
445
            $product = \Yii::$container->get(Product::class);
446
                $product->name = $product->title = $product->h1 = $item[static::ELEMENT_NAIMENOVANIE];
447
                $product->slug = Helper::createSlug($product->name);
448
                $product->main_category_id = isset($this->categoryCache[$category]) ? $this->categoryCache[$category] : $this->rootCategoryCache;
449
                $product->content = empty($item[static::ELEMENT_OPISANIE]) ? '' : $item[static::ELEMENT_OPISANIE];
450
            if ($product->validate() && $product->save()) {
451
                $product->refresh();
452
                $product->linkToCategory($this->rootCategoryCache);
453
                $guid = new CommercemlGuid();
454
                    $guid->guid = $item[static::ELEMENT_ID];
455
                    $guid->name = $item[static::ELEMENT_NAIMENOVANIE];
456
                    $guid->model_id = $product->id;
457
                    $guid->type = 'PRODUCT';
458
                $guid->save();
459
460
                return true;
461
            }
462
        }
463
464
        if (!empty($guid)) {
465
            /** @var Product $product */
466
            $product = isset($product) ? $product : $guid->product;
467
            if (!empty($product)) {
468
                $product->price = empty($item['price']) ?: array_shift($item['price']);
469
                $product->content = empty($item[static::ELEMENT_OPISANIE]) ?: $item[static::ELEMENT_OPISANIE];
470
                $product->name = empty($item[static::ELEMENT_NAIMENOVANIE]) ?: $item[static::ELEMENT_NAIMENOVANIE];
471
472
                if (!empty($item['properties'])) {
473
                    AbstractPropertyEavModel::setTableName($this->objectProduct->eav_table_name);
474
                    $product_eav = array_reduce(AbstractPropertyEavModel::findByModelId($product->id),
475
                        function ($result, $item)
476
                        {
477
                            $key = $item->property_group_id . ':' . $item->key;
478
                            $result[$key] = $item;
479
                            return $result;
480
                        }, []);
481
                    $product_groups = array_reduce(ObjectPropertyGroup::getForModel($product),
482
                        function ($result, $item)
483
                        {
484
                            $result[] = $item->property_group_id;
485
                            return $result;
486
                        }, []);
487
                    $product_osv = array_reduce(ObjectStaticValues::findAll(['object_id' => $this->objectProduct->id, 'object_model_id' => $product->id]),
488
                        function ($result, $item)
489
                        {
490
                            $result[] = $item->property_static_value_id;
491
                            return $result;
492
                        }, []);
493
494
                    foreach ($item['properties'] as $key => $value) {
495
                        if (isset(static::$propertiesCache[$key])) {
496
                            /** @var Property $prop */
497
                            $prop = static::$propertiesCache[$key];
498 View Code Duplication
                            if (!in_array($prop->property_group_id, $product_groups)) {
499
                                $objectGroup = new ObjectPropertyGroup();
500
                                    $objectGroup->object_id = $this->objectProduct->id;
501
                                    $objectGroup->object_model_id = $product->id;
502
                                    $objectGroup->property_group_id = $prop->property_group_id;
503
                                $objectGroup->save();
504
                            }
505
                            if ($prop->has_static_values) {
506
                                $psv = PropertyStaticValues::findOne(['value' => $value]);
507
                                if (empty($psv)) {
508
                                    $psv = new PropertyStaticValues();
509
                                        $psv->name = $psv->value = $value;
510
                                        $psv->property_id = $prop->id;
511
                                        $psv->slug = Helper::createSlug($value);
512
                                        if ($psv->validate() && $psv->save()) {
513
                                            $psv->refresh();
514
                                        } else {
515
                                            $psv = null;
516
                                        }
517
                                }
518 View Code Duplication
                                if (!empty($psv) && !in_array($psv->id, $product_osv)) {
519
                                    $osv = new ObjectStaticValues();
520
                                        $osv->object_id = $this->objectProduct->id;
521
                                        $osv->object_model_id = $product->id;
522
                                        $osv->property_static_value_id = $psv->id;
523
                                    $osv->save();
524
                                }
525
                            } elseif ($prop->is_eav) {
526
                                $_key = $prop->property_group_id . ':' . $prop->key;
527
                                if (isset($product_eav[$_key])) {
528
                                    /** @var AbstractPropertyEavModel $eav */
529
                                    $eav = $product_eav[$_key];
530
                                        $eav->value = $value;
531
                                    $eav->save();
532
                                } else {
533
                                    $eav = new AbstractPropertyEavModel();
534
                                        $eav->object_model_id = $product->id;
535
                                        $eav->property_group_id = $prop->property_group_id;
536
                                        $eav->key = $prop->key;
537
                                        $eav->value = $value;
538
                                    $eav->save();
539
                                }
540
                            }
541
                        }
542
                    }
543
                }
544
545
                $product->save();
546
547
                return true;
548
            }
549
        }
550
551
        return false;
552
    }
553
554
    /**
555
     * @param string|null $elementName
556
     * @param int $nodeType
557
     * @param null $defaultValue
558
     * @return string|null
559
     */
560
    protected function getElementText($elementName = null, $nodeType = \XMLReader::TEXT, $defaultValue = null)
561
    {
562
        if (empty($elementName)) {
563
            return $defaultValue;
564
        }
565
566
        $xml = $this->xml;
567
        if (!$xml->isEmptyElement) {
568
            while ($xml->read()) {
569
                if (\XMLReader::END_ELEMENT === $xml->nodeType && $elementName === $xml->name) {
570
                    break;
571
                } elseif ($nodeType === $xml->nodeType) {
572
                    return $xml->value;
573
                }
574
            }
575
        }
576
577
        return $defaultValue;
578
    }
579
}
580
?>