ModelAdditionalMethod::getModelInstanceFromPath()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace OfflineAgency\MongoAutoSync\Traits;
4
5
use DateTime;
6
use Exception;
7
use Illuminate\Support\Arr;
8
use MongoDB\BSON\UTCDateTime;
9
use OfflineAgency\MongoAutoSync\Extensions\MongoCollection;
10
use OfflineAgency\MongoAutoSync\Http\Models\MDModel;
11
use stdClass;
12
13
trait ModelAdditionalMethod
14
{
15
    protected $mini_models;
16
17
    public function newCollection(array $models = [])
18
    {
19
        return new MongoCollection($models);
20
    }
21
22
    /**
23
     * @return array
24
     */
25
    public function getItems(): array
26
    {
27
        return $this->items;
28
    }
29
30
    /**
31
     * @return array
32
     */
33
    public function getMongoRelation(): array
34
    {
35
        if (! empty($this->mongoRelation)) {
36
            return $this->mongoRelation;
37
        } else {
38
            return [];
39
        }
40
    }
41
42
    /**
43
     * @return void
44
     *
45
     * @throws Exception
46
     */
47
    public function setMiniModels()
48
    {
49
        $miniModelList = $this->getUniqueMiniModelList();
50
        $this->mini_models = $this->populateMiniModels($miniModelList);
51
    }
52
53
    /**
54
     * @return array
55
     */
56
    public function getMiniModels()
57
    {
58
        return $this->mini_models;
59
    }
60
61
    /**
62
     * @return array
63
     *
64
     * @throws Exception
65
     */
66
    public function getUniqueMiniModelList()
67
    {
68
        $relationships = $this->getMongoRelation();
69
70
        $models = [];
71
        $embedded_object = [];
72
73
        foreach ($relationships as $method => $relationship) {
74
            $hasTarget = hasTarget($relationship);
75
            if ($hasTarget) {
76
                $relationshipsContainsTarget = Arr::has($relationship, 'modelOnTarget');
77
                if ($relationshipsContainsTarget) {
78
                    $models[] = Arr::get($relationship, 'modelOnTarget');
79
                    $embedded_object[$method] = $this->getObjWithRefId($method, $relationship);
80
                } else {
81
                    throw new Exception('modelOnTarget not found on relationship '.$method.' array. Check your Model configuration '.get_class($this));
82
                }
83
            }
84
        }
85
        $this->setPartialGeneratedRequest($embedded_object);
0 ignored issues
show
Bug introduced by
It seems like setPartialGeneratedRequest() 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

85
        $this->/** @scrutinizer ignore-call */ 
86
               setPartialGeneratedRequest($embedded_object);
Loading history...
86
87
        return collect($models)->unique()->toArray();
88
    }
89
90
    /**
91
     * @param  array  $miniModelList
92
     * @return mixed
93
     *
94
     * @throws Exception
95
     */
96
    public function populateMiniModels(array $miniModelList)
97
    {
98
        $miniModels = [];
99
        foreach ($miniModelList as $miniModel) {
100
            $miniModels[$miniModel] = $this->getFreshMiniModel($miniModel);
101
        }
102
103
        return $miniModels;
104
    }
105
106
    /**
107
     * @param  string  $mini_model_path
108
     * @return MDModel
109
     *
110
     * @throws Exception
111
     */
112
    public function getFreshMiniModel(string $mini_model_path)
113
    {
114
        $embededModel = $this->getModelInstanceFromPath($mini_model_path);
115
        $items = $embededModel->getItems();
116
        foreach ($items as $key => $item) {
117
            $embededModel->$key = $this->castValueToBeSaved($key, $item, $mini_model_path);
118
        }
119
120
        return $embededModel;
121
    }
122
123
    /**
124
     * @param  string  $key
125
     * @param  $item
126
     * @param  string  $mini_model_path
127
     * @return array|mixed|UTCDateTime|null
128
     *
129
     * @throws Exception
130
     */
131
    public function castValueToBeSaved(string $key, $item, string $mini_model_path)
132
    {
133
        $is_ML = isML($item);
134
        $is_MD = isMD($item);
135
        $is_array = $this->isArray($item);
0 ignored issues
show
Bug introduced by
It seems like isArray() 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

135
        /** @scrutinizer ignore-call */ 
136
        $is_array = $this->isArray($item);
Loading history...
136
        $is_carbon_date = $this->isCarbonDate($item);
0 ignored issues
show
Bug introduced by
It seems like isCarbonDate() 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

136
        /** @scrutinizer ignore-call */ 
137
        $is_carbon_date = $this->isCarbonDate($item);
Loading history...
137
138
        $value = $this->getObjValueToBeSaved($key, $mini_model_path);
139
        if ($is_ML) {
140
            return is_array($value) ? $value : ml([], $value);
141
        } elseif ($is_MD) {
142
            if ($value instanceof UTCDateTime) {
143
                return $value;
144
            }
145
146
            if ($value == '') {
147
                return null;
148
            }
149
150
            return new UTCDateTime(new DateTime($value));
151
        } elseif ($is_carbon_date) {
152
            if ($value == '') {
153
                return new UTCDateTime();
154
            }
155
156
            return new UTCDateTime($value);
157
        } elseif ($is_array) {
158
            return is_null($value) ? [] : (is_array($value) ? $value : $value->getAttributes());
159
        } else {
160
            return $value;
161
        }
162
    }
163
164
    /**
165
     * @param  string  $mini_model_path
166
     * @return MDModel
167
     */
168
    public function getModelInstanceFromPath(string $mini_model_path)
169
    {
170
        return new $mini_model_path;
171
    }
172
173
    /**
174
     * @param  string  $key
175
     * @param  string  $mini_model_path
176
     * @param  bool  $rewrite_ref_id_key
177
     * @return mixed
178
     */
179
    public function getObjValueToBeSaved(string $key, string $mini_model_path, $rewrite_ref_id_key = true)
180
    {
181
        $key = $key === 'ref_id' && $rewrite_ref_id_key ? '_id' : $key;
182
        $target_additional_data = $this->getTargetAdditionalData();
0 ignored issues
show
Bug introduced by
It seems like getTargetAdditionalData() 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

182
        /** @scrutinizer ignore-call */ 
183
        $target_additional_data = $this->getTargetAdditionalData();
Loading history...
183
        $request = $this->getRequest();
0 ignored issues
show
Bug introduced by
It seems like getRequest() 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

183
        /** @scrutinizer ignore-call */ 
184
        $request = $this->getRequest();
Loading history...
184
185
        $db_value = $this->getDbValue($key);
186
187
        return Arr::has($target_additional_data, $mini_model_path.'.'.$key) ? Arr::get($target_additional_data, $mini_model_path.'.'.$key) : // Search on target_additional_data [] 4th parameter of updateWithSync() / storeWithSync()
188
            ($request->has($key) ? $request->input($key) : $db_value); // Search on Main Request 1st parameter of updateWithSync() / storeWithSync() or directly on database
189
        //TODO: Add default value from Item Model
190
    }
191
192
    /**
193
     * @param  string  $key
194
     * @return mixed
195
     */
196
    private function getDbValue(string $key)
197
    {
198
        return $this->$key;
199
    }
200
201
    /**
202
     * @param  string  $key
203
     * @return array
204
     *
205
     * @throws Exception
206
     */
207
    public function getEmbedModel(string $key)
208
    {
209
        $embedModels = $this->getMiniModels();
210
211
        if (Arr::has($embedModels, $key)) {
212
            return Arr::get($embedModels, $key);
213
        } else {
214
            throw new Exception('I cannot find an embedded model with key: '.$key.'. Check on your model configuration');
215
        }
216
    }
217
218
    /**
219
     * @param  string  $method
220
     * @param  array  $relationship
221
     * @return false|string
222
     *
223
     * @throws Exception
224
     */
225
    public function getObjWithRefId(string $method, array $relationship)
226
    {
227
        $objs = [];
228
        $type = $relationship['type'];
229
230
        $is_EO = is_EO($type);
231
        $is_EM = is_EM($type);
232
233
        if ($is_EO) {
234
            $objs[] = $this->getObjValueToBeSaved($method, '', false);
235
        } elseif ($is_EM) {
236
            if (! is_null($this->$method) > 0) {
237
                foreach ($this->$method as $value) {
238
                    $obj = new stdClass;
239
                    $obj->ref_id = $value->ref_id;
240
                    $objs[] = $obj;
241
                }
242
            }
243
        } else {
244
            throw new Exception('Relationship '.$method.' type '.$type.' is not valid! Possible values are: EmbedsMany and EmbedsOne');
245
        }
246
247
        return json_encode($objs);
248
    }
249
}
250