1 | <?php |
||||||
2 | |||||||
3 | namespace SoliDry\Blocks; |
||||||
4 | |||||||
5 | use Illuminate\Container\Container; |
||||||
6 | use Illuminate\Database\Eloquent\Collection; |
||||||
7 | use Illuminate\Http\Request; |
||||||
8 | use Illuminate\Http\Response; |
||||||
9 | use Illuminate\Database\Eloquent\SoftDeletes; |
||||||
10 | use Illuminate\Support\Facades\DB; |
||||||
11 | use SoliDry\Exceptions\ErrorHandler; |
||||||
12 | use SoliDry\Extension\ApiController; |
||||||
13 | use SoliDry\Extension\BaseFormRequest; |
||||||
14 | use SoliDry\Extension\BaseModel; |
||||||
15 | use SoliDry\Extension\JSONApiInterface; |
||||||
16 | use SoliDry\Helpers\Classes; |
||||||
17 | use SoliDry\Helpers\ConfigHelper as conf; |
||||||
18 | use SoliDry\Helpers\ConfigOptions; |
||||||
19 | use SoliDry\Helpers\Json; |
||||||
20 | use SoliDry\Types\DefaultInterface; |
||||||
21 | use SoliDry\Types\DirsInterface; |
||||||
22 | use SoliDry\Types\ModelsInterface; |
||||||
23 | use SoliDry\Types\PhpInterface; |
||||||
24 | use SoliDry\Types\ApiInterface; |
||||||
25 | |||||||
26 | /** |
||||||
27 | * Class EntitiesTrait |
||||||
28 | * |
||||||
29 | * @package SoliDry\Blocks |
||||||
30 | * @property ApiController entity |
||||||
31 | * @property BaseFormRequest $formRequest |
||||||
32 | * @property ApiController props |
||||||
33 | * @property BaseModel model |
||||||
34 | * @property ApiController modelEntity |
||||||
35 | * @property ConfigOptions configOptions |
||||||
36 | * @property Json json |
||||||
37 | * @property \SoliDry\Containers\Response response |
||||||
38 | */ |
||||||
39 | trait EntitiesTrait |
||||||
40 | { |
||||||
41 | use ErrorHandler; |
||||||
42 | |||||||
43 | /** |
||||||
44 | * Gets form request entity fully qualified path |
||||||
45 | * |
||||||
46 | * @param string $version |
||||||
47 | * @param string $object |
||||||
48 | * @return string |
||||||
49 | */ |
||||||
50 | public function getFormRequestEntity(string $version, string $object): string |
||||||
51 | { |
||||||
52 | return DirsInterface::MODULES_DIR . PhpInterface::BACKSLASH . strtoupper($version) . |
||||||
53 | PhpInterface::BACKSLASH . DirsInterface::HTTP_DIR . |
||||||
54 | PhpInterface::BACKSLASH . |
||||||
55 | DirsInterface::FORM_REQUEST_DIR . PhpInterface::BACKSLASH . |
||||||
56 | $object . |
||||||
57 | DefaultInterface::FORM_REQUEST_POSTFIX; |
||||||
58 | } |
||||||
59 | |||||||
60 | /** |
||||||
61 | * Sets all props/entities needed to process request |
||||||
62 | * |
||||||
63 | * @throws \Illuminate\Contracts\Container\BindingResolutionException |
||||||
64 | * @throws \ReflectionException |
||||||
65 | */ |
||||||
66 | protected function setEntities(): void |
||||||
67 | { |
||||||
68 | $this->entity = Classes::cutEntity(Classes::getObjectName($this), DefaultInterface::CONTROLLER_POSTFIX); |
||||||
0 ignored issues
–
show
|
|||||||
69 | $formRequestEntity = $this->getFormRequestEntity(conf::getModuleName(), $this->entity); |
||||||
70 | |||||||
71 | $this->formRequest = new $formRequestEntity(); |
||||||
72 | $this->props = get_object_vars($this->formRequest); |
||||||
0 ignored issues
–
show
It seems like
get_object_vars($this->formRequest) of type array is incompatible with the declared type SoliDry\Extension\ApiController of property $props .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..
Loading history...
|
|||||||
73 | |||||||
74 | $this->modelEntity = Classes::getModelEntity($this->entity); |
||||||
0 ignored issues
–
show
It seems like
SoliDry\Helpers\Classes:...elEntity($this->entity) of type string is incompatible with the declared type SoliDry\Extension\ApiController of property $modelEntity .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..
Loading history...
|
|||||||
75 | $this->model = new $this->modelEntity(); |
||||||
76 | |||||||
77 | $container = Container::getInstance(); |
||||||
78 | $this->response = $container->make(\SoliDry\Containers\Response::class); |
||||||
79 | $this->response->setFormRequest($this->formRequest); |
||||||
80 | $this->response->setEntity($this->entity); |
||||||
81 | } |
||||||
82 | |||||||
83 | /** |
||||||
84 | * Save bulk transactionally, if there are some errors - rollback |
||||||
85 | * |
||||||
86 | * @param Request $request |
||||||
87 | * @return Response |
||||||
88 | * @throws \InvalidArgumentException |
||||||
89 | * @throws \LogicException |
||||||
90 | */ |
||||||
91 | protected function saveBulk(Request $request): Response |
||||||
92 | { |
||||||
93 | $meta = []; |
||||||
94 | $collection = new Collection(); |
||||||
95 | |||||||
96 | $json = Json::decode($request->getContent()); |
||||||
97 | $jsonApiAttributes = Json::getBulkAttributes($json); |
||||||
98 | |||||||
99 | try { |
||||||
100 | DB::beginTransaction(); |
||||||
101 | foreach ($jsonApiAttributes as $jsonObject) { |
||||||
102 | |||||||
103 | $this->model = new $this->modelEntity(); |
||||||
0 ignored issues
–
show
The call to
SoliDry\Extension\ApiController::__construct() has too few arguments starting with route .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.
Loading history...
|
|||||||
104 | |||||||
105 | // FSM initial state check |
||||||
106 | if ($this->configOptions->isStateMachine() === true) { |
||||||
107 | $this->checkFsmCreate($jsonObject); |
||||||
0 ignored issues
–
show
It seems like
checkFsmCreate() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
108 | } |
||||||
109 | |||||||
110 | // spell check |
||||||
111 | if ($this->configOptions->isSpellCheck() === true) { |
||||||
112 | $meta[] = $this->spellCheck($jsonObject); |
||||||
0 ignored issues
–
show
It seems like
spellCheck() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
113 | } |
||||||
114 | |||||||
115 | // fill in model |
||||||
116 | foreach ($this->props as $k => $v) { |
||||||
117 | // request fields should match FormRequest fields |
||||||
118 | if (isset($jsonObject[$k])) { |
||||||
119 | $this->model->$k = $jsonObject[$k]; |
||||||
120 | } |
||||||
121 | } |
||||||
122 | |||||||
123 | // set bit mask |
||||||
124 | if ($this->configOptions->isBitMask() === true) { |
||||||
125 | $this->setMaskCreate($jsonObject); |
||||||
0 ignored issues
–
show
It seems like
setMaskCreate() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
126 | } |
||||||
127 | |||||||
128 | $collection->push($this->model); |
||||||
129 | $this->model->save(); |
||||||
130 | |||||||
131 | // jwt |
||||||
132 | if ($this->configOptions->getIsJwtAction() === true) { |
||||||
133 | $this->createJwtUser(); // !!! model is overridden |
||||||
0 ignored issues
–
show
It seems like
createJwtUser() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
134 | } |
||||||
135 | |||||||
136 | // set bit mask from model -> response |
||||||
137 | if ($this->configOptions->isBitMask() === true) { |
||||||
138 | $this->model = $this->setFlagsCreate(); |
||||||
0 ignored issues
–
show
It seems like
setFlagsCreate() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
139 | } |
||||||
140 | } |
||||||
141 | |||||||
142 | DB::commit(); |
||||||
143 | } catch (\PDOException $e) { |
||||||
144 | DB::rollBack(); |
||||||
145 | |||||||
146 | return $this->getErrorResponse($request, $e); |
||||||
147 | } |
||||||
148 | |||||||
149 | return $this->response->get($collection, $meta); |
||||||
150 | } |
||||||
151 | |||||||
152 | /** |
||||||
153 | * Mutates/Updates a bulk by applying it to transaction/rollback procedure |
||||||
154 | * |
||||||
155 | * @param Request $request |
||||||
156 | * @return Response |
||||||
157 | * @throws \InvalidArgumentException |
||||||
158 | * @throws \SoliDry\Exceptions\AttributesException |
||||||
159 | * @throws \LogicException |
||||||
160 | */ |
||||||
161 | protected function mutateBulk(Request $request): Response |
||||||
162 | { |
||||||
163 | $meta = []; |
||||||
164 | $collection = new Collection(); |
||||||
165 | |||||||
166 | $json = Json::decode($request->getContent()); |
||||||
167 | $jsonApiAttributes = Json::getBulkAttributes($json); |
||||||
168 | |||||||
169 | try { |
||||||
170 | DB::beginTransaction(); |
||||||
171 | foreach ($jsonApiAttributes as $jsonObject) { |
||||||
172 | |||||||
173 | $model = $this->getEntity($jsonObject[JSONApiInterface::CONTENT_ID]); |
||||||
0 ignored issues
–
show
It seems like
getEntity() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
174 | |||||||
175 | // FSM transition check |
||||||
176 | if ($this->configOptions->isStateMachine() === true) { |
||||||
177 | $this->checkFsmUpdate($jsonObject, $model); |
||||||
0 ignored issues
–
show
It seems like
checkFsmUpdate() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
178 | } |
||||||
179 | |||||||
180 | // spell check |
||||||
181 | if ($this->configOptions->isSpellCheck() === true) { |
||||||
182 | $meta[] = $this->spellCheck($jsonObject); |
||||||
183 | } |
||||||
184 | |||||||
185 | $this->processUpdate($model, $jsonObject); |
||||||
0 ignored issues
–
show
It seems like
processUpdate() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
186 | $collection->push($model); |
||||||
187 | $model->save(); |
||||||
188 | |||||||
189 | // set bit mask |
||||||
190 | if ($this->configOptions->isBitMask() === true) { |
||||||
191 | $this->setFlagsUpdate($model); |
||||||
0 ignored issues
–
show
It seems like
setFlagsUpdate() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
192 | } |
||||||
193 | |||||||
194 | } |
||||||
195 | DB::commit(); |
||||||
196 | } catch (\PDOException $e) { |
||||||
197 | DB::rollBack(); |
||||||
198 | |||||||
199 | return $this->getErrorResponse($request, $e); |
||||||
200 | } |
||||||
201 | |||||||
202 | return $this->response->get($collection, $meta); |
||||||
203 | } |
||||||
204 | |||||||
205 | /** |
||||||
206 | * Deletes bulk by applying it to transaction/rollback procedure |
||||||
207 | * |
||||||
208 | * @param Request $request |
||||||
209 | * @return Response |
||||||
210 | * @throws \LogicException |
||||||
211 | */ |
||||||
212 | public function removeBulk(Request $request): Response |
||||||
213 | { |
||||||
214 | $json = Json::decode($request->getContent()); |
||||||
215 | $jsonApiAttributes = Json::getBulkAttributes($json); |
||||||
216 | |||||||
217 | try { |
||||||
218 | DB::beginTransaction(); |
||||||
219 | |||||||
220 | foreach ($jsonApiAttributes as $jsonObject) { |
||||||
221 | $model = $this->getEntity($jsonObject[JSONApiInterface::CONTENT_ID]); |
||||||
222 | |||||||
223 | if ($model === null) { |
||||||
224 | DB::rollBack(); |
||||||
225 | |||||||
226 | return $this->response->getModelNotFoundError($this->modelEntity, $jsonObject[JSONApiInterface::CONTENT_ID]); |
||||||
0 ignored issues
–
show
$this->modelEntity of type SoliDry\Extension\ApiController is incompatible with the type string expected by parameter $entity of SoliDry\Containers\Respo...getModelNotFoundError() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
227 | } |
||||||
228 | |||||||
229 | $model->delete(); |
||||||
230 | } |
||||||
231 | |||||||
232 | DB::commit(); |
||||||
233 | } catch (\PDOException $e) { |
||||||
234 | DB::rollBack(); |
||||||
235 | |||||||
236 | return $this->getErrorResponse($request, $e); |
||||||
237 | } |
||||||
238 | |||||||
239 | return $this->response->removeBulk(); |
||||||
240 | } |
||||||
241 | |||||||
242 | /** |
||||||
243 | * Gets the relations of entity or null |
||||||
244 | * @param string $objectName |
||||||
245 | * |
||||||
246 | * @return mixed |
||||||
247 | */ |
||||||
248 | private function getRelationType(string $objectName) |
||||||
249 | { |
||||||
250 | if (empty($this->generator->types[$objectName][ApiInterface::RAML_PROPS] |
||||||
251 | [ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE]) === false |
||||||
252 | ) { |
||||||
253 | return trim( |
||||||
254 | $this->generator->types[$objectName][ApiInterface::RAML_PROPS] |
||||||
255 | [ApiInterface::RAML_RELATIONSHIPS][ApiInterface::RAML_TYPE] |
||||||
256 | ); |
||||||
257 | } |
||||||
258 | |||||||
259 | return null; |
||||||
260 | } |
||||||
261 | |||||||
262 | /** |
||||||
263 | * Sets use stmt for Soft Delete op on model Entity |
||||||
264 | * |
||||||
265 | * @throws \ReflectionException |
||||||
266 | */ |
||||||
267 | private function setUseSoftDelete(): void |
||||||
268 | { |
||||||
269 | if ($this->isSoftDelete()) { |
||||||
0 ignored issues
–
show
It seems like
isSoftDelete() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
270 | $this->setUse(Classes::getObjectName(SoftDeletes::class), true, true); |
||||||
0 ignored issues
–
show
The method
setUse() does not exist on SoliDry\Blocks\EntitiesTrait . Did you maybe mean setUseSoftDelete() ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
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...
|
|||||||
271 | } |
||||||
272 | } |
||||||
273 | |||||||
274 | /** |
||||||
275 | * Sets property for Soft Delete op on model Entity |
||||||
276 | */ |
||||||
277 | private function setPropSoftDelete(): void |
||||||
278 | { |
||||||
279 | if ($this->isSoftDelete()) { |
||||||
280 | $this->createPropertyArray(ModelsInterface::PROPERTY_DATES, PhpInterface::PHP_MODIFIER_PROTECTED, [ModelsInterface::COLUMN_DEL_AT]); |
||||||
0 ignored issues
–
show
It seems like
createPropertyArray() must be provided by classes using this trait. How about adding it as abstract method to this trait?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
281 | } |
||||||
282 | } |
||||||
283 | } |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..