Completed
Push — master ( 136cb7...59b361 )
by Nekrasov
02:22
created

D7Model::internalCreate()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.0534
c 0
b 0
f 0
cc 4
eloc 13
nc 3
nop 1
1
<?php
2
3
namespace Arrilot\BitrixModels\Models;
4
5
use Arrilot\BitrixModels\Adapters\D7Adapter;
6
use Arrilot\BitrixModels\Exceptions\ExceptionFromBitrix;
7
use Arrilot\BitrixModels\Queries\D7Query;
8
use Illuminate\Support\Collection;
9
use LogicException;
10
11
/**
12
 * static int count()
13
 *
14
 * D7Query methods
15
 * @method static D7Query runtime(array|\Bitrix\Main\Entity\ExpressionField $fields)
16
 * @method static D7Query enableDataDoubling()
17
 * @method static D7Query disableDataDoubling()
18
 * @method static D7Query cacheJoins(bool $value)
19
 *
20
 * BaseQuery methods
21
 * @method static Collection getList()
22
 * @method static D7Model first()
23
 * @method static D7Model getById(int $id)
24
 * @method static D7Query sort(string|array $by, string $order='ASC')
25
 * @method static D7Query order(string|array $by, string $order='ASC') // same as sort()
26
 * @method static D7Query filter(array $filter)
27
 * @method static D7Query addFilter(array $filters)
28
 * @method static D7Query resetFilter()
29
 * @method static D7Query navigation(array $filter)
30
 * @method static D7Query select($value)
31
 * @method static D7Query keyBy(string $value)
32
 * @method static D7Query limit(int $value)
33
 * @method static D7Query offset(int $value)
34
 * @method static D7Query page(int $num)
35
 * @method static D7Query take(int $value) // same as limit()
36
 * @method static D7Query forPage(int $page, int $perPage=15)
37
 * @method static \Illuminate\Pagination\LengthAwarePaginator paginate(int $perPage = 15, string $pageName = 'page')
38
 * @method static \Illuminate\Pagination\Paginator simplePaginate(int $perPage = 15, string $pageName = 'page')
39
 * @method static D7Query stopQuery()
40
 * @method static D7Query cache(float|int $minutes)
41
 */
