Test Failed
Push — master ( 23cc6e...476483 )
by Alexey
05:28
created

Item::getPrice()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 4
nc 4
nop 1
dl 0
loc 6
rs 9.2
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Item
5
 *
6
 * @author Alexey Krupskiy <[email protected]>
7
 * @link http://inji.ru/
8
 * @copyright 2015 Alexey Krupskiy
9
 * @license https://github.com/injitools/cms-Inji/blob/master/LICENSE
10
 */
11
12
namespace Ecommerce;
13
/**
14
 * @property int $id
15
 * @property int $category_id
16
 * @property int $image_file_id
17
 * @property string $name
18
 * @property string $subtitle
19
 * @property string $alias
20
 * @property string $description
21
 * @property int $item_type_id
22
 * @property bool $best
23
 * @property int $item_badge_id
24
 * @property bool $deleted
25
 * @property int $user_id
26
 * @property int $weight
27
 * @property int $sales
28
 * @property string $imported
29
 * @property string $tree_path
30
 * @property string $search_index
31
 * @property string $date_create
32
 * @property string $widget
33
 * @property string $view
34
 *
35
 * @property-read \Ecommerce\Item\Badge $badge
36
 * @property-read \Ecommerce\Category $category
37
 * @property-read \Ecommerce\Item\Param[] $options
38
 * @property-read \Ecommerce\Item\Offer[] $offers
39
 * @method  \Ecommerce\Item\Offer[] offers($options)
40
 * @property-read \Ecommerce\Item\Type $type
41
 * @property-read \Files\File $image
42
 * @property-read \Ecommerce\Item\Image[] $images
43
 * @property-read \Users\User $user
44
 */
