Passed
Push — master ( f2e88d...3da52d )
by
unknown
01:48 queued 13s
created

RelationshipMongoTrait::updateRelationWithSync()   B

Complexity

Conditions 8
Paths 4

Size

Total Lines 52
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 2 Features 0
Metric Value
eloc 34
c 3
b 2
f 0
dl 0
loc 52
rs 8.1315
cc 8
nc 4
nop 4

How to fix   Long Method   

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:

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

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

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

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

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

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