Test Failed
Pull Request — master (#74)
by
unknown
11:03
created

RelationshipMongoTrait::updateRelationWithSync()   B

Complexity

Conditions 8
Paths 4

Size

Total Lines 48
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 2 Features 0
Metric Value
eloc 31
c 3
b 2
f 0
dl 0
loc 48
rs 8.1795
cc 8
nc 4
nop 4
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
    /**
14
     * @param  Request  $request
15
     * @param  string  $event
16
     * @param  string  $parent
17
     * @param  string  $counter
18
     * @param  array  $options
19
     *
20
     * @throws Exception
21
     */
22
    public function processAllRelationships(Request $request, string $event, string $parent, string $counter, array $options)
23
    {
24
        $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

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

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

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

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

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

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

139
                    ' 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...
140
                )
141
            );
142
143
            $is_update_operation = false;
144
            foreach ($this->$method_on_target as $temp) {
145
                throw_if(
146
                    is_array($temp),
147
                    new Exception(
148
                        'Error during target update. Remember to declare '.$method_on_target.' as '.
149
                        'EmbedsMany relationship on model '.get_class($this)
150
                    )
151
                );
152
153
                if (!is_null($temp)) {
154
                    if ($this->getHasPartialRequest() && Arr::get($temp->attributes, 'ref_id') !== Arr::get($mini_model->attributes, 'ref_id')) {
0 ignored issues
show
Bug introduced by
It seems like getHasPartialRequest() 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

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

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

278
    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...
279
    {
280
        //Init the embed one model
281
        $embedObj = new $model;
282
283
        $EOitems = $embedObj->getItems();
284
        //Current Obj Create
285
        foreach ($EOitems as $EOkey => $item) {
286
            if (! is_null($obj)) {
287
                $is_ML = isML($item);
288
                $is_MD = isMD($item);
289
                $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

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

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

337
            /** @scrutinizer ignore-call */ 
338
            $miniModel = $this->getEmbedModel($modelOnTarget);
Loading history...
338
            $modelToBeSync->updateRelationWithSync($miniModel, $methodOnTarget, $is_EO_target, $is_EM_target);
339
            //TODO:Sync target on level > 1
340
            //$modelToBeSync->processAllRelationships($request, $event, $methodOnTarget, $methodOnTarget . "-");
341
        }
342
    }
343
}
344