1 | <?php |
||||||
2 | |||||||
3 | namespace OfflineAgency\MongoAutoSync\Traits; |
||||||
4 | |||||||
5 | use DateTime; |
||||||
6 | use Exception; |
||||||
7 | use Illuminate\Http\Request; |
||||||
8 | use Illuminate\Support\Arr; |
||||||
9 | use MongoDB\BSON\UTCDateTime; |
||||||
10 | |||||||
11 | trait RelationshipMongoTrait |
||||||
12 | { |
||||||
13 | public $is_partial_request; |
||||||
14 | |||||||
15 | /** |
||||||
16 | * @param Request $request |
||||||
17 | * @param string $event |
||||||
18 | * @param string $parent |
||||||
19 | * @param string $counter |
||||||
20 | * @param array $options |
||||||
21 | * |
||||||
22 | * @throws Exception |
||||||
23 | */ |
||||||
24 | public function processAllRelationships(Request $request, string $event, string $parent, string $counter, array $options) |
||||||
25 | { |
||||||
26 | $this->setIsPartialRequest($options); |
||||||
27 | $this->setMiniModels(); // For target Sync |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
28 | |||||||
29 | //Get the relation info |
||||||
30 | $relations = $this->getMongoRelation(); |
||||||
0 ignored issues
–
show
It seems like
getMongoRelation() 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
![]() |
|||||||
31 | |||||||
32 | //Process all relationships |
||||||
33 | foreach ($relations as $method => $relation) { |
||||||
34 | //Get Relation Save Mode |
||||||
35 | $type = $relation['type']; |
||||||
36 | $model = $relation['model']; |
||||||
37 | $hasTarget = hasTarget($relation); |
||||||
38 | if ($hasTarget) { |
||||||
39 | $modelTarget = $relation['modelTarget']; |
||||||
40 | $methodOnTarget = $relation['methodOnTarget']; |
||||||
41 | $modelOnTarget = $relation['modelOnTarget']; |
||||||
42 | $typeOnTarget = getTypeOnTarget($relation); |
||||||
43 | } else { |
||||||
44 | $modelTarget = ''; |
||||||
45 | $methodOnTarget = ''; |
||||||
46 | $modelOnTarget = ''; |
||||||
47 | $typeOnTarget = ''; |
||||||
48 | } |
||||||
49 | |||||||
50 | $is_EO = is_EO($type); |
||||||
51 | $is_EM = is_EM($type); |
||||||
52 | |||||||
53 | $is_EM_target = is_EM($typeOnTarget); |
||||||
54 | $is_EO_target = is_EO($typeOnTarget); |
||||||
55 | |||||||
56 | $key = $parent.$method.$counter; |
||||||
57 | $is_skippable = $this->getIsSkippable($request->has($key), $hasTarget); |
||||||
0 ignored issues
–
show
It seems like
getIsSkippable() 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
![]() |
|||||||
58 | |||||||
59 | if ($is_skippable) { |
||||||
60 | continue; |
||||||
61 | } |
||||||
62 | $current_request = $request->has($key) ? $request : $this->getPartialGeneratedRequest(); |
||||||
0 ignored issues
–
show
It seems like
getPartialGeneratedRequest() 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
![]() |
|||||||
63 | |||||||
64 | $value = $this->getRelationshipRequest($key, $current_request); |
||||||
0 ignored issues
–
show
It seems like
getRelationshipRequest() 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
![]() |
|||||||
65 | |||||||
66 | $is_embeds_has_to_be_updated = $request->has($key); |
||||||
67 | |||||||
68 | if (! is_null($value) && ! ($value == '') && ! ($value == '[]')) { |
||||||
69 | $objs = json_decode($value); |
||||||
70 | } else { |
||||||
71 | $objs = getArrayWithEmptyObj($model, $is_EO, $is_EM); |
||||||
72 | } |
||||||
73 | |||||||
74 | if ($is_EO || $is_EM) {//EmbedsOne Create - EmbedsMany Create |
||||||
75 | if ($event == 'update' && $is_embeds_has_to_be_updated) { |
||||||
76 | //Delete EmbedsMany or EmbedsOne on Target - TODO: check if it is necessary to run deleteTargetObj method |
||||||
77 | if ($hasTarget) { |
||||||
78 | $this->deleteTargetObj($method, $modelTarget, $methodOnTarget, $is_EO, $is_EM, $is_EO_target, $is_EM_target); |
||||||
79 | } |
||||||
80 | //Delete EmbedsMany or EmbedsOne on current object |
||||||
81 | if ($is_EM) { |
||||||
82 | $this->$method = []; |
||||||
83 | $this->save(); |
||||||
0 ignored issues
–
show
It seems like
save() 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
![]() |
|||||||
84 | } |
||||||
85 | } |
||||||
86 | |||||||
87 | if (! empty($objs)) { |
||||||
88 | if ($is_EM) { |
||||||
89 | $this->tempEM = []; |
||||||
0 ignored issues
–
show
|
|||||||
90 | } |
||||||
91 | |||||||
92 | $i = 0; |
||||||
93 | foreach ($objs as $obj) { |
||||||
94 | $this->processOneEmbeddedRelationship( |
||||||
95 | $request, |
||||||
96 | $obj, |
||||||
97 | $type, |
||||||
98 | $model, |
||||||
99 | $method, |
||||||
100 | $modelTarget, |
||||||
101 | $methodOnTarget, |
||||||
102 | $modelOnTarget, $event, |
||||||
103 | $hasTarget, |
||||||
104 | $is_EO, |
||||||
105 | $is_EM, |
||||||
106 | $is_EO_target, |
||||||
107 | $is_EM_target, |
||||||
108 | $i, |
||||||
109 | $is_embeds_has_to_be_updated, |
||||||
110 | $options); |
||||||
111 | $i++; |
||||||
112 | } |
||||||
113 | |||||||
114 | if ($is_EM) { |
||||||
115 | $this->$method = $this->tempEM; |
||||||
116 | } |
||||||
117 | } else { |
||||||
118 | $this->$method = []; |
||||||
119 | } |
||||||
120 | $this->save(); |
||||||
121 | } |
||||||
122 | } |
||||||
123 | } |
||||||
124 | |||||||
125 | /** |
||||||
126 | * @param $mini_model |
||||||
127 | * @param string $method_on_target |
||||||
128 | * @param bool $is_EO_target |
||||||
129 | * @param bool $is_EM_target |
||||||
130 | * |
||||||
131 | * @throws \Throwable |
||||||
132 | */ |
||||||
133 | public function updateRelationWithSync($mini_model, string $method_on_target, $is_EO_target, $is_EM_target) |
||||||
134 | { |
||||||
135 | if ($is_EM_target) { |
||||||
136 | $new_values = []; |
||||||
137 | throw_if( |
||||||
138 | ! isset($this->$method_on_target), |
||||||
139 | new Exception( |
||||||
140 | 'Error during target update. Remember to init the attribute '.$method_on_target. |
||||||
141 | ' on collection '.$this->getCollection() |
||||||
0 ignored issues
–
show
The method
getCollection() does not exist on OfflineAgency\MongoAutoS...\RelationshipMongoTrait . Did you maybe mean processEmbedOnTargetCollection() ?
(
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. ![]() |
|||||||
142 | ) |
||||||
143 | ); |
||||||
144 | |||||||
145 | $is_update_operation = false; |
||||||
146 | |||||||
147 | foreach ($this->$method_on_target as $temp) { |
||||||
148 | throw_if( |
||||||
149 | is_array($temp), |
||||||
150 | new Exception( |
||||||
151 | 'Error during target update. Remember to declare '.$method_on_target.' as '. |
||||||
152 | 'EmbedsMany relationship on model '.get_class($this) |
||||||
153 | ) |
||||||
154 | ); |
||||||
155 | |||||||
156 | if (! is_null($temp)) { |
||||||
157 | if ($this->getIsPartialRequest()) { |
||||||
158 | if (Arr::get($temp->attributes, 'ref_id') !== Arr::get($mini_model->attributes, 'ref_id')) { |
||||||
159 | $new_values[] = $temp->attributes; |
||||||
160 | } else { |
||||||
161 | $new_values[] = $mini_model->attributes; |
||||||
162 | $is_update_operation = true; |
||||||
163 | } |
||||||
164 | } else { |
||||||
165 | $new_values[] = $temp->attributes; |
||||||
166 | } |
||||||
167 | } |
||||||
168 | } |
||||||
169 | |||||||
170 | if (! $is_update_operation) { |
||||||
171 | $new_values[] = $mini_model->attributes; |
||||||
172 | } |
||||||
173 | } elseif ($is_EO_target) { |
||||||
174 | throw_if( |
||||||
175 | is_array($mini_model), |
||||||
176 | new Exception( |
||||||
177 | 'Error during target update. Remember to declare '.$method_on_target.' as '. |
||||||
178 | 'EmbedOne relationship on model '.get_class($this) |
||||||
179 | ) |
||||||
180 | ); |
||||||
181 | $new_values = $mini_model->attributes; |
||||||
182 | } |
||||||
183 | |||||||
184 | $this->$method_on_target = $new_values; |
||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||
185 | $this->save(); |
||||||
186 | } |
||||||
187 | |||||||
188 | /** |
||||||
189 | * @param Request $request |
||||||
190 | * @param $obj |
||||||
191 | * @param $type |
||||||
192 | * @param $model |
||||||
193 | * @param $method |
||||||
194 | * @param $modelTarget |
||||||
195 | * @param $methodOnTarget |
||||||
196 | * @param $modelOnTarget |
||||||
197 | * @param $event |
||||||
198 | * @param $hasTarget |
||||||
199 | * @param bool $is_EO |
||||||
200 | * @param bool $is_EM |
||||||
201 | * @param bool $is_EO_target |
||||||
202 | * @param bool $is_EM_target |
||||||
203 | * @param $i |
||||||
204 | * @param bool $is_embeds_has_to_be_updated |
||||||
205 | * @param $options |
||||||
206 | * |
||||||
207 | * @throws Exception |
||||||
208 | */ |
||||||
209 | public function processOneEmbeddedRelationship(Request $request, $obj, $type, $model, $method, $modelTarget, $methodOnTarget, $modelOnTarget, $event, $hasTarget, $is_EO, $is_EM, $is_EO_target, $is_EM_target, $i, $is_embeds_has_to_be_updated, $options) |
||||||
210 | { |
||||||
211 | if ($is_embeds_has_to_be_updated) { |
||||||
212 | $this->processEmbedOnCurrentCollection($request, $obj, $type, $model, $method, $event, $is_EO, $is_EM, $i, $options); |
||||||
213 | } |
||||||
214 | |||||||
215 | if ($hasTarget) { |
||||||
216 | $this->processEmbedOnTargetCollection($modelTarget, $obj, $methodOnTarget, $modelOnTarget, $is_EO_target, $is_EM_target); |
||||||
217 | } |
||||||
218 | } |
||||||
219 | |||||||
220 | /** |
||||||
221 | * @param string $method |
||||||
222 | * @param string $modelTarget |
||||||
223 | * @param string $methodOnTarget |
||||||
224 | * @param bool $is_EO |
||||||
225 | * @param bool $is_EM |
||||||
226 | * @param bool $is_EO_target |
||||||
227 | * @param bool $is_EM_target |
||||||
228 | */ |
||||||
229 | public function deleteTargetObj($method, $modelTarget, $methodOnTarget, bool $is_EO, bool $is_EM, bool $is_EO_target, bool $is_EM_target) |
||||||
230 | { |
||||||
231 | if ($is_EO) { |
||||||
232 | $embedObj = $this->$method; |
||||||
233 | if (! is_null($embedObj)) { |
||||||
234 | $target_id = $embedObj->ref_id; |
||||||
235 | $this->handleSubTarget($target_id, $modelTarget, $methodOnTarget, $is_EO_target, $is_EM_target); |
||||||
236 | } |
||||||
237 | } elseif ($is_EM) { |
||||||
238 | foreach ($this->$method as $target) { |
||||||
239 | $this->handleSubTarget($target->ref_id, $modelTarget, $methodOnTarget, $is_EO_target, $is_EM_target); |
||||||
240 | } |
||||||
241 | } |
||||||
242 | } |
||||||
243 | |||||||
244 | /** |
||||||
245 | * @param string|null $target_id |
||||||
246 | * @param string $modelTarget |
||||||
247 | * @param string $methodOnTarget |
||||||
248 | * @param bool $is_EO_target |
||||||
249 | * @param bool $is_EM_target |
||||||
250 | */ |
||||||
251 | public function handleSubTarget(?string $target_id, string $modelTarget, string $methodOnTarget, bool $is_EO_target, bool $is_EM_target) |
||||||
252 | { |
||||||
253 | if ($is_EM_target) { |
||||||
254 | $target = new $modelTarget; |
||||||
255 | $target = $target->all()->where('id', $target_id)->first(); |
||||||
256 | if (! is_null($target)) { |
||||||
257 | $new_values = []; |
||||||
258 | foreach ($target->$methodOnTarget as $temp) { |
||||||
259 | if ($temp->ref_id !== $this->getId()) { |
||||||
0 ignored issues
–
show
It seems like
getId() 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
![]() |
|||||||
260 | $new_values[] = $temp->attributes; |
||||||
261 | } |
||||||
262 | } |
||||||
263 | $target->$methodOnTarget = $new_values; |
||||||
264 | $target->save(); |
||||||
265 | } |
||||||
266 | } elseif ($is_EO_target) { |
||||||
267 | //Do nothing because when we are updating we already init the informations |
||||||
268 | } |
||||||
269 | } |
||||||
270 | |||||||
271 | /** |
||||||
272 | * @param Request $request |
||||||
273 | * @param $obj |
||||||
274 | * @param $type |
||||||
275 | * @param $model |
||||||
276 | * @param $method |
||||||
277 | * @param $event |
||||||
278 | * @param $is_EO |
||||||
279 | * @param $is_EM |
||||||
280 | * @param $i |
||||||
281 | * @param $options |
||||||
282 | * |
||||||
283 | * @throws Exception |
||||||
284 | */ |
||||||
285 | private function processEmbedOnCurrentCollection(Request $request, $obj, $type, $model, $method, $event, $is_EO, $is_EM, $i, $options) |
||||||
0 ignored issues
–
show
The parameter
$type is not used and could be removed.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for parameters that have been defined for a function or method, but which are not used in the method body. ![]() |
|||||||
286 | { |
||||||
287 | //Init the embed one model |
||||||
288 | $embedObj = new $model; |
||||||
289 | |||||||
290 | $EOitems = $embedObj->getItems(); |
||||||
291 | //Current Obj Create |
||||||
292 | foreach ($EOitems as $EOkey => $item) { |
||||||
293 | if (! is_null($obj)) { |
||||||
294 | $is_ML = isML($item); |
||||||
295 | $is_MD = isMD($item); |
||||||
296 | $this->checkPropertyExistence($obj, $EOkey, $method, $model); |
||||||
0 ignored issues
–
show
It seems like
checkPropertyExistence() 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
![]() |
|||||||
297 | |||||||
298 | if ($is_ML) { |
||||||
299 | $embedObj->$EOkey = ml([], $obj->$EOkey); |
||||||
300 | } elseif ($EOkey == 'updated_at' || $EOkey == 'created_at') { |
||||||
301 | $embedObj->$EOkey = now(); |
||||||
302 | } elseif ($is_MD) { |
||||||
303 | if ($obj->$EOkey == '' || $obj->$EOkey == null) { |
||||||
304 | $embedObj->$EOkey = null; |
||||||
305 | } else { |
||||||
306 | $embedObj->$EOkey = new UTCDateTime(new DateTime($obj->$EOkey)); |
||||||
307 | } |
||||||
308 | } else { |
||||||
309 | $embedObj->$EOkey = $obj->$EOkey; |
||||||
310 | } |
||||||
311 | } |
||||||
312 | } |
||||||
313 | |||||||
314 | //else if($is_EM){//To be implemented} |
||||||
315 | //else if($is_HM){//To be implemented} |
||||||
316 | //else if($is_HO){//To be implemented} |
||||||
317 | |||||||
318 | //Get counter for embeds many with level > 1 |
||||||
319 | $counter = getCounterForRelationships($method, $is_EO, $is_EM, $i); |
||||||
320 | //Check for another Level of Relationship |
||||||
321 | $embedObj->processAllRelationships($request, $event, $method.'-', $counter, $options); |
||||||
322 | |||||||
323 | if ($is_EO) { |
||||||
324 | $this->$method = $embedObj->attributes; |
||||||
325 | } else { |
||||||
326 | $this->tempEM[] = $embedObj->attributes; |
||||||
0 ignored issues
–
show
|
|||||||
327 | } |
||||||
328 | } |
||||||
329 | |||||||
330 | /** |
||||||
331 | * @param $modelTarget |
||||||
332 | * @param $obj |
||||||
333 | * @param $methodOnTarget |
||||||
334 | * @param $modelOnTarget |
||||||
335 | * @param bool $is_EO_target |
||||||
336 | * @param bool $is_EM_target |
||||||
337 | * |
||||||
338 | * @throws Exception |
||||||
339 | */ |
||||||
340 | private function processEmbedOnTargetCollection($modelTarget, $obj, $methodOnTarget, $modelOnTarget, bool $is_EO_target, bool $is_EM_target) |
||||||
341 | { |
||||||
342 | $modelToBeSync = $this->getModelTobeSync($modelTarget, $obj); |
||||||
0 ignored issues
–
show
It seems like
getModelTobeSync() 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
![]() |
|||||||
343 | if (! is_null($modelToBeSync)) { |
||||||
344 | $miniModel = $this->getEmbedModel($modelOnTarget); |
||||||
0 ignored issues
–
show
It seems like
getEmbedModel() 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
![]() |
|||||||
345 | $modelToBeSync->setIsPartialRequest([], $this->getIsPartialRequest()); |
||||||
346 | $modelToBeSync->updateRelationWithSync($miniModel, $methodOnTarget, $is_EO_target, $is_EM_target); |
||||||
347 | //TODO:Sync target on level > 1 |
||||||
348 | //$modelToBeSync->processAllRelationships($request, $event, $methodOnTarget, $methodOnTarget . "-"); |
||||||
349 | } |
||||||
350 | } |
||||||
351 | |||||||
352 | public function getIsPartialRequest() |
||||||
353 | { |
||||||
354 | return $this->is_partial_request; |
||||||
355 | } |
||||||
356 | |||||||
357 | public function setIsPartialRequest(array $options, $is_partial_request = null): void |
||||||
358 | { |
||||||
359 | if (! is_null($is_partial_request)) { |
||||||
360 | $this->is_partial_request = $is_partial_request; |
||||||
361 | |||||||
362 | return; |
||||||
363 | } |
||||||
364 | |||||||
365 | if (Arr::has($options, 'request_type')) { |
||||||
366 | $this->is_partial_request = Arr::get($options, 'request_type') == 'partial'; |
||||||
367 | |||||||
368 | return; |
||||||
369 | } |
||||||
370 | |||||||
371 | $this->is_partial_request = false; |
||||||
372 | } |
||||||
373 | } |
||||||
374 |