ElementModel   F
last analyzed

Complexity

Total Complexity 81

Size/Duplication

Total Lines 573
Duplicated Lines 7.5 %

Coupling/Cohesion

Components 2
Dependencies 4

Importance

Changes 0
Metric Value
wmc 81
lcom 2
cbo 4
dl 43
loc 573
rs 2
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A iblockId() 0 9 2
A internalDirectCreate() 0 4 1
A getCachedIblockPropertiesData() 0 15 3
A setCachedIblockPropertiesData() 0 4 1
A sectionModel() 0 4 1
A query() 0 4 1
A scopeSortByDate() 0 4 1
A scopeFromSectionWithId() 0 6 1
A scopeFromSectionWithCode() 0 6 1
A afterFill() 0 4 1
A load() 0 6 1
A getSections() 0 8 2
A refresh() 0 4 1
A refreshFields() 21 21 4
A refreshSections() 0 16 3
A getSection() 0 15 3
A section() 0 11 2
A getPanelButtons() 0 9 1
A saveProps() 0 16 3
A normalizePropertyFormat() 0 14 3
D constructPropertyValuesForSave() 14 78 28
A fieldShouldNotBeSaved() 0 14 4
A internalUpdate() 0 15 6
A getValueFromLanguageField() 0 6 2
A setWorkflow() 0 4 1
A setUpdateSearch() 0 4 1
A setResizePictures() 0 4 1
A create() 8 8 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ElementModel often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ElementModel, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Arrilot\BitrixModels\Models;
4
5
use Arrilot\BitrixModels\Exceptions\ExceptionFromBitrix;
6
use Arrilot\BitrixModels\Queries\ElementQuery;
7
use CIBlock;
8
use Illuminate\Support\Collection;
9
use LogicException;
10
11
/**
12
 * ElementQuery methods
13
 * @method static ElementQuery groupBy($value)
14
 * @method static static getByCode(string $code)
15
 * @method static static getByExternalId(string $id)
16
 *
17
 * Base Query methods
18
 * @method static Collection|static[] getList()
19
 * @method static static first()
20
 * @method static static getById(int $id)
21
 * @method static ElementQuery sort(string|array $by, string $order='ASC')
22
 * @method static ElementQuery order(string|array $by, string $order='ASC') // same as sort()
23
 * @method static ElementQuery filter(array $filter)
24
 * @method static ElementQuery addFilter(array $filters)
25
 * @method static ElementQuery resetFilter()
26
 * @method static ElementQuery navigation(array $filter)
27
 * @method static ElementQuery select($value)
28
 * @method static ElementQuery keyBy(string $value)
29
 * @method static ElementQuery limit(int $value)
30
 * @method static ElementQuery offset(int $value)
31
 * @method static ElementQuery page(int $num)
32
 * @method static ElementQuery take(int $value) // same as limit()
33
 * @method static ElementQuery forPage(int $page, int $perPage=15)
34
 * @method static \Illuminate\Pagination\LengthAwarePaginator paginate(int $perPage = 15, string $pageName = 'page')
35
 * @method static \Illuminate\Pagination\Paginator simplePaginate(int $perPage = 15, string $pageName = 'page')
36
 * @method static ElementQuery stopQuery()
37
 * @method static ElementQuery cache(float|int $minutes)
38
 *
39
 * Scopes
40
 * @method static ElementQuery active()
41
 * @method static ElementQuery sortByDate(string $sort = 'DESC')
42
 * @method static ElementQuery fromSectionWithId(int $id)
43
 * @method static ElementQuery fromSectionWithCode(string $code)
44
 */
