Completed
Push — master ( 889fac...47d4c3 )
by Nekrasov
01:32
created

BitrixModel   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 260
Duplicated Lines 2.31 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 30
lcom 1
cbo 3
dl 6
loc 260
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A activate() 0 6 1
A deactivate() 0 6 1
B internalCreate() 0 22 4
A internalDirectCreate() 0 4 1
A delete() 0 15 2
B save() 6 22 4
A internalUpdate() 0 4 2
A scopeActive() 0 6 1
B fieldShouldNotBeSaved() 0 15 5
A instantiateObject() 0 12 3
A destroyObject() 0 4 1
A setEventErrorsOnFail() 0 6 2
A throwExceptionOnFail() 0 6 2

How to fix   Duplicated Code   

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:

1
<?php
2
3
namespace Arrilot\BitrixModels\Models;
4
5
use Arrilot\BitrixModels\Exceptions\ExceptionFromBitrix;
6
use Arrilot\BitrixModels\Queries\BaseQuery;
7
use LogicException;
8
9
abstract class BitrixModel extends BaseBitrixModel
10
{
11
    /**
12
     * Bitrix entity object.
13
     *
14
     * @var object
15
     */
16
    public static $bxObject;
17
18
    /**
19
     * Corresponding object class name.
20
     *
21
     * @var string
22
     */
23
    protected static $objectClass = '';
24
25
    /**
26
     * Fetch method and parameters.
27
     *
28
     * @var array|string
29
     */
30
    public static $fetchUsing = [
31
        'method' => 'Fetch',
32
        'params' => [],
33
    ];
34
35
    /**
36
     * Constructor.
37
     *
38
     * @param $id
39
     * @param $fields
40
     */
41
    public function __construct($id = null, $fields = null)
42
    {
43
        static::instantiateObject();
44
45
        $this->id = $id;
46
47
        $this->fill($fields);
48
    }
49
50
    /**
51
     * Activate model.
52
     *
53
     * @return bool
54
     */
55
    public function activate()
56
    {
57
        $this->fields['ACTIVE'] = 'Y';
58
59
        return $this->save(['ACTIVE']);
60
    }
61
62
    /**
63
     * Deactivate model.
64
     *
65
     * @return bool
66
     */
67
    public function deactivate()
68
    {
69
        $this->fields['ACTIVE'] = 'N';
70
71
        return $this->save(['ACTIVE']);
72
    }
73
74
    /**
75
     * Internal part of create to avoid problems with static and inheritance
76
     *
77
     * @param $fields
78
     *
79
     * @throws ExceptionFromBitrix
80
     *
81
     * @return static|bool
82
     */
83
    protected static function internalCreate($fields)
84
    {
85
        $model = new static(null, $fields);
86
        
87
        if ($model->onBeforeSave() === false || $model->onBeforeCreate() === false) {
88
            return false;
89
        }
90
91
        $bxObject = static::instantiateObject();
92
        $id = static::internalDirectCreate($bxObject, $model->fields);
93
        $model->setId($id);
94
        
95
        $result = $id ? true : false;
96
97
        $model->setEventErrorsOnFail($result, $bxObject);
98
        $model->onAfterCreate($result);
99
        $model->onAfterSave($result);
100
        $model->resetEventErrors();
101
        $model->throwExceptionOnFail($result, $bxObject);
102
103
        return $model;
104
    }
105
106
    public static function internalDirectCreate($bxObject, $fields)
107
    {
108
        return $bxObject->add($fields);
109
    }
110
111
    /**
112
     * Delete model.
113
     *
114
     * @return bool
115
     * @throws ExceptionFromBitrix
116
     */
117
    public function delete()
118
    {
119
        if ($this->onBeforeDelete() === false) {
120
            return false;
121
        }
122
123
        $result = static::$bxObject->delete($this->id);
124
125
        $this->setEventErrorsOnFail($result, static::$bxObject);
126
        $this->onAfterDelete($result);
127
        $this->resetEventErrors();
128
        $this->throwExceptionOnFail($result, static::$bxObject);
129
130
        return $result;
131
    }
132
    
133
    /**
134
     * Save model to database.
135
     *
136
     * @param array $selectedFields save only these fields instead of all.
137
     * @return bool
138
     * @throws ExceptionFromBitrix
139
     */
140
    public function save($selectedFields = [])
141
    {
142
        $fieldsSelectedForSave = is_array($selectedFields) ? $selectedFields : func_get_args();
143
        $this->fieldsSelectedForSave = $fieldsSelectedForSave;
144 View Code Duplication
        if ($this->onBeforeSave() === false || $this->onBeforeUpdate() === false) {
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...
145
            $this->fieldsSelectedForSave = [];
146
            return false;
147
        } else {
148
            $this->fieldsSelectedForSave = [];
149
        }
150
151
        $fields = $this->normalizeFieldsForSave($fieldsSelectedForSave);
152
        $result = $this->internalUpdate($fields, $fieldsSelectedForSave);
153
154
        $this->setEventErrorsOnFail($result, static::$bxObject);
155
        $this->onAfterUpdate($result);
156
        $this->onAfterSave($result);
157
        $this->resetEventErrors();
158
        $this->throwExceptionOnFail($result, static::$bxObject);
159
160
        return $result;
161
    }
162
163
    /**
164
     * @param $fields
165
     * @param $fieldsSelectedForSave
166
     * @return bool
167
     */
168
    protected function internalUpdate($fields, $fieldsSelectedForSave)
169
    {
170
        return !empty($fields) ? static::$bxObject->update($this->id, $fields) : false;
171
    }
172
173
    /**
174
     * Scope to get only active items.
175
     *
176
     * @param BaseQuery $query
177
     *
178
     * @return BaseQuery
179
     */
180
    public function scopeActive($query)
181
    {
182
        $query->filter['ACTIVE'] = 'Y';
183
184
        return $query;
185
    }
186
187
    /**
188
     * Determine whether the field should be stopped from passing to "update".
189
     *
190
     * @param string $field
191
     * @param mixed  $value
192
     * @param array  $selectedFields
193
     *
194
     * @return bool
195
     */
196
    protected function fieldShouldNotBeSaved($field, $value, $selectedFields)
197
    {
198
        $blacklistedFields = [
199
            'ID',
200
            'IBLOCK_ID',
201
            'PROPERTIES',
202
            'GROUPS',
203
            'PROPERTY_VALUES',
204
        ];
205
206
        return (!empty($selectedFields) && !in_array($field, $selectedFields))
207
            || in_array($field, $blacklistedFields)
208
            || ($field[0] === '~')
209
            || (substr($field, 0, 9) === 'PROPERTY_');
210
    }
211
212
    /**
213
     * Instantiate bitrix entity object.
214
     *
215
     * @throws LogicException
216
     *
217
     * @return object
218
     */
219
    public static function instantiateObject()
220
    {
221
        if (static::$bxObject) {
222
            return static::$bxObject;
223
        }
224
225
        if (class_exists(static::$objectClass)) {
226
            return static::$bxObject = new static::$objectClass();
227
        }
228
229
        throw new LogicException('Object initialization failed');
230
    }
231
232
    /**
233
     * Destroy bitrix entity object.
234
     *
235
     * @return void
236
     */
237
    public static function destroyObject()
238
    {
239
        static::$bxObject = null;
240
    }
241
242
    /**
243
     * Set eventErrors field on error.
244
     *
245
     * @param bool $result
246
     * @param object $bxObject
247
     */
248
    protected function setEventErrorsOnFail($result, $bxObject)
249
    {
250
        if (!$result) {
251
            $this->eventErrors = (array) $bxObject->LAST_ERROR;
252
        }
253
    }
254
255
    /**
256
     * Throw bitrix exception on fail
257
     *
258
     * @param bool $result
259
     * @param object $bxObject
260
     * @throws ExceptionFromBitrix
261
     */
262
    protected function throwExceptionOnFail($result, $bxObject)
263
    {
264
        if (!$result) {
265
            throw new ExceptionFromBitrix($bxObject->LAST_ERROR);
266
        }
267
    }
268
}
269