Passed
Push — main ( a267a2...e9480d )
by Jonas
12:42 queued 09:49
created

HasJsonRelationships::newHasOneJson()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 4
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Staudenmeir\EloquentJsonRelations;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
use Illuminate\Database\Eloquent\Relations\HasMany;
10
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
11
use Illuminate\Database\Eloquent\Relations\HasOne;
12
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
13
use Illuminate\Database\Eloquent\Relations\MorphMany;
14
use Illuminate\Database\Eloquent\Relations\MorphOne;
15
use RuntimeException;
16
use Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson;
17
use Staudenmeir\EloquentJsonRelations\Relations\HasManyJson;
18
use Staudenmeir\EloquentJsonRelations\Relations\HasOneJson;
19
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\BelongsTo as BelongsToPostgres;
20
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\HasMany as HasManyPostgres;
21
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\HasManyThrough as HasManyThroughPostgres;
22
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\HasOne as HasOnePostgres;
23
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\HasOneThrough as HasOneThroughPostgres;
24
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\MorphMany as MorphManyPostgres;
25
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\MorphOne as MorphOnePostgres;
26
27
trait HasJsonRelationships
28
{
29
    /**
30
     * Get an attribute from the model.
31
     *
32
     * @param string $key
33
     * @return mixed
34
     */
35
    public function getAttribute($key)
36
    {
37
        $attribute = preg_split('/(->|\[])/', $key)[0];
38
39
        if (array_key_exists($attribute, $this->attributes)) {
40
            return $this->getAttributeValue($key);
41
        }
42
43
        return parent::getAttribute($key);
44
    }
45
46
    /**
47
     * Get an attribute from the $attributes array.
48
     *
49
     * @param string $key
50
     * @return mixed
51
     */
52
    public function getAttributeFromArray($key)
53
    {
54
        if (str_contains($key, '->')) {
55
            return $this->getAttributeValue($key);
56
        }
57
58
        return parent::getAttributeFromArray($key);
59
    }
60
61
    /**
62
     * Get a plain attribute (not a relationship).
63
     *
64
     * @param string $key
65
     * @return mixed
66
     */
67
    public function getAttributeValue($key)
68
    {
69
        if (str_contains($key, '->')) {
70
            [$key, $path] = explode('->', $key, 2);
71
72
            if (substr($key, -2) === '[]') {
73
                $key = substr($key, 0, -2);
74
75
                $path = '*.'.$path;
76
            }
77
78
            $path = str_replace(['->', '[]'], ['.', '.*'], $path);
79
80
            return data_get($this->getAttributeValue($key), $path);
81
        }
82
83
        return parent::getAttributeValue($key);
84
    }
85
86
    /**
87
     * Instantiate a new HasOne relationship.
88
     *
89
     * @param \Illuminate\Database\Eloquent\Builder $query
90
     * @param \Illuminate\Database\Eloquent\Model $parent
91
     * @param string $foreignKey
92
     * @param string $localKey
93
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
94
     */
95
    protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey)
96
    {
97
        if ($query->getConnection()->getDriverName() === 'pgsql') {
98
            return new HasOnePostgres($query, $parent, $foreignKey, $localKey);
99
        }
100
101
        return new HasOne($query, $parent, $foreignKey, $localKey);
102
    }
103
104
    /**
105
     * Instantiate a new HasOneThrough relationship.
106
     *
107
     * @param \Illuminate\Database\Eloquent\Builder $query
108
     * @param \Illuminate\Database\Eloquent\Model $farParent
109
     * @param \Illuminate\Database\Eloquent\Model $throughParent
110
     * @param string $firstKey
111
     * @param string $secondKey
112
     * @param string $localKey
113
     * @param string $secondLocalKey
114
     * @return \Illuminate\Database\Eloquent\Relations\HasOneThrough
115
     */
116
    protected function newHasOneThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)
117
    {
118
        if ($query->getConnection()->getDriverName() === 'pgsql') {
119
            return new HasOneThroughPostgres($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
120
        }
121
122
        return new HasOneThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
123
    }
124
125
    /**
126
     * Instantiate a new MorphOne relationship.
127
     *
128
     * @param \Illuminate\Database\Eloquent\Builder $query
129
     * @param \Illuminate\Database\Eloquent\Model $parent
130
     * @param string $type
131
     * @param string $id
132
     * @param string $localKey
133
     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
134
     */
135
    protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey)
