Issues (364)

src/Query/Concerns/HandlesBindings.php (8 issues)

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...
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
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
$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