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.
Completed
Push — master ( b0ca7b...3d88e0 )
by Alexsandr
64:09 queued 47:03
created

Offer::rules()   B

Complexity

Conditions 7
Paths 1

Size

Total Lines 108

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 7.2269

Importance

Changes 0
Metric Value
dl 0
loc 108
ccs 30
cts 36
cp 0.8333
rs 7.0666
c 0
b 0
f 0
cc 7
nc 1
nop 0
crap 7.2269

How to fix   Long Method   

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
 * @link https://github.com/corpsepk/yii2-yandex-market-yml
4
 * @copyright Copyright (c) 2016 Corpsepk
5
 * @license http://opensource.org/licenses/MIT
6
 */
7
namespace corpsepk\yml\models;
8
9
use yii\base\Model;
10
11
/**
12
 * @link https://partner.market.yandex.ru/legal/tt
13
 * @package corpsepk\yml
14
 */
15
class Offer extends Model
16
{
17
    /**
18
     * @link https://yandex.ru/support/partnermarket/currencies.xml
19
     * @var array
20
     */
21
    const CURRENCY_AVAILABLE = ['RUR', 'RUB', 'UAH', 'BYN', 'KZT', 'USD', 'EUR'];
22
23
    /**
24
     * В атрибуте id указывается идентификатор товарного предложения.
25
     * Атрибут может содержать только цифры и латинские буквы.
26
     * Максимальная длина id — 20 символов.
27
     * Идентификатор предложения должен быть уникальным среди всех товарных
28
     * предложений одного прайс-листа.
29
     *
30
     * Если у двух и более товарных предложений указать одинаковые атрибуты id,
31
     * то идентификатор будет присвоен только первому из этих предложений.
32
     * Для остальных будет выводиться предупреждающее сообщение об отсутствии идентификатора.
33
     *
34
     * @var string
35
     */
36
    public $id;
37
38
    /**
39
     * В атрибуте type указывается тип описания —
40
     * в YML существуют несколько типов описаний предложений товаров:
41
     * упрощенный (значение не указывается),
42
     * произвольный (значение "vendor.model"),
43
     * книги (значение "book"),
44
     * аудиокниги (значение "audiobook"),
45
     * музыкальная и видео продукция (значение "artist.title"),
46
     * туры (значение "tour")
47
     * и билеты на мероприятие (значение "event-ticket").
48
     *
49
     * Указание типа описания обязательно за исключением упрощенного описания.
50
     * Товарные предложения, описанные не в соответствии со своим типом, могут не приниматься к публикации.
51
     * @var string
52
     */
53
    public $type;
54
55
    /**
56
     * В атрибуте available указывается статус доступности товара:
57
     * «false» — товарное предложение на заказ.
58
     * Магазин готов принять заказ и осуществить поставку товара
59
     * в течение согласованного с покупателем срока, не превышающего двух месяцев
60
     * (за исключением товаров, изготавливаемых на заказ,
61
     * ориентировочный срок поставки которых оговаривается с покупателем во время заказа).
62
     * «true» — товарное предложение в наличии.
63
     * Магазин готов сразу договариваться с покупателем о доставке/покупке товара.
64
     *
65
     * @var bool
66
     */
67
    public $available;
68
69
    /**
70
     * В атрибуте bid указывается основная ставка товарного предложения,
71
     * @var string
72
     */
73
    public $bid;
74
75
    /**
76
     * В атрибуте cbid — ставка для карточки модели.
77
     * @var string
78
     */
79
    public $cbid;
80
81
    /**
82
     * URL страницы товара.
83
     * Максимальная длина URL — 512 символов.
84
     * Необязательный элемент для магазинов-салонов.
85
     *
86
     * @var string|null
87
     */
88
    public $url;
89
90
    /**
91
     * Цена, по которой данный товар можно приобрести.
92
     * Цена товарного предложения округляется, формат, в котором она отображается,
93
     * зависит от настроек пользователя.
94
     *
95
     * Обязательный элемент.
96
     *
97
     * В следующих категориях допускается передавать начальную цену "от" с помощью атрибута from=true:
98
     * Банкетки и скамьи;
99
     * Ванные комнаты;
100
     * Гостиные;
101
     * Детские;
102
     * Детские комоды;
103
     * Диваны;
104
     * Кабинеты;
105
     * Колыбели и люльки;
106
     * Комоды;
107
     * Компьютерные столы;
108
     * Кресла;
109
     * Кровати;
110
     * Кухонные гарнитуры;
111
     * Кухонные уголки и объединенные группы;
112
     * Манежи;
113
     * Парты и стулья;
114
     * Полки;
115
     * Прихожие;
116
     * Пуфики;
117
     * Спальни;
118
     * Стеллажи;
119
     * Столы и столики;
120
     * Стулья, табуретки;
121
     * Тумбы;
122
     * Шкафы.
123
     * Пример: <price from=true>2000</price>
124
     *
125
     * @var string
126
     */
127
    public $price;
128
129
    /**
130
     * Параметр необходим для показа скидки на товар.
131
     * В <oldprice> указывается старая цена товара,
132
     * которая должна быть обязательно выше новой цены (<price>).
133
     *
134
     * Скидка может показываться в процентах.
135
     * Процент рассчитывается автоматически на основе разницы между <oldprice> и <price>,
136
     * округляется до целого числа по общематематическим правилам.
137
     * Необязательный элемент.
138
     *
139
     * @var string
140
     */
141
    public $oldprice;
142
143
    /**
144
     * Идентификатор валюты товара (RUR, USD, EUR, UAH, KZT).
145
     * Для корректного отображения цены в национальной валюте необходимо
146
     * использовать идентификатор (например, UAH) с соответствующим значением цены.
147
     * Обязательный элемент.
148
     *
149
     * @var string
150
     */
151
    public $currencyId;
152
153
    /**
154
     * Идентификатор категории товара (целое число не более 18 знаков).
155
     * Товарное предложение может принадлежать только одной категории.
156
     * Обязательный элемент.
157
     * Элемент offer может содержать только один элемент categoryId.
158
     *
159
     * @var string
160
     */
161
    public $categoryId;
162
163
    /**
164
     * Ссылка на картинку соответствующего товарного предложения.
165
     * Недопустимо давать ссылку на "заглушку",
166
     * т.е. на картинку где написано "картинка отсутствует", или на логотип магазина.
167
     *
168
     * Максимальная длина URL — 512 символов.
169
     * Размер картинки — не менее 250 пикселей по одной из сторон.
170
     *
171
     * Является обязательным элементом для категорий,
172
     * данные по которым должны быть представлены только в формате YML:
173
     * «Мягкая мебель»;
174
     * «Компьютерные столы»;
175
     * «Массажные столы»;
176
     * «Одежда, обувь и аксессуары»;
177
     * «Косметика, парфюмерия и уход»;
178
     * «Детские товары» (за исключением подкатегорий «Детские коляски», «Подгузники», «Автокресла», «Конструкторы», «Железные дороги», «Трехколесные велосипеды», «Кроватки»);
179
     * «Чехлы» для мобильных телефонов;
180
     * «Защитные пленки и наклейки» для телефонов;
181
     * «Зарядные устройства» и «Переходники» для мобильных телефонов;
182
     * «Сумки и чехлы для планшетов».
183
     *
184
     * Для всех остальных категорий – необязательный элемент.
185
     *
186
     * @var array|string|null
187
     */
188
    public $picture;
189
190
    /**
191
     * Элемент позволяет указать возможность купить соответствующий товар в розничном магазине.
192
     *
193
     * Возможные значения:
194
     * 1) false — возможность покупки в розничном магазине отсутствует;
195
     * 2) true — товар можно купить в розничном магазине.
196
     *
197
     * Необязательный элемент.
198
     *
199
     * @var bool|null
200
     */
201
    public $store;
202
203
    /**
204
     * Элемент позволяет указать возможность зарезервировать выбранный товар и забрать его самостоятельно.
205
     *
206
     * Возможные значения:
207
     * 1) false — возможность «самовывоза» отсутствует;
208
     * 2) true — товар можно забрать самостоятельно.
209
     *
210
     * Необязательный элемент.
211
     *
212
     * @var bool|null
213
     */
214
    public $pickup;
215
216
    /**
217
     * Элемент позволяет указать возможность доставки соответствующего товара.
218
     *
219
     * Возможные значения:
220
     * 1) false — товар не может быть доставлен;
221
     * 2) true — товар доставляется на условиях, которые описываются в партнерском интерфейсе в разделе Параметры размещения.
222
     *
223
     * Необязательный элемент.
224
     *
225
     * @var bool|null
226
     */
227
    public $delivery;
228
229
    /**
230
     * Стоимость доставки данного товара в своем регионе.
231
     *
232
     * Необязательный элемент.
233
     *
234
     * @var string|null
235
     */
236
    public $local_delivery_cost;
237
238
    /**
239
     * Группа товаров \ категория.
240
     * Элемент обязателен для произвольного описания.
241
     *
242
     * @var string|null
243
     */
244
    public $typePrefix;
245
246
    /**
247
     * Название товарного предложения.
248
     * В названии упрощенного предложения рекомендуется указывать тип товара,
249
     * наименование и код производителя.
250
     * Элемент обязателен для упрощенного описания.
251
     *
252
     * @var string|null
253
     */
254
    public $name;
255
256
    /**
257
     * Производитель.
258
     * Необязательный элемент.
259
     *
260
     * @var string
261
     */
262
    public $vendor;
263
264
    /**
265
     * Код товара (указывается код производителя).
266
     * Необязательный элемент.
267
     *
268
     * @var string|null
269
     */
270
    public $vendorCode;
271
272
    /**
273
     * Модель.
274
     * Обязательный элемент для произвольного описания.
275
     *
276
     * @var string|null
277
     */
278
    public $model;
279
280
    /**
281
     * Описание товарного предложения.
282
     * Необязательный элемент.
283
     *
284
     * @var string
285
     */
286
    public $description;
287
288
    /**
289
     * Элемент используется для отражения информации о минимальной сумме заказа, минимальной партии товара или необходимости предоплаты, а также для описания акций, скидок и распродаж.
290
     * Допустимая длина текста в элементе — не более 50 символов.
291
     * Необязательный элемент.
292
     *
293
     * Элемент обязателен, если у вас есть ограничения при заказе товара
294
     * (например, минимальная сумма заказа, минимальное количество товаров или
295
     * необходимость предоплаты).
296
     * @link https://yandex.ru/support/partnermarket/elements/sales_notes.html
297
     *
298
     * @var string|null
299
     */
300
    public $sales_notes;
301
302
    /**
303
     * Элемент предназначен для отметки товаров, имеющих официальную гарантию производителя.
304
     *
305
     * Возможные значения:
306
     * 1) false — товар не имеет официальной гарантии;
307
     * 2) true — товар имеет официальную гарантию;
308
     * 3) указание срока гарантии. Формат должен соответствовать ISO 8601, например: P1Y2M10DT2H30M.
309
     * Расшифровка — 1 год, 2 месяца, 10 дней, 2 часа и 30 минут.
310
     *
311
     * Необязательный элемент.
312
     *
313
     * @var string|null
314
     */
315
    public $manufacturer_warranty;
316
317
    /**
318
     * Элемент предназначен для отметки товаров, имеющих гарантию продавца.
319
     *
320
     * Необязательный элемент.
321
     *
322
     * Возможные значения:
323
     * 1) false — товар не имеет гарантию продавца;
324
     * 2) true — товар имеет гарантию продавца;
325
     * 3) указание срока гарантии. Формат должен соответствовать ISO 8601, например: P3Y. Расшифровка — 3 года.
326
     *
327
     * @var string|null
328
     */
329
    public $seller_warranty;
330
331
    /**
332
     * Элемент предназначен для указания страны производства товара.
333
     * Список стран, которые могут быть указаны в этом элементе, доступен по адресу:
334
     * @link http://partner.market.yandex.ru/pages/help/Countries.pdf.
335
     * Если вы хотите участвовать в программе «Заказ на Маркете»,
336
     * то желательно указывать данный элемент в YML-файле.
337
     *
338
     * Необязательный элемент.
339
     *
340
     * @var string|null
341
     */
342
    public $country_of_origin;
343
344
    /**
345
     * Элемент предназначен для обозначения товара, который можно скачать.
346
     * Необязательный элемент.
347
     *
348
     * @var bool|null
349
     */
350
    public $downloadable;
351
352
    /**
353
     * Элемент обязателен для обозначения товара,
354
     * имеющего отношение к удовлетворению сексуальных потребностей,
355
     * либо иным образом эксплуатирующего интерес к сексу.
356
     *
357
     * Необязательный элемент.
358
     *
359
     * @var bool|null
360
     */
361
    public $adult;
362
363
    /**
364
     * Необязательный элемент.
365
     *
366
     * TODO
367
     * @link https://yandex.ru/support/partnermarket/export/vendor-model.xml
368
     * В форматеYML:
369
     * Годы задаются с помощью атрибута unit со значением year. Допустимые значения параметра age при unit="year": 0, 6, 12, 16, 18.
370
     * Месяцы задаются с помощью атрибута unit со значением month. Допустимые значения параметра age при unit="month": 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.
371
     *
372
     * @var integer|null
373
     */
374
    public $age;
375
376
    /**
377
     * Штрихкод товара, указанный производителем.
378
     * Необязательный элемент. Элемент offer может содержать несколько элементов barcode.
379
     *
380
     * @var string|array|null
381
     */
382
    public $barcode;
383
384
    /**
385
     * Элемент предназначен для управления участием товарных предложений в программе «Заказ на Маркете».
386
     *
387
     * Необязательный элемент.
388
     *
389
     * @var bool|null
390
     */
391
    public $cpa;
392
393
    /**
394
     * Элемент обозначает товары, рекомендуемые для покупки вместе с текущим.
395
     * Необязательный элемент.
396
     *
397
     * @var string|null
398
     */
399
    public $rec;
400
401
    /**
402
     * Элемент предназначен для указания срока годности/срока службы
403
     * либо для указания даты истечения срока годности \ срока службы.
404
     *
405
     * Значение элемента должно быть в формате ISO8601:
406
     * для срока годности \ срока службы: P1Y2M10DT2H30M.
407
     * Расшифровка примера — 1 год, 2 месяца, 10 дней, 2 часа и 30 минут;
408
     * для даты истечения срока годности \ срока службы: YYYY-MM-DDThh:mm.
409
     *
410
     * Необязательный элемент.
411
     *
412
     * @var string|null
413
     */
414
    public $expiry;
415
416
    /**
417
     * Элемент предназначен для указания веса товара. Вес указывается в килограммах с учетом упаковки.
418
     * Формат элемента: положительное число с точностью 0.001, разделитель целой и дробной части — точка.
419
     *
420
     * При указании более высокой точности значение автоматически округляется следующим способом:
421
     * если 4-ый знак после разделителя меньше 5, то 3-й знак сохраняется, а все последующие обнуляются;
422
     * если 4-ый знак после разделителя больше или равен 5, то 3-й знак увеличивается на единицу, а все последующие обнуляются.
423
     *
424
     * Необязательный элемент.
425
     *
426
     * @var string|null
427
     */
428
    public $weight;
429
430
    /**
431
     * Элемент предназначен для указания габаритов товара (длина, ширина, высота) в упаковке. Размеры указываются в сантиметрах.
432
     * Формат элемента: три положительных числа с точностью 0.001, разделитель целой и дробной части — точка. Числа должны быть разделены символом «/» без пробелов.
433
     *
434
     * При указании более высокой точности значение автоматически округляется следующим способом:
435
     * если 4-ый знак после разделителя меньше 5, то 3-й знак сохраняется, а все последующие обнуляются;
436
     * если 4-ый знак после разделителя больше или равен 5, то 3-й знак увеличивается на единицу, а все последующие обнуляются.
437
     *
438
     * Является обязательным элементом для категории «Одежда, обувь и аксессуары». Для остальных категорий необязательный элемент.
439
     *
440
     * @var string|null
441
     */
442
    public $dimensions;
443
444
    /**
445
     * Элемент предназначен для указания характеристик товара.
446
     * Для описания каждого параметра используется отдельный элемент param.
447
     *
448
     * Является обязательным элементом для категорий:
449
     * «Косметика, парфюмерия и уход» при указании объема.
450
     * «Одежда, обувь, аксессуары» при указании размера и цвета.
451
     * Для остальных категорий — необязательный элемент.
452
     * Элемент offer может содержать несколько элементов param.
453
     *
454
     * Массив должен содержать элементы с ключами `name` и `value` например,
455
     * [
456
     *      ['name' => 'Размер', 'value' => '42-44'],
457
     *      ['name' => 'Цвет', 'value' => 'Красный']
458
     * ]
459
     *
460
     * @var array|null
461
     */
462
    public $param;
463
464
    /**
465
     * Атрибуты элемента <offer>
466
     * @var array
467
     */
468
    public $offerElementAttributes = [
469
        'id', 'type', 'available', 'bid', 'cbid'
470
    ];
471
472
    /**
473
     * @return array
474
     */
475 1
    public function getOfferElements()
476
    {
477 1
        return array_diff(
478 1
            array_keys($this->attributes),
479 1
            $this->offerElementAttributes,
480 1
            ['param', 'offerElementAttributes']
481
        );
482
    }
483
484 14
    public function rules()
485
    {
486
        return [
487
            ['id', function () {
488 1
                $this->id = (string)$this->id;
489 1
                return true;
490 14
            }],
491
            ['id', 'required'],
492
            ['id', 'string', 'max' => 20],
493
494
            ['url', 'string', 'max' => 512],
495
496
            ['currencyId', 'required'],
497 14
            ['currencyId', 'in', 'range' => self::CURRENCY_AVAILABLE],
498
499
            ['categoryId', 'required'],
500
            ['categoryId', 'number', 'min' => 1],
501
            ['categoryId', function () {
502 1
                if (strlen($this->categoryId) > 18) {
503 1
                    return false;
504
                };
505
506 1
                return true;
507 14
            }, 'message' => 'Category id must be less than 18 symbols'],
508
509
            // TODO Add `expiry` date validator
510
            // TODO Add `weight` number validator
511
            // TODO Add `dimensions` validator
512
            [
513
                [
514
                    'type', 'bid', 'cbid', 'price', 'categoryId',
515
                    'typePrefix', 'name', 'vendor', 'vendorCode', 'model',
516
                    'description', 'manufacturer_warranty',
517
                    'seller_warranty', 'country_of_origin',
518
                    'expiry', 'weight', 'dimensions',
519
                ],
520
                'safe'
521
            ],
522
523
            ['price', 'required'],
524
            ['oldprice', 'safe'],
525
            // В <oldprice> указывается старая цена товара, которая должна быть обязательно выше новой цены (<price>).
526
            // Скидка может показываться в процентах.
527
            ['oldprice', 'compare', 'compareAttribute' => 'price', 'operator' => '>', 'type' => 'number', 'when' => function (self $model) {
0 ignored issues
show
Unused Code introduced by
The parameter $model is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
528 1
                return strpos($this->oldprice, '%') === false;
529 14
            }],
530
531
            ['local_delivery_cost', 'number'],
532
533
            ['sales_notes', 'string', 'max' => 50],
534
535
            // TODO Not implemented yet
536
//            ['age', 'integer'],
537
//            ['age', 'in', 'range' => [0, 6, 12, 16, 18]],
538
539
            [['available', 'store', 'pickup', 'delivery', 'downloadable', 'adult', 'cpa'], 'boolean'],
540
            // Булево должно быть преобразовано к строке "true"/"false"
541
            // https://yandex.ru/support/partnermarket/elements/id-type-available.xml
542
            [['available', 'store', 'pickup', 'delivery', 'downloadable', 'adult', 'cpa'], function ($attribute) {
543
                $this->$attribute = $this->$attribute ? 'true' : 'false';
544
            }, 'when' => function ($model, $attribute) {
545
                /** @var $model self */
546
                return is_bool($model->$attribute);
547 14
            }],
548
549
            ['barcode', 'safe'],
550
551
            ['picture', 'string', 'max' => 512, 'when' => function ($model) {
552
                /** @var $model self */
553 1
                return is_string($model->picture);
554 14
            }],
555
            ['picture', 'each', 'rule' => ['string', 'max' => 512], 'when' => function ($model) {
556
                /** @var $model self */
557 1
                return is_array($model->picture);
558 14
            }],
559
            ['picture', function () {
560 1
                if (count($this->picture) > 10) {
561 1
                    $this->addError('Offer can contain maximum 10 pictures, ' . count($this->picture) . ' included');
562 1
                    return;
563
                }
564
            }, 'when' => function ($model) {
565
                /** @var self $model */
566 1
                return is_array($model->picture);
567 14
            }],
568
569
            ['rec', function () {
570
                $this->rec = implode(',', $this->rec);
571
            }, 'when' => function (self $model) {
572
                return is_array($model->rec);
573 14
            }],
574
            ['rec', 'string'],
575
576
            ['param', function() {
577 1
                if (!is_array($this->param)) {
578
                    $this->addError('param', 'Attribute "param" must be an array');
579
                    return;
580
                }
581 1
                foreach ($this->param as $param) {
582 1
                    if (!isset($param['name'], $param['value'])) {
583 1
                        $this->addError('param', 'Each param element must contain `name` and `value` keys');
584 1
                        return;
585
                    }
586
                }
587 14
            }, 'when' => function ($model) {
588 1
                return !empty($model);
589 14
            }]
590
        ];
591
    }
592
}
593