45
class ElementModel extends BitrixModel
46
{
47
    /**
48
     * Corresponding IBLOCK_ID
49
     *
50
     * @var int
51
     */
52
    const IBLOCK_ID = null;
53
54
    /**
55
     * IBLOCK version (1 or 2)
56
     *
57
     * @var int
58
     */
59
    const IBLOCK_VERSION = 2;
60
61
    /**
62
     * Bitrix entity object.
63
     *
64
     * @var object
65
     */
66
    public static $bxObject;
67
68
    /**
69
     * Corresponding object class name.
70
     *
71
     * @var string
72
     */
73
    protected static $objectClass = 'CIBlockElement';
74
75
    /**
76
     * Iblock PropertiesData from Bitrix DB
77
     *
78
     * @var null|array
79
     */
80
    protected static $iblockPropertiesData = [];
81
82
    /**
83
     * Have sections been already fetched from DB?
84
     *
85
     * @var bool
86
     */
87
    protected $sectionsAreFetched = false;
88
89
    /**
90
     * Log in Bitrix workflow ($bWorkFlow for CIBlockElement::Add/Update).
91
     *
92
     * @var bool
93
     */
94
    protected static $workFlow = false;
95
96
    /**
97
     * Update search after each create or update ($bUpdateSearch for CIBlockElement::Add/Update).
98
     *
99
     * @var bool
100
     */
101
    protected static $updateSearch = true;
102
103
    /**
104
     * Resize pictures during add/update ($bResizePictures for CIBlockElement::Add/Update).
105
     *
106
     * @var bool
107
     */
108
    protected static $resizePictures = false;
109
110
    /**
111
     * Getter for corresponding iblock id.
112
     *
113
     * @throws LogicException
114
     *
115
     * @return int
116
     */
117
    public static function iblockId()
118
    {
119
        $id = static::IBLOCK_ID;
120
        if (!$id) {
121
            throw new LogicException('You must set IBLOCK_ID constant inside a model or override iblockId() method');
122
        }
123
        
124
        return $id;
125
    }
126
    
127
    /**
128
     * Create new item in database.
129
     *
130
     * @param $fields
131
     *
132
     * @throws LogicException
133
     *
134
     * @return static|bool
135
     * @throws ExceptionFromBitrix
136
     */
137 View Code Duplication
    public static function create($fields)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
138
    {
139
        if (!isset($fields['IBLOCK_ID'])) {
140
            $fields['IBLOCK_ID'] = static::iblockId();
141
        }
142
143
        return static::internalCreate($fields);
144
    }
145
146
    public static function internalDirectCreate($bxObject, $fields)
147
    {
148
        return $bxObject->add($fields, static::$workFlow, static::$updateSearch, static::$resizePictures);
149
    }
150
151
    /**
152
     * Fetches static::$iblockPropertiesData if it's not fetched and returns it.
153
     *
154
     * @return array
155
     */
156
    protected static function getCachedIblockPropertiesData()
157
    {
158
        $iblockId = static::iblockId();
159
        if (!empty(self::$iblockPropertiesData[$iblockId])) {
160
            return self::$iblockPropertiesData[$iblockId];
161
        }
162
163
        $props = [];
164
        $dbRes = CIBlock::GetProperties($iblockId, [], []);
165
        while($property = $dbRes->Fetch()) {
166
            $props[$property['CODE']] = $property;
167
        }
168
169
        return self::$iblockPropertiesData[$iblockId] = $props;
170
    }
171
172
    /**
173
     * Setter for self::$iblockPropertiesData[static::iblockId()] mainly for testing.
174
     *
175
     * @param $data
176
     * @return void
177
     */
178
    public static function setCachedIblockPropertiesData($data)
179
    {
180
        self::$iblockPropertiesData[static::iblockId()] = $data;
181
    }
182
183
    /**
184
     * Corresponding section model full qualified class name.
185
     * MUST be overridden if you are going to use section model for this iblock.
186
     *
187
     * @throws LogicException
188
     *
189
     * @return string
190
     */
191
    public static function sectionModel()
192
    {
193
        throw new LogicException('public static function sectionModel() MUST be overridden');
194
    }
195
196
    /**
197
     * Instantiate a query object for the model.
198
     *
199
     * @return ElementQuery
200
     */
201
    public static function query()
202
    {
203
        return new ElementQuery(static::instantiateObject(), get_called_class());
204
    }
205
206
    /**
207
     * Scope to sort by date.
208
     *
209
     * @param ElementQuery $query
210
     * @param string       $sort
211
     *
212
     * @return ElementQuery
213
     */
214
    public function scopeSortByDate($query, $sort = 'DESC')
215
    {
216
        return $query->sort(['ACTIVE_FROM' => $sort]);
217
    }
218
219
    /**
220
     * Scope to get only items from a given section.
221
     *
222
     * @param ElementQuery $query
223
     * @param mixed        $id
224
     *
225
     * @return ElementQuery
226
     */
227
    public function scopeFromSectionWithId($query, $id)
228
    {
229
        $query->filter['SECTION_ID'] = $id;
230
231
        return $query;
232
    }
233
234
    /**
235
     * Scope to get only items from a given section.
236
     *
237
     * @param ElementQuery $query
238
     * @param string       $code
239
     *
240
     * @return ElementQuery
241
     */
242
    public function scopeFromSectionWithCode($query, $code)
243
    {
244
        $query->filter['SECTION_CODE'] = $code;
245
246
        return $query;
247
    }
248
249
    /**
250
     * Fill extra fields when $this->field is called.
251
     *
252
     * @return null
253
     */
254
    protected function afterFill()
255
    {
256
        $this->normalizePropertyFormat();
257
    }
258
259
    /**
260
     * Load all model attributes from cache or database.
261
     *
262
     * @return $this
263
     */
264
    public function load()
265
    {
266
        $this->getFields();
267
268
        return $this;
269
    }
270
271
    /**
272
     * Get element's sections from cache or database.
273
     *
274
     * @return array
275
     */
276
    public function getSections()
277
    {
278
        if ($this->sectionsAreFetched) {
279
            return $this->fields['IBLOCK_SECTION'];
280
        }
281
282
        return $this->refreshSections();
283
    }
284
285
    /**
286
     * Refresh model from database and place data to $this->fields.
287
     *
288
     * @return array
289
     */
290
    public function refresh()
291
    {
292
        return $this->refreshFields();
293
    }
294
295
    /**
296
     * Refresh element's fields and save them to a class field.
297
     *
298
     * @return array
299
     */
300 View Code Duplication
    public function refreshFields()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
301
    {
302
        if ($this->id === null) {
303
            $this->original = [];
304
            return $this->fields = [];
305
        }
306
307
        $sectionsBackup = isset($this->fields['IBLOCK_SECTION']) ? $this->fields['IBLOCK_SECTION'] : null;
308
309
        $this->fields = static::query()->getById($this->id)->fields;
310
311
        if (!empty($sectionsBackup)) {
312
            $this->fields['IBLOCK_SECTION'] = $sectionsBackup;
313
        }
314
315
        $this->fieldsAreFetched = true;
316
317
        $this->original = $this->fields;
318
319
        return $this->fields;
320
    }
321
322
    /**
323
     * Refresh element's sections and save them to a class field.
324
     *
325
     * @return array
326
     */
327
    public function refreshSections()
328
    {
329
        if ($this->id === null) {
330
            return [];
331
        }
332
333
        $this->fields['IBLOCK_SECTION'] = [];
334
        $dbSections = static::$bxObject->getElementGroups($this->id, true);
335
        while ($section = $dbSections->Fetch()) {
336
            $this->fields['IBLOCK_SECTION'][] = $section;
337
        }
338
339
        $this->sectionsAreFetched = true;
340
341
        return $this->fields['IBLOCK_SECTION'];
342
    }
343
344
    /**
345
     * @deprecated in favour of `->section()`
346
     * Get element direct section as ID or array of fields.
347
     *
348
     * @param bool $load
349
     *
350
     * @return false|int|array
351
     */
352
    public function getSection($load = false)
353
    {
354
        $fields = $this->getFields();
355
        if (!$load) {
356
            return $fields['IBLOCK_SECTION_ID'];
357
        }
358
359
        /** @var SectionModel $sectionModel */
360
        $sectionModel = static::sectionModel();
361
        if (!$fields['IBLOCK_SECTION_ID']) {
362
            return false;
363
        }
364
365
        return $sectionModel::query()->getById($fields['IBLOCK_SECTION_ID'])->toArray();
366
    }
367
368
    /**
369
     * Get element direct section as model object.
370
     *
371
     * @param bool $load
372
     *
373
     * @return false|SectionModel
374
     */
375
    public function section($load = false)
376
    {
377
        $fields = $this->getFields();
378
379
        /** @var SectionModel $sectionModel */
380
        $sectionModel = static::sectionModel();
381
382
        return $load
383
            ? $sectionModel::query()->getById($fields['IBLOCK_SECTION_ID'])
384
            : new $sectionModel($fields['IBLOCK_SECTION_ID']);
385
    }
386
387
    /**
388
     * Proxy for GetPanelButtons
389
     *
390
     * @param array $options
391
     * @return array
392
     */
393
    public function getPanelButtons($options = [])
394
    {
395
        return CIBlock::GetPanelButtons(
396
            static::iblockId(),
397
            $this->id,
398
            0,
399
            $options
400
        );
401
    }
402
403
    /**
404
     * Save props to database.
405
     * If selected is not empty then only props from it are saved.
406
     *
407
     * @param array $selected
408
     *
409
     * @return bool
410
     */
411
    public function saveProps($selected = [])
412
    {
413
        $propertyValues = $this->constructPropertyValuesForSave($selected);
414
        if (empty($propertyValues)) {
415
            return false;
416
        }
417
418
        $bxMethod = empty($selected) ? 'setPropertyValues' : 'setPropertyValuesEx';
419
        static::$bxObject->$bxMethod(
420
            $this->id,
421
            static::iblockId(),
422
            $propertyValues
423
        );
424
425
        return true;
426
    }
427
428
    /**
429
     * Normalize properties's format converting it to 'PROPERTY_"CODE"_VALUE'.
430
     *
431
     * @return null
432
     */
433
    protected function normalizePropertyFormat()
434
    {
435
        if (empty($this->fields['PROPERTIES'])) {
436
            return;
437
        }
438
439
        foreach ($this->fields['PROPERTIES'] as $code => $prop) {
440
            $this->fields['PROPERTY_'.$code.'_VALUE'] = $prop['VALUE'];
441
            $this->fields['~PROPERTY_'.$code.'_VALUE'] = $prop['~VALUE'];
442
            $this->fields['PROPERTY_'.$code.'_DESCRIPTION'] = $prop['DESCRIPTION'];
443
            $this->fields['~PROPERTY_'.$code.'_DESCRIPTION'] = $prop['~DESCRIPTION'];
444
            $this->fields['PROPERTY_'.$code.'_VALUE_ID'] = $prop['PROPERTY_VALUE_ID'];
445
        }
446
    }
447
448
    /**
449
     * Construct 'PROPERTY_VALUES' => [...] from flat fields array.
450
     * This is used in save.
451
     * If $selectedFields are specified only those are saved.
452
     *
453
     * @param $selectedFields
454
     *
455
     * @return array
456
     */
457
    protected function constructPropertyValuesForSave($selectedFields = [])
458
    {
459
        $propertyValues = [];
460
        $saveOnlySelected = !empty($selectedFields);
461
462
        $iblockPropertiesData = static::getCachedIblockPropertiesData();
463
464
        if ($saveOnlySelected) {
465
            foreach ($selectedFields as $code) {
466
                // if we pass PROPERTY_X_DESCRIPTION as selected field, we need to add PROPERTY_X_VALUE as well.
467 View Code Duplication
                if (preg_match('/^PROPERTY_(.*)_DESCRIPTION$/', $code, $matches) && !empty($matches[1])) {
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...
468
                    $propertyCode = $matches[1];
469
                    $propertyValueKey = "PROPERTY_{$propertyCode}_VALUE";
470
                    if (!in_array($propertyValueKey, $selectedFields)) {
471
                        $selectedFields[] = $propertyValueKey;
472
                    }
473
                }
474
475
                // if we pass PROPERTY_X_ENUM_ID as selected field, we need to add PROPERTY_X_VALUE as well.
476 View Code Duplication
                if (preg_match('/^PROPERTY_(.*)_ENUM_ID$/', $code, $matches) && !empty($matches[1])) {
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...
477
                    $propertyCode = $matches[1];
478
                    $propertyValueKey = "PROPERTY_{$propertyCode}_VALUE";
479
                    if (!in_array($propertyValueKey, $selectedFields)) {
480
                        $selectedFields[] = $propertyValueKey;
481
                    }
482
                }
483
            }
484
        }
485
486
        foreach ($this->fields as $code => $value) {
0 ignored issues
show
Bug introduced by
The expression $this->fields of type null|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
487
            if ($saveOnlySelected && !in_array($code, $selectedFields)) {
488
                continue;
489
            }
490
491
            if (preg_match('/^PROPERTY_(.*)_VALUE$/', $code, $matches) && !empty($matches[1])) {
492
                $propertyCode = $matches[1];
493
                $iblockPropertyData = (array) $iblockPropertiesData[$propertyCode];
494
495
                // if file was not changed skip it or it will be duplicated
496
                if ($iblockPropertyData && $iblockPropertyData['PROPERTY_TYPE'] === 'F' && !empty($this->original[$code]) && $this->original[$code] === $value) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $iblockPropertyData of type array 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...
497
                    continue;
498
                }
499
500
                // if property type is a list we need to use enum ID/IDs as value/values
501
                if (array_key_exists("PROPERTY_{$propertyCode}_ENUM_ID", $this->fields)) {
502
                    $value = $this->fields["PROPERTY_{$propertyCode}_ENUM_ID"];
503
                } elseif ($iblockPropertyData && $iblockPropertyData['PROPERTY_TYPE'] === 'L' && $iblockPropertyData['MULTIPLE'] === 'Y') {
0 ignored issues
show
Bug Best Practice introduced by
The expression $iblockPropertyData of type array 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...
504
                    $value = array_keys($value);
505
                }
506
507
                // if property values have descriptions
508
                // we skip file properties here for now because they cause endless problems. Handle them manually.
509
                if (array_key_exists("PROPERTY_{$propertyCode}_DESCRIPTION", $this->fields) && (!$iblockPropertyData || $iblockPropertyData['PROPERTY_TYPE'] !== 'F')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $iblockPropertyData of type array 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...
510
                    $description = $this->fields["PROPERTY_{$propertyCode}_DESCRIPTION"];
511
512
                    if (is_array($value) && is_array($description)) {
513
                        // for multiple property
514
                        foreach ($value as $rowIndex => $rowValue) {
515
                            $propertyValues[$propertyCode][] = [
516
                                'VALUE' => $rowValue,
517
                                'DESCRIPTION' => $description[$rowIndex]
518
                            ];
519
                        }
520
                    } else {
521
                        // for single property
522
                        $propertyValues[$propertyCode] = [
523
                            'VALUE' => $value,
524
                            'DESCRIPTION' => $description
525
                        ];
526
                    }
527
                } else {
528
                    $propertyValues[$propertyCode] = $value;
529
                }
530
            }
531
        }
532
533
        return $propertyValues;
534
    }
