Failed Conditions
Push — refactor/improve-static-analys... ( ba8000...c6edde )
by Bas
14:06
created

BuildsSelects::select()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 9
c 1
b 0
f 0
nc 6
nop 1
dl 0
loc 17
rs 9.6111
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LaravelFreelancerNL\Aranguent\Query\Concerns;
6
7
use Exception;
8
use Illuminate\Database\Query\Builder as IlluminateQueryBuilder;
9
use Illuminate\Database\Query\Expression;
10
use InvalidArgumentException;
11
use LaravelFreelancerNL\Aranguent\Query\Grammar;
12
13
/**
14
 * @method isQueryable(mixed $column)
15
 */
16
trait BuildsSelects
17
{
18
    /**
19
     * Set the table which the query is targeting.
20
     *
21
     * @param \Closure|IlluminateQueryBuilder|string $table
22
     * @param string|null $as
23
     * @return IlluminateQueryBuilder
24
     */
25
    public function from($table, $as = null)
26
    {
27
        if ($this->isQueryable($table)) {
28
            return $this->fromSub($table, $as);
0 ignored issues
show
Bug introduced by
The method fromSub() does not exist on LaravelFreelancerNL\Aran...\Concerns\BuildsSelects. Did you maybe mean from()? ( Ignorable by Annotation )

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

28
            return $this->/** @scrutinizer ignore-call */ fromSub($table, $as);

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...
29
        }
30
        $this->registerTableAlias($table, $as);
0 ignored issues
show
Bug introduced by
It seems like registerTableAlias() 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
        $this->/** @scrutinizer ignore-call */ 
31
               registerTableAlias($table, $as);
Loading history...
31
32
        $this->from = $table;
0 ignored issues
show
Bug Best Practice introduced by
The property from does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
33
34
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...\Concerns\BuildsSelects which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
35
    }
36
37
    /**
38
     * Set the columns to be selected.
39
     *
40
     * @param array<mixed>|mixed $columns
41
     * @return IlluminateQueryBuilder
42
     * @throws Exception
43
     */
44
    public function select($columns = ['*']): IlluminateQueryBuilder
45
    {
46
        $this->columns = [];
0 ignored issues
show
Bug Best Practice introduced by
The property columns does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
47
        $this->bindings['select'] = [];
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...
48
49
        $columns = is_array($columns) ? $columns : func_get_args();
50
51
        foreach ($columns as $as => $column) {
52
            if (is_string($as) && $this->isQueryable($column)) {
53
                $this->selectSub($column, $as);
54
                continue;
55
            }
56
57
            $this->addColumns([$as => $column]);
58
        }
59
60
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...\Concerns\BuildsSelects which is incompatible with the type-hinted return Illuminate\Database\Query\Builder.
Loading history...
61
    }
62
63
    /**
64
     * Add a subselect expression to the query.
65
     *
66
     * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|string $query
67
     * @param string $as
68
     * @return $this
69
     *
70
     * @throws \InvalidArgumentException
71
     * @throws Exception
72
     */
73
    public function selectSub($query, $as)
74
    {
75
        [$query] = $this->createSub($query, true);
0 ignored issues
show
Bug introduced by
It seems like createSub() 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
        /** @scrutinizer ignore-call */ 
76
        [$query] = $this->createSub($query, true);
Loading history...
76
77
        $this->set($as, new Expression($query), 'postIterationVariables');
0 ignored issues
show
Bug introduced by
It seems like set() 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

77
        $this->/** @scrutinizer ignore-call */ 
78
               set($as, new Expression($query), 'postIterationVariables');
Loading history...
78
79
        $this->addColumns([$as]);
80
81
        return $this;
82
    }
83
84
    /**
85
     * Add a new select column to the query.
86
     *
87
     * @param array|mixed $column
88
     * @return $this
89
     */
90
    public function addSelect($column)
91
    {
92
        $columns = is_array($column) ? $column : func_get_args();
93
94
        $this->addColumns($columns);
95
96
        return $this;
97
    }
98
99
    /**
100
     * @param array<mixed> $columns
101
     */
102
    protected function addColumns(array $columns): void
103
    {
104
        foreach ($columns as $as => $column) {
105
            if (is_string($as) && $this->isQueryable($column)) {
106
                if (is_null($this->columns)) {
107
                    $this->select($this->from . '.*');
108
                }
109
110
                $this->selectSub($column, $as);
111
112
                continue;
113
            }
114
115
            if (is_string($as)) {
116
                $this->columns[$as] = $column;
0 ignored issues
show
Bug Best Practice introduced by
The property columns does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
117
118
                continue;
119
            }
120
121
            $this->columns[] = $column;
122
        }
123
    }
124
125
    /**
126
     * Add an "order by" clause to the query.
127
     *
128
     * @param \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder|\Illuminate\Contracts\Database\Query\Expression|string $column
129
     * @param string $direction
130
     * @return $this
131
     *
132
     * @throws \InvalidArgumentException
133
     */
134
    public function orderBy($column, $direction = 'asc')
135
    {
136
        if ($this->isQueryable($column)) {
137
            [$query, $bindings] = $this->createSub($column);
138
139
            $column = new Expression('(' . $query . ')');
140
141
            $this->addBinding($bindings, $this->unions ? 'unionOrder' : 'order');
0 ignored issues
show
Bug introduced by
It seems like addBinding() 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

141
            $this->/** @scrutinizer ignore-call */ 
142
                   addBinding($bindings, $this->unions ? 'unionOrder' : 'order');
Loading history...
142
        }
143
144
        $direction = strtoupper($direction);
145
146
        if (!in_array($direction, ['ASC', 'DESC'], true)) {
147
            throw new InvalidArgumentException('Order direction must be "asc" or "desc".');
148
        }
149
150
        $this->{$this->unions ? 'unionOrders' : 'orders'}[] = [
151
            'column' => $column,
152
            'direction' => $direction,
153
        ];
154
155
        return $this;
156
    }
157
158
    public function orderByRaw($sql, $bindings = [])
159
    {
160
        $type = 'Raw';
161
162
        $sql = new Expression($sql);
163
164
        $this->{$this->unions ? 'unionOrders' : 'orders'}[] = compact('type', 'sql');
165
166
        if (!isset($this->bindings[$this->unions ? 'unionOrders' : 'orders'])) {
167
            $this->bindings[$this->unions ? 'unionOrders' : 'orders'] = $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...
168
169
            return $this;
170
        }
171
172
        $this->bindings[$this->unions ? 'unionOrders' : 'orders'] = array_merge(
173
            $this->bindings[$this->unions ? 'unionOrders' : 'orders'],
174
            $bindings
175
        );
176
177
        return $this;
178
    }
179
180
    /**
181
     * Put the query's results in random order.
182
     *
183
     * @param string $seed
184
     * @return $this
185
     */
186
    public function inRandomOrder($seed = '')
187
    {
188
        assert($this->grammar instanceof Grammar);
189
190
        // ArangoDB's random function doesn't accept a seed.
191
        unset($seed);
192
193
        return $this->orderByRaw($this->grammar->compileRandom());
194
    }
195
196
    /**
197
     * Add a union statement to the query.
198
     *
199
     * @param  \Closure|\Illuminate\Database\Query\Builder|\Illuminate\Database\Eloquent\Builder  $query
200
     * @param  bool  $all
201
     * @return $this
202
     */
203
    public function union($query, $all = false)
204
    {
205
        if ($query instanceof \Closure) {
206
            $query($query = $this->newQuery());
0 ignored issues
show
Bug introduced by
It seems like newQuery() 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

206
            $query($query = $this->/** @scrutinizer ignore-call */ newQuery());
Loading history...
207
        }
208
        $this->importBindings($query);
0 ignored issues
show
Bug introduced by
It seems like importBindings() 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

208
        $this->/** @scrutinizer ignore-call */ 
209
               importBindings($query);
Loading history...
209
        $this->unions[] = compact('query', 'all');
0 ignored issues
show
Bug Best Practice introduced by
The property unions does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
210
211
        return $this;
212
    }
213
}
214