ConcatenatesNativeRelationships   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 227
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 13
eloc 64
dl 0
loc 227
rs 10
c 2
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A hasOneOrManyDeepFromHasManyThrough() 0 15 1
A hasOneOrManyDeepFromHasOneOrMany() 0 22 2
A hasOneOrManyDeepFromHasOneThrough() 0 15 1
A hasOneOrManyDeepRelationMethod() 0 19 3
A hasOneOrManyDeepFromBelongsToMany() 0 15 1
A hasOneOrManyDeepFromMorphOneOrMany() 0 11 1
A hasOneOrManyDeepFromMorphToMany() 0 23 2
A hasOneOrManyDeepFromBelongsTo() 0 22 2
1
<?php
2
3
namespace Staudenmeir\EloquentHasManyDeep\Eloquent\Traits;
4
5
use Illuminate\Database\Eloquent\Relations\BelongsTo;
6
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
7
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
8
use Illuminate\Database\Eloquent\Relations\HasOneOrMany;
9
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
10
use Illuminate\Database\Eloquent\Relations\MorphOneOrMany;
11
use Illuminate\Database\Eloquent\Relations\MorphToMany;
12
use Illuminate\Database\Eloquent\Relations\Relation;
13
use RuntimeException;
14
use Staudenmeir\EloquentHasManyDeep\Eloquent\CompositeKey;
15
16
trait ConcatenatesNativeRelationships
17
{
18
    /**
19
     * Prepare a has-one-deep or has-many-deep relationship from an existing belongs-to relationship.
20
     *
21
     * @param \Illuminate\Database\Eloquent\Relations\BelongsTo $relation
22
     * @param \Illuminate\Database\Eloquent\Model[] $through
23
     * @param array $foreignKeys
24
     * @param array $localKeys
25
     * @return array
26
     */
27
    protected function hasOneOrManyDeepFromBelongsTo(
28
        BelongsTo $relation,
29
        array $through,
30
        array $foreignKeys,
31
        array $localKeys
32
    ) {
33
        if (is_array($relation->getOwnerKeyName())) {
34
            // https://github.com/topclaudy/compoships
35
            $foreignKeys[] = new CompositeKey(
36
                ...(array)$relation->getOwnerKeyName()
37
            );
38
39
            $localKeys[] = new CompositeKey(
40
                ...(array)$relation->getForeignKeyName()
41
            );
42
        } else {
43
            $foreignKeys[] = $relation->getOwnerKeyName();
44
45
            $localKeys[] = $relation->getForeignKeyName();
46
        }
47
48
        return [$through, $foreignKeys, $localKeys];
49
    }
50
51
    /**
52
     * Prepare a has-one-deep or has-many-deep relationship from an existing belongs-to-many relationship.
53
     *
54
     * @param \Illuminate\Database\Eloquent\Relations\BelongsToMany $relation
55
     * @param \Illuminate\Database\Eloquent\Model[] $through
56
     * @param array $foreignKeys
57
     * @param array $localKeys
58
     * @return array
59
     */
60
    protected function hasOneOrManyDeepFromBelongsToMany(
61
        BelongsToMany $relation,
62
        array $through,
63
        array $foreignKeys,
64
        array $localKeys
65
    ) {
66
        $through[] = $relation->getTable();
67
68
        $foreignKeys[] = $relation->getForeignPivotKeyName();
69
        $foreignKeys[] = $relation->getRelatedKeyName();
70
71
        $localKeys[] = $relation->getParentKeyName();
72
        $localKeys[] = $relation->getRelatedPivotKeyName();
73
74
        return [$through, $foreignKeys, $localKeys];
75
    }
76
77
    /**
78
     * Prepare a has-one-deep or has-many-deep relationship from an existing has-one or has-many relationship.
79
     *
80
     * @param \Illuminate\Database\Eloquent\Relations\HasOneOrMany $relation
81
     * @param \Illuminate\Database\Eloquent\Model[] $through
82
     * @param array $foreignKeys
83
     * @param array $localKeys
84
     * @return array
85
     */
86
    protected function hasOneOrManyDeepFromHasOneOrMany(
87
        HasOneOrMany $relation,
88
        array $through,
89
        array $foreignKeys,
90
        array $localKeys
91
    ) {
92
        if (is_array($relation->getForeignKeyName())) {
93
            // https://github.com/topclaudy/compoships
94
            $foreignKeys[] = new CompositeKey(
95
                ...(array)$relation->getForeignKeyName()
96
            );
97
98
            $localKeys[] = new CompositeKey(
99
                ...(array)$relation->getLocalKeyName()
100
            );
101
        } else {
102
            $foreignKeys[] = $relation->getForeignKeyName();
103
104
            $localKeys[] = $relation->getLocalKeyName();
105
        }
106
107
        return [$through, $foreignKeys, $localKeys];
108
    }
109
110
    /**
111
     * Prepare a has-one-deep or has-many-deep relationship from an existing has-many-through relationship.
112
     *
113
     * @param \Illuminate\Database\Eloquent\Relations\HasManyThrough $relation
114
     * @param \Illuminate\Database\Eloquent\Model[] $through
115
     * @param array $foreignKeys
116
     * @param array $localKeys
117
     * @return array
118
     */
119
    protected function hasOneOrManyDeepFromHasManyThrough(
120
        HasManyThrough $relation,
121
        array $through,
122
        array $foreignKeys,
123
        array $localKeys
124
    ) {
125
        $through[] = get_class($relation->getParent());
126
127
        $foreignKeys[] = $relation->getFirstKeyName();
128
        $foreignKeys[] = $relation->getForeignKeyName();
129
130
        $localKeys[] = $relation->getLocalKeyName();
131
        $localKeys[] = $relation->getSecondLocalKeyName();
132
133
        return [$through, $foreignKeys, $localKeys];
134
    }
135
136
    /**
137
     * Prepare a has-one-deep or has-many-deep relationship from an existing has-one-through relationship.
138
     *
139
     * @param \Illuminate\Database\Eloquent\Relations\HasOneThrough $relation
140
     * @param \Illuminate\Database\Eloquent\Model[] $through
141
     * @param array $foreignKeys
142
     * @param array $localKeys
143
     * @return array
144
     */
145
    protected function hasOneOrManyDeepFromHasOneThrough(
146
        HasOneThrough $relation,
147
        array $through,
148
        array $foreignKeys,
149
        array $localKeys
150
    ) {
151
        $through[] = get_class($relation->getParent());
152
153
        $foreignKeys[] = $relation->getFirstKeyName();
154
        $foreignKeys[] = $relation->getForeignKeyName();
155
156
        $localKeys[] = $relation->getLocalKeyName();
157
        $localKeys[] = $relation->getSecondLocalKeyName();
158
159
        return [$through, $foreignKeys, $localKeys];
160
    }
161
162
    /**
163
     * Prepare a has-one-deep or has-many-deep relationship from an existing morph-one or morph-many relationship.
164
     *
165
     * @param \Illuminate\Database\Eloquent\Relations\MorphOneOrMany $relation
166
     * @param \Illuminate\Database\Eloquent\Model[] $through
167
     * @param array $foreignKeys
168
     * @param array $localKeys
169
     * @return array
170
     */
171
    protected function hasOneOrManyDeepFromMorphOneOrMany(
172
        MorphOneOrMany $relation,
173
        array $through,
174
        array $foreignKeys,
175
        array $localKeys
176
    ) {
177
        $foreignKeys[] = [$relation->getMorphType(), $relation->getForeignKeyName()];
178
179
        $localKeys[] = $relation->getLocalKeyName();
180
181
        return [$through, $foreignKeys, $localKeys];
182
    }
183
184
    /**
185
     * Prepare a has-one-deep or has-many-deep relationship from an existing morph-to-many relationship.
186
     *
187
     * @param \Illuminate\Database\Eloquent\Relations\MorphToMany $relation
188
     * @param \Illuminate\Database\Eloquent\Model[] $through
189
     * @param array $foreignKeys
190
     * @param array $localKeys
191
     * @return array
192
     */
193
    protected function hasOneOrManyDeepFromMorphToMany(
194
        MorphToMany $relation,
195
        array $through,
196
        array $foreignKeys,
197
        array $localKeys
198
    ) {
199
        $through[] = $relation->getTable();
200
201
        if ($relation->getInverse()) {
202
            $foreignKeys[] = $relation->getForeignPivotKeyName();
203
            $foreignKeys[] = $relation->getRelatedKeyName();
204
205
            $localKeys[] = $relation->getParentKeyName();
206
            $localKeys[] = [$relation->getMorphType(), $relation->getRelatedPivotKeyName()];
207
        } else {
208
            $foreignKeys[] = [$relation->getMorphType(), $relation->getForeignPivotKeyName()];
209
            $foreignKeys[] = $relation->getRelatedKeyName();
210
211
            $localKeys[] = $relation->getParentKeyName();
212
            $localKeys[] = $relation->getRelatedPivotKeyName();
213
        }
214
215
        return [$through, $foreignKeys, $localKeys];
216
    }
217
218
    /**
219
     * Get the relationship method name.
220
     *
221
     * @param \Illuminate\Database\Eloquent\Relations\Relation $relation
222
     * @return string
223
     */
224
    protected function hasOneOrManyDeepRelationMethod(Relation $relation)
225
    {
226
        $classes = [
227
            BelongsTo::class,
228
            HasManyThrough::class, // TODO[L12]
229
            HasOneThrough::class,
230
            MorphOneOrMany::class,
231
            HasOneOrMany::class,
232
            MorphToMany::class,
233
            BelongsToMany::class,
234
        ];
235
236
        foreach ($classes as $class) {
237
            if ($relation instanceof $class) {
238
                return 'hasOneOrManyDeepFrom' . class_basename($class);
239
            }
240
        }
241
242
        throw new RuntimeException('This relationship is not supported.'); // @codeCoverageIgnore
243
    }
244
}
245