Completed
Pull Request — master (#12)
by
unknown
01:18
created

HLModel::tableName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Arrilot\BitrixModels\Models;
4
5
6
use Arrilot\BitrixModels\Models\ArrayableModel;
7
use Arrilot\BitrixModels\ModelEventsTrait;
8
use Bitrix\Highloadblock\HighloadBlockTable;
9
use Arrilot\BitrixModels\Queries\HLQuery;
10
11
class HLModel extends ArrayableModel
12
{
13
    use ModelEventsTrait;
14
15
    /**
16
     * Bitrix entity object.
17
     *
18
     * @var object
19
     */
20
    public static $bxObject;
21
22
    protected static $tableName;
23
24
25
    /**
26
     * Have fields been already fetched from DB?
27
     *
28
     * @var bool
29
     */
30
    protected $fieldsAreFetched = false;
31
32
    /**
33
     * Constructor.
34
     *
35
     * @param $id
36
     * @param $fields
37
     */
38
    public function __construct($id = null, $fields = null)
39
    {
40
        static::instantiateObject();
41
42
        $this->id = $id;
43
44
        $this->fill($fields);
45
    }
46
47
    static public function tableName()
0 ignored issues
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
48
    {
49
        return static::$tableName;
50
    }
51
52
    /**
53
     * Get all model attributes from cache or database.
54
     *
55
     * @return array
56
     */
57
    public function get()
58
    {
59
        $this->load();
60
61
        return $this->fields;
62
    }
63
64
    /**
65
     * Load model fields from database if they are not loaded yet.
66
     *
67
     * @return $this
68
     */
69
    public function load()
70
    {
71
        if (!$this->fieldsAreFetched) {
72
            $this->refresh();
73
        }
74
75
        return $this;
76
    }
77
78
    /**
79
     * Get model fields from cache or database.
80
     *
81
     * @return array
82
     */
83
    public function getFields()
84
    {
85
        if ($this->fieldsAreFetched) {
86
            return $this->fields;
87
        }
88
89
        return $this->refreshFields();
90
    }
91
92
    /**
93
     * Refresh model from database and place data to $this->fields.
94
     *
95
     * @return array
96
     */
97
    public function refresh()
98
    {
99
        return $this->refreshFields();
100
    }
101
102
    /**
103
     * Refresh model fields and save them to a class field.
104
     *
105
     * @return array
106
     */
107 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...
108
    {
109
        if ($this->id === null) {
110
            return $this->fields = [];
111
        }
112
113
        $this->fields = static::query()->getById($this->id)->fields;
114
115
        $this->fieldsAreFetched = true;
116
117
        return $this->fields;
118
    }
119
120
    /**
121
     * Fill model fields if they are already known.
122
     * Saves DB queries.
123
     *
124
     * @param array $fields
125
     *
126
     * @return void
127
     */
128 View Code Duplication
    public function fill($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...
129
    {
130
        if (!is_array($fields)) {
131
            return;
132
        }
133
134
        if (isset($fields['ID'])) {
135
            $this->id = $fields['ID'];
136
        }
137
138
        $this->fields = $fields;
139
140
        $this->fieldsAreFetched = true;
141
142
        if (method_exists($this, 'afterFill')) {
143
            $this->afterFill();
0 ignored issues
show
Bug introduced by
The method afterFill() does not seem to exist on object<Arrilot\BitrixModels\Models\HLModel>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
144
        }
145
    }
146
147
148
    /**
149
     * Create new item in database.
150
     *
151
     * @param $fields
152
     *
153
     * @throws Exception
154
     *
155
     * @return static|bool
156
     */
157
    public static function create($fields)
158
    {
159
        return static::internalCreate($fields);
160
    }
161
162
    /**
163
     * Internal part of create to avoid problems with static and inheritance
164
     *
165
     * @param $fields
166
     *
167
     * @throws Exception
168
     *
169
     * @return static|bool
170
     */
171
    protected static function internalCreate($fields)
172
    {
173
        $model = new static(null, $fields);
174
175
        if ($model->onBeforeSave() === false || $model->onBeforeCreate() === false) {
176
            return false;
177
        }
178
179
        $bxObject = static::instantiateObject();
180
        $id = $bxObject::add($fields);
181
        $model->setId($id);
182
183
        $result = $id ? true : false;
184
185
        $model->onAfterCreate($result);
186
        $model->onAfterSave($result);
187
188
        return $model;
189
    }
190
191
    /**
192
     * Get count of items that match $filter.
193
     *
194
     * @param array $filter
195
     *
196
     * @return int
197
     */
198
    public static function count(array $filter = [])
199
    {
200
        return static::query()->filter($filter)->count();
201
    }
202
203
    /**
204
     * Get item by its id.
205
     *
206
     * @param int $id
207
     *
208
     * @return static|bool
209
     */
210
    public static function find($id)
211
    {
212
        return static::query()->getById($id);
213
    }
214
215
    /**
216
     * Delete model.
217
     *
218
     * @return bool
219
     */
220 View Code Duplication
    public function delete()
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...
221
    {
222
        if ($this->onBeforeDelete() === false) {
223
            return false;
224
        }
225
226
        $result = static::$bxObject::delete($this->id);
227
228
        $this->onAfterDelete($result);
229
230
        return $result;
231
    }
232
233
    /**
234
     * Update model.
235
     *
236
     * @param array $fields
237
     *
238
     * @return bool
239
     */
240 View Code Duplication
    public function update(array $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...
241
    {
242
        $keys = [];
243
        foreach ($fields as $key => $value) {
244
            array_set($this->fields, $key, $value);
245
            $keys[] = $key;
246
        }
247
248
        return $this->save($keys);
249
    }
250
251
    /**
252
     * Save model to database.
253
     *
254
     * @param array $selectedFields save only these fields instead of all.
255
     *
256
     * @return bool
257
     */
258
    public function save($selectedFields = [])
259
    {
260
        $selectedFields = is_array($selectedFields) ? $selectedFields : func_get_args();
261
262
        if ($this->onBeforeSave() === false || $this->onBeforeUpdate() === false) {
263
            return false;
264
        }
265
266
        $fields = $this->normalizeFieldsForSave($selectedFields);
267
        $result = !empty($fields) ? static::$bxObject::update($this->id, $fields) : false;
268
269
        $this->onAfterUpdate($result);
270
        $this->onAfterSave($result);
271
272
        return $result;
273
    }
274
275
    /**
276
     * Create an array of fields that will be saved to database.
277
     *
278
     * @param $selectedFields
279
     *
280
     * @return array
281
     */
282 View Code Duplication
    protected function normalizeFieldsForSave($selectedFields)
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...
283
    {
284
        $fields = [];
285
        if ($this->fields === null) {
286
            return [];
287
        }
288
289
        foreach ($this->fields as $field => $value) {
290
            if (!$this->fieldShouldNotBeSaved($field, $value, $selectedFields)) {
291
                $fields[$field] = $value;
292
            }
293
        }
294
295
        return $fields;
296
    }
297
298
    /**
299
     * Determine whether the field should be stopped from passing to "update".
300
     *
301
     * @param string $field
302
     * @param mixed  $value
303
     * @param array  $selectedFields
304
     *
305
     * @return bool
306
     */
307
    protected function fieldShouldNotBeSaved($field, $value, $selectedFields)
0 ignored issues
show
Unused Code introduced by
The parameter $value 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...
308
    {
309
        $blacklistedFields = [
310
            'ID',
311
        ];
312
313
        return (!empty($selectedFields) && !in_array($field, $selectedFields))
314
            || in_array($field, $blacklistedFields)
315
            || !(substr($field, 0, 3) === 'UF_');
316
    }
317
318
    /**
319
     * Instantiate bitrix entity object.
320
     *
321
     * @throws Exception
322
     *
323
     * @return object
324
     */
325
    public static function instantiateObject()
326
    {
327
        $tableName = static::tableName();
328
        if (static::$bxObject[$tableName]) {
329
            return static::$bxObject[$tableName];
330
        }
331
332
        $item = HighloadBlockTable::getList(['filter' => ['TABLE_NAME' => $tableName ]])->fetch();
333
        return static::$bxObject[$tableName] = HighloadBlockTable::compileEntity($item)->getDataClass();
334
    }
335
336
    /**
337
     * Destroy bitrix entity object.
338
     *
339
     * @return void
340
     */
341
    public static function destroyObject()
342
    {
343
        static::$bxObject = null;
344
    }
345
346
    /**
347
     * Instantiate a query object for the model.
348
     *
349
     * @throws Exception
350
     *
351
     * @return BaseQuery
352
     */
353
    public static function query()
354
    {
355
        return new HLQuery(static::instantiateObject(), get_called_class());
356
    }
357
358
    /**
359
     * Set current model id.
360
     *
361
     * @param $id
362
     */
363
    protected function setId($id)
364
    {
365
        $this->id = $id;
366
        $this->fields['ID'] = $id;
367
    }
368
369
    /**
370
     * Handle dynamic static method calls into a new query.
371
     *
372
     * @param  string  $method
373
     * @param  array  $parameters
374
     * @return mixed
375
     */
376
    public static function __callStatic($method, $parameters)
377
    {
378
        return static::query()->$method(...$parameters);
379
    }
380
}