matchResultsForDeepRelationship()   A
last analyzed

Complexity

Conditions 6
Paths 7

Size

Total Lines 25
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 11
nc 7
nop 4
dl 0
loc 25
rs 9.2222
c 1
b 0
f 0
1
<?php
2
3
namespace Staudenmeir\EloquentJsonRelations\Relations\Traits\Concatenation;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Database\Query\JoinClause;
8
9
trait IsConcatenableBelongsToJsonRelation
10
{
11
    use IsConcatenableRelation;
12
13
    /**
14
     * Append the relation's through parents, foreign and local keys to a deep relationship.
15
     *
16
     * @param \Illuminate\Database\Eloquent\Model[] $through
17
     * @param array $foreignKeys
18
     * @param array $localKeys
19
     * @param int $position
20
     * @return array
21
     */
22
    public function appendToDeepRelationship(array $through, array $foreignKeys, array $localKeys, int $position): array
23
    {
24
        if ($position === 0) {
25
            $foreignKeys[] = $this->ownerKey;
26
27
            $localKeys[] = function (Builder $query, ?Builder $parentQuery = null) {
28
                if ($parentQuery) {
29
                    $this->getRelationExistenceQuery($this->query, $parentQuery);
0 ignored issues
show
Bug introduced by
It seems like getRelationExistenceQuery() 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

29
                    $this->/** @scrutinizer ignore-call */ 
30
                           getRelationExistenceQuery($this->query, $parentQuery);
Loading history...
30
                }
31
32
                $this->mergeWhereConstraints($query, $this->query);
33
            };
34
        } else {
35
            $foreignKeys[] = function (Builder $query, JoinClause $join) {
36
                $ownerKey = $this->query->qualifyColumn($this->ownerKey);
37
38
                [$sql, $bindings] = $this->relationExistenceQueryOwnerKey($query, $ownerKey);
0 ignored issues
show
Bug introduced by
It seems like relationExistenceQueryOwnerKey() 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

38
                /** @scrutinizer ignore-call */ 
39
                [$sql, $bindings] = $this->relationExistenceQueryOwnerKey($query, $ownerKey);
Loading history...
39
40
                $query->addBinding($bindings, 'join');
41
42
                $this->whereJsonContainsOrMemberOf(
0 ignored issues
show
Bug introduced by
It seems like whereJsonContainsOrMemberOf() 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

42
                $this->/** @scrutinizer ignore-call */ 
43
                       whereJsonContainsOrMemberOf(
Loading history...
43
                    $join,
44
                    $this->getQualifiedPath(),
0 ignored issues
show
Bug introduced by
It seems like getQualifiedPath() 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

44
                    $this->/** @scrutinizer ignore-call */ 
45
                           getQualifiedPath(),
Loading history...
45
                    $query->getQuery()->connection->raw($sql)
46
                );
47
            };
48
49
            $localKeys[] = null;
50
        }
51
52
        return [$through, $foreignKeys, $localKeys];
53
    }
54
55
    /**
56
     * Match the eagerly loaded results for a deep relationship to their parents.
57
     *
58
     * @param array $models
59
     * @param \Illuminate\Database\Eloquent\Collection $results
60
     * @param string $relation
61
     * @param string $type
62
     * @return array
63
     */
64
    public function matchResultsForDeepRelationship(
65
        array $models,
66
        Collection $results,
67
        string $relation,
68
        string $type = 'many'
69
    ): array {
70
        $dictionary = $this->buildDictionaryForDeepRelationship($results);
71
72
        foreach ($models as $model) {
73
            $matches = [];
74
75
            foreach ($this->getForeignKeys($model) as $id) {
0 ignored issues
show
Bug introduced by
It seems like getForeignKeys() 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

75
            foreach ($this->/** @scrutinizer ignore-call */ getForeignKeys($model) as $id) {
Loading history...
76
                if (isset($dictionary[$id])) {
77
                    $matches = array_merge($matches, $dictionary[$id]);
78
                }
79
            }
80
81
            $value = $type === 'one'
82
                ? (reset($matches) ?: null)
83
                : $this->related->newCollection($matches);
84
85
            $model->setRelation($relation, $value);
86
        }
87
88
        return $models;
89
    }
90
91
    /**
92
     * Build the model dictionary for a deep relation.
93
     *
94
     * @param \Illuminate\Database\Eloquent\Collection $results
95
     * @return array
96
     */
97
    protected function buildDictionaryForDeepRelationship(Collection $results): array
98
    {
99
        $dictionary = [];
100
101
        foreach ($results as $result) {
102
            $dictionary[$result->laravel_through_key][] = $result;
103
        }
104
105
        return $dictionary;
106
    }
107
}
108