HandlesBindings::setBindings()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.7085

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 13
ccs 4
cts 7
cp 0.5714
crap 3.7085
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LaravelFreelancerNL\Aranguent\Query\Concerns;
6
7
use Illuminate\Database\Query\Expression;
8
use Illuminate\Database\Query\Builder as IlluminateQueryBuilder;
9
use InvalidArgumentException;
10
use LaravelFreelancerNL\Aranguent\Query\Grammar;
11
12
trait HandlesBindings
13
{
14
    /**
15
     * Add a binding to the query.
16
     *
17
     * @param mixed $value
18
     * @param string $type
19
     * @return IlluminateQueryBuilder
20
     *
21
     * @throws \InvalidArgumentException
22
     */
23 295
    public function addBinding($value, $type = 'where')
24
    {
25 295
        if (!array_key_exists($type, $this->bindings)) {
26
            throw new InvalidArgumentException("Invalid binding type: {$type}.");
27
        }
28
29 295
        $bindVariable = $this->generateBindVariable($type);
30 295
        $this->bindings[$type][$bindVariable] = $this->castBinding($value);
0 ignored issues
show
Bug Best Practice introduced by
The property bindings does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
Bug introduced by
It seems like castBinding() 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

30
        /** @scrutinizer ignore-call */ 
31
        $this->bindings[$type][$bindVariable] = $this->castBinding($value);
Loading history...
31
32 295
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...oncerns\HandlesBindings which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
33
    }
34
35 292
    protected function bindValue(mixed $value, string $type = 'where'): mixed
36
    {
37
        assert($this->grammar instanceof Grammar);
38
39 292
        if ($this->grammar->isBind($value)) {
40
            return $value;
41
        }
42 292
        if (!$value instanceof Expression && !$this->isReference($value)) {
0 ignored issues
show
Bug introduced by
It seems like isReference() 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
        if (!$value instanceof Expression && !$this->/** @scrutinizer ignore-call */ isReference($value)) {
Loading history...
43 291
            $this->addBinding($value, $type);
44 291
            $value = $this->replaceValueWithBindVariable($type);
45
        }
46
47 292
        return $value;
48
    }
49
50
    /**
51
     * Remove all of the expressions from a list of bindings.
52
     *
53
     * @param array<mixed> $bindings
54
     * @return array<mixed>
55
     */
56 57
    public function cleanBindings(array $bindings)
57
    {
58 57
        return collect($bindings)
0 ignored issues
show
Bug introduced by
$bindings of type array<mixed,mixed> is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

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

58
        return collect(/** @scrutinizer ignore-type */ $bindings)
Loading history...
59 57
            ->reject(function ($binding) {
60 56
                return $binding instanceof Expression;
61 57
            })
62 57
            ->map([$this, 'castBinding'])
63 57
            ->all();
64
    }
65
66 295
    protected function generateBindVariable(string $type = 'where'): string
67
    {
68 295
        return $this->queryId . '_' . $type . '_' . (count($this->bindings[$type]) + 1);
69
    }
70
71 291
    protected function getLastBindVariable(string $type = 'where'): string
72
    {
73 291
        return array_key_last($this->bindings[$type]);
0 ignored issues
show
Bug Best Practice introduced by
The expression return array_key_last($this->bindings[$type]) could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
74
    }
75
76
    /**
77
     * @param IlluminateQueryBuilder $query
78
     * @param string|null $type
79
     * @return void
80
     */
81 89
    public function importBindings($query, ?string $type = null): void
82
    {
83 89
        if ($type) {
84
            $this->bindings[$type] = array_merge($this->bindings[$type], $query->bindings[$type]);
0 ignored issues
show
Bug Best Practice introduced by
The property bindings does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
85
            return;
86
        }
87 89
        $this->bindings = array_merge_recursive($this->bindings, $query->bindings);
88
    }
89
90
    /**
91
     * Set the bindings on the query builder.
92
     *
93
     * @param  array<mixed>  $bindings
94
     * @param  string  $type
95
     * @return $this
96
     *
97
     * @throws \InvalidArgumentException
98
     */
99 2
    public function setBindings(array $bindings, $type = 'where')
100
    {
101 2
        if (!array_key_exists($type, $this->bindings)) {
102
            throw new InvalidArgumentException("Invalid binding type: {$type}.");
103
        }
104
105 2
        if (empty($bindings)) {
106 2
            return $this;
107
        }
108
109
        $this->bindings[$type] = array_merge($this->bindings[$type], $bindings);
0 ignored issues
show
Bug Best Practice introduced by
The property bindings does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
110
111
        return $this;
112
    }
113
114 291
    protected function replaceValueWithBindVariable(string $type = 'where'): string
115
    {
116 291
        return '@' . $this->getLastBindVariable($type);
117
    }
118
}
119