1 | <?php |
||||||
2 | |||||||
3 | namespace MaksimM\CompositePrimaryKeys\Http\Traits; |
||||||
4 | |||||||
5 | use Closure; |
||||||
6 | use Illuminate\Database\Eloquent\Builder; |
||||||
7 | use Illuminate\Database\Eloquent\Model; |
||||||
8 | use Illuminate\Database\Eloquent\Relations\BelongsTo; |
||||||
9 | use Illuminate\Database\Eloquent\Relations\BelongsToMany; |
||||||
10 | use Illuminate\Database\Eloquent\Relations\HasMany; |
||||||
11 | use Illuminate\Database\Eloquent\Relations\HasManyThrough; |
||||||
12 | use Illuminate\Database\Eloquent\Relations\HasOne; |
||||||
13 | use Illuminate\Database\Eloquent\Relations\MorphMany; |
||||||
14 | use Illuminate\Database\Eloquent\Relations\MorphOne; |
||||||
15 | use Illuminate\Database\Eloquent\Relations\MorphTo; |
||||||
16 | use Illuminate\Database\Eloquent\Relations\MorphToMany; |
||||||
17 | use Illuminate\Support\Str; |
||||||
18 | use MaksimM\CompositePrimaryKeys\Eloquent\Relationships\CompositeBelongsTo; |
||||||
19 | use MaksimM\CompositePrimaryKeys\Eloquent\Relationships\CompositeBelongsToMany; |
||||||
20 | |||||||
21 | trait CompositeRelationships |
||||||
22 | { |
||||||
23 | /** |
||||||
24 | * @param $related |
||||||
25 | * @param null $foreignKey |
||||||
0 ignored issues
–
show
Documentation
Bug
introduced
by
![]() |
|||||||
26 | * @param null $ownerKey |
||||||
0 ignored issues
–
show
|
|||||||
27 | * @param null $relation |
||||||
0 ignored issues
–
show
|
|||||||
28 | * |
||||||
29 | * @return BelongsTo |
||||||
30 | */ |
||||||
31 | public function belongsTo($related, $foreignKey = null, $ownerKey = null, $relation = null) |
||||||
32 | { |
||||||
33 | // If no relation name was given, we will use this debug backtrace to extract |
||||||
34 | // the calling method's name and use that as the relationship name as most |
||||||
35 | // of the time this will be what we desire to use for the relationships. |
||||||
36 | if (is_null($relation)) { |
||||||
0 ignored issues
–
show
|
|||||||
37 | $relation = $this->guessBelongsToRelation(); |
||||||
0 ignored issues
–
show
It seems like
guessBelongsToRelation() 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
![]() |
|||||||
38 | } |
||||||
39 | |||||||
40 | /** |
||||||
41 | * @var Model $instance |
||||||
42 | */ |
||||||
43 | $instance = $this->newRelatedInstance($related); |
||||||
0 ignored issues
–
show
It seems like
newRelatedInstance() 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
![]() |
|||||||
44 | |||||||
45 | // If no foreign key was supplied, we can use a backtrace to guess the proper |
||||||
46 | // foreign key name by using the name of the relationship function, which |
||||||
47 | // when combined with an "_id" should conventionally match the columns. |
||||||
48 | if (is_null($foreignKey)) { |
||||||
0 ignored issues
–
show
|
|||||||
49 | $foreignKey = is_array($instance->getKeyName()) ? array_map( |
||||||
0 ignored issues
–
show
|
|||||||
50 | function ($key) use ($relation) { |
||||||
51 | return Str::snake($relation).'_'.$key; |
||||||
52 | }, |
||||||
53 | $instance->getKeyName() |
||||||
54 | ) : Str::snake($relation).'_'.$instance->getKeyName(); |
||||||
55 | } |
||||||
56 | |||||||
57 | // Once we have the foreign key names, we'll just create a new Eloquent query |
||||||
58 | // for the related models and returns the relationship instance which will |
||||||
59 | // actually be responsible for retrieving and hydrating every relations. |
||||||
60 | $ownerKey = $ownerKey ?: $instance->getKeyName(); |
||||||
0 ignored issues
–
show
|
|||||||
61 | |||||||
62 | $relationQuery = $this->newBelongsTo( |
||||||
63 | $instance->newQuery(), |
||||||
64 | $this, |
||||||
0 ignored issues
–
show
$this of type MaksimM\CompositePrimary...\CompositeRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $child of MaksimM\CompositePrimary...onships::newBelongsTo() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
65 | $foreignKey, |
||||||
66 | $ownerKey, |
||||||
67 | $relation |
||||||
68 | ); |
||||||
69 | |||||||
70 | return $relationQuery; |
||||||
71 | } |
||||||
72 | |||||||
73 | protected function executeWithinOptionalBinaryTransformation(Closure $relation, ...$models) |
||||||
74 | { |
||||||
75 | foreach ($models as $model) { |
||||||
76 | if (method_exists($model, 'disableBinaryMutators')) { |
||||||
77 | $model->disableBinaryMutators(); |
||||||
78 | } |
||||||
79 | } |
||||||
80 | $relationResult = $relation(); |
||||||
81 | foreach ($models as $model) { |
||||||
82 | if (method_exists($model, 'enableBinaryMutators')) { |
||||||
83 | $model->enableBinaryMutators(); |
||||||
84 | } |
||||||
85 | } |
||||||
86 | |||||||
87 | return $relationResult; |
||||||
88 | } |
||||||
89 | |||||||
90 | /** |
||||||
91 | * Instantiate a new BelongsTo relationship. |
||||||
92 | * |
||||||
93 | * @param Builder $query |
||||||
94 | * @param Model $child |
||||||
95 | * @param string $foreignKey |
||||||
96 | * @param string $ownerKey |
||||||
97 | * @param string $relation |
||||||
98 | * |
||||||
99 | * @return BelongsTo |
||||||
100 | */ |
||||||
101 | protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation) |
||||||
102 | { |
||||||
103 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $child, $foreignKey, $ownerKey, $relation) { |
||||||
104 | return new CompositeBelongsTo($query, $child, $foreignKey, $ownerKey, $relation); |
||||||
105 | }, $query->getModel(), $child); |
||||||
106 | } |
||||||
107 | |||||||
108 | /** |
||||||
109 | * Instantiate a new HasOne relationship. |
||||||
110 | * |
||||||
111 | * @param Builder $query |
||||||
112 | * @param Model $parent |
||||||
113 | * @param string $foreignKey |
||||||
114 | * @param string $localKey |
||||||
115 | * |
||||||
116 | * @return HasOne |
||||||
117 | */ |
||||||
118 | protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey) |
||||||
119 | { |
||||||
120 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $foreignKey, $localKey) { |
||||||
121 | return new HasOne($query, $parent, $foreignKey, $localKey); |
||||||
122 | }, $query->getModel(), $parent); |
||||||
123 | } |
||||||
124 | |||||||
125 | /** |
||||||
126 | * Instantiate a new MorphOne relationship. |
||||||
127 | * |
||||||
128 | * @param Builder $query |
||||||
129 | * @param Model $parent |
||||||
130 | * @param string $type |
||||||
131 | * @param string $id |
||||||
132 | * @param string $localKey |
||||||
133 | * |
||||||
134 | * @return MorphOne |
||||||
135 | */ |
||||||
136 | protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey) |
||||||
137 | { |
||||||
138 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $type, $id, $localKey) { |
||||||
139 | return new MorphOne($query, $parent, $type, $id, $localKey); |
||||||
140 | }, $query->getModel(), $parent); |
||||||
141 | } |
||||||
142 | |||||||
143 | /** |
||||||
144 | * Instantiate a new MorphTo relationship. |
||||||
145 | * |
||||||
146 | * @param Builder $query |
||||||
147 | * @param Model $parent |
||||||
148 | * @param string $foreignKey |
||||||
149 | * @param string $ownerKey |
||||||
150 | * @param string $type |
||||||
151 | * @param string $relation |
||||||
152 | * |
||||||
153 | * @return MorphTo |
||||||
154 | */ |
||||||
155 | protected function newMorphTo(Builder $query, Model $parent, $foreignKey, $ownerKey, $type, $relation) |
||||||
156 | { |
||||||
157 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $foreignKey, $ownerKey, $type, $relation) { |
||||||
158 | return new MorphTo($query, $parent, $foreignKey, $ownerKey, $type, $relation); |
||||||
159 | }, $query->getModel(), $parent); |
||||||
160 | } |
||||||
161 | |||||||
162 | /** |
||||||
163 | * Instantiate a new HasMany relationship. |
||||||
164 | * |
||||||
165 | * @param Builder $query |
||||||
166 | * @param Model $parent |
||||||
167 | * @param string $foreignKey |
||||||
168 | * @param string $localKey |
||||||
169 | * |
||||||
170 | * @return HasMany |
||||||
171 | */ |
||||||
172 | protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey) |
||||||
173 | { |
||||||
174 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $foreignKey, $localKey) { |
||||||
175 | return new HasMany($query, $parent, $foreignKey, $localKey); |
||||||
176 | }, $query->getModel(), $parent); |
||||||
177 | } |
||||||
178 | |||||||
179 | /** |
||||||
180 | * Instantiate a new HasManyThrough relationship. |
||||||
181 | * |
||||||
182 | * @param Builder $query |
||||||
183 | * @param Model $farParent |
||||||
184 | * @param Model $throughParent |
||||||
185 | * @param string $firstKey |
||||||
186 | * @param string $secondKey |
||||||
187 | * @param string $localKey |
||||||
188 | * @param string $secondLocalKey |
||||||
189 | * |
||||||
190 | * @return HasManyThrough |
||||||
191 | */ |
||||||
192 | protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey) |
||||||
193 | { |
||||||
194 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey) { |
||||||
195 | return new HasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey); |
||||||
196 | }, $query->getModel(), $farParent); |
||||||
197 | } |
||||||
198 | |||||||
199 | /** |
||||||
200 | * Instantiate a new MorphMany relationship. |
||||||
201 | * |
||||||
202 | * @param Builder $query |
||||||
203 | * @param Model $parent |
||||||
204 | * @param string $type |
||||||
205 | * @param string $id |
||||||
206 | * @param string $localKey |
||||||
207 | * |
||||||
208 | * @return MorphMany |
||||||
209 | */ |
||||||
210 | protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey) |
||||||
211 | { |
||||||
212 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $type, $id, $localKey) { |
||||||
213 | return new MorphMany($query, $parent, $type, $id, $localKey); |
||||||
214 | }, $query->getModel(), $parent); |
||||||
215 | } |
||||||
216 | |||||||
217 | /** |
||||||
218 | * Instantiate a new BelongsToMany relationship. |
||||||
219 | * |
||||||
220 | * @param Builder $query |
||||||
221 | * @param Model $parent |
||||||
222 | * @param string $table |
||||||
223 | * @param string $foreignPivotKey |
||||||
224 | * @param string $relatedPivotKey |
||||||
225 | * @param string $parentKey |
||||||
226 | * @param string $relatedKey |
||||||
227 | * @param string $relationName |
||||||
228 | * |
||||||
229 | * @return BelongsToMany |
||||||
230 | */ |
||||||
231 | protected function newBelongsToMany( |
||||||
232 | Builder $query, |
||||||
233 | Model $parent, |
||||||
234 | $table, |
||||||
235 | $foreignPivotKey, |
||||||
236 | $relatedPivotKey, |
||||||
237 | $parentKey, |
||||||
238 | $relatedKey, |
||||||
239 | $relationName = null |
||||||
240 | ) { |
||||||
241 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName) { |
||||||
242 | return new CompositeBelongsToMany($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, $relationName); |
||||||
243 | }, $query->getModel(), $parent); |
||||||
244 | } |
||||||
245 | |||||||
246 | /** |
||||||
247 | * Instantiate a new MorphToMany relationship. |
||||||
248 | * |
||||||
249 | * @param Builder $query |
||||||
250 | * @param Model $parent |
||||||
251 | * @param string $name |
||||||
252 | * @param string $table |
||||||
253 | * @param string $foreignPivotKey |
||||||
254 | * @param string $relatedPivotKey |
||||||
255 | * @param string $parentKey |
||||||
256 | * @param string $relatedKey |
||||||
257 | * @param string $relationName |
||||||
258 | * @param bool $inverse |
||||||
259 | * |
||||||
260 | * @return MorphToMany |
||||||
261 | */ |
||||||
262 | protected function newMorphToMany( |
||||||
263 | Builder $query, |
||||||
264 | Model $parent, |
||||||
265 | $name, |
||||||
266 | $table, |
||||||
267 | $foreignPivotKey, |
||||||
268 | $relatedPivotKey, |
||||||
269 | $parentKey, |
||||||
270 | $relatedKey, |
||||||
271 | $relationName = null, |
||||||
272 | $inverse = false |
||||||
273 | ) { |
||||||
274 | return $this->executeWithinOptionalBinaryTransformation(function () use ($query, $parent, $name, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey, |
||||||
275 | $relationName, $inverse) { |
||||||
276 | return new MorphToMany( |
||||||
277 | $query, |
||||||
278 | $parent, |
||||||
279 | $name, |
||||||
280 | $table, |
||||||
281 | $foreignPivotKey, |
||||||
282 | $relatedPivotKey, |
||||||
283 | $parentKey, |
||||||
284 | $relatedKey, |
||||||
285 | $relationName, |
||||||
286 | $inverse |
||||||
287 | ); |
||||||
288 | }, $query->getModel(), $parent); |
||||||
289 | } |
||||||
290 | } |
||||||
291 |