BuildsWheres::mergeWheres()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 3
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 7
ccs 4
cts 4
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LaravelFreelancerNL\Aranguent\Query\Concerns;
6
7
use Carbon\CarbonPeriod;
8
use Closure;
9
use DateTimeInterface;
10
use Illuminate\Contracts\Database\Query\ConditionExpression;
11
use Illuminate\Contracts\Support\Arrayable;
12
use Illuminate\Database\Eloquent\Builder as IlluminateEloquentBuilder;
13
use Illuminate\Database\Query\Builder as IlluminateQueryBuilder;
14
use Illuminate\Database\Query\Expression;
15
use Illuminate\Support\Arr;
16
use InvalidArgumentException;
17
use LaravelFreelancerNL\Aranguent\Query\Builder;
18
use LogicException;
19
20
trait BuildsWheres
21
{
22
    /**
23
     * Add a "where fulltext" clause to the query.
24
     *
25
     * @param string|string[] $columns
26
     * @param string $value
27
     * @param array<mixed> $options
28
     * @param string $boolean
29
     * @return $this
30
     *
31
     * @SuppressWarnings("PHPMD.UnusedFormalParameter")
32
     */
33
    public function whereFullText($columns, $value, array $options = [], $boolean = 'and')
34
    {
35
        // NOTE: can be done by listing all fulltext calls and using it on the collection name from $builder->from
36
        // distinctly merging results from multiple calls on the same collection.
37
        // For a call on a joined collection it might need to be moved to the JoinClause
38
        throw new LogicException('This database driver does not support the whereFullText method.');
39
    }
40
41
    /**
42
     * Prepare the value and operator for a where clause.
43
     *
44
     * @param  DateTimeInterface|float|int|string|null  $value
45
     * @param  string|null  $operator
46
     * @param  bool  $useDefault
47
     * @return array<mixed>
48
     *
49
     * @throws \InvalidArgumentException
50
     *
51
     * @SuppressWarnings("PHPMD.BooleanArgumentFlag")
52
     */
53 257
    public function prepareValueAndOperator($value, $operator, $useDefault = false)
54
    {
55 257
        if ($useDefault) {
56 155
            return [$operator, '=='];
57 167
        } elseif (!is_null($operator) && $this->invalidOperatorAndValue($operator, $value)) {
0 ignored issues
show
Bug introduced by
It seems like invalidOperatorAndValue() 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

57
        } elseif (!is_null($operator) && $this->/** @scrutinizer ignore-call */ invalidOperatorAndValue($operator, $value)) {
Loading history...
58
            throw new InvalidArgumentException('Illegal operator and value combination.');
59
        }
60
61 167
        return [$value, $operator];
62
    }
63
64
    /**
65
     * Add an array of where clauses to the query.
66
     *
67
     * @param  array<mixed>  $column
68
     * @param  string  $boolean
69
     * @param  string  $method
70
     * @return $this
71
     */
72 29
    protected function addArrayOfWheres($column, $boolean, $method = 'where')
73
    {
74 29
        $column = associativeFlatten($column);
75
76 29
        return $this->whereNested(function ($query) use ($column, $method, $boolean) {
0 ignored issues
show
Bug introduced by
The method whereNested() does not exist on LaravelFreelancerNL\Aran...y\Concerns\BuildsWheres. 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

76
        return $this->/** @scrutinizer ignore-call */ whereNested(function ($query) use ($column, $method, $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...
77 29
            foreach ($column as $key => $value) {
78 29
                $query->{$method}($key, '==', $value, $boolean);
79
            }
80 29
        }, $boolean);
81
    }
82
83
    /**
84
     * @param mixed $operator
85
     * @param mixed $value
86
     * @return array<mixed>
87
     */
88 248
    public function validateOperator(mixed $operator, mixed $value): array
89
    {
90
        // If the given operator is not found in the list of valid operators we will
91
        // assume that the developer is just short-cutting the '==' operators and
92
        // we will set the operators to '==' and set the values appropriately.
93 248
        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

93
        if ($this->/** @scrutinizer ignore-call */ invalidOperator($operator)) {
Loading history...
94 10
            [$value, $operator] = [$operator, '=='];
95
        }
96 248
        return [$value, $operator];
97
    }
98
99
    /**
100
     * @param mixed $operator
101
     * @return string
102
     */
103 241
    public function getType(mixed $operator): string
104
    {
105 241
        $type = 'Basic';
106
107 241
        if ($this->isBitwiseOperator($operator)) {
0 ignored issues
show
Bug introduced by
It seems like isBitwiseOperator() 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

107
        if ($this->/** @scrutinizer ignore-call */ isBitwiseOperator($operator)) {
Loading history...
108
            $type = 'Bitwise';
109
        }
110
111 241
        return $type;
112
    }
113
114
    /**
115
     * Add a date based (year, month, day, time) statement to the query.
116
     *
117
     * @param  string  $type
118
     * @param  string  $column
119
     * @param  string  $operator
120
     * @param  mixed  $value
121
     * @param  string  $boolean
122
     * @return IlluminateQueryBuilder
123
     */
124 5
    protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and')
125
    {
126 5
        $value = $this->bindValue($value);
0 ignored issues
show
Bug introduced by
It seems like bindValue() 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

126
        /** @scrutinizer ignore-call */ 
127
        $value = $this->bindValue($value);
Loading history...
127
128 5
        $this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value');
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...
129
130 5
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...y\Concerns\BuildsWheres which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
131
    }
132
133
134
    /**
135
     * Add another query builder as a nested where to the query builder.
136
     *
137
     * @param  \Illuminate\Database\Query\Builder  $query
138
     * @param  string  $boolean
139
     * @return $this
140
     */
141 52
    public function addNestedWhereQuery($query, $boolean = 'and')
142
    {
143 52
        if (count($query->wheres)) {
144 52
            $type = 'Nested';
145
146 52
            $this->wheres[] = compact('type', 'query', '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...
147 52
            $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

147
            $this->/** @scrutinizer ignore-call */ 
148
                   importBindings($query);
Loading history...
148
        }
149
150 52
        return $this;
151
    }
152
153
    /**
154
     * Add an exists clause to the query.
155
     *
156
     * @param  \Illuminate\Database\Query\Builder  $query
157
     * @param  string  $boolean
158
     * @param  bool  $not
159
     * @return $this
160
     *
161
     * @SuppressWarnings("PHPMD.BooleanArgumentFlag")
162
     */
163 25
    public function addWhereExistsQuery(IlluminateQueryBuilder $query, $boolean = 'and', $not = false)
164
    {
165 25
        $type = $not ? 'NotExists' : 'Exists';
166
167 25
        [$subquery] = $this->parseSub($query);
0 ignored issues
show
Bug introduced by
It seems like parseSub() 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

167
        /** @scrutinizer ignore-call */ 
168
        [$subquery] = $this->parseSub($query);
Loading history...
168
169 25
        $this->wheres[] = compact('type', 'subquery', '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...
170
171 25
        return $this;
172
    }
173
174
    /**
175
     * Merge an array of where clauses and bindings.
176
     *
177
     * @param  array<mixed>  $wheres
178
     * @param  array<mixed>  $bindings
179
     * @return $this
180
     */
181 25
    public function mergeWheres($wheres, $bindings)
182
    {
183 25
        $this->wheres = array_merge($this->wheres, (array) $wheres);
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...
184
185 25
        $this->bindings['where'] = array_merge($this->bindings['where'], (array) $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...
186
187 25
        return $this;
188
    }
189
190
    /**
191
     * Add a basic where clause to the query.
192
     *
193
     * @param  \Closure|IlluminateQueryBuilder|IlluminateEloquentBuilder|Expression|string|array<mixed>  $column
194
     * @param  mixed  $operator
195
     * @param  mixed  $value
196
     * @param  string  $boolean
197
     * @return IlluminateQueryBuilder
198
     *
199
     * @SuppressWarnings("PHPMD.CyclomaticComplexity")
200
     * @SuppressWarnings("PHPMD.NPathComplexity")
201
     */
202 248
    public function where($column, $operator = null, $value = null, $boolean = 'and')
203
    {
204 248
        if ($column instanceof ConditionExpression) {
205
            $type = 'Expression';
206
207
            $this->wheres[] = compact('type', 'column', '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...
208
209
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...y\Concerns\BuildsWheres which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
210
        }
211
212
        // If the column is an array, we will assume it is an array of key-value pairs
213
        // and can add them each as a where clause. We will maintain the boolean we
214
        // received when the method was called and pass it into the nested where.
215 248
        if (is_array($column) && !array_is_list($column)) {
216 29
            return $this->addArrayOfWheres($column, $boolean);
217
        }
218
219
        // Here we will make some assumptions about the operator. If only 2 values are
220
        // passed to the method, we will assume that the operator is an equals sign
221
        // and keep going. Otherwise, we'll require the operator to be passed in.
222 248
        [$value, $operator] = $this->prepareValueAndOperator(
223 248
            $value,
224 248
            $operator,
225 248
            func_num_args() === 2,
226 248
        );
227
228
        // If the column is actually a Closure instance, we will assume the developer
229
        // wants to begin a nested where statement which is wrapped in parentheses.
230
        // We will add that Closure to the query and return back out immediately.
231 248
        if ($column instanceof Closure && is_null($operator)) {
232 4
            return $this->whereNested($column, $boolean);
233
        }
234
235
        // If the column is a Closure instance and there is an operator value, we will
236
        // assume the developer wants to run a subquery and then compare the result
237
        // of that subquery with the given value that was provided to the method.
238 248
        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

238
        if ($this->/** @scrutinizer ignore-call */ isQueryable($column) && !is_null($operator)) {
Loading history...
239
            /** @phpstan-ignore-next-line  */
240 1
            [$subquery] = $this->createSub($column, 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

240
            /** @scrutinizer ignore-call */ 
241
            [$subquery] = $this->createSub($column, true);
Loading history...
241
242 1
            return $this->where(new Expression($subquery), $operator, $value, $boolean);
243
        }
244
245 248
        list($value, $operator) = $this->validateOperator($operator, $value);
246
247
        // If the value is a Closure, it means the developer is performing an entire
248
        // sub-select within the query and we will need to compile the sub-select
249
        // within the where clause to get the appropriate query record results.
250 248
        if ($this->isQueryable($value)) {
251
            /** @phpstan-ignore-next-line  */
252 1
            return $this->whereSub($column, $operator, $value, $boolean);
253
        }
254
255
        // If the value is "null", we will just assume the developer wants to add a
256
        // where null clause to the query. So, we will allow a short-cut here to
257
        // that method for convenience so the developer doesn't have to check.
258 248
        if (is_null($value)) {
259
            /** @phpstan-ignore-next-line  */
260 16
            return $this->whereNull($column, $boolean, $operator !== '==');
0 ignored issues
show
Bug introduced by
It seems like $column can also be of type Closure and Illuminate\Database\Eloquent\Builder and Illuminate\Database\Query\Builder; however, parameter $columns of LaravelFreelancerNL\Aran...ildsWheres::whereNull() does only seem to accept Illuminate\Contracts\Dat...ray<mixed,mixed>|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

260
            return $this->whereNull(/** @scrutinizer ignore-type */ $column, $boolean, $operator !== '==');
Loading history...
Bug Best Practice introduced by
The expression return $this->whereNull(...an, $operator !== '==') returns the type LaravelFreelancerNL\Aran...y\Concerns\BuildsWheres which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
261
        }
262
263 241
        $type = $this->getType($operator);
264
265 241
        $value = $this->bindValue($value);
266
267
        // Now that we are working with just a simple query we can put the elements
268
        // in our array and add the query binding to our array of bindings that
269
        // will be bound to each SQL statements when it is finally executed.
270 241
        $this->wheres[] = compact(
271 241
            'type',
272 241
            'column',
273 241
            'operator',
274 241
            'value',
275 241
            'boolean',
276 241
        );
277
278 241
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...y\Concerns\BuildsWheres which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
279
    }
280
281
    /**
282
     * Add a where between statement to the query.
283
     *
284
     * @param string|Expression $column
285
     * @param iterable<mixed> $values
286
     * @param string $boolean
287
     * @param bool $not
288
     * @return IlluminateQueryBuilder
289
     *
290
     * @SuppressWarnings("PHPMD.BooleanArgumentFlag")
291
     */
292 2
    public function whereBetween($column, iterable $values, $boolean = 'and', $not = false)
293
    {
294 2
        $type = 'between';
295
296 2
        if ($values instanceof CarbonPeriod) {
297
            $values = $values->toArray();
298
        }
299
300 2
        $values = array_slice($this->cleanBindings(Arr::flatten($values)), 0, 2);
0 ignored issues
show
Bug introduced by
It seems like cleanBindings() 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

300
        $values = array_slice($this->/** @scrutinizer ignore-call */ cleanBindings(Arr::flatten($values)), 0, 2);
Loading history...
301 2
        $values[0] = $this->bindValue($values[0]);
302 2
        $values[1] = $this->bindValue($values[1]);
303
304 2
        $this->wheres[] = compact('type', 'column', 'values', '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...
305
306 2
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...y\Concerns\BuildsWheres which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
307
    }
308
309
    /**
310
     * Add a "where" clause comparing two columns to the query.
311
     *
312
     * @param  Expression|string|array<mixed>  $first
313
     * @param  string|null  $operator
314
     * @param  Expression|string|null  $second
315
     * @param  string|null  $boolean
316
     * @return $this
317
     */
318 59
    public function whereColumn($first, $operator = null, $second = null, $boolean = 'and')
319
    {
320
        // If the column is an array, we will assume it is an array of key-value pairs
321
        // and can add them each as a where clause. We will maintain the boolean we
322
        // received when the method was called and pass it into the nested where.
323 59
        if (is_array($first) && !array_is_list($first) && $boolean !== null) {
324
            return $this->addArrayOfWheres($first, $boolean, 'whereColumn');
325
        }
326
327
        // If the given operator is not found in the list of valid operators we will
328
        // assume that the developer is just short-cutting the '=' operators and
329
        // we will set the operators to '=' and set the values appropriately.
330 59
        if ($operator !== null && $this->invalidOperator($operator)) {
331 6
            [$second, $operator] = [$operator, '='];
332
        }
333
334
        // Finally, we will add this where clause into this array of clauses that we
335
        // are building for the query. All of them will be compiled via a grammar
336
        // once the query is about to be executed and run against the database.
337 59
        $type = 'Column';
338
339 59
        $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...
340 59
            'type',
341 59
            'first',
342 59
            'operator',
343 59
            'second',
344 59
            'boolean',
345 59
        );
346
347 59
        return $this;
348
    }
349
350
351
    /**
352
     * Add a "where in" clause to the query.
353
     *
354
     * @param  string  $column
355
     * @param  mixed  $values
356
     * @param  string  $boolean
357
     * @param  bool  $not
358
     * @return IlluminateQueryBuilder
359
     *
360
     * @SuppressWarnings("PHPMD.BooleanArgumentFlag")
361
     */
362 20
    public function whereIn($column, $values, $boolean = 'and', $not = false)
363
    {
364 20
        $type = $not ? 'NotIn' : 'In';
365
366
        // If the value is a query builder instance we will assume the developer wants to
367
        // look for any values that exist within this given query. So, we will add the
368
        // query accordingly so that this query is properly executed when it is run.
369 20
        if ($this->isQueryable($values)) {
370
            [$query, $bindings] = $this->createSub($values);
371
372
            $values = [new Expression($query)];
373
374
            $this->addBinding($bindings, 'where');
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

374
            $this->/** @scrutinizer ignore-call */ 
375
                   addBinding($bindings, 'where');
Loading history...
375
        }
376
377
        // Next, if the value is Arrayable we need to cast it to its raw array form so we
378
        // have the underlying array value instead of an Arrayable object which is not
379
        // able to be added as a binding, etc. We will then add to the wheres array.
380 20
        if ($values instanceof Arrayable) {
381
            $values = $values->toArray();
382
        }
383
384 20
        $values = $this->bindValue($this->cleanBindings($values));
385
386 20
        $this->wheres[] = compact('type', 'column', 'values', '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...
387
388 20
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...y\Concerns\BuildsWheres which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
389
    }
390
391
    /**
392
     * Add a "where JSON contains" clause to the query.
393
     *
394
     * @SuppressWarnings("PHPMD.BooleanArgumentFlag")
395
     *
396
     * @param  string  $column
397
     * @param  mixed  $value
398
     * @param  string  $boolean
399
     * @param  bool  $not
400
     * @return IlluminateQueryBuilder
401
     */
402 1
    public function whereJsonContains($column, $value, $boolean = 'and', $not = false)
403
    {
404 1
        $type = 'JsonContains';
405
406 1
        $value = $this->bindValue($value);
407
408 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...
409
410 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...y\Concerns\BuildsWheres which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
411
    }
412
413
    /**
414
     * Add a "where JSON length" clause to the query.
415
     *
416
     * @param  string  $column
417
     * @param  mixed  $operator
418
     * @param  mixed  $value
419
     * @param  string  $boolean
420
     * @return IlluminateQueryBuilder
421
     */
422 1
    public function whereJsonLength($column, $operator, $value = null, $boolean = 'and')
423
    {
424 1
        $type = 'JsonLength';
425
426 1
        [$value, $operator] = $this->prepareValueAndOperator(
427 1
            $value,
428 1
            $operator,
429 1
            func_num_args() === 2,
430 1
        );
431
432 1
        $value = $this->bindValue((int) $this->flattenValue($value));
0 ignored issues
show
Bug introduced by
It seems like flattenValue() 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

432
        $value = $this->bindValue((int) $this->/** @scrutinizer ignore-call */ flattenValue($value));
Loading history...
433
434 1
        $this->wheres[] = compact('type', 'column', '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...
435
436 1
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type LaravelFreelancerNL\Aran...y\Concerns\BuildsWheres which is incompatible with the documented return type Illuminate\Database\Query\Builder.
Loading history...
437
    }
438
439
    /**
440
     * Add a "where like" clause to the query.
441
     *
442
     * @param  \Illuminate\Contracts\Database\Query\Expression|string  $column
443
     * @param  string  $value
444
     * @param  bool  $caseSensitive
445
     * @param  string  $boolean
446
     * @param  bool  $not
447
     * @return $this
448
     *
449
     * @SuppressWarnings("PHPMD.BooleanArgumentFlag")
450
     */
451 4
    public function whereLike($column, $value, $caseSensitive = false, $boolean = 'and', $not = false)
452
    {
453 4
        $type = 'Like';
454
455 4
        $value = $this->bindValue($value);
456
457 4
        $this->wheres[] = compact('type', 'column', 'value', 'caseSensitive', '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...
458
459 4
        return $this;
460
    }
461
462
    /**
463
     * Add a "where null" clause to the query.
464
     *
465
     * @param  string|array<mixed>|\Illuminate\Contracts\Database\Query\Expression  $columns
466
     * @param  string  $boolean
467
     * @param  bool  $not
468
     * @return $this
469
     *
470
     * @SuppressWarnings("PHPMD.BooleanArgumentFlag")
471
     */
472 107
    public function whereNull($columns, $boolean = 'and', $not = false)
473
    {
474 107
        $type = $not ? 'NotNull' : 'Null';
475
476 107
        foreach (Arr::wrap($columns) as $column) {
477 107
            $this->wheres[] = compact('type', 'column', '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...
478
        }
479
480 107
        return $this;
481
    }
482
483
    /**
484
     * Add a full sub-select to the query.
485
     *
486
     * @param  \Illuminate\Contracts\Database\Query\Expression|string  $column
487
     * @param  string  $operator
488
     * @param  mixed $callback
489
     * @param  string  $boolean
490
     * @return $this
491
     */
492 1
    protected function whereSub($column, $operator, $callback, $boolean)
493
    {
494
        assert($this instanceof Builder);
495
496 1
        $type = 'Sub';
497
498
        // Once we have the query instance we can simply execute it so it can add all
499
        // of the sub-select's conditions to itself, and then we can cache it off
500
        // in the array of where clauses for the "main" parent query instance.
501 1
        call_user_func($callback, $query = $this->forSubQuery());
502
503
        assert($query instanceof Builder);
504
505 1
        $query->returnSingleValue = true;
506
507 1
        [$subquery] = $this->parseSub($query);
508
509 1
        $this->wheres[] = compact(
510 1
            'type',
511 1
            'column',
512 1
            'operator',
513 1
            'subquery',
514 1
            'boolean',
515 1
        );
516
517 1
        return $this;
518
    }
519
}
520