processEmbedOnCurrentCollection()   B
last analyzed

Complexity

Conditions 10
Paths 14

Size

Total Lines 42
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 24
c 1
b 0
f 0
dl 0
loc 42
rs 7.6666
cc 10
nc 14
nop 10

How to fix   Complexity    Many Parameters   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

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
It seems like setMiniModels() 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 ignore-call  annotation

27
        $this->/** @scrutinizer ignore-call */ 
28
               setMiniModels(); // For target Sync
Loading history...
28
29
        //Get the relation info
30
        $relations = $this->getMongoRelation();
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

30
        /** @scrutinizer ignore-call */ 
31
        $relations = $this->getMongoRelation();
Loading history...
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
Bug introduced by
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 ignore-call  annotation

57
            /** @scrutinizer ignore-call */ 
58
            $is_skippable = $this->getIsSkippable($request->has($key), $hasTarget);
Loading history...
58
59
            if ($is_skippable) {
60
                continue;
61
            }
62
            $current_request = $request->has($key) ? $request : $this->getPartialGeneratedRequest();
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

62
            $current_request = $request->has($key) ? $request : $this->/** @scrutinizer ignore-call */ getPartialGeneratedRequest();
Loading history...
63
64
            $value = $this->getRelationshipRequest($key, $current_request);
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

64
            /** @scrutinizer ignore-call */ 
65
            $value = $this->getRelationshipRequest($key, $current_request);
Loading history...
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
Bug introduced by
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 ignore-call  annotation

83
                        $this->/** @scrutinizer ignore-call */ 
84
                               save();
Loading history...
84
                    }
85
                }
86
87
                if (! empty($objs)) {
88
                    if ($is_EM) {
89
                        $this->tempEM = [];
0 ignored issues
show
Bug Best Practice introduced by
The property tempEM does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
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
Bug introduced by
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 ignore-call  annotation

141
                    ' on collection '.$this->/** @scrutinizer ignore-call */ getCollection()

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...
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
The variable $new_values does not seem to be defined for all execution paths leading up to this point.
Loading history...
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
Bug introduced by
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 ignore-call  annotation

259
                    if ($temp->ref_id !== $this->/** @scrutinizer ignore-call */ getId()) {
Loading history...
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
Unused Code introduced by
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 ignore-unused  annotation

285
    private function processEmbedOnCurrentCollection(Request $request, $obj, /** @scrutinizer ignore-unused */ $type, $model, $method, $event, $is_EO, $is_EM, $i, $options)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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
Bug introduced by
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 ignore-call  annotation

296
                $this->/** @scrutinizer ignore-call */ 
297
                       checkPropertyExistence($obj, $EOkey, $method, $model);
Loading history...
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
Bug Best Practice introduced by
The property tempEM does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
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
Bug introduced by
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 ignore-call  annotation

342
        /** @scrutinizer ignore-call */ 
343
        $modelToBeSync = $this->getModelTobeSync($modelTarget, $obj);
Loading history...
343
        if (! is_null($modelToBeSync)) {
344
            $miniModel = $this->getEmbedModel($modelOnTarget);
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

344
            /** @scrutinizer ignore-call */ 
345
            $miniModel = $this->getEmbedModel($modelOnTarget);
Loading history...
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