Passed
Push — master ( 348272...316c2a )
by Giacomo
14:14
created

MongoSyncTrait::processOneEmbededRelationship()   C

Complexity

Conditions 14
Paths 64

Size

Total Lines 71
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 14
eloc 39
c 2
b 1
f 0
nc 64
nop 13
dl 0
loc 71
rs 6.2666

How to fix   Long Method    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 MongoDB\BSON\UTCDateTime;
9
10
trait MongoSyncTrait
11
{
12
    /**
13
     * @param Request $request
14
     * @param array $additionalData
15
     * @return $this
16
     * @throws Exception
17
     */
18
    public function storeWithSync(Request $request, array $additionalData = [])
19
    {
20
        $request = $request->merge($additionalData);
21
        //$request = prepareRequest($request,$additionalData);
22
23
        $this->storeEditAllItems($request, "add");
24
        $this->processAllRelationships($request, "add", "", "");
25
26
        //Dispatch the creation event
27
        $this->fireModelEvent('storeWithSync');
0 ignored issues
show
Bug introduced by
It seems like fireModelEvent() 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
               fireModelEvent('storeWithSync');
Loading history...
28
29
        return $this;
30
    }
31
32
    /**
33
     * @param $request
34
     * @param $event
35
     * @throws Exception
36
     */
37
    public function storeEditAllItems($request, $event)
38
    {
39
        //Get the item name
40
        $items = $this->getItems();
0 ignored issues
show
Bug introduced by
It seems like getItems() 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

40
        /** @scrutinizer ignore-call */ 
41
        $items = $this->getItems();
Loading history...
41
        //Current Obj Create
42
        foreach ($items as $key => $item) {
43
            $is_ML = isML($item);
44
            $is_MD = isMD($item);
45
            $is_fillable = isFillable($item, $event);
46
            if ($is_fillable) {
47
                if ($is_ML) {
48
                    if (is_null($this->$key)) {
49
                        $old_value = array();
50
                    } else {
51
                        $old_value = $this->$key;
52
                    }
53
                    $this->$key = ml($old_value, $request->input($key));
54
                } elseif ($is_MD) {
55
                    //  dd( new UTCDateTime(new DateTime($request->input($key))));
56
                    if ($request->input($key) == "" || $request->input($key) == null) {
57
                        //dd('if');
58
                        $this->$key = null;
59
                    } else {
60
                        $this->$key = new UTCDateTime(new DateTime($request->input($key)));
0 ignored issues
show
Bug introduced by
new DateTime($request->input($key)) of type 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

60
                        $this->$key = new UTCDateTime(/** @scrutinizer ignore-type */ new DateTime($request->input($key)));
Loading history...
61
                    }
62
                } else {
63
                    $this->$key = $request->input($key);
64
                }
65
            }
66
        }
67
        $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

67
        $this->/** @scrutinizer ignore-call */ 
68
               save();
Loading history...
68
    }
69
70
    /**
71
     * @param Request $request
72
     * @param $event
73
     * @param $parent
74
     * @param $counter
75
     * @throws Exception
76
     */
77
    public function processAllRelationships(Request $request, $event, $parent, $counter)
78
    {
79
        //Get the relation info
80
        $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

80
        /** @scrutinizer ignore-call */ 
81
        $relations = $this->getMongoRelation();
Loading history...
81
82
        //Process all relationships
83
        foreach ($relations as $method => $relation) {
84
            //Get Relation Save Mode
85
            $type = $relation['type'];
86
            $mode = $relation['mode'];
0 ignored issues
show
Unused Code introduced by
The assignment to $mode is dead and can be removed.
Loading history...
87
            $model = $relation['model'];
88
            $hasTarget = hasTarget($relation);
89
            if ($hasTarget) {
90
                $modelTarget = $relation['modelTarget'];
91
                $methodOnTarget = $relation['methodOnTarget'];
92
                $modelOnTarget = $relation['modelOnTarget'];
93
            } else {
94
                $modelTarget = "";
95
                $methodOnTarget = "";
96
                $modelOnTarget = "";
97
            }
98
99
            $is_EO = is_EO($type);
100
            $is_EM = is_EM($type);
101
            $is_HO = is_HO($type);
0 ignored issues
show
Unused Code introduced by
The assignment to $is_HO is dead and can be removed.
Loading history...
102
            $is_HM = is_HM($type);
0 ignored issues
show
Unused Code introduced by
The assignment to $is_HM is dead and can be removed.
Loading history...
103
104
            $key = $parent . $method . $counter;
105
            $value = $request->input($key);
106
107
            if (!is_null($value) && !($value == "") && !($value == "[]")) {
108
                $objs = json_decode($value);
109
            } else {
110
                $objs = getArrayWithEmptyObj($model, $is_EO, $is_EM);
111
            }
112
113
            if ($is_EO || $is_EM) {//EmbedsOne Create - EmbedsMany Create
114
                if ($event == "update") {
115
116
                    //Delete EmbedsMany or EmbedsOne on Target
117
                    if ($hasTarget) {
118
                        $this->deleteTargetObj($method, $modelTarget, $methodOnTarget, $is_EO);
119
                    }
120
                    //Delete EmbedsMany or EmbedsOne on current object
121
                    if ($is_EM) {
122
                        $this->$method()->delete();
123
                    }
124
                }
125
126
                if (!empty($objs)) {
127
                    $i = 0;
128
                    foreach ($objs as $obj) {
129
                        $this->processOneEmbededRelationship($request, $obj, $type, $model, $method, $modelTarget, $methodOnTarget, $modelOnTarget, $event, $hasTarget, $is_EO, $is_EM, $i);
130
                        $i++;
131
                    }
132
                } else {
133
                    $this->$method = [];
134
                    $this->save();
135
                }
136
            }
137
        }
138
    }
139
140
    /**
141
     * @param Request $request
142
     * @param $methodOnTarget
143
     * @param $modelOnTarget
144
     * @throws Exception
145
     */
146
    public function updateRelationWithSync(Request $request, $methodOnTarget, $modelOnTarget)
147
    {
148
        $embededModel = new $modelOnTarget;
149
        //Get the item name
150
        $items = $embededModel->getItems();
151
        $embededObj = $request->input($methodOnTarget);
152
        $embededObj = json_decode($embededObj);
153
154
        //Current Obj Create
155
        foreach ($items as $key => $item) {
156
            $is_ML = isML($item);
157
            $is_MD = isMD($item);
158
159
            if ($is_ML) {
160
                $embededModel->$key = ml(array(), $embededObj->$key);
161
            } elseif ($is_MD) {
162
                if ($embededObj->$key == "" || $embededObj->$key == null) {
163
                    $embededModel->$key = null;
164
                } else {
165
                    $embededModel->$key = new UTCDateTime(new DateTime($embededObj->$key));
0 ignored issues
show
Bug introduced by
new DateTime($embededObj->$key) of type 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

165
                    $embededModel->$key = new UTCDateTime(/** @scrutinizer ignore-type */ new DateTime($embededObj->$key));
Loading history...
166
                }
167
            } else {
168
                $embededModel->$key = $embededObj->$key;
169
            }
170
        }
171
        $this->$methodOnTarget()->associate($embededModel);
172
        $this->save();
173
    }
174
175
    /**
176
     * @param Request $request
177
     * @param $obj
178
     * @param $type
179
     * @param $model
180
     * @param $method
181
     * @param $modelTarget
182
     * @param $methodOnTarget
183
     * @param $modelOnTarget
184
     * @param $event
185
     * @param $hasTarget
186
     * @param $is_EO
187
     * @param $is_EM
188
     * @param $i
189
     * @throws Exception
190
     */
191
    public function processOneEmbededRelationship(Request $request, $obj, $type, $model, $method, $modelTarget, $methodOnTarget, $modelOnTarget, $event, $hasTarget, $is_EO, $is_EM, $i)
192
    {
193
        //Init the embedone model
194
        $embedObj = new $model;
195
196
        $EOitems = $embedObj->getItems();
197
        //Current Obj Create
198
        foreach ($EOitems as $EOkey => $item) {
199
            if (!is_null($obj)) {
200
                $is_ML = isML($item);
201
                $is_MD = isMD($item);
202
203
                if ($is_ML) {
204
                    $embedObj->$EOkey = ml(array(), $obj->$EOkey);
205
                } elseif ($EOkey == "updated_at" || $EOkey == "created_at") {
206
                    $embedObj->$EOkey = now();
207
                } elseif ($is_MD) {
208
                    if ($obj->$EOkey == "" ||  $obj->$EOkey == null) {
209
                        //dd('if');
210
                        $embedObj->$EOkey = null;
211
                    } else {
212
                        $embedObj->$EOkey = new UTCDateTime(new DateTime($obj->$EOkey));
0 ignored issues
show
Bug introduced by
new DateTime($obj->$EOkey) of type 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

212
                        $embedObj->$EOkey = new UTCDateTime(/** @scrutinizer ignore-type */ new DateTime($obj->$EOkey));
Loading history...
213
                    }
214
                } else {
215
                    if (!property_exists($obj, $EOkey)) {
216
                        $msg = ('Error - ' . $EOkey . ' attribute not found on obj ' . json_encode($obj));
217
                          (new Exception($msg) );
218
                    }
219
                    $embedObj->$EOkey = $obj->$EOkey;
220
                }
221
            }
222
        }
223
224
        //else if($is_EM){//To be implemented}
225
        //else if($is_HM){//To be implemented}
226
        //else if($is_HO){//To be implemented}
227
228
        //Get counter for embeds many with level > 1
229
        $counter = getCounterForRelationships($method, $is_EO, $is_EM, $i);
230
        //Check for another Level of Relationship
231
        $embedObj->processAllRelationships($request, $event, $method . "-", $counter);
232
233
        if ($is_EO) {
234
            $this->$method = $embedObj->attributes;
235
        } else {
236
            $this->$method()->associate($embedObj);
237
        }
238
        $this->save();
239
240
        //dd($embedObj, $this);
241
242
        if ($hasTarget) {
243
            //sync Permission to Permissiongroup
244
            //Init the Target Model
245
            $target_model = new $modelTarget;
0 ignored issues
show
Unused Code introduced by
The assignment to $target_model is dead and can be removed.
Loading history...
246
247
            if (!property_exists($obj, 'ref_id')) {
248
                $msg = ('Error - ref_id attribute not found on obj ' . json_encode($obj));
249
                throw (new \Exception($msg) );
250
            }
251
252
            $target_id = $obj->ref_id;
253
254
            $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

254
            /** @scrutinizer ignore-call */ 
255
            $ref_id = $this->getId();
Loading history...
255
256
            $requestToBeSync = getRequestToBeSync($ref_id, $modelOnTarget, $request, $methodOnTarget);
257
258
            $modelToBeSync = new $modelTarget;
259
            $modelToBeSync = $modelToBeSync->find($target_id);
260
            if (!is_null($modelToBeSync)) {
261
                $modelToBeSync->updateRelationWithSync($requestToBeSync, $methodOnTarget, $modelOnTarget);
262
                //TODO:Sync target on level > 1
263
                //$modelToBeSync->processAllRelationships($request, $event, $methodOnTarget, $methodOnTarget . "-");
264
            }
265
        }
266
    }
267
268
269
    /**
270
     * @param Request $request
271
     * @param array $additionalData
272
     * @return $this
273
     */
274
    public function updateWithSync(Request $request, array $additionalData = [])
275
    {
276
        $request = $request->merge($additionalData);
277
        $this->storeEditAllItems($request, "update");
278
        $this->processAllRelationships($request, "update", "", "");
279
280
        //Dispatch the update event
281
        $this->fireModelEvent('updateWithSync');
282
283
        return $this;
284
    }
285
286
    /**
287
     * @param $method
288
     * @param $modelTarget
289
     * @param $methodOnTarget
290
     * @param $id
291
     */
292
    public function deleteTargetObj($method, $modelTarget, $methodOnTarget, $is_EO)
293
    {
294
        if ($is_EO) {
295
            $embedObj = $this->$method;
296
            if (!is_null($embedObj)) {
297
                $target_id = $embedObj->ref_id;
298
                $this->handleSubTarget($target_id, $modelTarget, $methodOnTarget);
299
            }
300
        } else {
301
            foreach ($this->$method as $target) {
302
                $this->handleSubTarget($target->ref_id, $modelTarget, $methodOnTarget);
303
            }
304
        }
305
    }
306
307
    /**
308
     * @param $target_id
309
     * @param $modelTarget
310
     * @param $methodOnTarget
311
     */
312
    public function handleSubTarget($target_id, $modelTarget, $methodOnTarget)
313
    {
314
        $id = $this->getId();
315
        $target = new $modelTarget;
316
        $target = $target->all()->where('id', $target_id)->first();
317
        if (!is_null($target)) {
318
            $subTarget = $target->$methodOnTarget()->where('ref_id', $id)->first();
319
            $temps = $target->$methodOnTarget()->where('ref_id', '!=', $id);
320
            $target->$methodOnTarget()->delete($subTarget);
321
            foreach ($temps as $temp) {
322
                $target->$methodOnTarget()->associate($temp);
323
                $target->save();
324
            }
325
        }
326
    }
327
328
    /**
329
     * @return $this
330
     */
331
    public function destroyWithSync()
332
    {
333
        //Get the relation info
334
        $relations = $this->getMongoRelation();
335
336
        //Process all relationships
337
        foreach ($relations as $method => $relation) {
338
            //Get Relation Save Mode
339
            $type = $relation['type'];
340
            $hasTarget = hasTarget($relation);
341
            if ($hasTarget) {
342
                $modelTarget = $relation['modelTarget'];
343
                $methodOnTarget = $relation['methodOnTarget'];
344
                $modelOnTarget = $relation['modelOnTarget'];
0 ignored issues
show
Unused Code introduced by
The assignment to $modelOnTarget is dead and can be removed.
Loading history...
345
346
                $is_EO = is_EO($type);
347
                $is_EM = is_EM($type);
348
                $is_HO = is_HO($type);
0 ignored issues
show
Unused Code introduced by
The assignment to $is_HO is dead and can be removed.
Loading history...
349
                $is_HM = is_HM($type);
0 ignored issues
show
Unused Code introduced by
The assignment to $is_HM is dead and can be removed.
Loading history...
350
351
352
                if ($is_EO || $is_EM) {//EmbedsOne Create - EmbedsMany Create
353
                    //Delete EmbedsMany or EmbedsOne on Target
354
                    $this->deleteTargetObj($method, $modelTarget, $methodOnTarget, $is_EO);
355
                }
356
357
                //TODO: Need to be implemented
358
               /* elseif ($is_HM) {//HasMany
359
                } elseif ($is_HO) {//HasOne Create
360
                }*/
361
            }
362
        }
363
        //Delete current object
364
        $this->delete();
0 ignored issues
show
Bug introduced by
The method delete() does not exist on OfflineAgency\MongoAutoSync\Traits\MongoSyncTrait. Did you maybe mean deleteTargetObj()? ( Ignorable by Annotation )

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

364
        $this->/** @scrutinizer ignore-call */ 
365
               delete();

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...
365
366
        //Dispatch the destroy event
367
        $this->fireModelEvent('destroyWithSync');
368
369
        return $this;
370
    }
371
}
372