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

MongoSyncTrait::destroyWithSync()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 39
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 17
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 39
rs 9.3888
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