This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | namespace Childish\query; |
||
3 | |||
4 | use Closure; |
||
5 | use RuntimeException; |
||
6 | use Childish\connection\ConnectionInterface; |
||
7 | use Childish\support\Collection; |
||
8 | use InvalidArgumentException; |
||
9 | use Childish\support\Tools; |
||
10 | |||
11 | |||
12 | /** |
||
13 | * Builder |
||
14 | * |
||
15 | * @author Pu ShaoWei <[email protected]> |
||
16 | * @date 2017/12/6 |
||
17 | * @package App\db |
||
18 | * @version 1.0 |
||
19 | */ |
||
20 | class Builder |
||
21 | { |
||
22 | /** |
||
23 | * The base query builder instance. |
||
24 | * |
||
25 | * @var \Childish\connection\ConnectionInterface |
||
26 | */ |
||
27 | public $connection; |
||
28 | |||
29 | /** |
||
30 | * The database query grammar instance. |
||
31 | * |
||
32 | * @var \Childish\query\Grammar |
||
33 | */ |
||
34 | public $grammar; |
||
35 | |||
36 | /** |
||
37 | * The database query post processor instance. |
||
38 | * |
||
39 | * @var \Childish\query\Processor |
||
40 | */ |
||
41 | public $processor; |
||
42 | |||
43 | /** |
||
44 | * The current query value bindings. |
||
45 | * |
||
46 | * @var array |
||
47 | */ |
||
48 | public $bindings = [ |
||
49 | 'select' => [], |
||
50 | 'join' => [], |
||
51 | 'where' => [], |
||
52 | 'having' => [], |
||
53 | 'order' => [], |
||
54 | 'union' => [], |
||
55 | ]; |
||
56 | |||
57 | /** |
||
58 | * An aggregate function and column to be run. |
||
59 | * |
||
60 | * @var array |
||
61 | */ |
||
62 | public $aggregate; |
||
63 | |||
64 | /** |
||
65 | * The columns that should be returned. |
||
66 | * |
||
67 | * @var array |
||
68 | */ |
||
69 | public $columns; |
||
70 | |||
71 | /** |
||
72 | * Indicates if the query returns distinct results. |
||
73 | * |
||
74 | * @var bool |
||
75 | */ |
||
76 | public $distinct = false; |
||
77 | |||
78 | /** |
||
79 | * The table which the query is targeting. |
||
80 | * |
||
81 | * @var string |
||
82 | */ |
||
83 | public $from; |
||
84 | |||
85 | /** |
||
86 | * The table joins for the query. |
||
87 | * |
||
88 | * @var array |
||
89 | */ |
||
90 | public $joins; |
||
91 | |||
92 | /** |
||
93 | * The where constraints for the query. |
||
94 | * |
||
95 | * @var array |
||
96 | */ |
||
97 | public $wheres = []; |
||
98 | |||
99 | /** |
||
100 | * The groupings for the query. |
||
101 | * |
||
102 | * @var array |
||
103 | */ |
||
104 | public $groups; |
||
105 | |||
106 | /** |
||
107 | * The having constraints for the query. |
||
108 | * |
||
109 | * @var array |
||
110 | */ |
||
111 | public $havings; |
||
112 | |||
113 | /** |
||
114 | * The orderings for the query. |
||
115 | * |
||
116 | * @var array |
||
117 | */ |
||
118 | public $orders; |
||
119 | |||
120 | /** |
||
121 | * The maximum number of records to return. |
||
122 | * |
||
123 | * @var int |
||
124 | */ |
||
125 | public $limit; |
||
126 | |||
127 | /** |
||
128 | * The number of records to skip. |
||
129 | * |
||
130 | * @var int |
||
131 | */ |
||
132 | public $offset; |
||
133 | |||
134 | /** |
||
135 | * The query union statements. |
||
136 | * |
||
137 | * @var array |
||
138 | */ |
||
139 | public $unions; |
||
140 | |||
141 | /** |
||
142 | * The maximum number of union records to return. |
||
143 | * |
||
144 | * @var int |
||
145 | */ |
||
146 | public $unionLimit; |
||
147 | |||
148 | /** |
||
149 | * The number of union records to skip. |
||
150 | * |
||
151 | * @var int |
||
152 | */ |
||
153 | public $unionOffset; |
||
154 | |||
155 | /** |
||
156 | * The orderings for the union query. |
||
157 | * |
||
158 | * @var array |
||
159 | */ |
||
160 | public $unionOrders; |
||
161 | |||
162 | /** |
||
163 | * Indicates whether row locking is being used. |
||
164 | * |
||
165 | * @var string|bool |
||
166 | */ |
||
167 | public $lock; |
||
168 | |||
169 | /** |
||
170 | * All of the available clause operators. |
||
171 | * |
||
172 | * @var array |
||
173 | */ |
||
174 | public $operators = [ |
||
175 | '=', '<', '>', '<=', '>=', '<>', '!=', '<=>', |
||
176 | 'like', 'like binary', 'not like', 'between', 'ilike', |
||
177 | '&', '|', '^', '<<', '>>', |
||
178 | 'rlike', 'regexp', 'not regexp', |
||
179 | '~', '~*', '!~', '!~*', 'similar to', |
||
180 | 'not similar to', 'not ilike', '~~*', '!~~*', |
||
181 | ]; |
||
182 | |||
183 | /** |
||
184 | * Whether use write pdo for select. |
||
185 | * |
||
186 | * @var bool |
||
187 | */ |
||
188 | public $useWritePdo = false; |
||
189 | |||
190 | |||
191 | /** |
||
192 | * Builder constructor. |
||
193 | * |
||
194 | * @param \Childish\connection\ConnectionInterface $connection |
||
195 | * @param \Childish\query\Grammar|null $grammar |
||
196 | * @param \Childish\query\Processor|null $processor |
||
197 | */ |
||
198 | public function __construct( |
||
199 | ConnectionInterface $connection, |
||
200 | Grammar $grammar = null, |
||
201 | Processor $processor = null) |
||
202 | { |
||
203 | $this->connection = $connection; |
||
204 | $this->grammar = $grammar; |
||
205 | $this->processor = $processor; |
||
206 | } |
||
207 | |||
208 | /** |
||
209 | * Set the columns to be selected. |
||
210 | * |
||
211 | * @param array|mixed $columns |
||
212 | * @return $this |
||
213 | */ |
||
214 | public function select($columns = ['*']) |
||
215 | { |
||
216 | $this->columns = is_array($columns) ? $columns : func_get_args(); |
||
217 | |||
218 | return $this; |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * Parse the sub-select query into SQL and bindings. |
||
223 | * |
||
224 | * @param mixed $query |
||
225 | * @return array |
||
226 | */ |
||
227 | protected function parseSubSelect($query) |
||
228 | { |
||
229 | if ($query instanceof self) { |
||
230 | $query->columns = [$query->columns[0]]; |
||
231 | |||
232 | return [$query->toSql(), $query->getBindings()]; |
||
233 | } else if (is_string($query)) { |
||
234 | return [$query, []]; |
||
235 | } else { |
||
236 | throw new InvalidArgumentException; |
||
237 | } |
||
238 | } |
||
239 | |||
240 | /** |
||
241 | * Add a new select column to the query. |
||
242 | * |
||
243 | * @param array|mixed $column |
||
244 | * @return $this |
||
245 | */ |
||
246 | public function addSelect($column) |
||
247 | { |
||
248 | $column = is_array($column) ? $column : func_get_args(); |
||
249 | |||
250 | $this->columns = array_merge((array)$this->columns, $column); |
||
251 | |||
252 | return $this; |
||
253 | } |
||
254 | |||
255 | /** |
||
256 | * Force the query to only return distinct results. |
||
257 | * |
||
258 | * @return $this |
||
259 | */ |
||
260 | public function distinct() |
||
261 | { |
||
262 | $this->distinct = true; |
||
263 | |||
264 | return $this; |
||
265 | } |
||
266 | |||
267 | /** |
||
268 | * Set the table which the query is targeting. |
||
269 | * |
||
270 | * @param string $table |
||
271 | * @return $this |
||
272 | */ |
||
273 | public function from($table) |
||
274 | { |
||
275 | $this->from = $table; |
||
276 | |||
277 | return $this; |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * Merge an array of where clauses and bindings. |
||
282 | * |
||
283 | * @param array $wheres |
||
284 | * @param array $bindings |
||
285 | * @return void |
||
286 | */ |
||
287 | public function mergeWheres($wheres, $bindings) |
||
288 | { |
||
289 | $this->wheres = array_merge($this->wheres, (array)$wheres); |
||
290 | |||
291 | $this->bindings['where'] = array_values( |
||
292 | array_merge($this->bindings['where'], (array)$bindings) |
||
293 | ); |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * Add a basic where clause to the query. |
||
298 | * |
||
299 | * @param string|array|\Closure $column |
||
300 | * @param string|null $operator |
||
301 | * @param mixed $value |
||
302 | * @param string $boolean |
||
303 | * @return $this |
||
304 | */ |
||
305 | public function where($column, $operator = null, $value = null, $boolean = 'and') |
||
306 | { |
||
307 | // If the column is an array, we will assume it is an array of key-value pairs |
||
308 | // and can add them each as a where clause. We will maintain the boolean we |
||
309 | // received when the method was called and pass it into the nested where. |
||
310 | if (is_array($column)) { |
||
311 | return $this->addArrayOfWheres($column, $boolean); |
||
312 | } |
||
313 | |||
314 | // Here we will make some assumptions about the operator. If only 2 values are |
||
315 | // passed to the method, we will assume that the operator is an equals sign |
||
316 | // and keep going. Otherwise, we'll require the operator to be passed in. |
||
317 | list($value, $operator) = $this->prepareValueAndOperator( |
||
318 | $value, $operator, func_num_args() == 2 |
||
319 | ); |
||
320 | |||
321 | // If the columns is actually a Closure instance, we will assume the developer |
||
322 | // wants to begin a nested where statement which is wrapped in parenthesis. |
||
323 | // We'll add that Closure to the query then return back out immediately. |
||
324 | if ($column instanceof Closure) { |
||
325 | return $this->whereNested($column, $boolean); |
||
326 | } |
||
327 | |||
328 | // If the given operator is not found in the list of valid operators we will |
||
329 | // assume that the developer is just short-cutting the '=' operators and |
||
330 | // we will set the operators to '=' and set the values appropriately. |
||
331 | if ($this->invalidOperator($operator)) { |
||
332 | list($value, $operator) = [$operator, '=']; |
||
333 | } |
||
334 | |||
335 | // If the value is a Closure, it means the developer is performing an entire |
||
336 | // sub-select within the query and we will need to compile the sub-select |
||
337 | // within the where clause to get the appropriate query record results. |
||
338 | if ($value instanceof Closure) { |
||
339 | return $this->whereSub($column, $operator, $value, $boolean); |
||
0 ignored issues
–
show
|
|||
340 | } |
||
341 | |||
342 | // If the value is "null", we will just assume the developer wants to add a |
||
343 | // where null clause to the query. So, we will allow a short-cut here to |
||
344 | // that method for convenience so the developer doesn't have to check. |
||
345 | if (is_null($value)) { |
||
346 | return $this->whereNull($column, $boolean, $operator !== '='); |
||
347 | } |
||
348 | |||
349 | // Now that we are working with just a simple query we can put the elements |
||
350 | // in our array and add the query binding to our array of bindings that |
||
351 | // will be bound to each SQL statements when it is finally executed. |
||
352 | $type = 'Basic'; |
||
353 | |||
354 | $this->wheres[] = compact( |
||
355 | 'type', 'column', 'operator', 'value', 'boolean' |
||
356 | ); |
||
357 | |||
358 | $this->addBinding($value, 'where'); |
||
359 | return $this; |
||
360 | } |
||
361 | |||
362 | /** |
||
363 | * Add an array of where clauses to the query. |
||
364 | * |
||
365 | * @param array $column |
||
366 | * @param string $boolean |
||
367 | * @param string $method |
||
368 | * @return $this |
||
369 | */ |
||
370 | protected function addArrayOfWheres($column, $boolean, $method = 'where') |
||
371 | { |
||
372 | return $this->whereNested(function ($query) use ($column, $method, $boolean) { |
||
373 | foreach ($column as $key => $value) { |
||
374 | if (is_numeric($key) && is_array($value)) { |
||
375 | $query->{$method}(...array_values($value)); |
||
376 | } else { |
||
377 | $query->$method($key, '=', $value, $boolean); |
||
378 | } |
||
379 | } |
||
380 | }, $boolean); |
||
381 | } |
||
382 | |||
383 | /** |
||
384 | * Prepare the value and operator for a where clause. |
||
385 | * |
||
386 | * @param string $value |
||
387 | * @param string $operator |
||
388 | * @param bool $useDefault |
||
389 | * @return array |
||
390 | * @throws \InvalidArgumentException |
||
391 | */ |
||
392 | protected function prepareValueAndOperator($value, $operator, $useDefault = false) |
||
393 | { |
||
394 | if ($useDefault) { |
||
395 | return [$operator, '=']; |
||
396 | } else if ($this->invalidOperatorAndValue($operator, $value)) { |
||
397 | throw new InvalidArgumentException('Illegal operator and value combination.'); |
||
398 | } |
||
399 | |||
400 | return [$value, $operator]; |
||
401 | } |
||
402 | |||
403 | /** |
||
404 | * Determine if the given operator and value combination is legal. |
||
405 | * Prevents using Null values with invalid operators. |
||
406 | * |
||
407 | * @param string $operator |
||
408 | * @param mixed $value |
||
409 | * @return bool |
||
410 | */ |
||
411 | protected function invalidOperatorAndValue($operator, $value) |
||
412 | { |
||
413 | return is_null($value) && in_array($operator, $this->operators) && |
||
414 | !in_array($operator, ['=', '<>', '!=']); |
||
415 | } |
||
416 | |||
417 | /** |
||
418 | * Determine if the given operator is supported. |
||
419 | * |
||
420 | * @param string $operator |
||
421 | * @return bool |
||
422 | */ |
||
423 | protected function invalidOperator($operator) |
||
424 | { |
||
425 | return !in_array(strtolower($operator), $this->operators, true) && |
||
426 | !in_array(strtolower($operator), $this->grammar->getOperators(), true); |
||
427 | } |
||
428 | |||
429 | /** |
||
430 | * Add an "or where" clause to the query. |
||
431 | * |
||
432 | * @param string|array|\Closure $column |
||
433 | * @param string|null $operator |
||
434 | * @param mixed $value |
||
435 | * @return \Childish\query\Builder|static |
||
436 | */ |
||
437 | public function orWhere($column, $operator = null, $value = null) |
||
438 | { |
||
439 | return $this->where($column, $operator, $value, 'or'); |
||
440 | } |
||
441 | |||
442 | /** |
||
443 | * Add a "where" clause comparing two columns to the query. |
||
444 | * |
||
445 | * @param string|array $first |
||
446 | * @param string|null $operator |
||
447 | * @param string|null $second |
||
448 | * @param string|null $boolean |
||
449 | * @return \Childish\query\Builder|static |
||
450 | */ |
||
451 | public function whereColumn($first, $operator = null, $second = null, $boolean = 'and') |
||
452 | { |
||
453 | // If the column is an array, we will assume it is an array of key-value pairs |
||
454 | // and can add them each as a where clause. We will maintain the boolean we |
||
455 | // received when the method was called and pass it into the nested where. |
||
456 | if (is_array($first)) { |
||
457 | return $this->addArrayOfWheres($first, $boolean, 'whereColumn'); |
||
458 | } |
||
459 | |||
460 | // If the given operator is not found in the list of valid operators we will |
||
461 | // assume that the developer is just short-cutting the '=' operators and |
||
462 | // we will set the operators to '=' and set the values appropriately. |
||
463 | if ($this->invalidOperator($operator)) { |
||
464 | list($second, $operator) = [$operator, '=']; |
||
465 | } |
||
466 | |||
467 | // Finally, we will add this where clause into this array of clauses that we |
||
468 | // are building for the query. All of them will be compiled via a grammar |
||
469 | // once the query is about to be executed and run against the database. |
||
470 | $type = 'Column'; |
||
471 | |||
472 | $this->wheres[] = compact( |
||
473 | 'type', 'first', 'operator', 'second', 'boolean' |
||
474 | ); |
||
475 | |||
476 | return $this; |
||
477 | } |
||
478 | |||
479 | /** |
||
480 | * Add an "or where" clause comparing two columns to the query. |
||
481 | * |
||
482 | * @param string|array $first |
||
483 | * @param string|null $operator |
||
484 | * @param string|null $second |
||
485 | * @return \Childish\query\Builder|static |
||
486 | */ |
||
487 | public function orWhereColumn($first, $operator = null, $second = null) |
||
488 | { |
||
489 | return $this->whereColumn($first, $operator, $second, 'or'); |
||
490 | } |
||
491 | |||
492 | /** |
||
493 | * Add a raw where clause to the query. |
||
494 | * |
||
495 | * @param string $sql |
||
496 | * @param mixed $bindings |
||
497 | * @param string $boolean |
||
498 | * @return $this |
||
499 | */ |
||
500 | public function whereRaw($sql, $bindings = [], $boolean = 'and') |
||
501 | { |
||
502 | $this->wheres[] = ['type' => 'raw', 'sql' => $sql, 'boolean' => $boolean]; |
||
503 | |||
504 | $this->addBinding((array)$bindings, 'where'); |
||
505 | |||
506 | return $this; |
||
507 | } |
||
508 | |||
509 | /** |
||
510 | * Add a raw or where clause to the query. |
||
511 | * |
||
512 | * @param string $sql |
||
513 | * @param mixed $bindings |
||
514 | * @return \Childish\query\Builder|static |
||
515 | */ |
||
516 | public function orWhereRaw($sql, $bindings = []) |
||
517 | { |
||
518 | return $this->whereRaw($sql, $bindings, 'or'); |
||
519 | } |
||
520 | |||
521 | /** |
||
522 | * Add a "where in" clause to the query. |
||
523 | * |
||
524 | * @param string $column |
||
525 | * @param mixed $values |
||
526 | * @param string $boolean |
||
527 | * @param bool $not |
||
528 | * @return $this |
||
529 | */ |
||
530 | public function whereIn($column, $values, $boolean = 'and', $not = false) |
||
531 | { |
||
532 | $type = $not ? 'NotIn' : 'In'; |
||
533 | |||
534 | if ($values instanceof Builder) { |
||
535 | $values = $values->getQuery(); |
||
0 ignored issues
–
show
The method
getQuery() does not seem to exist on object<Childish\query\Builder> .
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. ![]() |
|||
536 | } |
||
537 | |||
538 | // If the value is a query builder instance we will assume the developer wants to |
||
539 | // look for any values that exists within this given query. So we will add the |
||
540 | // query accordingly so that this query is properly executed when it is run. |
||
541 | if ($values instanceof self) { |
||
542 | return $this->whereInExistingQuery( |
||
543 | $column, $values, $boolean, $not |
||
544 | ); |
||
545 | } |
||
546 | |||
547 | |||
548 | // If the value of the where in clause is actually a Closure, we will assume that |
||
549 | // the developer is using a full sub-select for this "in" statement, and will |
||
550 | // execute those Closures, then we can re-construct the entire sub-selects. |
||
551 | if ($values instanceof \Closure) { |
||
552 | return $this->whereInSub($column, $values, $boolean, $not); |
||
0 ignored issues
–
show
|
|||
553 | } |
||
554 | foreach ($values as $value) { |
||
555 | $this->addBinding($value, 'where'); |
||
556 | } |
||
557 | $this->wheres[] = compact('type', 'column', 'values', 'boolean'); |
||
558 | return $this; |
||
559 | } |
||
560 | |||
561 | /** |
||
562 | * Add an "or where in" clause to the query. |
||
563 | * |
||
564 | * @param string $column |
||
565 | * @param mixed $values |
||
566 | * @return \Childish\query\Builder|static |
||
567 | */ |
||
568 | public function orWhereIn($column, $values) |
||
569 | { |
||
570 | return $this->whereIn($column, $values, 'or'); |
||
571 | } |
||
572 | |||
573 | /** |
||
574 | * Add a "where not in" clause to the query. |
||
575 | * |
||
576 | * @param string $column |
||
577 | * @param mixed $values |
||
578 | * @param string $boolean |
||
579 | * @return \Childish\query\Builder|static |
||
580 | */ |
||
581 | public function whereNotIn($column, $values, $boolean = 'and') |
||
582 | { |
||
583 | return $this->whereIn($column, $values, $boolean, true); |
||
584 | } |
||
585 | |||
586 | /** |
||
587 | * Add an "or where not in" clause to the query. |
||
588 | * |
||
589 | * @param string $column |
||
590 | * @param mixed $values |
||
591 | * @return \Childish\query\Builder|static |
||
592 | */ |
||
593 | public function orWhereNotIn($column, $values) |
||
594 | { |
||
595 | return $this->whereNotIn($column, $values, 'or'); |
||
596 | } |
||
597 | |||
598 | |||
599 | /** |
||
600 | * Add an external sub-select to the query. |
||
601 | * |
||
602 | * @param string $column |
||
603 | * @param \Childish\query\Builder|static $query |
||
604 | * @param string $boolean |
||
605 | * @param bool $not |
||
606 | * @return $this |
||
607 | */ |
||
608 | protected function whereInExistingQuery($column, $query, $boolean, $not) |
||
609 | { |
||
610 | $type = $not ? 'NotInSub' : 'InSub'; |
||
611 | |||
612 | $this->wheres[] = compact('type', 'column', 'query', 'boolean'); |
||
613 | |||
614 | $this->addBinding($query->getBindings(), 'where'); |
||
615 | |||
616 | return $this; |
||
617 | } |
||
618 | |||
619 | /** |
||
620 | * Add a "where null" clause to the query. |
||
621 | * |
||
622 | * @param string $column |
||
623 | * @param string $boolean |
||
624 | * @param bool $not |
||
625 | * @return $this |
||
626 | */ |
||
627 | public function whereNull($column, $boolean = 'and', $not = false) |
||
628 | { |
||
629 | $type = $not ? 'NotNull' : 'Null'; |
||
630 | |||
631 | $this->wheres[] = compact('type', 'column', 'boolean'); |
||
632 | |||
633 | return $this; |
||
634 | } |
||
635 | |||
636 | /** |
||
637 | * Add an "or where null" clause to the query. |
||
638 | * |
||
639 | * @param string $column |
||
640 | * @return \Childish\query\Builder|static |
||
641 | */ |
||
642 | public function orWhereNull($column) |
||
643 | { |
||
644 | return $this->whereNull($column, 'or'); |
||
645 | } |
||
646 | |||
647 | /** |
||
648 | * Add a "where not null" clause to the query. |
||
649 | * |
||
650 | * @param string $column |
||
651 | * @param string $boolean |
||
652 | * @return \Childish\query\Builder|static |
||
653 | */ |
||
654 | public function whereNotNull($column, $boolean = 'and') |
||
655 | { |
||
656 | return $this->whereNull($column, $boolean, true); |
||
657 | } |
||
658 | |||
659 | /** |
||
660 | * Add a where between statement to the query. |
||
661 | * |
||
662 | * @param string $column |
||
663 | * @param array $values |
||
664 | * @param string $boolean |
||
665 | * @param bool $not |
||
666 | * @return $this |
||
667 | */ |
||
668 | public function whereBetween($column, array $values, $boolean = 'and', $not = false) |
||
669 | { |
||
670 | $type = 'between'; |
||
671 | |||
672 | $this->wheres[] = compact('column', 'type', 'boolean', 'not'); |
||
673 | |||
674 | $this->addBinding($values, 'where'); |
||
675 | |||
676 | return $this; |
||
677 | } |
||
678 | |||
679 | /** |
||
680 | * Add an or where between statement to the query. |
||
681 | * |
||
682 | * @param string $column |
||
683 | * @param array $values |
||
684 | * @return \Childish\query\Builder|static |
||
685 | */ |
||
686 | public function orWhereBetween($column, array $values) |
||
687 | { |
||
688 | return $this->whereBetween($column, $values, 'or'); |
||
689 | } |
||
690 | |||
691 | /** |
||
692 | * Add a where not between statement to the query. |
||
693 | * |
||
694 | * @param string $column |
||
695 | * @param array $values |
||
696 | * @param string $boolean |
||
697 | * @return \Childish\query\Builder|static |
||
698 | */ |
||
699 | public function whereNotBetween($column, array $values, $boolean = 'and') |
||
700 | { |
||
701 | return $this->whereBetween($column, $values, $boolean, true); |
||
702 | } |
||
703 | |||
704 | /** |
||
705 | * Add an or where not between statement to the query. |
||
706 | * |
||
707 | * @param string $column |
||
708 | * @param array $values |
||
709 | * @return \Childish\query\Builder|static |
||
710 | */ |
||
711 | public function orWhereNotBetween($column, array $values) |
||
712 | { |
||
713 | return $this->whereNotBetween($column, $values, 'or'); |
||
714 | } |
||
715 | |||
716 | /** |
||
717 | * Add an "or where not null" clause to the query. |
||
718 | * |
||
719 | * @param string $column |
||
720 | * @return \Childish\query\Builder|static |
||
721 | */ |
||
722 | public function orWhereNotNull($column) |
||
723 | { |
||
724 | return $this->whereNotNull($column, 'or'); |
||
725 | } |
||
726 | |||
727 | /** |
||
728 | * Add a "where date" statement to the query. |
||
729 | * |
||
730 | * @param string $column |
||
731 | * @param string $operator |
||
732 | * @param mixed $value |
||
733 | * @param string $boolean |
||
734 | * @return \Childish\query\Builder|static |
||
735 | */ |
||
736 | public function whereDate($column, $operator, $value = null, $boolean = 'and') |
||
737 | { |
||
738 | list($value, $operator) = $this->prepareValueAndOperator( |
||
739 | $value, $operator, func_num_args() == 2 |
||
740 | ); |
||
741 | |||
742 | return $this->addDateBasedWhere('Date', $column, $operator, $value, $boolean); |
||
743 | } |
||
744 | |||
745 | /** |
||
746 | * Add an "or where date" statement to the query. |
||
747 | * |
||
748 | * @param string $column |
||
749 | * @param string $operator |
||
750 | * @param string $value |
||
751 | * @return \Childish\query\Builder|static |
||
752 | */ |
||
753 | public function orWhereDate($column, $operator, $value) |
||
754 | { |
||
755 | return $this->whereDate($column, $operator, $value, 'or'); |
||
756 | } |
||
757 | |||
758 | /** |
||
759 | * Add a "where time" statement to the query. |
||
760 | * |
||
761 | * @param string $column |
||
762 | * @param string $operator |
||
763 | * @param int $value |
||
764 | * @param string $boolean |
||
765 | * @return \Childish\query\Builder|static |
||
766 | */ |
||
767 | public function whereTime($column, $operator, $value, $boolean = 'and') |
||
768 | { |
||
769 | return $this->addDateBasedWhere('Time', $column, $operator, $value, $boolean); |
||
770 | } |
||
771 | |||
772 | /** |
||
773 | * Add an "or where time" statement to the query. |
||
774 | * |
||
775 | * @param string $column |
||
776 | * @param string $operator |
||
777 | * @param int $value |
||
778 | * @return \Childish\query\Builder|static |
||
779 | */ |
||
780 | public function orWhereTime($column, $operator, $value) |
||
781 | { |
||
782 | return $this->whereTime($column, $operator, $value, 'or'); |
||
783 | } |
||
784 | |||
785 | /** |
||
786 | * Add a "where day" statement to the query. |
||
787 | * |
||
788 | * @param string $column |
||
789 | * @param string $operator |
||
790 | * @param mixed $value |
||
791 | * @param string $boolean |
||
792 | * @return \Childish\query\Builder|static |
||
793 | */ |
||
794 | public function whereDay($column, $operator, $value = null, $boolean = 'and') |
||
795 | { |
||
796 | list($value, $operator) = $this->prepareValueAndOperator( |
||
797 | $value, $operator, func_num_args() == 2 |
||
798 | ); |
||
799 | |||
800 | return $this->addDateBasedWhere('Day', $column, $operator, $value, $boolean); |
||
801 | } |
||
802 | |||
803 | /** |
||
804 | * Add a "where month" statement to the query. |
||
805 | * |
||
806 | * @param string $column |
||
807 | * @param string $operator |
||
808 | * @param mixed $value |
||
809 | * @param string $boolean |
||
810 | * @return \Childish\query\Builder|static |
||
811 | */ |
||
812 | public function whereMonth($column, $operator, $value = null, $boolean = 'and') |
||
813 | { |
||
814 | list($value, $operator) = $this->prepareValueAndOperator( |
||
815 | $value, $operator, func_num_args() == 2 |
||
816 | ); |
||
817 | |||
818 | return $this->addDateBasedWhere('Month', $column, $operator, $value, $boolean); |
||
819 | } |
||
820 | |||
821 | /** |
||
822 | * Add a "where year" statement to the query. |
||
823 | * |
||
824 | * @param string $column |
||
825 | * @param string $operator |
||
826 | * @param mixed $value |
||
827 | * @param string $boolean |
||
828 | * @return \Childish\query\Builder|static |
||
829 | */ |
||
830 | public function whereYear($column, $operator, $value = null, $boolean = 'and') |
||
831 | { |
||
832 | list($value, $operator) = $this->prepareValueAndOperator( |
||
833 | $value, $operator, func_num_args() == 2 |
||
834 | ); |
||
835 | |||
836 | return $this->addDateBasedWhere('Year', $column, $operator, $value, $boolean); |
||
837 | } |
||
838 | |||
839 | /** |
||
840 | * Add a date based (year, month, day, time) statement to the query. |
||
841 | * |
||
842 | * @param string $type |
||
843 | * @param string $column |
||
844 | * @param string $operator |
||
845 | * @param int $value |
||
846 | * @param string $boolean |
||
847 | * @return $this |
||
848 | */ |
||
849 | protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and') |
||
850 | { |
||
851 | $this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value'); |
||
852 | |||
853 | $this->addBinding($value, 'where'); |
||
854 | |||
855 | return $this; |
||
856 | } |
||
857 | |||
858 | /** |
||
859 | * Add a nested where statement to the query. |
||
860 | * |
||
861 | * @param \Closure $callback |
||
862 | * @param string $boolean |
||
863 | * @return \Childish\query\Builder|static |
||
864 | */ |
||
865 | public function whereNested(Closure $callback, $boolean = 'and') |
||
866 | { |
||
867 | call_user_func($callback, $query = $this->forNestedWhere()); |
||
868 | |||
869 | return $this->addNestedWhereQuery($query, $boolean); |
||
870 | } |
||
871 | |||
872 | /** |
||
873 | * Create a new query instance for nested where condition. |
||
874 | * |
||
875 | * @return \Childish\query\Builder |
||
876 | */ |
||
877 | public function forNestedWhere() |
||
878 | { |
||
879 | return $this->newQuery()->from($this->from); |
||
880 | } |
||
881 | |||
882 | /** |
||
883 | * Add another query builder as a nested where to the query builder. |
||
884 | * |
||
885 | * @param \Childish\query\Builder|static $query |
||
886 | * @param string $boolean |
||
887 | * @return $this |
||
888 | */ |
||
889 | public function addNestedWhereQuery($query, $boolean = 'and') |
||
890 | { |
||
891 | if (count($query->wheres)) { |
||
892 | $type = 'Nested'; |
||
893 | |||
894 | $this->wheres[] = compact('type', 'query', 'boolean'); |
||
895 | |||
896 | $this->addBinding($query->getBindings(), 'where'); |
||
897 | } |
||
898 | |||
899 | return $this; |
||
900 | } |
||
901 | |||
902 | /** |
||
903 | * Add an exists clause to the query. |
||
904 | * |
||
905 | * @param \Closure $callback |
||
906 | * @param string $boolean |
||
907 | * @param bool $not |
||
908 | * @return $this |
||
909 | */ |
||
910 | public function whereExists(Closure $callback, $boolean = 'and', $not = false) |
||
911 | { |
||
912 | $query = $this->forSubQuery(); |
||
913 | |||
914 | // Similar to the sub-select clause, we will create a new query instance so |
||
915 | // the developer may cleanly specify the entire exists query and we will |
||
916 | // compile the whole thing in the grammar and insert it into the SQL. |
||
917 | call_user_func($callback, $query); |
||
918 | |||
919 | return $this->addWhereExistsQuery($query, $boolean, $not); |
||
920 | } |
||
921 | |||
922 | /** |
||
923 | * Add an or exists clause to the query. |
||
924 | * |
||
925 | * @param \Closure $callback |
||
926 | * @param bool $not |
||
927 | * @return \Childish\query\Builder|static |
||
928 | */ |
||
929 | public function orWhereExists(Closure $callback, $not = false) |
||
930 | { |
||
931 | return $this->whereExists($callback, 'or', $not); |
||
932 | } |
||
933 | |||
934 | /** |
||
935 | * Add a where not exists clause to the query. |
||
936 | * |
||
937 | * @param \Closure $callback |
||
938 | * @param string $boolean |
||
939 | * @return \Childish\query\Builder|static |
||
940 | */ |
||
941 | public function whereNotExists(Closure $callback, $boolean = 'and') |
||
942 | { |
||
943 | return $this->whereExists($callback, $boolean, true); |
||
944 | } |
||
945 | |||
946 | /** |
||
947 | * Add a where not exists clause to the query. |
||
948 | * |
||
949 | * @param \Closure $callback |
||
950 | * @return \Childish\query\Builder|static |
||
951 | */ |
||
952 | public function orWhereNotExists(Closure $callback) |
||
953 | { |
||
954 | return $this->orWhereExists($callback, true); |
||
955 | } |
||
956 | |||
957 | /** |
||
958 | * Add an exists clause to the query. |
||
959 | * |
||
960 | * @param \Childish\query\Builder $query |
||
961 | * @param string $boolean |
||
962 | * @param bool $not |
||
963 | * @return $this |
||
964 | */ |
||
965 | public function addWhereExistsQuery(Builder $query, $boolean = 'and', $not = false) |
||
966 | { |
||
967 | $type = $not ? 'NotExists' : 'Exists'; |
||
968 | |||
969 | $this->wheres[] = compact('type', 'operator', 'query', 'boolean'); |
||
970 | |||
971 | $this->addBinding($query->getBindings(), 'where'); |
||
972 | |||
973 | return $this; |
||
974 | } |
||
975 | |||
976 | |||
977 | /** |
||
978 | * Add a "group by" clause to the query. |
||
979 | * |
||
980 | * @param array ...$groups |
||
981 | * @return $this |
||
982 | */ |
||
983 | public function groupBy(...$groups) |
||
984 | { |
||
985 | foreach ($groups as $group) { |
||
986 | $this->groups = array_merge( |
||
987 | (array)$this->groups, |
||
988 | Tools::wrap($group) |
||
989 | ); |
||
990 | } |
||
991 | |||
992 | return $this; |
||
993 | } |
||
994 | |||
995 | /** |
||
996 | * Add a "having" clause to the query. |
||
997 | * |
||
998 | * @param string $column |
||
999 | * @param string|null $operator |
||
1000 | * @param string|null $value |
||
1001 | * @param string $boolean |
||
1002 | * @return $this |
||
1003 | */ |
||
1004 | public function having($column, $operator = null, $value = null, $boolean = 'and') |
||
1005 | { |
||
1006 | $type = 'Basic'; |
||
1007 | |||
1008 | // Here we will make some assumptions about the operator. If only 2 values are |
||
1009 | // passed to the method, we will assume that the operator is an equals sign |
||
1010 | // and keep going. Otherwise, we'll require the operator to be passed in. |
||
1011 | list($value, $operator) = $this->prepareValueAndOperator( |
||
1012 | $value, $operator, func_num_args() == 2 |
||
1013 | ); |
||
1014 | |||
1015 | // If the given operator is not found in the list of valid operators we will |
||
1016 | // assume that the developer is just short-cutting the '=' operators and |
||
1017 | // we will set the operators to '=' and set the values appropriately. |
||
1018 | if ($this->invalidOperator($operator)) { |
||
1019 | list($value, $operator) = [$operator, '=']; |
||
1020 | } |
||
1021 | |||
1022 | $this->havings[] = compact('type', 'column', 'operator', 'value', 'boolean'); |
||
1023 | |||
1024 | if (!$value instanceof Expression) { |
||
0 ignored issues
–
show
The class
Childish\query\Expression does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
1025 | $this->addBinding($value, 'having'); |
||
1026 | } |
||
1027 | |||
1028 | return $this; |
||
1029 | } |
||
1030 | |||
1031 | /** |
||
1032 | * Add a "or having" clause to the query. |
||
1033 | * |
||
1034 | * @param string $column |
||
1035 | * @param string|null $operator |
||
1036 | * @param string|null $value |
||
1037 | * @return \Childish\query\Builder|static |
||
1038 | */ |
||
1039 | public function orHaving($column, $operator = null, $value = null) |
||
1040 | { |
||
1041 | return $this->having($column, $operator, $value, 'or'); |
||
1042 | } |
||
1043 | |||
1044 | /** |
||
1045 | * Add a raw having clause to the query. |
||
1046 | * |
||
1047 | * @param string $sql |
||
1048 | * @param array $bindings |
||
1049 | * @param string $boolean |
||
1050 | * @return $this |
||
1051 | */ |
||
1052 | public function havingRaw($sql, array $bindings = [], $boolean = 'and') |
||
1053 | { |
||
1054 | $type = 'Raw'; |
||
1055 | |||
1056 | $this->havings[] = compact('type', 'sql', 'boolean'); |
||
1057 | |||
1058 | $this->addBinding($bindings, 'having'); |
||
1059 | |||
1060 | return $this; |
||
1061 | } |
||
1062 | |||
1063 | /** |
||
1064 | * Add a raw or having clause to the query. |
||
1065 | * |
||
1066 | * @param string $sql |
||
1067 | * @param array $bindings |
||
1068 | * @return \Childish\query\Builder|static |
||
1069 | */ |
||
1070 | public function orHavingRaw($sql, array $bindings = []) |
||
1071 | { |
||
1072 | return $this->havingRaw($sql, $bindings, 'or'); |
||
1073 | } |
||
1074 | |||
1075 | /** |
||
1076 | * Add an "order by" clause to the query. |
||
1077 | * |
||
1078 | * @param string $column |
||
1079 | * @param string $direction |
||
1080 | * @return $this |
||
1081 | */ |
||
1082 | public function orderBy($column, $direction = 'asc') |
||
1083 | { |
||
1084 | $this->{$this->unions ? 'unionOrders' : 'orders'}[] = [ |
||
1085 | 'column' => $column, |
||
1086 | 'direction' => strtolower($direction) == 'asc' ? 'asc' : 'desc', |
||
1087 | ]; |
||
1088 | |||
1089 | return $this; |
||
1090 | } |
||
1091 | |||
1092 | /** |
||
1093 | * Add a descending "order by" clause to the query. |
||
1094 | * |
||
1095 | * @param string $column |
||
1096 | * @return $this |
||
1097 | */ |
||
1098 | public function orderByDesc($column) |
||
1099 | { |
||
1100 | return $this->orderBy($column, 'desc'); |
||
1101 | } |
||
1102 | |||
1103 | /** |
||
1104 | * Add a raw "order by" clause to the query. |
||
1105 | * |
||
1106 | * @param string $sql |
||
1107 | * @param array $bindings |
||
1108 | * @return $this |
||
1109 | */ |
||
1110 | public function orderByRaw($sql, $bindings = []) |
||
1111 | { |
||
1112 | $type = 'Raw'; |
||
1113 | |||
1114 | $this->{$this->unions ? 'unionOrders' : 'orders'}[] = compact('type', 'sql'); |
||
1115 | |||
1116 | $this->addBinding($bindings, 'order'); |
||
1117 | |||
1118 | return $this; |
||
1119 | } |
||
1120 | |||
1121 | /** |
||
1122 | * Alias to set the "offset" value of the query. |
||
1123 | * |
||
1124 | * @param int $value |
||
1125 | * @return \Childish\query\Builder|static |
||
1126 | */ |
||
1127 | public function skip($value) |
||
1128 | { |
||
1129 | return $this->offset($value); |
||
1130 | } |
||
1131 | |||
1132 | /** |
||
1133 | * Set the "offset" value of the query. |
||
1134 | * |
||
1135 | * @param int $value |
||
1136 | * @return $this |
||
1137 | */ |
||
1138 | public function offset($value) |
||
1139 | { |
||
1140 | $property = $this->unions ? 'unionOffset' : 'offset'; |
||
1141 | |||
1142 | $this->$property = max(0, $value); |
||
1143 | |||
1144 | return $this; |
||
1145 | } |
||
1146 | |||
1147 | /** |
||
1148 | * Alias to set the "limit" value of the query. |
||
1149 | * |
||
1150 | * @param int $value |
||
1151 | * @return \Childish\query\Builder|static |
||
1152 | */ |
||
1153 | public function take($value) |
||
1154 | { |
||
1155 | return $this->limit($value); |
||
1156 | } |
||
1157 | |||
1158 | /** |
||
1159 | * Set the "limit" value of the query. |
||
1160 | * |
||
1161 | * @param int $value |
||
1162 | * @return $this |
||
1163 | */ |
||
1164 | public function limit($value) |
||
1165 | { |
||
1166 | $property = $this->unions ? 'unionLimit' : 'limit'; |
||
1167 | |||
1168 | if ($value >= 0) { |
||
1169 | $this->$property = $value; |
||
1170 | } |
||
1171 | |||
1172 | return $this; |
||
1173 | } |
||
1174 | |||
1175 | /** |
||
1176 | * Set the limit and offset for a given page. |
||
1177 | * |
||
1178 | * @param int $page |
||
1179 | * @param int $perPage |
||
1180 | * @return \Childish\query\Builder|static |
||
1181 | */ |
||
1182 | public function forPage($page, $perPage = 15) |
||
1183 | { |
||
1184 | return $this->skip(($page - 1) * $perPage)->take($perPage); |
||
1185 | } |
||
1186 | |||
1187 | /** |
||
1188 | * Add a union statement to the query. |
||
1189 | * |
||
1190 | * @param \Childish\query\Builder|\Closure $query |
||
1191 | * @param bool $all |
||
1192 | * @return \Childish\query\Builder|static |
||
1193 | */ |
||
1194 | public function union($query, $all = false) |
||
1195 | { |
||
1196 | if ($query instanceof Closure) { |
||
1197 | call_user_func($query, $query = $this->newQuery()); |
||
1198 | } |
||
1199 | |||
1200 | $this->unions[] = compact('query', 'all'); |
||
1201 | |||
1202 | $this->addBinding($query->getBindings(), 'union'); |
||
1203 | |||
1204 | return $this; |
||
1205 | } |
||
1206 | |||
1207 | /** |
||
1208 | * Add a union all statement to the query. |
||
1209 | * |
||
1210 | * @param \Childish\query\Builder|\Closure $query |
||
1211 | * @return \Childish\query\Builder|static |
||
1212 | */ |
||
1213 | public function unionAll($query) |
||
1214 | { |
||
1215 | return $this->union($query, true); |
||
1216 | } |
||
1217 | |||
1218 | /** |
||
1219 | * Lock the selected rows in the table. |
||
1220 | * |
||
1221 | * @param string|bool $value |
||
1222 | * @return $this |
||
1223 | */ |
||
1224 | public function lock($value = true) |
||
1225 | { |
||
1226 | $this->lock = $value; |
||
1227 | |||
1228 | if (!is_null($this->lock)) { |
||
1229 | $this->useWritePdo(); |
||
1230 | } |
||
1231 | |||
1232 | return $this; |
||
1233 | } |
||
1234 | |||
1235 | /** |
||
1236 | * Lock the selected rows in the table for updating. |
||
1237 | * |
||
1238 | * @return \Childish\query\Builder |
||
1239 | */ |
||
1240 | public function lockForUpdate() |
||
1241 | { |
||
1242 | return $this->lock(true); |
||
1243 | } |
||
1244 | |||
1245 | /** |
||
1246 | * Share lock the selected rows in the table. |
||
1247 | * |
||
1248 | * @return \Childish\query\Builder |
||
1249 | */ |
||
1250 | public function sharedLock() |
||
1251 | { |
||
1252 | return $this->lock(false); |
||
1253 | } |
||
1254 | |||
1255 | /** |
||
1256 | * Get the SQL representation of the query. |
||
1257 | * |
||
1258 | * @return string |
||
1259 | */ |
||
1260 | public function toSql() |
||
1261 | { |
||
1262 | return $this->grammar->compileSelect($this); |
||
1263 | } |
||
1264 | |||
1265 | /** |
||
1266 | * Execute a query for a single record by ID. |
||
1267 | * |
||
1268 | * @param int $id |
||
1269 | * @param array $columns |
||
1270 | * @return mixed|static |
||
1271 | */ |
||
1272 | public function find($id, $columns = ['*']) |
||
1273 | { |
||
1274 | return $this->where('id', '=', $id)->first($columns); |
||
1275 | } |
||
1276 | |||
1277 | /** |
||
1278 | * Get a single column's value from the first result of a query. |
||
1279 | * |
||
1280 | * @param string $column |
||
1281 | * @return mixed |
||
1282 | */ |
||
1283 | public function value($column) |
||
1284 | { |
||
1285 | $result = (array)$this->first([$column]); |
||
1286 | |||
1287 | return count($result) > 0 ? reset($result) : null; |
||
1288 | } |
||
1289 | |||
1290 | /** |
||
1291 | * Execute the query as a "select" statement. |
||
1292 | * |
||
1293 | * @param array $columns |
||
1294 | * @return \childish\support\Collection |
||
1295 | */ |
||
1296 | public function get($columns = ['*']) |
||
1297 | { |
||
1298 | $original = $this->columns; |
||
1299 | |||
1300 | if (is_null($original)) { |
||
1301 | $this->columns = $columns; |
||
1302 | } |
||
1303 | |||
1304 | $results = $this->processor->processSelect($this, $this->runSelect()); |
||
1305 | |||
1306 | $this->columns = $original; |
||
0 ignored issues
–
show
It seems like
$original can be null . However, the property $columns is declared as array . Maybe change the type of the property to array|null or add a type check?
Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property. To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter. function aContainsB(array $needle = null, array $haystack) {
if (!$needle) {
return false;
}
return array_intersect($haystack, $needle) == $haystack;
}
The function can be called with either null or an array for the parameter ![]() |
|||
1307 | |||
1308 | return new Collection($results); |
||
1309 | } |
||
1310 | |||
1311 | /** |
||
1312 | * Run the query as a "select" statement against the connection. |
||
1313 | * |
||
1314 | * @return array |
||
1315 | */ |
||
1316 | protected function runSelect() |
||
1317 | { |
||
1318 | return $this->connection->select( |
||
1319 | $this->toSql(), $this->getBindings(), !$this->useWritePdo |
||
0 ignored issues
–
show
The call to
ConnectionInterface::select() has too many arguments starting with !$this->useWritePdo .
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the ![]() |
|||
1320 | ); |
||
1321 | } |
||
1322 | |||
1323 | |||
1324 | /** |
||
1325 | * Remove the column aliases since they will break count queries. |
||
1326 | * |
||
1327 | * @param array $columns |
||
1328 | * @return array |
||
1329 | */ |
||
1330 | protected function withoutSelectAliases(array $columns) |
||
1331 | { |
||
1332 | return array_map(function ($column) { |
||
1333 | return is_string($column) && ($aliasPosition = strpos(strtolower($column), ' as ')) !== false |
||
1334 | ? substr($column, 0, $aliasPosition) : $column; |
||
0 ignored issues
–
show
The variable
$aliasPosition does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
|||
1335 | }, $columns); |
||
1336 | } |
||
1337 | |||
1338 | /** |
||
1339 | * Get a generator for the given query. |
||
1340 | * |
||
1341 | * @return \Generator |
||
1342 | */ |
||
1343 | public function cursor() |
||
1344 | { |
||
1345 | if (is_null($this->columns)) { |
||
1346 | $this->columns = ['*']; |
||
1347 | } |
||
1348 | |||
1349 | return $this->connection->cursor( |
||
1350 | $this->toSql(), $this->getBindings(), !$this->useWritePdo |
||
1351 | ); |
||
1352 | } |
||
1353 | |||
1354 | /** |
||
1355 | * Chunk the results of a query by comparing numeric IDs. |
||
1356 | * |
||
1357 | * @param int $count |
||
1358 | * @param callable $callback |
||
1359 | * @param string $column |
||
1360 | * @param string $alias |
||
1361 | * @return bool |
||
1362 | */ |
||
1363 | public function chunkById($count, callable $callback, $column = 'id', $alias = null) |
||
1364 | { |
||
1365 | $alias = $alias ? : $column; |
||
1366 | |||
1367 | $lastId = 0; |
||
1368 | |||
1369 | do { |
||
1370 | $clone = clone $this; |
||
1371 | |||
1372 | // We'll execute the query for the given page and get the results. If there are |
||
1373 | // no results we can just break and return from here. When there are results |
||
1374 | // we will call the callback with the current chunk of these results here. |
||
1375 | $results = $clone->forPageAfterId($count, $lastId, $column)->get(); |
||
0 ignored issues
–
show
The method
forPageAfterId() does not exist on Childish\query\Builder . Did you maybe mean forPage() ?
This check marks calls to methods that do not seem to exist on an object. This is most likely the result of a method being renamed without all references to it being renamed likewise. ![]() |
|||
1376 | |||
1377 | $countResults = $results->count(); |
||
1378 | |||
1379 | if ($countResults == 0) { |
||
1380 | break; |
||
1381 | } |
||
1382 | |||
1383 | // On each chunk result set, we will pass them to the callback and then let the |
||
1384 | // developer take care of everything within the callback, which allows us to |
||
1385 | // keep the memory low for spinning through large result sets for working. |
||
1386 | if ($callback($results) === false) { |
||
1387 | return false; |
||
1388 | } |
||
1389 | |||
1390 | $lastId = $results->last()->{$alias}; |
||
1391 | |||
1392 | unset($results); |
||
1393 | } while ($countResults == $count); |
||
1394 | |||
1395 | return true; |
||
1396 | } |
||
1397 | |||
1398 | /** |
||
1399 | * Throw an exception if the query doesn't have an orderBy clause. |
||
1400 | * |
||
1401 | * @return void |
||
1402 | * @throws \RuntimeException |
||
1403 | */ |
||
1404 | protected function enforceOrderBy() |
||
1405 | { |
||
1406 | if (empty($this->orders) && empty($this->unionOrders)) { |
||
1407 | throw new RuntimeException('You must specify an orderBy clause when using this function.'); |
||
1408 | } |
||
1409 | } |
||
1410 | |||
1411 | /** |
||
1412 | * Get an array with the values of a given column. |
||
1413 | * |
||
1414 | * @param string $column |
||
1415 | * @param string|null $key |
||
1416 | * @return \Childish\support\Collection |
||
1417 | */ |
||
1418 | public function pluck($column, $key = null) |
||
1419 | { |
||
1420 | $results = $this->get(is_null($key) ? [$column] : [$column, $key]); |
||
1421 | |||
1422 | // If the columns are qualified with a table or have an alias, we cannot use |
||
1423 | // those directly in the "pluck" operations since the results from the DB |
||
1424 | // are only keyed by the column itself. We'll strip the table out here. |
||
1425 | return $results->pluck( |
||
1426 | $this->stripTableForPluck($column), |
||
1427 | $this->stripTableForPluck($key) |
||
1428 | ); |
||
1429 | } |
||
1430 | |||
1431 | /** |
||
1432 | * Strip off the table name or alias from a column identifier. |
||
1433 | * |
||
1434 | * @param string $column |
||
1435 | * @return string|null |
||
1436 | */ |
||
1437 | protected function stripTableForPluck($column) |
||
1438 | { |
||
1439 | return is_null($column) ? $column : last(preg_split('~\.| ~', $column)); |
||
1440 | } |
||
1441 | |||
1442 | /** |
||
1443 | * Concatenate values of a given column as a string. |
||
1444 | * |
||
1445 | * @param string $column |
||
1446 | * @param string $glue |
||
1447 | * @return string |
||
1448 | */ |
||
1449 | public function implode($column, $glue = '') |
||
1450 | { |
||
1451 | return $this->pluck($column)->implode($glue); |
||
1452 | } |
||
1453 | |||
1454 | /** |
||
1455 | * Determine if any rows exist for the current query. |
||
1456 | * |
||
1457 | * @return bool |
||
1458 | */ |
||
1459 | public function exists() |
||
1460 | { |
||
1461 | $results = $this->connection->select( |
||
1462 | $this->grammar->compileExists($this), $this->getBindings(), !$this->useWritePdo |
||
0 ignored issues
–
show
The call to
ConnectionInterface::select() has too many arguments starting with !$this->useWritePdo .
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. In this case you can add the ![]() |
|||
1463 | ); |
||
1464 | |||
1465 | // If the results has rows, we will get the row and see if the exists column is a |
||
1466 | // boolean true. If there is no results for this query we will return false as |
||
1467 | // there are no rows for this query at all and we can return that info here. |
||
1468 | if (isset($results[0])) { |
||
1469 | $results = (array)$results[0]; |
||
1470 | |||
1471 | return (bool)$results['exists']; |
||
1472 | } |
||
1473 | |||
1474 | return false; |
||
1475 | } |
||
1476 | |||
1477 | /** |
||
1478 | * Retrieve the "count" result of the query. |
||
1479 | * |
||
1480 | * @param string $columns |
||
1481 | * @return int |
||
1482 | */ |
||
1483 | public function count($columns = '*') |
||
1484 | { |
||
1485 | return (int)$this->aggregate(__FUNCTION__, Tools::wrap($columns)); |
||
1486 | } |
||
1487 | |||
1488 | /** |
||
1489 | * Retrieve the minimum value of a given column. |
||
1490 | * |
||
1491 | * @param string $column |
||
1492 | * @return mixed |
||
1493 | */ |
||
1494 | public function min($column) |
||
1495 | { |
||
1496 | return $this->aggregate(__FUNCTION__, [$column]); |
||
1497 | } |
||
1498 | |||
1499 | /** |
||
1500 | * Retrieve the maximum value of a given column. |
||
1501 | * |
||
1502 | * @param string $column |
||
1503 | * @return mixed |
||
1504 | */ |
||
1505 | public function max($column) |
||
1506 | { |
||
1507 | return $this->aggregate(__FUNCTION__, [$column]); |
||
1508 | } |
||
1509 | |||
1510 | /** |
||
1511 | * Retrieve the sum of the values of a given column. |
||
1512 | * |
||
1513 | * @param string $column |
||
1514 | * @return mixed |
||
1515 | */ |
||
1516 | public function sum($column) |
||
1517 | { |
||
1518 | $result = $this->aggregate(__FUNCTION__, [$column]); |
||
1519 | |||
1520 | return $result ? : 0; |
||
1521 | } |
||
1522 | |||
1523 | /** |
||
1524 | * Retrieve the average of the values of a given column. |
||
1525 | * |
||
1526 | * @param string $column |
||
1527 | * @return mixed |
||
1528 | */ |
||
1529 | public function avg($column) |
||
1530 | { |
||
1531 | return $this->aggregate(__FUNCTION__, [$column]); |
||
1532 | } |
||
1533 | |||
1534 | /** |
||
1535 | * Alias for the "avg" method. |
||
1536 | * |
||
1537 | * @param string $column |
||
1538 | * @return mixed |
||
1539 | */ |
||
1540 | public function average($column) |
||
1541 | { |
||
1542 | return $this->avg($column); |
||
1543 | } |
||
1544 | |||
1545 | /** |
||
1546 | * Execute an aggregate function on the database. |
||
1547 | * |
||
1548 | * @param string $function |
||
1549 | * @param array $columns |
||
1550 | * @return mixed |
||
1551 | */ |
||
1552 | public function aggregate($function, $columns = ['*']) |
||
1553 | { |
||
1554 | $results = $this->cloneWithout(['columns']) |
||
1555 | ->cloneWithoutBindings(['select']) |
||
1556 | ->setAggregate($function, $columns) |
||
1557 | ->get($columns); |
||
1558 | |||
1559 | if (!$results->isEmpty()) { |
||
1560 | return array_change_key_case((array)$results[0])['aggregate']; |
||
1561 | } |
||
1562 | } |
||
1563 | |||
1564 | /** |
||
1565 | * Clone the query without the given properties. |
||
1566 | * |
||
1567 | * @param array $properties |
||
1568 | * @return static |
||
1569 | */ |
||
1570 | public function cloneWithout(array $properties) |
||
1571 | { |
||
1572 | return $this->higherOrderTap(clone $this, function ($clone) use ($properties) { |
||
1573 | foreach ($properties as $property) { |
||
1574 | $clone->{$property} = null; |
||
1575 | } |
||
1576 | }); |
||
1577 | } |
||
1578 | |||
1579 | /** |
||
1580 | * Clone the query without the given bindings. |
||
1581 | * |
||
1582 | * @param array $except |
||
1583 | * @return static |
||
1584 | */ |
||
1585 | public function cloneWithoutBindings(array $except) |
||
1586 | { |
||
1587 | return $this->higherOrderTap(clone $this, function ($clone) use ($except) { |
||
1588 | foreach ($except as $type) { |
||
1589 | $clone->bindings[$type] = []; |
||
1590 | } |
||
1591 | }); |
||
1592 | } |
||
1593 | |||
1594 | /** |
||
1595 | * Call the given Closure with the given value then return the value. |
||
1596 | * |
||
1597 | * @param mixed $value |
||
1598 | * @param callable|null $callback |
||
1599 | * @return mixed |
||
1600 | */ |
||
1601 | public function higherOrderTap($value, $callback = null) |
||
1602 | { |
||
1603 | if (is_null($callback) === false) { |
||
1604 | $callback($value); |
||
1605 | } |
||
1606 | return $value; |
||
1607 | } |
||
1608 | |||
1609 | /** |
||
1610 | * Execute a numeric aggregate function on the database. |
||
1611 | * |
||
1612 | * @param string $function |
||
1613 | * @param array $columns |
||
1614 | * @return float|int |
||
1615 | */ |
||
1616 | public function numericAggregate($function, $columns = ['*']) |
||
1617 | { |
||
1618 | $result = $this->aggregate($function, $columns); |
||
1619 | |||
1620 | // If there is no result, we can obviously just return 0 here. Next, we will check |
||
1621 | // if the result is an integer or float. If it is already one of these two data |
||
1622 | // types we can just return the result as-is, otherwise we will convert this. |
||
1623 | if (!$result) { |
||
1624 | return 0; |
||
1625 | } |
||
1626 | |||
1627 | if (is_int($result) || is_float($result)) { |
||
1628 | return $result; |
||
1629 | } |
||
1630 | |||
1631 | // If the result doesn't contain a decimal place, we will assume it is an int then |
||
1632 | // cast it to one. When it does we will cast it to a float since it needs to be |
||
1633 | // cast to the expected data type for the developers out of pure convenience. |
||
1634 | return strpos((string)$result, '.') === false |
||
1635 | ? (int)$result : (float)$result; |
||
1636 | } |
||
1637 | |||
1638 | /** |
||
1639 | * Set the aggregate property without running the query. |
||
1640 | * |
||
1641 | * @param string $function |
||
1642 | * @param array $columns |
||
1643 | * @return $this |
||
1644 | */ |
||
1645 | protected function setAggregate($function, $columns) |
||
1646 | { |
||
1647 | $this->aggregate = compact('function', 'columns'); |
||
1648 | |||
1649 | if (empty($this->groups)) { |
||
1650 | $this->orders = null; |
||
0 ignored issues
–
show
It seems like
null of type null is incompatible with the declared type array of property $orders .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||
1651 | |||
1652 | $this->bindings['order'] = []; |
||
1653 | } |
||
1654 | |||
1655 | return $this; |
||
1656 | } |
||
1657 | |||
1658 | /** |
||
1659 | * Insert a new record into the database. |
||
1660 | * |
||
1661 | * @param array $values |
||
1662 | * @return bool |
||
1663 | */ |
||
1664 | public function insert(array $values) |
||
1665 | { |
||
1666 | // Since every insert gets treated like a batch insert, we will make sure the |
||
1667 | // bindings are structured in a way that is convenient when building these |
||
1668 | // inserts statements by verifying these elements are actually an array. |
||
1669 | if (empty($values)) { |
||
1670 | return true; |
||
1671 | } |
||
1672 | |||
1673 | if (!is_array(reset($values))) { |
||
1674 | $values = [$values]; |
||
1675 | } |
||
1676 | |||
1677 | // Here, we will sort the insert keys for every record so that each insert is |
||
1678 | // in the same order for the record. We need to make sure this is the case |
||
1679 | // so there are not any errors or problems when inserting these records. |
||
1680 | else { |
||
1681 | foreach ($values as $key => $value) { |
||
1682 | ksort($value); |
||
1683 | |||
1684 | $values[$key] = $value; |
||
1685 | } |
||
1686 | } |
||
1687 | |||
1688 | // Finally, we will run this query against the database connection and return |
||
1689 | // the results. We will need to also flatten these bindings before running |
||
1690 | // the query so they are all in one huge, flattened array for execution. |
||
1691 | return $this->connection->insert( |
||
1692 | $this->grammar->compileInsert($this, $values), |
||
1693 | $this->cleanBindings(Tools::flatten($values, 1)) |
||
1694 | ); |
||
1695 | } |
||
1696 | |||
1697 | /** |
||
1698 | * Insert a new record and get the value of the primary key. |
||
1699 | * |
||
1700 | * @param array $values |
||
1701 | * @param string|null $sequence |
||
1702 | * @return int |
||
1703 | */ |
||
1704 | public function insertGetId(array $values, $sequence = null) |
||
1705 | { |
||
1706 | $sql = $this->grammar->compileInsertGetId($this, $values, $sequence); |
||
1707 | |||
1708 | $values = $this->cleanBindings($values); |
||
1709 | |||
1710 | return $this->processor->processInsertGetId($this, $sql, $values, $sequence); |
||
1711 | } |
||
1712 | |||
1713 | /** |
||
1714 | * Update a record in the database. |
||
1715 | * |
||
1716 | * @param array $values |
||
1717 | * @return int |
||
1718 | */ |
||
1719 | public function update(array $values) |
||
1720 | { |
||
1721 | $sql = $this->grammar->compileUpdate($this, $values); |
||
1722 | return $this->connection->update($sql, $this->cleanBindings( |
||
1723 | $this->grammar->prepareBindingsForUpdate($this->bindings, $values) |
||
1724 | )); |
||
1725 | } |
||
1726 | |||
1727 | /** |
||
1728 | * Insert or update a record matching the attributes, and fill it with values. |
||
1729 | * |
||
1730 | * @param array $attributes |
||
1731 | * @param array $values |
||
1732 | * @return bool |
||
1733 | */ |
||
1734 | public function updateOrInsert(array $attributes, array $values = []) |
||
1735 | { |
||
1736 | if (!$this->where($attributes)->exists()) { |
||
1737 | return $this->insert(array_merge($attributes, $values)); |
||
1738 | } |
||
1739 | |||
1740 | return (bool)$this->take(1)->update($values); |
||
1741 | } |
||
1742 | |||
1743 | /** |
||
1744 | * Increment a column's value by a given amount. |
||
1745 | * |
||
1746 | * @param string $column |
||
1747 | * @param int $amount |
||
1748 | * @param array $extra |
||
1749 | * @return int |
||
1750 | */ |
||
1751 | public function increment($column, $amount = 1, array $extra = []) |
||
1752 | { |
||
1753 | if (!is_numeric($amount)) { |
||
1754 | throw new InvalidArgumentException('Non-numeric value passed to increment method.'); |
||
1755 | } |
||
1756 | |||
1757 | $wrapped = $this->grammar->wrap($column); |
||
1758 | |||
1759 | $columns = array_merge([$column => $this->raw("$wrapped + $amount")], $extra); |
||
1760 | |||
1761 | return $this->update($columns); |
||
1762 | } |
||
1763 | |||
1764 | /** |
||
1765 | * Decrement a column's value by a given amount. |
||
1766 | * |
||
1767 | * @param string $column |
||
1768 | * @param int $amount |
||
1769 | * @param array $extra |
||
1770 | * @return int |
||
1771 | */ |
||
1772 | public function decrement($column, $amount = 1, array $extra = []) |
||
1773 | { |
||
1774 | if (!is_numeric($amount)) { |
||
1775 | throw new InvalidArgumentException('Non-numeric value passed to decrement method.'); |
||
1776 | } |
||
1777 | |||
1778 | $wrapped = $this->grammar->wrap($column); |
||
1779 | |||
1780 | $columns = array_merge([$column => $this->raw("$wrapped - $amount")], $extra); |
||
1781 | |||
1782 | return $this->update($columns); |
||
1783 | } |
||
1784 | |||
1785 | /** |
||
1786 | * Delete a record from the database. |
||
1787 | * |
||
1788 | * @param mixed $id |
||
1789 | * @return int |
||
1790 | */ |
||
1791 | public function delete($id = null) |
||
1792 | { |
||
1793 | // If an ID is passed to the method, we will set the where clause to check the |
||
1794 | // ID to let developers to simply and quickly remove a single row from this |
||
1795 | // database without manually specifying the "where" clauses on the query. |
||
1796 | if (!is_null($id)) { |
||
1797 | $this->where($this->from . '.id', '=', $id); |
||
1798 | } |
||
1799 | |||
1800 | return $this->connection->delete( |
||
1801 | $this->grammar->compileDelete($this), $this->getBindings() |
||
1802 | ); |
||
1803 | } |
||
1804 | |||
1805 | /** |
||
1806 | * Run a truncate statement on the table. |
||
1807 | * |
||
1808 | * @return void |
||
1809 | */ |
||
1810 | public function truncate() |
||
1811 | { |
||
1812 | foreach ($this->grammar->compileTruncate($this) as $sql => $bindings) { |
||
1813 | $this->connection->statement($sql, $bindings); |
||
1814 | } |
||
1815 | } |
||
1816 | |||
1817 | /** |
||
1818 | * Get a new instance of the query builder. |
||
1819 | * |
||
1820 | * @return \Childish\query\Builder |
||
1821 | */ |
||
1822 | public function newQuery() |
||
1823 | { |
||
1824 | return new static($this->connection, $this->grammar, $this->processor); |
||
1825 | } |
||
1826 | |||
1827 | /** |
||
1828 | * Create a new query instance for a sub-query. |
||
1829 | * |
||
1830 | * @return \Childish\query\Builder |
||
1831 | */ |
||
1832 | protected function forSubQuery() |
||
1833 | { |
||
1834 | return $this->newQuery(); |
||
1835 | } |
||
1836 | |||
1837 | /** |
||
1838 | * Create a raw database expression. |
||
1839 | * |
||
1840 | * @param $value |
||
1841 | * @return mixed |
||
1842 | */ |
||
1843 | public function raw($value) |
||
1844 | { |
||
1845 | return $value; |
||
1846 | } |
||
1847 | |||
1848 | /** |
||
1849 | * Get the current query value bindings in a flattened array. |
||
1850 | * |
||
1851 | * @return array |
||
1852 | */ |
||
1853 | public function getBindings() |
||
1854 | { |
||
1855 | return Tools::flatten($this->bindings); |
||
1856 | } |
||
1857 | |||
1858 | /** |
||
1859 | * Get the raw array of bindings. |
||
1860 | * |
||
1861 | * @return array |
||
1862 | */ |
||
1863 | public function getRawBindings() |
||
1864 | { |
||
1865 | return $this->bindings; |
||
1866 | } |
||
1867 | |||
1868 | /** |
||
1869 | * Set the bindings on the query builder. |
||
1870 | * |
||
1871 | * @param array $bindings |
||
1872 | * @param string $type |
||
1873 | * @return $this |
||
1874 | * @throws \InvalidArgumentException |
||
1875 | */ |
||
1876 | public function setBindings(array $bindings, $type = 'where') |
||
1877 | { |
||
1878 | if (!array_key_exists($type, $this->bindings)) { |
||
1879 | throw new InvalidArgumentException("Invalid binding type: {$type}."); |
||
1880 | } |
||
1881 | |||
1882 | $this->bindings[$type] = $bindings; |
||
1883 | |||
1884 | return $this; |
||
1885 | } |
||
1886 | |||
1887 | /** |
||
1888 | * Add a binding to the query. |
||
1889 | * |
||
1890 | * @param mixed $value |
||
1891 | * @param string $type |
||
1892 | * @return $this |
||
1893 | * @throws \InvalidArgumentException |
||
1894 | */ |
||
1895 | public function addBinding($value, $type = 'where') |
||
1896 | { |
||
1897 | if (!array_key_exists($type, $this->bindings)) { |
||
1898 | throw new InvalidArgumentException("Invalid binding type: {$type}."); |
||
1899 | } |
||
1900 | |||
1901 | if (is_array($value)) { |
||
1902 | $this->bindings[$type] = array_values(array_merge($this->bindings[$type], $value)); |
||
1903 | } else { |
||
1904 | $this->bindings[$type][] = $value; |
||
1905 | } |
||
1906 | |||
1907 | return $this; |
||
1908 | } |
||
1909 | |||
1910 | /** |
||
1911 | * Merge an array of bindings into our bindings. |
||
1912 | * |
||
1913 | * @param \Childish\query\Builder $query |
||
1914 | * @return $this |
||
1915 | */ |
||
1916 | public function mergeBindings(Builder $query) |
||
1917 | { |
||
1918 | $this->bindings = array_merge_recursive($this->bindings, $query->bindings); |
||
1919 | |||
1920 | return $this; |
||
1921 | } |
||
1922 | |||
1923 | /** |
||
1924 | * Remove all of the expressions from a list of bindings. |
||
1925 | * |
||
1926 | * @param array $bindings |
||
1927 | * @return array |
||
1928 | */ |
||
1929 | protected function cleanBindings(array $bindings) |
||
1930 | { |
||
1931 | return array_values($bindings); |
||
1932 | } |
||
1933 | |||
1934 | /** |
||
1935 | * Get the database connection instance. |
||
1936 | * |
||
1937 | * @return \Childish\connection\ConnectionInterface |
||
1938 | */ |
||
1939 | public function getConnection() |
||
1940 | { |
||
1941 | return $this->connection; |
||
1942 | } |
||
1943 | |||
1944 | /** |
||
1945 | * Get the database query processor instance. |
||
1946 | * |
||
1947 | * @return \Childish\query\Processor |
||
1948 | */ |
||
1949 | public function getProcessor() |
||
1950 | { |
||
1951 | return $this->processor; |
||
1952 | } |
||
1953 | |||
1954 | /** |
||
1955 | * Get the query grammar instance. |
||
1956 | * |
||
1957 | * @return \Childish\query\Grammar |
||
1958 | */ |
||
1959 | public function getGrammar() |
||
1960 | { |
||
1961 | return $this->grammar; |
||
1962 | } |
||
1963 | |||
1964 | /** |
||
1965 | * Use the write pdo for query. |
||
1966 | * |
||
1967 | * @return $this |
||
1968 | */ |
||
1969 | public function useWritePdo() |
||
1970 | { |
||
1971 | $this->useWritePdo = true; |
||
1972 | |||
1973 | return $this; |
||
1974 | } |
||
1975 | |||
1976 | /** |
||
1977 | * Chunk the results of the query. |
||
1978 | * |
||
1979 | * @param int $count |
||
1980 | * @param callable $callback |
||
1981 | * @return bool |
||
1982 | */ |
||
1983 | public function chunk($count, callable $callback) |
||
1984 | { |
||
1985 | $this->enforceOrderBy(); |
||
1986 | |||
1987 | $page = 1; |
||
1988 | |||
1989 | do { |
||
1990 | // We'll execute the query for the given page and get the results. If there are |
||
1991 | // no results we can just break and return from here. When there are results |
||
1992 | // we will call the callback with the current chunk of these results here. |
||
1993 | $results = $this->forPage($page, $count)->get(); |
||
1994 | |||
1995 | $countResults = $results->count(); |
||
1996 | |||
1997 | if ($countResults == 0) { |
||
1998 | break; |
||
1999 | } |
||
2000 | |||
2001 | // On each chunk result set, we will pass them to the callback and then let the |
||
2002 | // developer take care of everything within the callback, which allows us to |
||
2003 | // keep the memory low for spinning through large result sets for working. |
||
2004 | if ($callback($results, $page) === false) { |
||
2005 | return false; |
||
2006 | } |
||
2007 | |||
2008 | unset($results); |
||
2009 | |||
2010 | $page++; |
||
2011 | } while ($countResults == $count); |
||
2012 | |||
2013 | return true; |
||
2014 | } |
||
2015 | |||
2016 | /** |
||
2017 | * Execute a callback over each item while chunking. |
||
2018 | * |
||
2019 | * @param callable $callback |
||
2020 | * @param int $count |
||
2021 | * @return bool |
||
2022 | */ |
||
2023 | public function each(callable $callback, $count = 1000) |
||
2024 | { |
||
2025 | return $this->chunk($count, function ($results) use ($callback) { |
||
2026 | foreach ($results as $key => $value) { |
||
2027 | if ($callback($value, $key) === false) { |
||
2028 | return false; |
||
2029 | } |
||
2030 | } |
||
2031 | }); |
||
2032 | } |
||
2033 | |||
2034 | /** |
||
2035 | * Execute the query and get the first result. |
||
2036 | * |
||
2037 | * @param array $columns |
||
2038 | * @return \childish\support\Collection |
||
2039 | */ |
||
2040 | public function first($columns = ['*']) |
||
2041 | { |
||
2042 | return $this->take(1)->get($columns)->first(); |
||
2043 | } |
||
2044 | |||
2045 | /** |
||
2046 | * Apply the callback's query changes if the given "value" is true. |
||
2047 | * |
||
2048 | * @param mixed $value |
||
2049 | * @param callable $callback |
||
2050 | * @param callable $default |
||
2051 | * @return mixed |
||
2052 | */ |
||
2053 | public function when($value, $callback, $default = null) |
||
2054 | { |
||
2055 | if ($value) { |
||
2056 | return $callback($this, $value) ? : $this; |
||
2057 | } else if ($default) { |
||
2058 | return $default($this, $value) ? : $this; |
||
2059 | } |
||
2060 | |||
2061 | return $this; |
||
2062 | } |
||
2063 | |||
2064 | /** |
||
2065 | * Pass the query to a given callback. |
||
2066 | * |
||
2067 | * @param \Closure $callback |
||
2068 | * @return \Childish\query\Builder |
||
2069 | */ |
||
2070 | public function tap($callback) |
||
2071 | { |
||
2072 | return $this->when(true, $callback); |
||
2073 | } |
||
2074 | |||
2075 | /** |
||
2076 | * Apply the callback's query changes if the given "value" is false. |
||
2077 | * |
||
2078 | * @param mixed $value |
||
2079 | * @param callable $callback |
||
2080 | * @param callable $default |
||
2081 | * @return mixed |
||
2082 | */ |
||
2083 | public function unless($value, $callback, $default = null) |
||
2084 | { |
||
2085 | if (!$value) { |
||
2086 | return $callback($this, $value) ? : $this; |
||
2087 | } else if ($default) { |
||
2088 | return $default($this, $value) ? : $this; |
||
2089 | } |
||
2090 | |||
2091 | return $this; |
||
2092 | } |
||
2093 | } |
||
2094 |
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.