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
77
                    //Delete EmbedsMany or EmbedsOne on Target - TODO: check if it is necessary to run deleteTargetObj method
78
                    if ($hasTarget) {
79
                        $this->deleteTargetObj($method, $modelTarget, $methodOnTarget, $is_EO, $is_EM, $is_EO_target, $is_EM_target);
80
                    }
81
                    //Delete EmbedsMany or EmbedsOne on current object
82
                    if ($is_EM) {
83
                        $this->$method = [];
84
                        $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

84
                        $this->/** @scrutinizer ignore-call */ 
85
                               save();
Loading history...
85
                    }
86
                }
87
88
                if (! empty($objs)) {
89
                    if ($is_EM) {
90
                        $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...
91
                    }
92
93
                    $i = 0;
94
                    foreach ($objs as $obj) {
95
                        $this->processOneEmbeddedRelationship(
96
                            $request,
97
                            $obj,
98
                            $type,
99
                            $model,
100
                            $method,
101
                            $modelTarget,
102
                            $methodOnTarget,
103
                            $modelOnTarget, $event,
104
                            $hasTarget,
105
                            $is_EO,
106
                            $is_EM,
107
                            $is_EO_target,
108
                            $is_EM_target,
109
                            $i,
110
                            $is_embeds_has_to_be_updated,
111
                            $options);
112
                        $i++;
113
                    }
114
115
                    if ($is_EM) {
116
                        $this->$method = $this->tempEM;
117
                    }
118
                } else {
119
                    $this->$method = [];
120
                }
121
                $this->save();
122
            }
123
        }
124
    }
125
126
    /**
127
     * @param $mini_model
128
     * @param  string  $method_on_target
129
     * @param  bool  $is_EO_target
130
     * @param  bool  $is_EM_target
131
     *
132
     * @throws \Throwable
133
     */
134
    public function updateRelationWithSync($mini_model, string $method_on_target, $is_EO_target, $is_EM_target)
135
    {
136
        if ($is_EM_target) {
137
            $new_values = [];
138
            throw_if(
139
                ! isset($this->$method_on_target),
140
                new Exception(
141
                    'Error during target update. Remember to init the attribute '.$method_on_target.
142
                    ' 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

142
                    ' 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...
143
                )
144
            );
145
146
            $is_update_operation = false;
147
148
            foreach ($this->$method_on_target as $temp) {
149
                throw_if(
150
                    is_array($temp),
151
                    new Exception(
152
                        'Error during target update. Remember to declare '.$method_on_target.' as '.
153
                        'EmbedsMany relationship on model '.get_class($this)
154
                    )
155
                );
156
157
                if (! is_null($temp)) {
158
                    if ($this->getIsPartialRequest()) {
159
                        if (Arr::get($temp->attributes, 'ref_id') !== Arr::get($mini_model->attributes, 'ref_id')) {
160
                            $new_values[] = $temp->attributes;
161
                        } else {
162
                            $new_values[] = $mini_model->attributes;
163
                            $is_update_operation = true;
164
                        }
165
                    } else {
166
                        $new_values[] = $temp->attributes;
167
                    }
168
                }
169
            }
170
171
            if (! $is_update_operation) {
172
                $new_values[] = $mini_model->attributes;
173
            }
174
        } elseif ($is_EO_target) {
175
            throw_if(
176
                is_array($mini_model),
177
                new Exception(
178
                    'Error during target update. Remember to declare '.$method_on_target.' as '.
179
                    'EmbedOne relationship on model '.get_class($this)
180
                )
181
            );
182
            $new_values = $mini_model->attributes;
183
        }
184
185
        $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...
186
        $this->save();
187
    }
188
189
    /**
190
     * @param  Request  $request
191
     * @param $obj
192
     * @param $type
193
     * @param $model
194
     * @param $method
195
     * @param $modelTarget
196
     * @param $methodOnTarget
197
     * @param $modelOnTarget
198
     * @param $event
199
     * @param $hasTarget
200
     * @param  bool  $is_EO
201
     * @param  bool  $is_EM
202
     * @param  bool  $is_EO_target
203
     * @param  bool  $is_EM_target
204
     * @param $i
205
     * @param  bool  $is_embeds_has_to_be_updated
206
     * @param $options
207
     *
208
     * @throws Exception
209
     */
210
    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)
211
    {
212
        if ($is_embeds_has_to_be_updated) {
213
            $this->processEmbedOnCurrentCollection($request, $obj, $type, $model, $method, $event, $is_EO, $is_EM, $i, $options);
214
        }
215
216
        if ($hasTarget) {
217
            $this->processEmbedOnTargetCollection($modelTarget, $obj, $methodOnTarget, $modelOnTarget, $is_EO_target, $is_EM_target);
218
        }
219
    }
220
221
    /**
222
     * @param  string  $method
223
     * @param  string  $modelTarget
224
     * @param  string  $methodOnTarget
225
     * @param  bool  $is_EO
226
     * @param  bool  $is_EM
227
     * @param  bool  $is_EO_target
228
     * @param  bool  $is_EM_target
229
     */
230
    public function deleteTargetObj($method, $modelTarget, $methodOnTarget, bool $is_EO, bool $is_EM, bool $is_EO_target, bool $is_EM_target)