42
class D7Model extends BaseBitrixModel
43
{
44
    const TABLE_CLASS = null;
45
46
    /**
47
     * @var null|string
48
     */
49
    protected static $cachedTableClass = null;
50
51
    /**
52
     * Adapter to interact with Bitrix D7 API.
53
     *
54
     * @var D7Adapter
55
     */
56
    protected static $adapter;
57
58
    /**
59
     * Constructor.
60
     *
61
     * @param $id
62
     * @param $fields
63
     */
64
    public function __construct($id = null, $fields = null)
65
    {
66
        $this->id = $id;
67
        $this->fill($fields);
68
        static::instantiateAdapter();
69
    }
70
    
71
    /**
72
     * Setter for adapter (for testing)
73
     * @param $adapter
74
     */
75
    public static function setAdapter($adapter)
76
    {
77
        static::$adapter = $adapter;
78
    }
79
80
    /**
81
     * Instantiate adapter if it's not instantiated.
82
     *
83
     * @return D7Adapter
84
     */
85
    public static function instantiateAdapter()
86
    {
87
        if (static::$adapter) {
88
            return static::$adapter;
89
        }
90
91
        return static::$adapter = new D7Adapter(static::cachedTableClass());
92
    }
93
94
    /**
95
     * Instantiate a query object for the model.
96
     *
97
     * @return D7Query
98
     */
99
    public static function query()
100
    {
101
        return new D7Query(static::instantiateAdapter(), get_called_class());
102
    }
103
    
104
    /**
105
     * @return string
106
     * @throws LogicException
107
     */
108
    public static function tableClass()
109
    {
110
        $tableClass = static::TABLE_CLASS;
111
        if (!$tableClass) {
112
            throw new LogicException('You must set TABLE_CLASS constant inside a model or override tableClass() method');
113
        }
114
    
115
        return $tableClass;
116
    }
117
118
    /**
119
     * Cached version of table class.
120
     *
121
     * @return string
122
     */
123
    public static function cachedTableClass()
124
    {
125
        if (is_null(static::$cachedTableClass)) {
126
            static::$cachedTableClass = static::tableClass();
127
        }
128
129
        return static::$cachedTableClass;
130
    }
131
132
    /**
133
     * Internal part of create to avoid problems with static and inheritance
134
     *
135
     * @param $fields
136
     *
137
     * @throws ExceptionFromBitrix
138
     *
139
     * @return static|bool
140
     */
141
    protected static function internalCreate($fields)
142
    {
143
        $model = new static(null, $fields);
144
145
        if ($model->onBeforeSave() === false || $model->onBeforeCreate() === false) {
146
            return false;
147
        }
148
149
        $resultObject = static::instantiateAdapter()->add($model->fields);
0 ignored issues
show
Bug introduced by
It seems like $model->fields can also be of type null; however, Arrilot\BitrixModels\Adapters\D7Adapter::add() does only seem to accept array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
150
        $result = $resultObject->isSuccess();
151
        if ($result) {
152
            $model->setId($resultObject->getId());
153
        }
154
155
        $model->setEventErrorsOnFail($resultObject);
156
        $model->onAfterCreate($result);
157
        $model->onAfterSave($result);
158
        $model->throwExceptionOnFail($resultObject);
159
160
        return $model;
161
    }
162
163
    /**
164
     * Delete model
165
     *
166
     * @return bool
167
     * @throws ExceptionFromBitrix
168
     */
169
    public function delete()
170
    {
171
        if ($this->onBeforeDelete() === false) {
172
            return false;
173
        }
174
175
        $resultObject = static::instantiateAdapter()->delete($this->id);
176
        $result = $resultObject->isSuccess();
177
178
        $this->setEventErrorsOnFail($resultObject);
179
        $this->onAfterDelete($result);
180
        $this->throwExceptionOnFail($resultObject);
181
182
        return $result;
183
    }
184
    
185
    /**
186
     * Save model to database.
187
     *
188
     * @param array $selectedFields save only these fields instead of all.
189
     * @return bool
190
     * @throws ExceptionFromBitrix
191
     */
192
    public function save($selectedFields = [])
193
    {
194
        $this->fieldsSelectedForSave = is_array($selectedFields) ? $selectedFields : func_get_args();
195
        if ($this->onBeforeSave() === false || $this->onBeforeUpdate() === false) {
196
            return false;
197
        }
198
199
        $fields = $this->normalizeFieldsForSave($this->fieldsSelectedForSave);
200
        $resultObject = static::instantiateAdapter()->update($this->id, $fields);
201
        $result = $resultObject->isSuccess();
202
203
        $this->setEventErrorsOnFail($resultObject);
204
        $this->onAfterUpdate($result);
205
        $this->onAfterSave($result);
206
        $this->throwExceptionOnFail($resultObject);
207
208
        return $result;
209
    }
210
    
211
    /**
212
     * Determine whether the field should be stopped from passing to "update".
213
     *
214
     * @param string $field
215
     * @param mixed  $value
216
     * @param array  $selectedFields
217
     *
218
     * @return bool
219
     */
220
    protected function fieldShouldNotBeSaved($field, $value, $selectedFields)
221
    {
222
        return (!empty($selectedFields) && !in_array($field, $selectedFields)) || $field === 'ID';
223
    }
224
225
    /**
226
     * Throw bitrix exception on fail
227
     *
228
     * @param \Bitrix\Main\Entity\Result $resultObject
229
     * @throws ExceptionFromBitrix
230
     */
231
    protected function throwExceptionOnFail($resultObject)
232
    {
233
        if (!$resultObject->isSuccess()) {
234
            throw new ExceptionFromBitrix(implode('; ', $resultObject->getErrorMessages()));
235
        }
236
    }
237
238
    /**
239
     * Set eventErrors field on error.
240
     *
241
     * @param \Bitrix\Main\Entity\Result $resultObject
242
     */
243
    protected function setEventErrorsOnFail($resultObject)
244
    {
245
        if (!$resultObject->isSuccess()) {
246
            $this->eventErrors = (array) $resultObject->getErrorMessages();
247
        }
248
    }
249
}
250