IsRecursiveRelation::addEagerExpression()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 9
c 0
b 0
f 0
dl 0
loc 19
ccs 11
cts 11
cp 1
rs 9.9666
cc 4
nc 8
nop 2
crap 4
1
<?php
2
3
namespace Staudenmeir\LaravelAdjacencyList\Eloquent\Relations\Graph\Traits;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Query\Expression;
9
10
trait IsRecursiveRelation
11
{
12
    /**
13
     * Whether to include the parent model.
14
     *
15
     * @var bool
16
     */
17
    protected bool $andSelf;
18
19
    /**
20
     * Create a new recursive pivot relationship instance.
21
     *
22
     * @param \Illuminate\Database\Eloquent\Builder $query
23
     * @param \Illuminate\Database\Eloquent\Model $parent
24
     * @param string $table
25
     * @param string $foreignPivotKey
26
     * @param string $relatedPivotKey
27
     * @param string $parentKey
28
     * @param string $relatedKey
29
     * @param bool $andSelf
30
     * @return void
31
     */
32 262
    public function __construct(
33
        Builder $query,
34
        Model $parent,
35
        string $table,
36
        string $foreignPivotKey,
37
        string $relatedPivotKey,
38
        string $parentKey,
39
        string $relatedKey,
40
        bool $andSelf
41
    ) {
42 262
        $this->andSelf = $andSelf;
43
44 262
        parent::__construct($query, $parent, $table, $foreignPivotKey, $relatedPivotKey, $parentKey, $relatedKey);
45
    }
46
47
    /**
48
     * Add the recursive expression for an eager load of the relation.
49
     *
50
     * @param array $models
51
     * @param string $column
52
     * @return void
53
     */
54 88
    protected function addEagerExpression(array $models, string $column): void
55
    {
56 88
        $whereIn = $this->whereInMethod($this->parent, $this->parentKey);
0 ignored issues
show
Bug introduced by
The method whereInMethod() does not exist on Staudenmeir\LaravelAdjac...its\IsRecursiveRelation. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

56
        /** @scrutinizer ignore-call */ 
57
        $whereIn = $this->whereInMethod($this->parent, $this->parentKey);
Loading history...
57
58 88
        $keys = $this->getKeys($models, $this->parentKey);
0 ignored issues
show
Bug introduced by
The method getKeys() does not exist on Staudenmeir\LaravelAdjac...its\IsRecursiveRelation. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

58
        /** @scrutinizer ignore-call */ 
59
        $keys = $this->getKeys($models, $this->parentKey);
Loading history...
59
60 88
        $constraint = function (Builder $query) use ($whereIn, $column, $keys) {
61 88
            $query->$whereIn($column, $keys);
62 88
        };
63
64 88
        $supportsUnion = $this->query->getExpressionGrammar()->supportsUnionInRecursiveExpression();
65
66 88
        $union = $this->andSelf || !$supportsUnion ? 'unionAll' : 'union';
67
68 88
        if (!$supportsUnion) {
69 8
            $this->query->getQuery()->distinct();
70
        }
71
72 88
        $this->addExpression($constraint, null, null, $union);
0 ignored issues
show
Bug introduced by
The method addExpression() does not exist on Staudenmeir\LaravelAdjac...its\IsRecursiveRelation. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

72
        $this->/** @scrutinizer ignore-call */ 
73
               addExpression($constraint, null, null, $union);
Loading history...
73
    }
74
75
    /**
76
     * Build model dictionary.
77
     *
78
     * @param \Illuminate\Database\Eloquent\Collection $results
79
     * @return array
80
     */
81 32
    protected function buildDictionary(Collection $results)
82
    {
83 32
        return $results->mapToDictionary(function (Model $result) {
84 32
            return [$result->getFirstPathSegment() => $result];
85 32
        })->all();
86
    }
87
88
    /**
89
     * Handle dynamic method calls to the relationship.
90
     *
91
     * @param string $method
92
     * @param array $parameters
93
     * @return mixed
94
     */
95 134
    public function __call($method, $parameters)
96
    {
97 134
        $methods = ['update', 'increment', 'decrement', 'delete', 'forceDelete'];
98
99 134
        if (in_array($method, $methods)) {
100 8
            $expression = $this->query->getQuery()->from;
101
102 8
            $table = $this->parent->getTable();
103
104 8
            $this->query->getQuery()->from = $table;
105
106 8
            $this->query->getModel()->setTable($table);
107
108 8
            $keys = $this->query->getQuery()->newQuery()->from($expression)->select($this->parentKey);
109
110 8
            return $this->query->whereIn($this->parentKey, $keys)->$method(...$parameters);
111
        }
112
113 126
        return parent::__call($method, $parameters);
114
    }
115
116
    /**
117
     * Replace table hash with expression name in self-relation aggregate queries.
118
     *
119
     * @param \Illuminate\Database\Eloquent\Builder $query
120
     * @param \Illuminate\Database\Query\Expression $expression
121
     * @return \Illuminate\Database\Query\Expression
122
     */
123 18
    protected function replaceTableHash(Builder $query, Expression $expression): Expression
124
    {
125 18
        return new Expression(
126 18
            str_replace(
127 18
                $query->getGrammar()->wrap(
0 ignored issues
show
Bug introduced by
It seems like $query->getGrammar()->wr...lationCountHash(false)) can also be of type Illuminate\Database\Eloquent\Builder and Illuminate\Database\Query\Grammars\Grammar; however, parameter $search of str_replace() does only seem to accept string|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

127
                /** @scrutinizer ignore-type */ $query->getGrammar()->wrap(
Loading history...
128 18
                    $this->getRelationCountHash(false)
0 ignored issues
show
Bug introduced by
The method getRelationCountHash() does not exist on Staudenmeir\LaravelAdjac...its\IsRecursiveRelation. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

128
                    $this->/** @scrutinizer ignore-call */ 
129
                           getRelationCountHash(false)
Loading history...
129 18
                ),
130 18
                $query->getGrammar()->wrap(
0 ignored issues
show
Bug introduced by
It seems like $query->getGrammar()->wr...)->getExpressionName()) can also be of type Illuminate\Database\Eloquent\Builder and Illuminate\Database\Query\Grammars\Grammar; however, parameter $replace of str_replace() does only seem to accept string|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

130
                /** @scrutinizer ignore-type */ $query->getGrammar()->wrap(
Loading history...
131 18
                    $query->getModel()->getExpressionName()
132 18
                ),
133 18
                $expression->getValue(
134 18
                    $query->getGrammar()
0 ignored issues
show
Bug introduced by
It seems like $query->getGrammar() can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $grammar of Illuminate\Database\Query\Expression::getValue() does only seem to accept Illuminate\Database\Grammar, 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

134
                    /** @scrutinizer ignore-type */ $query->getGrammar()
Loading history...
135 18
                )
136 18
            )
137 18
        );
138
    }
139
140
    /**
141
     * Get the select columns for the relation query.
142
     *
143
     * @param array $columns
144
     * @return array
145
     */
146 230
    protected function shouldSelect(array $columns = ['*'])
147
    {
148 230
        return $columns;
149
    }
150
}
151