136
    {
137
        if ($query->getConnection()->getDriverName() === 'pgsql') {
138
            return new MorphOnePostgres($query, $parent, $type, $id, $localKey);
139
        }
140
141
        return new MorphOne($query, $parent, $type, $id, $localKey);
142
    }
143
144
    /**
145
     * Instantiate a new BelongsTo relationship.
146
     *
147
     * @param \Illuminate\Database\Eloquent\Builder $query
148
     * @param \Illuminate\Database\Eloquent\Model $child
149
     * @param string $foreignKey
150
     * @param string $ownerKey
151
     * @param string $relation
152
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
153
     */
154
    protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)
155
    {
156
        if ($query->getConnection()->getDriverName() === 'pgsql') {
157
            return new BelongsToPostgres($query, $child, $foreignKey, $ownerKey, $relation);
158
        }
159
160
        return new BelongsTo($query, $child, $foreignKey, $ownerKey, $relation);
161
    }
162
163
    /**
164
     * Instantiate a new HasMany relationship.
165
     *
166
     * @param \Illuminate\Database\Eloquent\Builder $query
167
     * @param \Illuminate\Database\Eloquent\Model $parent
168
     * @param string $foreignKey
169
     * @param string $localKey
170
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
171
     */
172
    protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey)
173
    {
174
        if ($query->getConnection()->getDriverName() === 'pgsql') {
175
            return new HasManyPostgres($query, $parent, $foreignKey, $localKey);
176
        }
177
178
        return new HasMany($query, $parent, $foreignKey, $localKey);
179
    }
180
181
    /**
182
     * Instantiate a new HasManyThrough relationship.
183
     *
184
     * @param \Illuminate\Database\Eloquent\Builder $query
185
     * @param \Illuminate\Database\Eloquent\Model $farParent
186
     * @param \Illuminate\Database\Eloquent\Model $throughParent
187
     * @param string $firstKey
188
     * @param string $secondKey
189
     * @param string $localKey
190
     * @param string $secondLocalKey
191
     * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
192
     */
193
    protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)
194
    {
195
        if ($query->getConnection()->getDriverName() === 'pgsql') {
196
            return new HasManyThroughPostgres($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
197
        }
198
199
        return new HasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
200
    }
201
202
    /**
203
     * Instantiate a new MorphMany relationship.
204
     *
205
     * @param \Illuminate\Database\Eloquent\Builder $query
206
     * @param \Illuminate\Database\Eloquent\Model $parent
207
     * @param string $type
208
     * @param string $id
209
     * @param string $localKey
210
     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
211
     */
212
    protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey)
213
    {
214
        if ($query->getConnection()->getDriverName() === 'pgsql') {
215
            return new MorphManyPostgres($query, $parent, $type, $id, $localKey);
216
        }
217
218
        return new MorphMany($query, $parent, $type, $id, $localKey);
219
    }
220
221
    /**
222
     * Define an inverse one-to-one or many JSON relationship.
223
     *
224
     * @param string $related
225
     * @param string|array $foreignKey
226
     * @param string|array $ownerKey
227
     * @param string $relation
228
     * @return \Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson
229
     */
230
    public function belongsToJson($related, $foreignKey, $ownerKey = null, $relation = null)
231
    {
232
        if (is_null($relation)) {
233
            $relation = $this->guessBelongsToRelation();
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

233
            /** @scrutinizer ignore-call */ 
234
            $relation = $this->guessBelongsToRelation();
Loading history...
234
        }
235
236
        /** @var \Illuminate\Database\Eloquent\Model $instance */
237
        $instance = $this->newRelatedInstance($related);
0 ignored issues
show
Bug introduced by
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 ignore-call  annotation

237
        /** @scrutinizer ignore-call */ 
238
        $instance = $this->newRelatedInstance($related);
Loading history...
238
239
        $ownerKey = $ownerKey ?: $instance->getKeyName();
240
241
        return $this->newBelongsToJson(
242
            $instance->newQuery(),
243
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\EloquentJson...ns\HasJsonRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $child of Staudenmeir\EloquentJson...ips::newBelongsToJson(). ( Ignorable by Annotation )

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

243
            /** @scrutinizer ignore-type */ $this,
Loading history...
244
            $foreignKey,
245
            $ownerKey,
246
            $relation
247
        );
248
    }
