Test Failed
Push — master ( 2a8a67...5ddd1f )
by Alexey
04:25
created

Item::getHref()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
rs 10
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', 'logging' => false],
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', 'logging' => false],
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 afterSave() {
273
        $itemId = $this->id;
274
        \App::$primary->daemon->task(function () use ($itemId) {
275
            $item = \Ecommerce\Item::get($itemId);
276
            $item->search_index = $item->name . ' ';
277
            if ($item->category) {
278
                $item->search_index .= $item->category->name . ' ';
279
            }
280
281
            if ($item->options) {
282
                $category = $item->category;
283
                if ($category) {
284
                    $categoryOptions = $category->options(['key' => 'item_option_id']);
285
                } else {
286
                    $categoryOptions = [];
287
                }
288
                foreach ($item->options as $option) {
289
                    if ($option->item_option_searchable && $option->value) {
290
                        if ($option->item_option_type != 'select') {
291
                            $item->search_index .= $option->value . ' ';
292
                        } elseif (!empty($option->option->items[$option->value])) {
293
                            $option->option->items(['where' => ['id', $option->value]])[$option->value]->value . ' ';
294
                        }
295
                    }
296
                    if ($option->item_option_view && !isset($categoryOptions[$option->item_option_id])) {
297
                        $item->category->addRelation('options', $option->item_option_id);
298
                        $categoryOptions = $item->category->options(['key' => 'item_option_id']);
299
                    } elseif (!$option->item_option_view && isset($categoryOptions[$option->item_option_id])) {
300
                        $categoryOptions[$option->item_option_id]->delete();
301
                        unset($categoryOptions[$option->item_option_id]);
302
                    }
303
                }
304
            }
305
            if ($item->offers) {
306
                foreach ($item->offers as $offer) {
307
                    if ($offer->options) {
308
                        foreach ($offer->options as $option) {
309
                            if ($option->item_offer_option_searchable && $option->value) {
310
                                if ($option->item_offer_option_type != 'select') {
311
                                    $item->search_index .= $option->value . ' ';
312
                                } elseif (!empty($option->option->items[$option->value])) {
313
                                    $option->option->items[$option->value]->value . ' ';
314
                                }
315
                            }
316
                        }
317
                    }
318
                }
319
            }
320
        });
321
322
    }
323
324
    public static function relations() {
325
326
        return [
327
            'badge' => [
328
                'model' => 'Ecommerce\Item\Badge',
329
                'col' => 'item_badge_id'
330
            ],
331
            'category' => [
332
                'model' => 'Ecommerce\Category',
333
                'col' => 'category_id'
334
            ],
335
            'options' => [
336
                'type' => 'many',
337
                'model' => 'Ecommerce\Item\Param',
338
                'col' => 'item_id',
339
                'resultKey' => 'item_option_id',
340
                'join' => [Item\Option::table(), Item\Option::index() . ' = ' . Item\Param::colPrefix() . Item\Option::index()]
341
            ],
342
            'offers' => [
343
                'type' => 'many',
344
                'model' => 'Ecommerce\Item\Offer',
345
                'col' => 'item_id',
346
            ],
347
            'type' => [
348
                'model' => 'Ecommerce\Item\Type',
349
                'col' => 'item_type_id',
350
            ],
351
            'image' => [
352
                'model' => 'Files\File',
353
                'col' => 'image_file_id'
354
            ],
355
            'images' => [
356
                'type' => 'many',
357
                'model' => 'Ecommerce\Item\Image',
358
                'col' => 'item_id'
359
            ],
360
            'user' => [
361
                'model' => 'Users\User',
362
                'col' => 'user_id'
363
            ]
364
        ];
365
    }
366
367
    /**
368
     * @return bool|Item\Offer\Price|null
369
     */
370
    public function getPrice($offerId = 0) {
371
        if ($offerId) {
372
            return $this->offers ? $this->offers[$offerId]->getPrice() : false;
373
        }
374
        return $this->offers(['key' => false]) ? $this->offers(['key' => false])[0]->getPrice() : false;
375
    }
376
377
    public function name() {
378
        if (!empty(\App::$primary->ecommerce->config['item_option_as_name'])) {
379
            $param = Item\Param::get([['item_id', $this->id], ['item_option_id', \App::$primary->ecommerce->config['item_option_as_name']]]);
380
            if ($param && $param->value) {
381
                return $param->value;
382
            }
383
        }
384
        return $this->name;
385
    }
386
387
    public function afterDelete() {
388
        if (!$this->id) {
389
            return;
390
        }
391
        $itemId = $this->id;
392
        \App::$primary->daemon->task(function () use ($itemId) {
393
            $item = \Ecommerce\Item::get($itemId);
394
            foreach ($item->options as $option) {
395
                $option->delete();
396
            }
397
            foreach ($item->offers as $offer) {
398
                $offer->delete();
399
            }
400
            foreach ($item->images as $image) {
401
                $image->delete();
402
            }
403
            if ($item->image) {
404
                $item->image->delete();
405
            }
406
        });
407
    }
408
409
    public function getHref() {
410
        return "/ecommerce/view/{$this->pk()}";
411
    }
412
413
    public function inFav() {
414
        if (\Users\User::$cur->id) {
415
            $fav = \Ecommerce\Favorite::get([['user_id', \Users\User::$cur->id], ['item_id', $this->id]]);
416
            return (bool) $fav;
417 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...
418
            $favs = !empty($_COOKIE['ecommerce_favitems']) ? json_decode($_COOKIE['ecommerce_favitems'], true) : [];
419
            return in_array($this->id, $favs);
420
        }
421
    }
422
}