Passed
Push — master ( 3b373d...6530d8 )
by Giacomo
02:21 queued 11s
created

RelationshipMongoTrait   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 285
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 46
eloc 126
c 1
b 0
f 0
dl 0
loc 285
rs 8.72

7 Methods

Rating   Name   Duplication   Size   Complexity  
A handleSubTarget() 0 14 5
A deleteTargetObj() 0 11 4
A processOneEmbeddedRelationship() 0 8 3
A updateRelationWithSync() 0 14 3
A processEmbedOnTargetCollection() 0 6 2
F processAllRelationships() 0 97 19
B processEmbedOnCurrentCollection() 0 42 10

How to fix   Complexity   

Complex Class

Complex classes like RelationshipMongoTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use RelationshipMongoTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace OfflineAgency\MongoAutoSync\Traits;
4
5
use Illuminate\Http\Request;
6
use Illuminate\Support\Arr;
7
use MongoDB\BSON\UTCDateTime;
8
9
trait RelationshipMongoTrait
10
{
11
    /**
12
     * @param Request $request
13
     * @param string $event
14
     * @param string $parent
15
     * @param string $counter
16
     * @param array $options
17
     * @throws Exception
18
     */
19
    public function processAllRelationships(Request $request, string $event, string $parent, string $counter, array $options)
20
    {
21
        $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

21
        $this->/** @scrutinizer ignore-call */ 
22
               setMiniModels(); // For target Sync
Loading history...
22
23
        //Get the relation info
24
        $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

24
        /** @scrutinizer ignore-call */ 
25
        $relations = $this->getMongoRelation();
Loading history...
25
26
        //Process all relationships
27
        foreach ($relations as $method => $relation) {
28
            //Get Relation Save Mode
29
            $type = $relation['type'];
30
            $model = $relation['model'];
31
            $hasTarget = hasTarget($relation);
32
            if ($hasTarget) {
33
                $modelTarget = $relation['modelTarget'];
34
                $methodOnTarget = $relation['methodOnTarget'];
35
                $modelOnTarget = $relation['modelOnTarget'];
36
                $typeOnTarget = Arr::has($relation, 'typeOnTarget') ? Arr::get($relation, 'typeOnTarget') : 'EmbedsMany';
37
            } else {
38
                $modelTarget = '';
39
                $methodOnTarget = '';
40
                $modelOnTarget = '';
41
                $typeOnTarget = '';
42
            }
43
44
            $is_EO = is_EO($type);
45
            $is_EM = is_EM($type);
46
47
            $is_EM_target = is_EM($typeOnTarget);
48
            $is_EO_target = is_EO($typeOnTarget);
49
50
            $key = $parent.$method.$counter;
51
            $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

51
            /** @scrutinizer ignore-call */ 
52
            $is_skippable = $this->getIsSkippable($request->has($key), $hasTarget);
Loading history...
52
53
            if ($is_skippable) {
54
                continue;
55
            }
56
            $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

56
            $current_request = $request->has($key) ? $request : $this->/** @scrutinizer ignore-call */ getPartialGeneratedRequest();
Loading history...
57
58
            $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

58
            /** @scrutinizer ignore-call */ 
59
            $value = $this->getRelationshipRequest($key, $current_request);
Loading history...
59
60
            $is_embeds_has_to_be_updated = $request->has($key);
61
62
            if (! is_null($value) && ! ($value == '') && ! ($value == '[]')) {
63
                $objs = json_decode($value);
64
            } else {
65
                $objs = getArrayWithEmptyObj($model, $is_EO, $is_EM);
66
            }
67
68
            if ($is_EO || $is_EM) {//EmbedsOne Create - EmbedsMany Create
69
                if ($event == 'update' && $is_embeds_has_to_be_updated) {
70
71
                    //Delete EmbedsMany or EmbedsOne on Target - TODO: check if it is necessary to run deleteTargetObj method
72
                    if ($hasTarget) {
73
                        $this->deleteTargetObj($method, $modelTarget, $methodOnTarget, $is_EO, $is_EO_target, $is_EM_target);
74
                    }
75
                    //Delete EmbedsMany or EmbedsOne on current object
76
                    if ($is_EM) {
77
                        $this->$method = [];
78
                        $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

78
                        $this->/** @scrutinizer ignore-call */ 
79
                               save();
Loading history...
79
                    }
80
                }
81
82
                if (! empty($objs)) {
83
                    if ($is_EM) {
84
                        $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...
85
                    }
86
87
                    $i = 0;
88
                    foreach ($objs as $obj) {
89
                        $this->processOneEmbeddedRelationship(
90
                            $request,
91
                            $obj,
92
                            $type,
93
                            $model,
94
                            $method,
95
                            $modelTarget,
96
                            $methodOnTarget,
97
                            $modelOnTarget, $event,
98
                            $hasTarget,
99
                            $is_EO,
100
                            $is_EM,
101
                            $is_EO_target,
102
                            $is_EM_target,
103
                            $i,
104
                            $is_embeds_has_to_be_updated,
105
                            $options);
106
                        $i++;
107
                    }
108
109
                    if ($is_EM) {
110
                        $this->$method = $this->tempEM;
111
                    }
112
                } else {
113
                    $this->$method = [];
114
                }
115
                $this->save();
116
            }
117
        }
118
    }
119
120
    /**
121
     * @param $mini_model
122
     * @param string $method_on_target
123
     * @param bool $is_EO_target
124
     * @param bool $is_EM_target
125
     */
126
    public function updateRelationWithSync($mini_model, string $method_on_target, $is_EO_target, $is_EM_target)
0 ignored issues
show
Unused Code introduced by
The parameter $is_EO_target 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

126
    public function updateRelationWithSync($mini_model, string $method_on_target, /** @scrutinizer ignore-unused */ $is_EO_target, $is_EM_target)

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...
127
    {
128
        if ($is_EM_target) {
129
            $new_values = [];
130
            foreach ($this->$method_on_target as $temp) {
131
                $new_values[] = $temp->attributes;
132
            }
133
            $new_values[] = $mini_model->attributes;
134
        } else {
135
            $new_values = $mini_model->attributes;
136
        }
137
138
        $this->$method_on_target = $new_values;
139
        $this->save();
140
    }
141
142
    /**
143
     * @param Request $request
144
     * @param $obj
145
     * @param $type
146
     * @param $model
147
     * @param $method
148
     * @param $modelTarget
149
     * @param $methodOnTarget
150
     * @param $modelOnTarget
151
     * @param $event
152
     * @param $hasTarget
153
     * @param bool $is_EO
154
     * @param bool $is_EM
155
     * @param bool $is_EO_target
156
     * @param bool $is_EM_target
157
     * @param $i
158
     * @param bool $is_embeds_has_to_be_updated
159
     * @param $options
160
     * @throws Exception
161
     */
162
    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)