249
250
    /**
251
     * Instantiate a new BelongsToJson relationship.
252
     *
253
     * @param \Illuminate\Database\Eloquent\Builder $query
254
     * @param \Illuminate\Database\Eloquent\Model $child
255
     * @param string|array $foreignKey
256
     * @param string|array $ownerKey
257
     * @param string $relation
258
     * @return \Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson
259
     */
260
    protected function newBelongsToJson(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)
261
    {
262
        return new BelongsToJson($query, $child, $foreignKey, $ownerKey, $relation);
0 ignored issues
show
Bug introduced by
It seems like $foreignKey can also be of type array; however, parameter $foreignKey of Staudenmeir\EloquentJson...gsToJson::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

262
        return new BelongsToJson($query, $child, /** @scrutinizer ignore-type */ $foreignKey, $ownerKey, $relation);
Loading history...
Bug introduced by
It seems like $ownerKey can also be of type array; however, parameter $ownerKey of Staudenmeir\EloquentJson...gsToJson::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

262
        return new BelongsToJson($query, $child, $foreignKey, /** @scrutinizer ignore-type */ $ownerKey, $relation);
Loading history...
263
    }
264
265
    /**
266
     * Define a one-to-many JSON relationship.
267
     *
268
     * @param string $related
269
     * @param string|array $foreignKey
270
     * @param string|array $localKey
271
     * @return \Staudenmeir\EloquentJsonRelations\Relations\HasManyJson
272
     */
273
    public function hasManyJson($related, $foreignKey, $localKey = null)
274
    {
275
        /** @var \Illuminate\Database\Eloquent\Model $instance */
276
        $instance = $this->newRelatedInstance($related);
277
278
        if (is_array($foreignKey)) {
279
            $foreignKey = array_map(
280
                fn (string $key) => "{$instance->getTable()}.$key",
281
                (array) $foreignKey
282
            );
283
        } else {
284
            $foreignKey = "{$instance->getTable()}.$foreignKey";
285
        }
286
287
        $localKey = $localKey ?: $this->getKeyName();
0 ignored issues
show
Bug introduced by
It seems like getKeyName() 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

287
        $localKey = $localKey ?: $this->/** @scrutinizer ignore-call */ getKeyName();
Loading history...
288
289
        return $this->newHasManyJson(
290
            $instance->newQuery(),
291
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\EloquentJson...ns\HasJsonRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\EloquentJson...ships::newHasManyJson(). ( Ignorable by Annotation )

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

291
            /** @scrutinizer ignore-type */ $this,
Loading history...
292
            $foreignKey,
293
            $localKey
294
        );
295
    }
296
297
    /**
298
     * Instantiate a new HasManyJson relationship.
299
     *
300
     * @param \Illuminate\Database\Eloquent\Builder $query
301
     * @param \Illuminate\Database\Eloquent\Model $parent
302
     * @param string|array $foreignKey
303
     * @param string|array $localKey
304
     * @return \Staudenmeir\EloquentJsonRelations\Relations\HasManyJson
305
     */
306
    protected function newHasManyJson(Builder $query, Model $parent, $foreignKey, $localKey)
307
    {
308
        return new HasManyJson($query, $parent, $foreignKey, $localKey);
0 ignored issues
show
Bug introduced by
It seems like $localKey can also be of type array; however, parameter $localKey of Staudenmeir\EloquentJson...ManyJson::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

308
        return new HasManyJson($query, $parent, $foreignKey, /** @scrutinizer ignore-type */ $localKey);
Loading history...
Bug introduced by
It seems like $foreignKey can also be of type array; however, parameter $foreignKey of Staudenmeir\EloquentJson...ManyJson::__construct() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

308
        return new HasManyJson($query, $parent, /** @scrutinizer ignore-type */ $foreignKey, $localKey);
Loading history...
309
    }
310
311
    /**
312
     * Define a one-to-one JSON relationship.
313
     *
314
     * @param string $related
315
     * @param string|array $foreignKey
316
     * @param string|array|null $localKey
317
     * @return \Staudenmeir\EloquentJsonRelations\Relations\HasOneJson
318
     */
319
    public function hasOneJson(string $related, string|array $foreignKey, string|array|null $localKey = null): HasOneJson