231
    {
232
        if ($is_EO) {
233
            $embedObj = $this->$method;
234
            if (! is_null($embedObj)) {
235
                $target_id = $embedObj->ref_id;
236
                $this->handleSubTarget($target_id, $modelTarget, $methodOnTarget, $is_EO_target, $is_EM_target);
237
            }
238
        } elseif ($is_EM) {
239
            foreach ($this->$method as $target) {
240
                $this->handleSubTarget($target->ref_id, $modelTarget, $methodOnTarget, $is_EO_target, $is_EM_target);
241
            }
242
        }
243
    }
244
245
    /**
246
     * @param  string|null  $target_id
247
     * @param  string  $modelTarget
248
     * @param  string  $methodOnTarget
249
     * @param  bool  $is_EO_target
250
     * @param  bool  $is_EM_target
251
     */
252
    public function handleSubTarget(?string $target_id, string $modelTarget, string $methodOnTarget, bool $is_EO_target, bool $is_EM_target)
253
    {
254
        if ($is_EM_target) {
255
            $target = new $modelTarget;
256
            $target = $target->all()->where('id', $target_id)->first();
257
            if (! is_null($target)) {
258
                $new_values = [];
259
                foreach ($target->$methodOnTarget as $temp) {
260
                    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

260
                    if ($temp->ref_id !== $this->/** @scrutinizer ignore-call */ getId()) {
Loading history...
261
                        $new_values[] = $temp->attributes;
262
                    }
263
                }
264
                $target->$methodOnTarget = $new_values;
265
                $target->save();
266
            }
267
        } elseif ($is_EO_target) {
268
            //Do nothing because when we are updating we already init the informations
269
        }
270
    }
271
272
    /**
273
     * @param  Request  $request
274
     * @param $obj
275
     * @param $type
276
     * @param $model
277
     * @param $method
278
     * @param $event
279
     * @param $is_EO
280
     * @param $is_EM
281
     * @param $i
282
     * @param $options
283
     *
284
     * @throws Exception
285
     */
286
    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

286
    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...
287
    {
288
        //Init the embed one model
289
        $embedObj = new $model;
290
291
        $EOitems = $embedObj->getItems();
292
        //Current Obj Create
293
        foreach ($EOitems as $EOkey => $item) {
294
            if (! is_null($obj)) {
295
                $is_ML = isML($item);
296
                $is_MD = isMD($item);
297
                $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

297
                $this->/** @scrutinizer ignore-call */ 
298
                       checkPropertyExistence($obj, $EOkey, $method, $model);
Loading history...
298
299
                if ($is_ML) {
300
                    $embedObj->$EOkey = ml([], $obj->$EOkey);
301
                } elseif ($EOkey == 'updated_at' || $EOkey == 'created_at') {
302
                    $embedObj->$EOkey = now();
303
                } elseif ($is_MD) {
304
                    if ($obj->$EOkey == '' || $obj->$EOkey == null) {
305
                        $embedObj->$EOkey = null;
306
                    } else {
307
                        $embedObj->$EOkey = new UTCDateTime(new DateTime($obj->$EOkey));
308
                    }
309
                } else {
310
                    $embedObj->$EOkey = $obj->$EOkey;
311
                }
312
            }
313
        }
314
315
        //else if($is_EM){//To be implemented}
316
        //else if($is_HM){//To be implemented}
317
        //else if($is_HO){//To be implemented}
318
319
        //Get counter for embeds many with level > 1
320
        $counter = getCounterForRelationships($method, $is_EO, $is_EM, $i);
321
        //Check for another Level of Relationship
322
        $embedObj->processAllRelationships($request, $event, $method.'-', $counter, $options);
323
324
        if ($is_EO) {
325
            $this->$method = $embedObj->attributes;
326
        } else {
327
            $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...
328
        }
329
    }
330
331
    /**
332
     * @param $modelTarget
333
     * @param $obj
334
     * @param $methodOnTarget
335
     * @param $modelOnTarget
336
     * @param  bool  $is_EO_target
337
     * @param  bool  $is_EM_target
338
     *
339
     * @throws Exception
340
     */
341
    private function processEmbedOnTargetCollection($modelTarget, $obj, $methodOnTarget, $modelOnTarget, bool $is_EO_target, bool $is_EM_target)
342
    {
343
        $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

343
        /** @scrutinizer ignore-call */ 
344
        $modelToBeSync = $this->getModelTobeSync($modelTarget, $obj);
Loading history...
344
        if (! is_null($modelToBeSync)) {
345
            $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

345
            /** @scrutinizer ignore-call */ 
346
            $miniModel = $this->getEmbedModel($modelOnTarget);
Loading history...
346
            $modelToBeSync->setIsPartialRequest([], $this->getIsPartialRequest());
347
            $modelToBeSync->updateRelationWithSync($miniModel, $methodOnTarget, $is_EO_target, $is_EM_target);
348
            //TODO:Sync target on level > 1
349
            //$modelToBeSync->processAllRelationships($request, $event, $methodOnTarget, $methodOnTarget . "-");
350
        }
351
    }
352
353
    public function getIsPartialRequest()
354
    {
355
        return $this->is_partial_request;
356
    }
357
358
    public function setIsPartialRequest(array $options, $is_partial_request = null): void
359
    {
360
        if (! is_null($is_partial_request)) {
361
            $this->is_partial_request = $is_partial_request;
362
363
            return;
364
        }
365
366
        if (Arr::has($options, 'request_type')) {
367
            $this->is_partial_request = Arr::get($options, 'request_type') == 'partial';
368
369
            return;
370
        }
371
372
        $this->is_partial_request = false;
373
    }
374
}
375