163
    {
164
        if ($is_embeds_has_to_be_updated) {
165
            $this->processEmbedOnCurrentCollection($request, $obj, $type, $model, $method, $event, $is_EO, $is_EM, $i, $options);
166
        }
167
168
        if ($hasTarget) {
169
            $this->processEmbedOnTargetCollection($modelTarget, $obj, $methodOnTarget, $modelOnTarget, $is_EO_target, $is_EM_target);
170
        }
171
    }
172
173
    /**
174
     * @param $method
175
     * @param $modelTarget
176
     * @param $methodOnTarget
177
     * @param bool $is_EO
178
     * @param bool $is_EO_target
179
     * @param bool $is_EM_target
180
     */
181
    public function deleteTargetObj($method, $modelTarget, $methodOnTarget, $is_EO, $is_EO_target, $is_EM_target)
182
    {
183
        if ($is_EO) {
184
            $embedObj = $this->$method;
185
            if (! is_null($embedObj)) {
186
                $target_id = $embedObj->ref_id;
187
                $this->handleSubTarget($target_id, $modelTarget, $methodOnTarget, $is_EO_target, $is_EM_target);
188
            }
189
        } else {
190
            foreach ($this->$method as $target) {
191
                $this->handleSubTarget($target->ref_id, $modelTarget, $methodOnTarget, $is_EO_target, $is_EM_target);
192
            }
193
        }
194
    }
195
196
    /**
197
     * @param $target_id
198
     * @param $modelTarget
199
     * @param $methodOnTarget
200
     * @param bool $is_EO_target
201
     * @param bool $is_EM_target
202
     */
203
    public function handleSubTarget($target_id, $modelTarget, $methodOnTarget, $is_EO_target, $is_EM_target)
0 ignored issues
show
Unused Code introduced by
The parameter $is_EO_target 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

