Passed
Push — master ( 979108...a70506 )
by Jonas
13:34
created

hasOneOrManyDeepFromBelongsToMany()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 6
c 1
b 0
f 0
dl 0
loc 15
ccs 6
cts 6
cp 1
rs 10
cc 1
nc 1
nop 4
crap 1
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 6
     */
27
    protected function hasOneOrManyDeepFromBelongsTo(
28
        BelongsTo $relation,
29
        array $through,
30
        array $foreignKeys,
31
        array $localKeys
32 6
    ) {
33
        if (is_array($relation->getOwnerKeyName())) {
34 2
            // https://github.com/topclaudy/compoships
35 2
            $foreignKeys[] = new CompositeKey(
36 2
                ...(array)$relation->getOwnerKeyName()
37
            );
38 2
39 2
            $localKeys[] = new CompositeKey(
40 2
                ...(array)$relation->getForeignKeyName()
41
            );
42 4
        } else {
43
            $foreignKeys[] = $relation->getOwnerKeyName();
44 4
45
            $localKeys[] = $relation->getForeignKeyName();
46
        }
47 6
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 2
     */
60
    protected function hasOneOrManyDeepFromBelongsToMany(
61
        BelongsToMany $relation,
62
        array $through,
63
        array $foreignKeys,
64
        array $localKeys
65 2
    ) {
66
        $through[] = $relation->getTable();
67 2
68 2
        $foreignKeys[] = $relation->getForeignPivotKeyName();
69
        $foreignKeys[] = $relation->getRelatedKeyName();
70 2
71 2
        $localKeys[] = $relation->getParentKeyName();
72
        $localKeys[] = $relation->getRelatedPivotKeyName();
73 2
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 110
     */
86
    protected function hasOneOrManyDeepFromHasOneOrMany(
87
        HasOneOrMany $relation,
88
        array $through,
89
        array $foreignKeys,
90
        array $localKeys
91 110
    ) {
92
        if (is_array($relation->getForeignKeyName())) {
93 2
            // https://github.com/topclaudy/compoships
94 2
            $foreignKeys[] = new CompositeKey(
95 2
                ...(array)$relation->getForeignKeyName()
96
            );
97 2
98 2
            $localKeys[] = new CompositeKey(
99 2
                ...(array)$relation->getLocalKeyName()
100
            );
101 108
        } else {
102
            $foreignKeys[] = $relation->getForeignKeyName();
103 108
104
            $localKeys[] = $relation->getLocalKeyName();
105
        }
106 110
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 22
     */
119
    protected function hasOneOrManyDeepFromHasManyThrough(
120
        HasManyThrough $relation,
121
        array $through,
122
        array $foreignKeys,
123
        array $localKeys
124 22
    ) {
125
        $through[] = get_class($relation->getParent());
126 22
127 22
        $foreignKeys[] = $relation->getFirstKeyName();
128
        $foreignKeys[] = $relation->getForeignKeyName();
129 22
130 22
        $localKeys[] = $relation->getLocalKeyName();
131
        $localKeys[] = $relation->getSecondLocalKeyName();
132 22
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 2
     */
145
    protected function hasOneOrManyDeepFromHasOneThrough(
146
        HasOneThrough $relation,
147
        array $through,
148
        array $foreignKeys,
149
        array $localKeys
150 2
    ) {
151
        $through[] = get_class($relation->getParent());
152 2
153
        $foreignKeys[] = $relation->getFirstKeyName();
154 2
        $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 4
     * @param \Illuminate\Database\Eloquent\Model[] $through
167
     * @param array $foreignKeys
168
     * @param array $localKeys
169
     * @return array
170
     */
171
    protected function hasOneOrManyDeepFromMorphOneOrMany(
172 4
        MorphOneOrMany $relation,
173
        array $through,
174 4
        array $foreignKeys,
175 2
        array $localKeys
176 2
    ) {
177
        $foreignKeys[] = [$relation->getMorphType(), $relation->getForeignKeyName()];
178 2
179 2
        $localKeys[] = $relation->getLocalKeyName();
180
181 2
        return [$through, $foreignKeys, $localKeys];
182 2
    }
183
184 2
    /**
185 2
     * 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 4
     * @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 112
        array $localKeys
198
    ) {
199 112
        $through[] = $relation->getTable();
200 112
201 112
        if ($relation->getInverse()) {
202 112
            $foreignKeys[] = $relation->getForeignPivotKeyName();
203 112
            $foreignKeys[] = $relation->getRelatedKeyName();
204 112
205 112
            $localKeys[] = $relation->getParentKeyName();
206 112
            $localKeys[] = [$relation->getMorphType(), $relation->getRelatedPivotKeyName()];
207
        } else {
208 112
            $foreignKeys[] = [$relation->getMorphType(), $relation->getForeignPivotKeyName()];
209 112
            $foreignKeys[] = $relation->getRelatedKeyName();
210 112
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