Passed
Push — dependabot/github_actions/depe... ( d1016c )
by
unknown
11:16
created

BuildsWhereClauses::where()   B

Complexity

Conditions 9
Paths 9

Size

Total Lines 69
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 27
CRAP Score 9.0036

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 25
c 2
b 0
f 0
dl 0
loc 69
ccs 27
cts 28
cp 0.9643
rs 8.0555
cc 9
nc 9
nop 4
crap 9.0036

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Query\Concerns;
4
5
use Closure;
6
use Illuminate\Database\Query\Builder as IlluminateQueryBuilder;
7
use LaravelFreelancerNL\Aranguent\Query\Builder;
8
use LaravelFreelancerNL\FluentAQL\QueryBuilder;
9
10
trait BuildsWhereClauses
11
{
12
    /**
13
     * Add a basic where clause to the query.
14
     *
15
     * @param  Closure|string|array|QueryBuilder  $column
16
     * @param  mixed  $operator
17
     * @param  mixed  $value
18
     * @param  string  $boolean
19
     * @return Builder
20
     */
21 84
    public function where($column, $operator = null, $value = null, $boolean = 'and')
22
    {
23
        // If the column is an array, we will assume it is an array of key-value pairs
24
        // and can add them each as a where clause. We will maintain the boolean we
25
        // received when the method was called and pass it into the nested where.
26 84
        if (is_array($column)) {
27 20
            return $this->addArrayOfWheres($column, $boolean);
0 ignored issues
show
Bug introduced by
It seems like addArrayOfWheres() 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

27
            return $this->/** @scrutinizer ignore-call */ addArrayOfWheres($column, $boolean);
Loading history...
28
        }
29
30
        // Here we will make some assumptions about the operator. If only 2 values are
31
        // passed to the method, we will assume that the operator is an equals sign
32
        // and keep going. Otherwise, we'll require the operator to be passed in.
33 84
        [$value, $operator] = $this->prepareValueAndOperator(
0 ignored issues
show
Bug introduced by
It seems like prepareValueAndOperator() 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

33
        /** @scrutinizer ignore-call */ 
34
        [$value, $operator] = $this->prepareValueAndOperator(
Loading history...
34 84
            $value,
35 84
            $operator,
36 84
            func_num_args() === 2
37 84
        );
38
39
        // If the columns is actually a Closure instance, we will assume the developer
40
        // wants to begin a nested where statement which is wrapped in parenthesis.
41
        // We'll add that Closure to the query then return back out immediately.
42 84
        if ($column instanceof Closure && is_null($operator)) {
43 1
            return $this->whereNested($column, $boolean);
0 ignored issues
show
Bug introduced by
The method whereNested() does not exist on LaravelFreelancerNL\Aran...erns\BuildsWhereClauses. Did you maybe mean where()? ( Ignorable by Annotation )

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

43
            return $this->/** @scrutinizer ignore-call */ whereNested($column, $boolean);

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...
44
        }
45
46
        // If the column is a Closure instance and there is an operator value, we will
47
        // assume the developer wants to run a subquery and then compare the result
48
        // of that subquery with the given value that was provided to the method.
49 84
        if ($this->isQueryable($column) && ! is_null($operator)) {
0 ignored issues
show
Bug introduced by
It seems like isQueryable() 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

49
        if ($this->/** @scrutinizer ignore-call */ isQueryable($column) && ! is_null($operator)) {
Loading history...
50 1
            $sub = $this->createSub($column);
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

50
            /** @scrutinizer ignore-call */ 
51
            $sub = $this->createSub($column);
Loading history...
51
52 1
            return $this->where($sub, $operator, $value, $boolean);
53
        }
54
55
        // If the given operator is not found in the list of valid operators we will
56
        // assume that the developer is just short-cutting the '=' operators and
57
        // we will set the operators to '==' and set the values appropriately.
58 84
        if ($this->invalidOperator($operator)) {
0 ignored issues
show
Bug introduced by
It seems like invalidOperator() 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

58
        if ($this->/** @scrutinizer ignore-call */ invalidOperator($operator)) {
Loading history...
59
            [$value, $operator] = [$operator, '=='];
60
        }
61
62
        // If the value is a Closure, it means the developer is performing an entire
63
        // sub-select within the query and we will need to compile the sub-select
64
        // within the where clause to get the appropriate query record results.
65 84
        if ($value instanceof Closure) {
66 1
            return $this->whereSub($column, $operator, $value, $boolean);
0 ignored issues
show
Bug introduced by
It seems like $column can also be of type Closure; however, parameter $column of LaravelFreelancerNL\Aran...hereClauses::whereSub() does only seem to accept 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

66
            return $this->whereSub(/** @scrutinizer ignore-type */ $column, $operator, $value, $boolean);
Loading history...
67
        }
68
69
        // If the value is "null", we will just assume the developer wants to add a
70
        // where null clause to the query. So, we will allow a short-cut here to
71
        // that method for convenience so the developer doesn't have to check.
72 84
        if (is_null($value)) {
73 7
            return $this->whereNull($column, $boolean, $operator !== '=');
0 ignored issues
show
Bug introduced by
The method whereNull() does not exist on LaravelFreelancerNL\Aran...erns\BuildsWhereClauses. Did you maybe mean where()? ( Ignorable by Annotation )

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

73
            return $this->/** @scrutinizer ignore-call */ whereNull($column, $boolean, $operator !== '=');

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...
74
        }
75
76 82
        $type = 'Basic';
77
78
        // Now that we are working with just a simple query we can put the elements
79
        // in our array and add the query binding to our array of bindings that
80
        // will be bound to each SQL statements when it is finally executed.
81 82
        $this->wheres[] = compact(
0 ignored issues
show
Bug Best Practice introduced by
The property wheres does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
82 82
            'type',
83 82
            'column',
84 82
            'operator',
85 82
            'value',
86 82
            'boolean'
87 82
        );
88
89 82
        return $this;
90
    }
91
92
    /**
93
     * Add an exists clause to the query.
94
     *
95
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
96
     *
97
     * @param  Builder  $query
98
     * @param  string  $boolean
99
     * @param  bool  $not
100
     * @return Builder
101
     */
102 7
    public function addWhereExistsQuery(IlluminateQueryBuilder $query, $boolean = 'and', $not = false)
103
    {
104 7
        if ($not) {
105 3
            return $this->addWhereNotExistsQuery($query, $boolean = 'and');
106
        }
107
108 4
        $type = 'Exists';
109 4
        $operator = '>';
110 4
        $value = 0;
111
112 4
        $query->grammar->compileSelect($query);
113
114 4
        if ($query->limit != 1) {
115 3
            $query->aqb = $query->aqb->length($query->aqb);
116
        }
117
118 4
        if (isset($query->limit) && $query->limit == 1) {
119 1
            $query->aqb = $query->aqb->first($query->aqb);
120 1
            $operator = '!=';
121 1
            $value = null;
122
        }
123
124 4
        $this->wheres[] = compact('type', 'query', 'operator', 'value', 'boolean');
0 ignored issues
show
Bug Best Practice introduced by
The property wheres does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
125
126 4
        return $this;
127
    }
128
129
    /**
130
     * Add an not exists clause to the query.
131
     *
132
     * @param  Builder  $query
133
     * @param  string  $boolean
134
     * @return Builder
135
     */
136 3
    public function addWhereNotExistsQuery(IlluminateQueryBuilder $query, $boolean = 'and')
137
    {
138 3
        $type = 'Exists';
139 3
        $operator = '==';
140 3
        $value = 0;
141
142 3
        $query->grammar->compileSelect($query);
143
144 3
        if ($query->limit != 1) {
145 2
            $query->aqb = $query->aqb->length($query->aqb);
146
        }
147
148 3
        if (isset($query->limit) && $query->limit == 1) {
149 1
            $query->aqb = $query->aqb->first($query->aqb);
150 1
            $value = null;
151
        }
152
153 3
        $this->wheres[] = compact('type', 'query', 'operator', 'value', 'boolean');
0 ignored issues
show
Bug Best Practice introduced by
The property wheres does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
154
155 3
        return $this;
156
    }
157
158
    /**
159
     * Add a "where JSON contains" clause to the query.
160
     *
161
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
162
     *
163
     * @param  string  $column
164
     * @param  mixed  $value
165
     * @param  string  $boolean
166
     * @param  bool  $not
167
     * @return IlluminateQueryBuilder
168
     */
169 1
    public function whereJsonContains($column, $value, $boolean = 'and', $not = false)
170
    {
171 1
        $type = 'JsonContains';
172
173 1
        $this->wheres[] = compact('type', 'column', 'value', 'boolean', 'not');
0 ignored issues
show
Bug Best Practice introduced by
The property wheres does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
174
175 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...erns\BuildsWhereClauses which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
176
    }
177
178
    /**
179
     * Add a full sub-select to the query.
180
     *
181
     * @param  string  $column
182
     * @param  string  $operator
183
     * @param  \Closure  $callback
184
     * @param  string  $boolean
185
     * @return Builder
186
     */
187 1
    protected function whereSub($column, $operator, Closure $callback, $boolean)
188
    {
189 1
        $type = 'Sub';
190
191
        // Once we have the query instance we can simply execute it so it can add all
192
        // of the sub-select's conditions to itself, and then we can cache it off
193
        // in the array of where clauses for the "main" parent query instance.
194 1
        call_user_func($callback, $query = $this->forSubQuery());
0 ignored issues
show
Bug introduced by
It seems like forSubQuery() 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

194
        call_user_func($callback, $query = $this->/** @scrutinizer ignore-call */ forSubQuery());
Loading history...
195
196 1
        $query->grammar->compileSelect($query);
197
198 1
        if (isset($query->limit) && $query->limit == 1) {
199
            //Return the value, not an array of values
200 1
            $query->aqb = $query->aqb->first($query->aqb);
201
        }
202
203 1
        $this->wheres[] = compact(
0 ignored issues
show
Bug Best Practice introduced by
The property wheres does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
204 1
            'type',
205 1
            'column',
206 1
            'operator',
207 1
            'query',
208 1
            'boolean'
209 1
        );
210
211 1
        return $this;
212
    }
213
}
214