320
    {
321
        /** @var \Illuminate\Database\Eloquent\Model $instance */
322
        $instance = $this->newRelatedInstance($related);
323
324
        if (is_array($foreignKey)) {
0 ignored issues
show
introduced by
The condition is_array($foreignKey) is always true.
Loading history...
325
            $foreignKey = array_map(
326
                fn (string $key) => "{$instance->getTable()}.$key",
327
                $foreignKey
328
            );
329
        } else {
330
            $foreignKey = "{$instance->getTable()}.$foreignKey";
331
        }
332
333
        $localKey = $localKey ?: $this->getKeyName();
334
335
        return $this->newHasOneJson(
336
            $instance->newQuery(),
337
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\EloquentJson...ns\HasJsonRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\EloquentJson...nships::newHasOneJson(). ( Ignorable by Annotation )

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

337
            /** @scrutinizer ignore-type */ $this,
Loading history...
338
            $foreignKey,
339
            $localKey
340
        );
341
    }
342
343
    /**
344
     * Instantiate a new HasOneJson relationship.
345
     *
346
     * @param \Illuminate\Database\Eloquent\Builder $query
347
     * @param \Illuminate\Database\Eloquent\Model $parent
348
     * @param string|array $foreignKey
349
     * @param string|array $localKey
350
     * @return \Staudenmeir\EloquentJsonRelations\Relations\HasOneJson
351
     */
352
    protected function newHasOneJson(Builder $query, Model $parent, string|array $foreignKey, string|array $localKey): HasOneJson
353
    {
354
        return new HasOneJson($query, $parent, $foreignKey, $localKey);
0 ignored issues
show
Bug introduced by
$foreignKey of type array is incompatible with the type string expected by parameter $foreignKey of Staudenmeir\EloquentJson...sOneJson::__construct(). ( Ignorable by Annotation )

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

354
        return new HasOneJson($query, $parent, /** @scrutinizer ignore-type */ $foreignKey, $localKey);
Loading history...
Bug introduced by
$localKey of type array is incompatible with the type string expected by parameter $localKey of Staudenmeir\EloquentJson...sOneJson::__construct(). ( Ignorable by Annotation )

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

354
        return new HasOneJson($query, $parent, $foreignKey, /** @scrutinizer ignore-type */ $localKey);
Loading history...
355
    }
356
357
    /**
358
     * Define has-many-through JSON relationship.
359
     *
360
     * @param string $related
361
     * @param string $through
362
     * @param string|\Staudenmeir\EloquentJsonRelations\JsonKey $firstKey
363
     * @param string|null $secondKey
364
     * @param string|null $localKey
365
     * @param string|\Staudenmeir\EloquentJsonRelations\JsonKey|null $secondLocalKey
366
     * @return \Staudenmeir\EloquentHasManyDeep\HasManyDeep
367
     */
