This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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 Bitrix\Main\Entity\UpdateResult; |
||
10 | use LogicException; |
||
11 | |||
12 | /** |
||
13 | * static int count() |
||
14 | * |
||
15 | * D7Query methods |
||
16 | * @method static D7Query runtime(array|\Bitrix\Main\Entity\ExpressionField $fields) |
||
17 | * @method static D7Query enableDataDoubling() |
||
18 | * @method static D7Query disableDataDoubling() |
||
19 | * @method static D7Query cacheJoins(bool $value) |
||
20 | * |
||
21 | * BaseQuery methods |
||
22 | * @method static Collection|static[] getList() |
||
23 | * @method static static first() |
||
24 | * @method static static getById(int $id) |
||
25 | * @method static D7Query sort(string|array $by, string $order='ASC') |
||
26 | * @method static D7Query order(string|array $by, string $order='ASC') // same as sort() |
||
27 | * @method static D7Query filter(array $filter) |
||
28 | * @method static D7Query addFilter(array $filters) |
||
29 | * @method static D7Query resetFilter() |
||
30 | * @method static D7Query navigation(array $filter) |
||
31 | * @method static D7Query select($value) |
||
32 | * @method static D7Query keyBy(string $value) |
||
33 | * @method static D7Query limit(int $value) |
||
34 | * @method static D7Query offset(int $value) |
||
35 | * @method static D7Query page(int $num) |
||
36 | * @method static D7Query take(int $value) // same as limit() |
||
37 | * @method static D7Query forPage(int $page, int $perPage=15) |
||
38 | * @method static \Illuminate\Pagination\LengthAwarePaginator paginate(int $perPage = 15, string $pageName = 'page') |
||
39 | * @method static \Illuminate\Pagination\Paginator simplePaginate(int $perPage = 15, string $pageName = 'page') |
||
40 | * @method static D7Query stopQuery() |
||
41 | * @method static D7Query cache(float|int $minutes) |
||
42 | */ |
||
43 | class D7Model extends BaseBitrixModel |
||
44 | { |
||
45 | const TABLE_CLASS = null; |
||
46 | |||
47 | /** |
||
48 | * @var null|string |
||
49 | */ |
||
50 | protected static $cachedTableClasses = []; |
||
51 | |||
52 | /** |
||
53 | * Array of adapters for each model to interact with Bitrix D7 API. |
||
54 | * |
||
55 | * @var D7Adapter[] |
||
56 | */ |
||
57 | protected static $adapters = []; |
||
58 | |||
59 | /** |
||
60 | * Constructor. |
||
61 | * |
||
62 | * @param $id |
||
63 | * @param $fields |
||
64 | */ |
||
65 | public function __construct($id = null, $fields = null) |
||
66 | { |
||
67 | $this->id = $id; |
||
68 | $this->fill($fields); |
||
69 | static::instantiateAdapter(); |
||
70 | } |
||
71 | |||
72 | /** |
||
73 | * Setter for adapter (for testing) |
||
74 | * @param $adapter |
||
75 | */ |
||
76 | public static function setAdapter($adapter) |
||
77 | { |
||
78 | static::$adapters[get_called_class()] = $adapter; |
||
79 | } |
||
80 | |||
81 | /** |
||
82 | * Instantiate adapter if it's not instantiated. |
||
83 | * |
||
84 | * @return D7Adapter |
||
85 | */ |
||
86 | public static function instantiateAdapter() |
||
87 | { |
||
88 | $class = get_called_class(); |
||
89 | if (isset(static::$adapters[$class])) { |
||
90 | return static::$adapters[$class]; |
||
91 | } |
||
92 | |||
93 | return static::$adapters[$class] = new D7Adapter(static::cachedTableClass()); |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * Instantiate a query object for the model. |
||
98 | * |
||
99 | * @return D7Query |
||
100 | */ |
||
101 | public static function query() |
||
102 | { |
||
103 | return new D7Query(static::instantiateAdapter(), get_called_class()); |
||
104 | } |
||
105 | |||
106 | /** |
||
107 | * @return string |
||
108 | * @throws LogicException |
||
109 | */ |
||
110 | public static function tableClass() |
||
111 | { |
||
112 | $tableClass = static::TABLE_CLASS; |
||
113 | if (!$tableClass) { |
||
114 | throw new LogicException('You must set TABLE_CLASS constant inside a model or override tableClass() method'); |
||
115 | } |
||
116 | |||
117 | return $tableClass; |
||
118 | } |
||
119 | |||
120 | /** |
||
121 | * Cached version of table class. |
||
122 | * |
||
123 | * @return string |
||
124 | */ |
||
125 | public static function cachedTableClass() |
||
126 | { |
||
127 | $class = get_called_class(); |
||
128 | if (!isset(static::$cachedTableClasses[$class])) { |
||
129 | static::$cachedTableClasses[$class] = static::tableClass(); |
||
130 | } |
||
131 | |||
132 | return static::$cachedTableClasses[$class]; |
||
133 | } |
||
134 | |||
135 | /** |
||
136 | * Internal part of create to avoid problems with static and inheritance |
||
137 | * |
||
138 | * @param $fields |
||
139 | * |
||
140 | * @throws ExceptionFromBitrix |
||
141 | * |
||
142 | * @return static|bool |
||
143 | */ |
||
144 | protected static function internalCreate($fields) |
||
145 | { |
||
146 | $model = new static(null, $fields); |
||
147 | |||
148 | if ($model->onBeforeSave() === false || $model->onBeforeCreate() === false) { |
||
149 | return false; |
||
150 | } |
||
151 | |||
152 | $resultObject = static::instantiateAdapter()->add($model->fields); |
||
0 ignored issues
–
show
|
|||
153 | $result = $resultObject->isSuccess(); |
||
154 | if ($result) { |
||
155 | $model->setId($resultObject->getId()); |
||
156 | } |
||
157 | |||
158 | $model->setEventErrorsOnFail($resultObject); |
||
159 | $model->onAfterCreate($result); |
||
160 | $model->onAfterSave($result); |
||
161 | $model->throwExceptionOnFail($resultObject); |
||
162 | |||
163 | return $model; |
||
164 | } |
||
165 | |||
166 | /** |
||
167 | * Delete model |
||
168 | * |
||
169 | * @return bool |
||
170 | * @throws ExceptionFromBitrix |
||
171 | */ |
||
172 | public function delete() |
||
173 | { |
||
174 | if ($this->onBeforeDelete() === false) { |
||
175 | return false; |
||
176 | } |
||
177 | |||
178 | $resultObject = static::instantiateAdapter()->delete($this->id); |
||
179 | $result = $resultObject->isSuccess(); |
||
180 | |||
181 | $this->setEventErrorsOnFail($resultObject); |
||
182 | $this->onAfterDelete($result); |
||
183 | $this->resetEventErrors(); |
||
184 | $this->throwExceptionOnFail($resultObject); |
||
185 | |||
186 | return $result; |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * Save model to database. |
||
191 | * |
||
192 | * @param array $selectedFields save only these fields instead of all. |
||
193 | * @return bool |
||
194 | * @throws ExceptionFromBitrix |
||
195 | */ |
||
196 | public function save($selectedFields = []) |
||
197 | { |
||
198 | $fieldsSelectedForSave = is_array($selectedFields) ? $selectedFields : func_get_args(); |
||
199 | $this->fieldsSelectedForSave = $fieldsSelectedForSave; |
||
200 | View Code Duplication | if ($this->onBeforeSave() === false || $this->onBeforeUpdate() === false) { |
|
0 ignored issues
–
show
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. ![]() |
|||
201 | $this->fieldsSelectedForSave = []; |
||
202 | return false; |
||
203 | } else { |
||
204 | $this->fieldsSelectedForSave = []; |
||
205 | } |
||
206 | |||
207 | $fields = $this->normalizeFieldsForSave($fieldsSelectedForSave); |
||
208 | $resultObject = $fields === null |
||
209 | ? new UpdateResult() |
||
210 | : static::instantiateAdapter()->update($this->id, $fields); |
||
211 | $result = $resultObject->isSuccess(); |
||
212 | |||
213 | $this->setEventErrorsOnFail($resultObject); |
||
214 | $this->onAfterUpdate($result); |
||
215 | $this->onAfterSave($result); |
||
216 | $this->throwExceptionOnFail($resultObject); |
||
217 | |||
218 | return $result; |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * Determine whether the field should be stopped from passing to "update". |
||
223 | * |
||
224 | * @param string $field |
||
225 | * @param mixed $value |
||
226 | * @param array $selectedFields |
||
227 | * |
||
228 | * @return bool |
||
229 | */ |
||
230 | protected function fieldShouldNotBeSaved($field, $value, $selectedFields) |
||
231 | { |
||
232 | return (!empty($selectedFields) && !in_array($field, $selectedFields)) || $field === 'ID'; |
||
233 | } |
||
234 | |||
235 | /** |
||
236 | * Throw bitrix exception on fail |
||
237 | * |
||
238 | * @param \Bitrix\Main\Entity\Result $resultObject |
||
239 | * @throws ExceptionFromBitrix |
||
240 | */ |
||
241 | protected function throwExceptionOnFail($resultObject) |
||
242 | { |
||
243 | if (!$resultObject->isSuccess()) { |
||
244 | throw new ExceptionFromBitrix(implode('; ', $resultObject->getErrorMessages())); |
||
245 | } |
||
246 | } |
||
247 | |||
248 | /** |
||
249 | * Set eventErrors field on error. |
||
250 | * |
||
251 | * @param \Bitrix\Main\Entity\Result $resultObject |
||
252 | */ |
||
253 | protected function setEventErrorsOnFail($resultObject) |
||
254 | { |
||
255 | if (!$resultObject->isSuccess()) { |
||
256 | $this->eventErrors = (array) $resultObject->getErrorMessages(); |
||
257 | } |
||
258 | } |
||
259 | } |
||
260 |
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:
If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.