535
536
    /**
537
     * Determine whether the field should be stopped from passing to "update".
538
     *
539
     * @param string $field
540
     * @param mixed  $value
541
     * @param array  $selectedFields
542
     *
543
     * @return bool
544
     */
545
    protected function fieldShouldNotBeSaved($field, $value, $selectedFields)
546
    {
547
        $blacklistedFields = [
548
            'ID',
549
            'IBLOCK_ID',
550
            'PROPERTIES',
551
            'PROPERTY_VALUES',
552
        ];
553
554
        return (!empty($selectedFields) && !in_array($field, $selectedFields))
555
            || in_array($field, $blacklistedFields)
556
            || ($field[0] === '~');
557
            //|| (substr($field, 0, 9) === 'PROPERTY_');
558
    }
559
560
    /**
561
     * @param $fields
562
     * @param $fieldsSelectedForSave
563
     * @return bool
564
     */
565
    protected function internalUpdate($fields, $fieldsSelectedForSave)
566
    {
567
        $fields = $fields ?: [];
568
        foreach ($fields as $key => $value) {
569
            if (substr($key, 0, 9) === 'PROPERTY_') {
570
                unset($fields[$key]);
571
            }
572
        }
573
574
        $result = !empty($fields) ? static::$bxObject->update($this->id, $fields, static::$workFlow, static::$updateSearch, static::$resizePictures) : false;
575
        $savePropsResult = $this->saveProps($fieldsSelectedForSave);
576
        $result = $result || $savePropsResult;
577
578
        return $result;
579
    }
580
581
    /**
582
     * Get value from language field according to current language.
583
     *
584
     * @param $field
585
     * @return mixed
586
     */
587
    protected function getValueFromLanguageField($field)
588
    {
589
        $key = $field . '_' . $this->getCurrentLanguage() . '_VALUE';
590
591
        return isset($this->fields[$key]) ? $this->fields[$key] : null;
592
    }
593
594
    /**
595
     * @param $value
596
     */
597
    public static function setWorkflow($value)
598
    {
599
        static::$workFlow = $value;
600
    }
601
602
    /**
603
     * @param $value
604
     */
605
    public static function setUpdateSearch($value)
606
    {
607
        static::$updateSearch = $value;
608
    }
609
610
    /**
611
     * @param $value
612
     */
613
    public static function setResizePictures($value)
614
    {
615
        static::$resizePictures = $value;
616
    }
617
}
618