203
    public function handleSubTarget($target_id, $modelTarget, $methodOnTarget, /** @scrutinizer ignore-unused */ $is_EO_target, $is_EM_target)

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...
204
    {
205
        if ($is_EM_target) {
206
            $target = new $modelTarget;
207
            $target = $target->all()->where('id', $target_id)->first();
208
            if (! is_null($target)) {
209
                $new_values = [];
210
                foreach ($target->$methodOnTarget as $temp) {
211
                    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

211
                    if ($temp->ref_id !== $this->/** @scrutinizer ignore-call */ getId()) {
Loading history...
212
                        $new_values[] = $temp->attributes;
213
                    }
214
                }
215
                $target->$methodOnTarget = $new_values;
216
                $target->save();
217
            }
218
        }
219
    }
220
221
    /**
222
     * @param Request $request
223
     * @param $obj
224
     * @param $type
225
     * @param $model
226
     * @param $method
227
     * @param $event
228
     * @param $is_EO
229
     * @param $is_EM
230
     * @param $i
231
     * @param $options
232
     * @throws Exception
233
     */
234
    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

234
    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...
235
    {
236
        //Init the embed one model
237
        $embedObj = new $model;
238
239
        $EOitems = $embedObj->getItems();
240
        //Current Obj Create
241
        foreach ($EOitems as $EOkey => $item) {
242
            if (! is_null($obj)) {
243
                $is_ML = isML($item);
244
                $is_MD = isMD($item);
245
                $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

245
                $this->/** @scrutinizer ignore-call */ 
246
                       checkPropertyExistence($obj, $EOkey, $method, $model);
Loading history...
246
247
                if ($is_ML) {
248
                    $embedObj->$EOkey = ml([], $obj->$EOkey);
249
                } elseif ($EOkey == 'updated_at' || $EOkey == 'created_at') {
250
                    $embedObj->$EOkey = now();
251
                } elseif ($is_MD) {
252
                    if ($obj->$EOkey == '' || $obj->$EOkey == null) {
253
                        $embedObj->$EOkey = null;
254
                    } else {
255
                        $embedObj->$EOkey = new UTCDateTime(new DateTime($obj->$EOkey));
0 ignored issues
show
Bug introduced by
new OfflineAgency\MongoA...\DateTime($obj->$EOkey) of type OfflineAgency\MongoAutoSync\Traits\DateTime is incompatible with the type integer expected by parameter $milliseconds of MongoDB\BSON\UTCDateTime::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

255
                        $embedObj->$EOkey = new UTCDateTime(/** @scrutinizer ignore-type */ new DateTime($obj->$EOkey));
Loading history...
Bug introduced by
The type OfflineAgency\MongoAutoSync\Traits\DateTime was not found. Did you mean DateTime? If so, make sure to prefix the type with \.
Loading history...
256
                    }
257
                } else {
258
                    $embedObj->$EOkey = $obj->$EOkey;
259
                }
260
            }
261
        }
262
263
        //else if($is_EM){//To be implemented}
264
        //else if($is_HM){//To be implemented}
265
        //else if($is_HO){//To be implemented}
266
267
        //Get counter for embeds many with level > 1
268
        $counter = getCounterForRelationships($method, $is_EO, $is_EM, $i);
269
        //Check for another Level of Relationship
270
        $embedObj->processAllRelationships($request, $event, $method.'-', $counter, $options);
271
272
        if ($is_EO) {
273
            $this->$method = $embedObj->attributes;
274
        } else {
275
            $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...
276
        }
277
    }
278
279
    /**
280
     * @param $modelTarget
281
     * @param $obj
282
     * @param $methodOnTarget
283
     * @param $modelOnTarget
284
     * @param bool $is_EO_target
285
     * @param bool $is_EM_target
286
     * @throws Exception
287
     */
288
    private function processEmbedOnTargetCollection($modelTarget, $obj, $methodOnTarget, $modelOnTarget, $is_EO_target, $is_EM_target)
289
    {
290
        $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

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

292
            /** @scrutinizer ignore-call */ 
293
            $miniModel = $this->getEmbedModel($modelOnTarget);
Loading history...
293
            $modelToBeSync->updateRelationWithSync($miniModel, $methodOnTarget, $is_EO_target, $is_EM_target);
294
            //TODO:Sync target on level > 1
295
            //$modelToBeSync->processAllRelationships($request, $event, $methodOnTarget, $methodOnTarget . "-");
296
        }
297
    }
298
}
299