45
class Item extends \Model {
46
47
    public static $categoryModel = 'Ecommerce\Category';
48
    public static $objectName = 'Товар';
49
    public static $labels = [
50
        'name' => 'Название',
51
        'title' => 'Торговое название',
52
        'subtitle' => 'Подзаголовок',
53
        'alias' => 'Алиас',
54
        'item_badge_id' => 'Наклейка',
55
        'category_id' => 'Раздел',
56
        'description' => 'Описание',
57
        'item_type_id' => 'Тип товара',
58
        'image_file_id' => 'Изображение',
59
        'best' => 'Лучшее предложение',
60
        'options' => 'Параметры',
61
        'offers' => 'Торговые предложения',
62
        'widget' => 'Виджет для отображения в каталоге',
63
        'view' => 'Шаблон для отображения полной информации',
64
        'deleted' => 'Удален',
65
        'imgs' => 'Фото',
66
        'date_create' => 'Дата создания'
67
    ];
68
    public static $cols = [
69
        //Основные параметры
70
        'category_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'category'],
71
        'image_file_id' => ['type' => 'image'],
72
        'name' => ['type' => 'text'],
73
        'title' => ['type' => 'text'],
74
        'subtitle' => ['type' => 'text'],
75
        'alias' => ['type' => 'text'],
76
        'description' => ['type' => 'html'],
77
        'item_type_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'type'],
78
        'best' => ['type' => 'bool'],
79
        'item_badge_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'badge'],
80
        'deleted' => ['type' => 'bool'],
81
        //Системные
82
        'user_id' => ['type' => 'select', 'source' => 'relation', 'relation' => 'user'],
83
        'weight' => ['type' => 'number'],
84
        'sales' => ['type' => 'number'],
85
        'imported' => ['type' => 'text'],
86
        'tree_path' => ['type' => 'text'],
87
        'search_index' => ['type' => 'text', 'logging' => false],
88
        'date_create' => ['type' => 'dateTime'],
89
        'widget' => ['type' => 'text'],
90
        'view' => ['type' => 'text'],
91
        //Менеджеры
92
        'options' => ['type' => 'dataManager', 'relation' => 'options'],
93
        'offers' => ['type' => 'dataManager', 'relation' => 'offers'],
94
        'imgs' => ['type' => 'dataManager', 'relation' => 'images'],
95
    ];
96
97
    public static function simpleItemHandler($request) {
98
        if ($request) {
99
            $item = new Item();
100
            $item->name = $request['name'];
101
            $item->description = $request['description'];
102
            $item->category_id = $request['category'];
103
            $item->save();
104
            if (!empty($_FILES['ActiveForm_simpleItem']['tmp_name']['Ecommerce\Item']['image'])) {
105
                $file_id = \App::$primary->files->upload([
106
                    'tmp_name' => $_FILES['ActiveForm_simpleItem']['tmp_name']['Ecommerce\Item']['image'],
107
                    'name' => $_FILES['ActiveForm_simpleItem']['name']['Ecommerce\Item']['image'],
108
                    'type' => $_FILES['ActiveForm_simpleItem']['type']['Ecommerce\Item']['image'],
109
                    'size' => $_FILES['ActiveForm_simpleItem']['size']['Ecommerce\Item']['image'],
110
                    'error' => $_FILES['ActiveForm_simpleItem']['error']['Ecommerce\Item']['image'],
111
                ], [
112
                    'upload_code' => 'activeForm:' . 'Ecommerce\Item' . ':' . $item->pk(),
113
                    'accept_group' => 'image'
114
                ]);
115
                if ($file_id) {
116
                    $item->image_file_id = $file_id;
117
                    $item->save();
118
                }
119
            }
120 View Code Duplication
            if (!empty($request['options']['option'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
121
                foreach ($request['options']['option'] as $key => $option_id) {
122
                    $param = new Item\Param();
123
                    $param->item_id = $item->id;
124
                    $param->value = $request['options']['value'][$key];
125
                    $param->item_option_id = $option_id;
126
                    $param->save();
127
                }
128
            }
129
            $offer = new Item\Offer();
130
            $offer->item_id = $item->id;
131
            $offer->save();
132 View Code Duplication
            if (!empty($request['offerOptions']['option'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
133
                foreach ($request['offerOptions']['option'] as $key => $option_id) {
134
                    $param = new Item\Offer\Param();
135
                    $param->item_offer_id = $offer->id;
136
                    $param->value = $request['offerOptions']['value'][$key];
137
                    $param->item_offer_option_id = $option_id;
138
                    $param->save();
139
                }
140
            }
141
            $price = new Item\Offer\Price();
142
            $price->price = $request['price'];
143
            $price->item_offer_id = $offer->id;
144
            $price->currency_id = $request['currency'];
145
            $price->save();
146
        }
147
    }
148
149
    public static $dataManagers = [
150
        'manager' => [
151
            'name' => 'Товары',
152
            'cols' => [
153
                'name',
154
                'imgs',
155
                'category_id',
156
                'item_type_id',
157
                'best',
158
                'deleted',
159
                'options',
160
                'offers',
161
                'date_create'
162
            ],
163
            'categorys' => [
164
                'model' => 'Ecommerce\Category',
165
            ],
166
            'sortable' => ['date_create'],
167
            'preSort' => [
168
                'date_create' => 'desc'
169
            ],
170
            'filters' => [
171
                'name', 'best', 'deleted', 'date_create'
172
            ],
173
            'sortMode' => true
174
        ]
175
    ];
176
    public static $forms = [
177
        'manager' => [
178
            'map' => [
179
                ['name', 'alias'],
180
                ['title', 'subtitle'],
181
                ['category_id', 'item_type_id', 'deleted'],
182
                ['widget', 'view'],
183
                ['best', 'item_badge_id', 'image_file_id'],
184
                ['description'],
185
                ['imgs'],
186
                ['options'],
187
                ['offers'],
188
            ]
189
        ],
190
        'simpleItem' => [
191
            'options' => [
192
                'access' => [
193
                    'groups' => [
194
                        3
195
                    ]
196
                ],
197
            ],
198
            'name' => 'Простой товар с ценой',
199
            'inputs' => [
200
                'name' => ['type' => 'text'],
201
                'description' => ['type' => 'html'],
202
                'category' => ['type' => 'select', 'source' => 'model', 'model' => 'Ecommerce\Category', 'label' => 'Категория'],
203
                'image' => ['type' => 'image', 'label' => 'Изображение'],
204
                'price' => ['type' => 'text', 'label' => 'Цена'],
205
                'currency' => ['type' => 'select', 'source' => 'model', 'model' => 'Money\Currency', 'label' => 'Валюта'],
206
                'options' => ['type' => 'dynamicList', 'source' => 'options', 'options' => [
207
                    'inputs' => [
208
                        'option' => ['type' => 'select', 'source' => 'model', 'model' => 'Ecommerce\Item\Option', 'label' => 'Свойство'],
209
                        'value' => ['type' => 'dynamicType', 'typeSource' => 'selfMethod', 'selfMethod' => 'realType', 'label' => 'Значение'],
210
                    ]
211
                ]
212
                ],
213
                'offerOptions' => ['type' => 'dynamicList', 'source' => 'options', 'options' => [
214
                    'inputs' => [
215
                        'option' => ['type' => 'select', 'source' => 'model', 'model' => 'Ecommerce\Item\Offer\Option', 'label' => 'Свойство предложения'],
216
                        'value' => ['type' => 'dynamicType', 'typeSource' => 'selfMethod', 'selfMethod' => 'realType', 'label' => 'Значение'],
217
                    ]
218
                ], 'label' => 'Параметры предложения'
219
                ]
220
            ],
221
            'map' => [
222
                ['name', 'category'],
223
                ['description'],
224
                ['image'],
225
                ['price', 'currency'],
226
                ['options'],
227
                ['offerOptions'],
228
            ],
229
            'handler' => 'simpleItemHandler'
230
        ]
231
    ];
232
233
    public function realType() {
234
        if ($this->option && $this->option->type) {
0 ignored issues
show
Bug introduced by
The property option does not seem to exist. Did you mean options?

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.

Loading history...
235
            $type = $this->option->type;
0 ignored issues
show
Bug introduced by
The property option does not seem to exist. Did you mean options?

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.

Loading history...
236
237
            if ($type == 'select') {
238
                return [
239
                    'type' => 'select',
240
                    'source' => 'relation',
241
                    'relation' => 'option:items',
242
                ];
243
            }
244
            return $type;
245
        }
246
        return 'text';
247
    }
248
249
    public static function indexes() {
250
        return [
251
            'ecommerce_item_item_category_id' => [
252
                'type' => 'INDEX',
253
                'cols' => [
254
                    'item_category_id'
255
                ]
256
            ],
257
            'inji_ecommerce_item_item_tree_path' => [
258
                'type' => 'INDEX',
259
                'cols' => [
260
                    'item_tree_path(255)'
261
                ]
262
            ],
263
            'ecommerce_item_item_search_index' => [
264
                'type' => 'INDEX',
265
                'cols' => [
266
                    'item_search_index(255)'
267
                ]
268
            ],
269
        ];
270
    }
271
272
    public function beforeSave() {
273
274
        if ($this->id) {
275
            $this->search_index = $this->name . ' ';
276
            if ($this->category) {
277
                $this->search_index .= $this->category->name . ' ';
278
            }
279
280
            if ($this->options) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->options of type Ecommerce\Item\Param[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
281
                $category = $this->category;
282
                if ($category) {
283
                    $categoryOptions = $category->options(['key' => 'item_option_id']);
284
                } else {
285
                    $categoryOptions = [];
286
                }
287
                foreach ($this->options as $option) {
288
                    if ($option->item_option_searchable && $option->value) {
0 ignored issues
show
Bug introduced by
The property item_option_searchable does not seem to exist. Did you mean option?

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.

Loading history...
289
                        if ($option->item_option_type != 'select') {
0 ignored issues
show
Bug introduced by
The property item_option_type does not seem to exist. Did you mean option?

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.

Loading history...
290
                            $this->search_index .= $option->value . ' ';
291
                        } elseif (!empty($option->option->items[$option->value])) {
292
                            $option->option->items(['where' => ['id', $option->value]])[$option->value]->value . ' ';
293
                        }
294
                    }
295
                    if ($option->item_option_view && !isset($categoryOptions[$option->item_option_id])) {
0 ignored issues
show
Bug introduced by
The property item_option_view does not seem to exist. Did you mean option?

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.

Loading history...
296
                        $this->category->addRelation('options', $option->item_option_id);
0 ignored issues
show
Documentation introduced by
$option->item_option_id is of type integer, but the function expects a object<Model>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
297
                        $categoryOptions = $this->category->options(['key' => 'item_option_id']);
298
                    } elseif (!$option->item_option_view && isset($categoryOptions[$option->item_option_id])) {
0 ignored issues
show
Bug introduced by
The property item_option_view does not seem to exist. Did you mean option?

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.

Loading history...
299
                        $categoryOptions[$option->item_option_id]->delete();
300
                        unset($categoryOptions[$option->item_option_id]);
301
                    }
302
                }
303
            }
304
            if ($this->offers) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->offers of type Ecommerce\Item\Offer[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
305
                foreach ($this->offers as $offer) {
306
                    if ($offer->options) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $offer->options of type Ecommerce\Item\Offer\Param[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
307
                        foreach ($offer->options as $option) {
308
                            if ($option->item_offer_option_searchable && $option->value) {
0 ignored issues
show
Bug introduced by
The property item_offer_option_searchable does not seem to exist. Did you mean option?

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.

Loading history...
309
                                if ($option->item_offer_option_type != 'select') {
0 ignored issues
show
Bug introduced by
The property item_offer_option_type does not seem to exist. Did you mean option?

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.

Loading history...
310
                                    $this->search_index .= $option->value . ' ';
311
                                } elseif (!empty($option->option->items[$option->value])) {
312
                                    $option->option->items[$option->value]->value . ' ';
313
                                }
314
                            }
315
                        }
316
                    }
317
                }
318
            }
319
        }
320
    }
321
322
    public static function relations() {
323
324
        return [
325
            'badge' => [
326
                'model' => 'Ecommerce\Item\Badge',
327
                'col' => 'item_badge_id'
328
            ],
329
            'category' => [
330
                'model' => 'Ecommerce\Category',
331
                'col' => 'category_id'
332
            ],
333
            'options' => [
334
                'type' => 'many',
335
                'model' => 'Ecommerce\Item\Param',
336
                'col' => 'item_id',
337
                'resultKey' => 'item_option_id',
338
                'join' => [Item\Option::table(), Item\Option::index() . ' = ' . Item\Param::colPrefix() . Item\Option::index()]
339
            ],
340
            'offers' => [
341
                'type' => 'many',
342
                'model' => 'Ecommerce\Item\Offer',
343
                'col' => 'item_id',
344
            ],
345
            'type' => [
346
                'model' => 'Ecommerce\Item\Type',
347
                'col' => 'item_type_id',
348
            ],
349
            'image' => [
350
                'model' => 'Files\File',
351
                'col' => 'image_file_id'
352
            ],
353
            'images' => [
354
                'type' => 'many',
355
                'model' => 'Ecommerce\Item\Image',
356
                'col' => 'item_id'
357
            ],
358
            'user' => [
359
                'model' => 'Users\User',
360
                'col' => 'user_id'
361
            ]
362
        ];
363
    }
364
365
    /**
366
     * @return bool|Item\Offer\Price|null
367
     */
368
    public function getPrice($offerId = 0) {
369
        if ($offerId) {
370
            return $this->offers ? $this->offers[$offerId]->getPrice() : false;
371
        }
372
        return $this->offers(['key' => false]) ? $this->offers(['key' => false])[0]->getPrice() : false;
373
    }
374
375
    public function name() {
376
        if (!empty(\App::$primary->ecommerce->config['item_option_as_name'])) {
377
            $param = Item\Param::get([['item_id', $this->id], ['item_option_id', \App::$primary->ecommerce->config['item_option_as_name']]]);
378
            if ($param && $param->value) {
379
                return $param->value;
380
            }
381
        }
382
        return $this->name;
383
    }
384
385
    public function beforeDelete() {
386
        if ($this->id) {
387
            if ($this->options) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->options of type Ecommerce\Item\Param[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
388
                foreach ($this->options as $option) {
389
                    $option->delete();
390
                }
391
            }
392
            if ($this->offers) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->offers of type Ecommerce\Item\Offer[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
393
                foreach ($this->offers as $offer) {
394
                    $offer->delete();
395
                }
396
            }
397
            if ($this->image) {
398
                $this->image->delete();
399
            }
400
        }
401
    }
402
403
    public function getHref() {
404
        return "/ecommerce/view/{$this->pk()}";
405
    }
406
407
    public function inFav() {
408
        if (\Users\User::$cur->id) {
409
            $fav = \Ecommerce\Favorite::get([['user_id', \Users\User::$cur->id], ['item_id', $this->id]]);
410
            return (bool) $fav;
411 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
412
            $favs = !empty($_COOKIE['ecommerce_favitems']) ? json_decode($_COOKIE['ecommerce_favitems'], true) : [];
413
            return in_array($this->id, $favs);
414
        }
415
    }
416
}