HasRelationsRecordsTrait::cloneRelations()   A
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 11
c 1
b 0
f 0
nc 5
nop 2
dl 0
loc 20
ccs 0
cts 12
cp 0
crap 30
rs 9.6111
1
<?php
2
3
namespace Nip\Records\Traits\Relations;
4
5
use Nip\Records\Record;
6
use Nip\Records\Relations\MorphToMany;
7
use Nip\Records\Relations\Relation;
8
use Nip\Records\Traits\AbstractTrait\RecordsTrait;
9
10
/**
11
 * Trait HasRelationsRecordsTrait
12
 * @package Nip\Records\Traits\Relations
13
 */
14
trait HasRelationsRecordsTrait
15
{
16
    use RecordsTrait;
17
18
    /**
19
     * The loaded relationships for the model table.
20
     * @var Relation[]
21
     */
22
    protected $relations = null;
23
24
    protected $relationTypes = ['belongsTo', 'hasMany', 'hasAndBelongsToMany'];
25
26
27
    /** @noinspection PhpDocMissingThrowsInspection
28
     * Get a specified relationship.
29
     * @param  string $relation
30
     * @return null|Relation
31
     * @throws \Exception
32
     */
33 1
    public function getRelation($relation)
34
    {
35
        /** @noinspection PhpUnhandledExceptionInspection */
36 1
        $this->checkInitRelations();
37
38 1
        return $this->relations[$relation];
39
    }
40
41
    /**
42
     * Check if the model needs to initRelations
43
     * @return void
44
     * @throws \Exception
45
     */
46 1
    protected function checkInitRelations()
47
    {
48 1
        if ($this->relations === null) {
49
            $this->initRelations();
50
        }
51 1
    }
52
53
    /**
54
     * @throws \Exception
55
     */
56
    protected function initRelations()
57
    {
58
        $this->relations = [];
59
        foreach ($this->relationTypes as $type) {
60
            $this->initRelationsType($type);
61
        }
62
    }
63
64
    /**
65
     * @param string $type
66
     * @throws \Exception
67
     */
68
    protected function initRelationsType($type)
69
    {
70
        if (property_exists($this, '_' . $type)) {
71
            $array = $this->{'_' . $type};
72
            $this->initRelationsFromArray($type, $array);
73
        }
74
    }
75
76
    /**
77
     * @param string $type
78
     * @param $array
79
     * @throws \Exception
80
     */
81
    public function initRelationsFromArray($type, $array)
82
    {
83
        foreach ($array as $key => $item) {
84
            $name = is_array($item) ? $key : $item;
85
            $params = is_array($item) ? $item : [];
86
            $this->initRelation($type, $name, $params);
87
        }
88
    }
89
90
    /**
91
     * @param string $type
92
     * @param string $name
93
     * @param array $params
94
     * @return Relation
95
     * @throws \Exception
96
     */
97 1
    protected function initRelation($type, $name, $params)
98
    {
99 1
        $relation = $this->newRelation($type);
100 1
        $relation->setName($name);
101 1
        $relation->addParams($params);
102
103 1
        $this->relations[$name] = $relation;
104
105 1
        return $relation;
106
    }
107
108
    /**
109
     * @param string $type
110
     * @return \Nip\Records\Relations\Relation
111
     */
112 9
    public function newRelation($type)
113
    {
114 9
        $class = $this->getRelationClass($type);
115
        /** @var \Nip\Records\Relations\Relation $relation */
116 9
        $relation = new $class();
117 9
        $relation->setManager($this);
118
119 9
        return $relation;
120
    }
121
122
    /**
123
     * @param string $type
124
     * @return string
125
     */
126 17
    public function getRelationClass($type)
127
    {
128 17
        $class = 'Nip\Records\Relations\\' . ucfirst($type);
129
130 17
        return $class;
131
    }
132
133
    /**
134
     * @param $name
135
     * @param array $params
136
     * @return Relation
137
     * @throws \Exception
138
     */
139 1
    public function belongsTo($name, $params = [])
140
    {
141 1
        return $this->initRelation('belongsTo', $name, $params);
142
    }
143
144
    /**
145
     * @param $name
146
     * @param array $params
147
     * @return Relation
148
     * @throws \Exception
149
     */
150
    public function hasMany($name, $params = [])
151
    {
152
        return $this->initRelation('hasMany', $name, $params);
153
    }
154
155
    /**
156
     * @param $name
157
     * @param array $params
158
     * @return Relation
159
     * @throws \Exception
160
     */
161
    public function hasOne($name, $params = [])
162
    {
163
        return $this->initRelation('hasOne', $name, $params);
164
    }
165
166
    /** @noinspection PhpMethodNamingConventionInspection
167
     * @param $name
168
     * @param array $params
169
     * @return Relation
170
     * @throws \Exception
171
     */
172
    public function HABTM($name, $params = [])
173
    {
174
        return $this->initRelation('hasAndBelongsToMany', $name, $params);
175
    }
176
177
    /**
178
     * @param $name
179
     * @param array $params
180
     * @return Relation
181
     * @throws \Exception
182
     */
183
    public function morphTo($name, $params = [])
184
    {
185
        return $this->initRelation('morphTo', $name, $params);
186
    }
187
188
    /**
189
     * @param $name
190
     * @param array $params
191
     * @return Relation
192
     * @throws \Exception
193
     */
194
    public function morphMany($name, $params = [])
195
    {
196
        return $this->initRelation('morphMany', $name, $params);
197
    }
198
199
    /**
200
     * @param $name
201
     * @param array $params
202
     * @return Relation
203
     * @throws \Exception
204
     */
205
    public function morphToMany($name, $params = [])
206
    {
207
        return $this->initRelation('morphToMany', $name, $params);
208
    }
209
210
    /**
211
     * @param $name
212
     * @param array $params
213
     * @return MorphToMany
214
     * @throws \Exception
215
     */
216
    public function morphedByMany($name, $params = [])
217
    {
218
        /** @var MorphToMany $relation */
219
        $relation = $this->initRelation('morphToMany', $name, $params);
220
        $relation->setInverse(true);
221
        return $relation;
222
    }
223
224
    /**
225
     * Determine if the given relation is loaded.
226
     * @param  string $key
227
     * @return bool
228
     * @throws \Exception
229
     */
230
    public function hasRelation($key)
231
    {
232
        $this->checkInitRelations();
233
234
        return array_key_exists($key, $this->relations);
235
    }
236
237
    /**
238
     * Set the specific relationship in the model.
239
     * @param  string $relation
240
     * @param  mixed $value
241
     * @return $this
242
     * @throws \Exception
243
     */
244
    public function setRelation($relation, $value)
245
    {
246
        $this->checkInitRelations();
247
        $this->relations[$relation] = $value;
248
249
        return $this;
250
    }
251
252
    /**
253
     * @param HasRelationsRecordTrait $from
254
     * @param HasRelationsRecordTrait $to
255
     * @return HasRelationsRecordTrait
256
     * @throws \Exception
257
     */
258
    public function cloneRelations($from, $to)
259
    {
260
        $relations = $from->getManager()->getRelations();
0 ignored issues
show
Bug introduced by
The method getRelations() does not exist on Nip\Records\AbstractModels\RecordManager. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

260
        $relations = $from->getManager()->/** @scrutinizer ignore-call */ getRelations();
Loading history...
261
        foreach ($relations as $name => $relation) {
262
            /** @var \Nip\Records\Relations\HasMany $relation */
263
            if ($relation->getType() != 'belongsTo') {
264
                /** @var Record[] $associatedOld */
265
                $associatedOld = $from->{'get' . $name}();
266
                if (count($associatedOld)) {
267
                    $associatedNew = $to->getRelation($name)->newCollection();
0 ignored issues
show
Bug introduced by
The method newCollection() does not exist on Nip\Records\Relations\Relation. It seems like you code against a sub-type of Nip\Records\Relations\Relation such as Nip\Records\Relations\HasOneOrMany. ( Ignorable by Annotation )

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

267
                    $associatedNew = $to->getRelation($name)->/** @scrutinizer ignore-call */ newCollection();
Loading history...
268
                    foreach ($associatedOld as $associated) {
269
                        $aItem = $associated->getCloneWithRelations();
270
                        $associatedNew[] = $aItem;
271
                    }
272
                    $to->getRelation($name)->setResults($associatedNew);
273
                }
274
            }
275
        }
276
277
        return $to;
278
    }
279
280
    /**
281
     * Get all the loaded relations for the instance.
282
     * @return array
283
     * @throws \Exception
284
     */
285
    public function getRelations()
286
    {
287
        $this->checkInitRelations();
288
289
        return $this->relations;
290
    }
291
292
    /**
293
     * Set the entire relations array on the model.
294
     * @param  array $relations
295
     * @return $this
296
     */
297
    public function setRelations(array $relations)
298
    {
299
        $this->relations = $relations;
300
301
        return $this;
302
    }
303
}
304