368
    public function hasManyThroughJson(
369
        string $related,
370
        string $through,
371
        string|JsonKey $firstKey,
372
        ?string $secondKey = null,
373
        ?string $localKey = null,
374
        string|JsonKey|null $secondLocalKey = null
375
    ) {
376
        $relationships = [];
377
378
        $through = new $through();
379
380
        if ($firstKey instanceof JsonKey) {
381
            $relationships[] = $this->hasManyJson($through, $firstKey, $localKey);
0 ignored issues
show
Bug introduced by
$through of type object is incompatible with the type string expected by parameter $related of Staudenmeir\EloquentJson...ionships::hasManyJson(). ( Ignorable by Annotation )

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

381
            $relationships[] = $this->hasManyJson(/** @scrutinizer ignore-type */ $through, $firstKey, $localKey);
Loading history...
382
383
            $relationships[] = $through->hasMany($related, $secondKey, $secondLocalKey);
384
        } else {
385
            if (!method_exists($through, 'belongsToJson')) {
386
                //@codeCoverageIgnoreStart
387
                $message = 'Please add the HasJsonRelationships trait to the ' . $through::class . ' model.';
388
389
                throw new RuntimeException($message);
390
                // @codeCoverageIgnoreEnd
391
            }
392
393
            $relationships[] = $this->hasMany($through, $firstKey, $localKey);
0 ignored issues
show
Bug introduced by
The method hasMany() does not exist on Staudenmeir\EloquentJson...ns\HasJsonRelationships. Did you maybe mean hasManyThroughJson()? ( Ignorable by Annotation )

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

393
            /** @scrutinizer ignore-call */ 
394
            $relationships[] = $this->hasMany($through, $firstKey, $localKey);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
394
395
            $relationships[] = $through->belongsToJson($related, $secondLocalKey, $secondKey);
396
        }
397
398
        $hasManyThroughJson = $this->newHasManyThroughJson($relationships);
399
400
        $jsonKey = $firstKey instanceof JsonKey ? $firstKey : $secondLocalKey;
401
402
        if (str_contains($jsonKey, '[]->')) {
0 ignored issues
show
Bug introduced by
It seems like $jsonKey can also be of type null; however, parameter $haystack of str_contains() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

402
        if (str_contains(/** @scrutinizer ignore-type */ $jsonKey, '[]->')) {
Loading history...
403
            $this->addHasManyThroughJsonPivotRelationship($hasManyThroughJson, $relationships, $through);
404
        }
405
406
        return $hasManyThroughJson;
407
    }
408
409
    /**
410
     * Add the pivot relationship to the has-many-through JSON relationship.
411
     *
412
     * @param \Staudenmeir\EloquentHasManyDeep\HasManyDeep $hasManyThroughJson
413
     * @param \Illuminate\Database\Eloquent\Relations\Relation[] $relationships
414
     * @param \Illuminate\Database\Eloquent\Model $through
415
     * @return void
416
     */
417
    protected function addHasManyThroughJsonPivotRelationship(
418
        $hasManyThroughJson,
419
        array $relationships,
420
        Model $through
421
    ): void {
422
        if ($relationships[0] instanceof HasManyJson) {
423
            /** @var \Staudenmeir\EloquentJsonRelations\Relations\HasManyJson $hasManyJson */
424
            $hasManyJson = $relationships[0];
425
426
            $postGetCallback = function (Collection $models) use ($hasManyJson, $relationships) {
0 ignored issues
show
Unused Code introduced by
The import $relationships is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
427
                if (isset($models[0]->laravel_through_key)) {
428
                    $hasManyJson->hydratePivotRelation(
429
                        $models,
430
                        $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\EloquentJson...ns\HasJsonRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\EloquentJson...:hydratePivotRelation(). ( Ignorable by Annotation )

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

430
                        /** @scrutinizer ignore-type */ $this,
Loading history...
431
                        fn (Model $model) => json_decode($model->laravel_through_key, true)
432
                    );
433
                }
434
            };
435
436
            $localKey = $this->{$hasManyJson->getLocalKeyName()};
437
438
            if (!is_null($localKey)) {
439
                $hasManyThroughJson->withPostGetCallbacks([$postGetCallback]);
440
            }
441
442
            $hasManyThroughJson->withCustomEagerMatchingCallback(
443
                function (array $models, Collection $results, string $relation) use ($hasManyJson, $hasManyThroughJson) {
0 ignored issues
show
Unused Code introduced by
The import $hasManyThroughJson is not used and could be removed.

This check looks for imports that have been defined, but are not used in the scope.

Loading history...
444
                    foreach ($models as $model) {
445
                        $hasManyJson->hydratePivotRelation(
446
                            $model->$relation,
447
                            $model,
448
                            fn (Model $model) => json_decode($model->laravel_through_key, true)
449
                        );
450
                    }
451
452
                    return $models;
453
                }
454
            );
455
        } else {
456
            /** @var \Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson $belongsToJson */
457
            $belongsToJson = $relationships[1];
458
459
            $path = $belongsToJson->getForeignKeyPath();
460
461
            $postProcessor = function (Model $model, array $attributes) use ($belongsToJson, $path) {
462
                $records = json_decode($attributes[$path], true);
463
464
                return $belongsToJson->pivotAttributes($model, $model, $records);
465
            };
466
467
            $hasManyThroughJson->withPivot(
468
                $through->getTable(),
469
                [$path],
470
                accessor: 'pivot',
471
                postProcessor: $postProcessor
472
            );
473
        }
474
    }
475
476
    /**
477
     * Instantiate a new HasManyThroughJson relationship.
478
     *
479
     * @param \Illuminate\Database\Eloquent\Relations\Relation[] $relationships
480
     * @return \Staudenmeir\EloquentHasManyDeep\HasManyDeep
481
     */
482
    protected function newHasManyThroughJson(array $relationships)
483
    {
484
        if (!method_exists($this, 'hasManyDeepFromRelations')) {
485
            //@codeCoverageIgnoreStart
486
            $message = 'Please install staudenmeir/eloquent-has-many-deep and add the HasRelationships trait to this model.';
487
488
            throw new RuntimeException($message);
489
            // @codeCoverageIgnoreEnd
490
        }
491
492
        return $this->hasManyDeepFromRelations($relationships);
493
    }
494
}
495