1
|
|
|
<?php |
2
|
|
|
namespace NwLaravel\Repositories\Criterias; |
3
|
|
|
|
4
|
|
|
use Prettus\Repository\Contracts\CriteriaInterface; |
5
|
|
|
use Prettus\Repository\Contracts\RepositoryInterface; |
6
|
|
|
use Illuminate\Database\Eloquent\Builder as EloquentBuilder; |
7
|
|
|
use Illuminate\Database\Eloquent\Model; |
8
|
|
|
use NwLaravel\Entities\AbstractEntity; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* Class InputCriteria |
12
|
|
|
*/ |
13
|
|
|
class InputCriteria implements CriteriaInterface |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* @var array |
17
|
|
|
*/ |
18
|
|
|
protected $input = []; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* @var array |
22
|
|
|
*/ |
23
|
|
|
protected $columns = []; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @var array |
27
|
|
|
*/ |
28
|
|
|
protected $dates = []; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* @var string |
32
|
|
|
*/ |
33
|
|
|
protected $table = ''; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* @var string |
37
|
|
|
*/ |
38
|
|
|
protected $nameSearchable = 'search'; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* @var array |
42
|
|
|
*/ |
43
|
|
|
protected $searchables = []; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @var string |
47
|
|
|
*/ |
48
|
|
|
protected $orderBy = null; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @var string |
52
|
|
|
*/ |
53
|
|
|
protected $sortedBy = 'asc'; |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* @var RepositoryInterface |
57
|
|
|
*/ |
58
|
|
|
protected $repository = null; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* @var Grammar |
62
|
|
|
*/ |
63
|
|
|
private $grammar = null; |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* Construct |
67
|
|
|
* |
68
|
|
|
* @param array $input |
69
|
|
|
*/ |
70
|
14 |
|
public function __construct(array $input = array()) |
71
|
|
|
{ |
72
|
|
|
$this->input = array_filter($input, function ($value) { |
73
|
14 |
|
return (!empty($value) || $value == "0" || is_null($value)); |
74
|
14 |
|
}); |
75
|
14 |
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Add Columns |
79
|
|
|
* |
80
|
|
|
* @param array $columns Array Columns |
81
|
|
|
* |
82
|
|
|
* @return this |
83
|
|
|
*/ |
84
|
5 |
|
public function addColumns(array $columns) |
85
|
|
|
{ |
86
|
5 |
|
$this->columns = array_unique(array_merge($this->columns, $columns)); |
87
|
5 |
|
return $this; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Set Fields Searchable |
92
|
|
|
* |
93
|
|
|
* @param array $searchables |
94
|
|
|
* |
95
|
|
|
* @return this |
96
|
|
|
*/ |
97
|
1 |
|
public function setSearchables(array $searchables) |
98
|
|
|
{ |
99
|
1 |
|
$this->searchables = $searchables; |
100
|
1 |
|
return $this; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Set Name Fields Searchable |
105
|
|
|
* |
106
|
|
|
* @param string $name |
107
|
|
|
* |
108
|
|
|
* @return this |
109
|
|
|
*/ |
110
|
5 |
|
public function setNameSearchable($name) |
111
|
|
|
{ |
112
|
5 |
|
$this->nameSearchable = $name; |
113
|
5 |
|
return $this; |
114
|
|
|
} |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Set Order BY |
118
|
|
|
* |
119
|
|
|
* @param string $orderBy |
120
|
|
|
* |
121
|
|
|
* @return this |
122
|
|
|
*/ |
123
|
5 |
|
public function setFieldOrderBy($orderBy) |
124
|
|
|
{ |
125
|
5 |
|
$this->orderBy = strtolower($orderBy); |
126
|
5 |
|
return $this; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** |
130
|
|
|
* Set Sorted By |
131
|
|
|
* |
132
|
|
|
* @param string $sortedBy |
133
|
|
|
* |
134
|
|
|
* @return this |
135
|
|
|
*/ |
136
|
5 |
|
public function setFieldSortedBy($sortedBy) |
137
|
|
|
{ |
138
|
5 |
|
$sortedBy = strtolower($sortedBy); |
139
|
5 |
|
$this->sortedBy = in_array($sortedBy, ['asc', 'desc']) ? $sortedBy : 'asc'; |
140
|
5 |
|
return $this; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Apply criteria in query |
145
|
|
|
* |
146
|
|
|
* @param Builder $query |
147
|
|
|
* |
148
|
|
|
* @return mixed |
149
|
|
|
*/ |
150
|
|
|
|
151
|
12 |
|
public function apply($query, RepositoryInterface $repository = null) |
152
|
|
|
{ |
153
|
12 |
|
if ($repository) { |
154
|
7 |
|
$this->searchables = array_merge($this->searchables, $repository->getFieldsSearchable()); |
155
|
7 |
|
} |
156
|
|
|
|
157
|
12 |
|
if ($nameSearchable = config('repository.criteria.params.search')) { |
158
|
5 |
|
$this->setNameSearchable($nameSearchable); |
159
|
5 |
|
} |
160
|
|
|
|
161
|
12 |
|
if ($orderBy = config('repository.criteria.params.orderBy')) { |
162
|
5 |
|
$this->setFieldOrderBy($orderBy); |
163
|
5 |
|
} |
164
|
|
|
|
165
|
12 |
|
if ($sortedBy = config('repository.criteria.params.sortedBy')) { |
166
|
5 |
|
$this->setFieldSortedBy($sortedBy); |
167
|
5 |
|
} |
168
|
|
|
|
169
|
12 |
|
$model = $query; |
170
|
|
|
|
171
|
12 |
|
if ($query instanceof EloquentBuilder) { |
172
|
4 |
|
$model = $query->getModel(); |
173
|
4 |
|
} |
174
|
|
|
|
175
|
12 |
|
if ($model instanceof Model) { |
176
|
10 |
|
$this->dates = $model->getDates(); |
177
|
10 |
|
$this->table = $model->getTable(); |
178
|
10 |
|
} |
179
|
|
|
|
180
|
12 |
|
if ($model instanceof AbstractEntity) { |
181
|
4 |
|
$this->addColumns($model->columns()); |
182
|
4 |
|
} |
183
|
|
|
|
184
|
|
|
$filters = [ |
185
|
12 |
|
new Filters\FilterClosure, |
186
|
12 |
|
new Filters\FilterScope($model), |
187
|
12 |
|
new Filters\FilterSearch($this->nameSearchable, $this->searchables, $this->table), |
188
|
12 |
|
new Filters\FilterExpression, |
189
|
12 |
|
new Filters\FilterArray($this->table, $this->columns, $this->dates), |
190
|
12 |
|
new Filters\FilterWhere($this->table, $this->columns, $this->dates), |
191
|
12 |
|
]; |
192
|
|
|
|
193
|
12 |
|
foreach ($this->input as $key => $value) : |
194
|
|
|
|
195
|
12 |
|
foreach ($filters as $filter) { |
196
|
12 |
|
if ($filter->filter($query, $key, $value)) { |
197
|
4 |
|
break; |
198
|
|
|
} |
199
|
12 |
|
} |
200
|
11 |
|
endforeach; |
201
|
|
|
|
202
|
|
|
// Order By |
203
|
11 |
|
if ($this->orderBy && in_array($this->orderBy, $this->columns)) { |
204
|
4 |
|
$query = $query->orderBy($this->orderBy, $this->sortedBy); |
205
|
4 |
|
} |
206
|
|
|
|
207
|
11 |
|
return $query; |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* Where |
212
|
|
|
* |
213
|
|
|
* @param Builder $query Builder |
214
|
|
|
* @param string $key Key |
215
|
|
|
* @param string $operator String Operator |
216
|
|
|
* @param int $value Value |
217
|
|
|
* |
218
|
|
|
* @throws InvalidArgumentException |
219
|
|
|
* @return mixed |
220
|
|
|
*/ |
221
|
|
|
protected function whereCriteria($query, $key, $operator = null, $value = null) |
222
|
|
|
{ |
223
|
|
|
$validOperator = function ($operator) { |
224
|
|
|
$operators = ['=', '<', '>', '<=', '>=', '<>', '!=']; |
225
|
|
|
return in_array($operator, $operators); |
226
|
|
|
}; |
227
|
|
|
|
228
|
|
|
if (! $validOperator($operator)) { |
229
|
|
|
throw new InvalidArgumentException("Illegal operator and value combination."); |
230
|
|
|
} |
231
|
|
|
|
232
|
|
|
// Raw Expression with Bidding |
233
|
|
|
if (strpos($key, '?') !== false) { |
234
|
|
|
$query = $query->whereRaw($key, (array) $value); |
235
|
|
|
return $query; |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
$table = $this->table; |
239
|
|
|
$column = $key; |
240
|
|
|
if (preg_match('/^(.+\.)(.+)/', $key, $matches)) { |
241
|
|
|
$table = $matches[1]; |
242
|
|
|
$column = $matches[2]; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
// Montagem Tabela com Coluns |
246
|
|
|
$key = $table.$column; |
247
|
|
|
|
248
|
|
|
// Attributes Valids |
249
|
|
|
if (in_array($column, $this->columns)) { |
250
|
|
|
if (is_null($value)) { |
251
|
|
|
if ($operator == '!=' || $operator == '<>') { |
252
|
|
|
$query = $query->whereNotNull($key); |
253
|
|
|
} else { |
254
|
|
|
$query = $query->whereNull($key); |
255
|
|
|
} |
256
|
|
|
return $query; |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
if (in_array($column, $this->dates)) { |
260
|
|
|
$query = $this->whereDate($query, $key, $operator, $value); |
261
|
|
|
return $query; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
// Using Where In With An Array |
265
|
|
|
if (is_array($value)) { |
266
|
|
|
if ($operator == '!=' || $operator == '<>') { |
267
|
|
|
$query = $query->whereNotIn($key, $value); |
268
|
|
|
} else { |
269
|
|
|
$query = $query->whereIn($key, $value); |
270
|
|
|
} |
271
|
|
|
return $query; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
// Busca Direta |
275
|
|
|
$query = $query->where($key, $operator, $value); |
276
|
|
|
return $query; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
$query = $this->whereBetweenColumn($query, $key, $value); |
280
|
|
|
return $query; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* Where Search |
285
|
|
|
* |
286
|
|
|
* @param Builder $query Builder |
287
|
|
|
* @param string $search String Search |
288
|
|
|
* |
289
|
|
|
* @return mixed |
290
|
|
|
*/ |
291
|
|
|
protected function whereSearch($query, $search) |
292
|
|
|
{ |
293
|
|
|
$fieldsSearchable = $this->searchables; |
294
|
|
|
$query = $query->where(function ($query) use ($fieldsSearchable, $search) { |
295
|
|
|
foreach ($fieldsSearchable as $field => $condition) { |
296
|
|
|
if (is_numeric($field)) { |
297
|
|
|
$field = $condition; |
298
|
|
|
$condition = "="; |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
$condition = trim(strtolower($condition)); |
302
|
|
|
|
303
|
|
|
if (!empty($search)) { |
304
|
|
|
$value = in_array($condition, ["like", "ilike"]) ? "%{$search}%" : $search; |
305
|
|
|
$query->orWhere($this->table.$field, $condition, $value); |
306
|
|
|
} |
307
|
|
|
} |
308
|
|
|
}); |
309
|
|
|
|
310
|
|
|
return $query; |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
/** |
314
|
|
|
* Where Date |
315
|
|
|
* |
316
|
|
|
* @param Builder $query Builder |
317
|
|
|
* @param string $key Key |
318
|
|
|
* @param string $operator String Operator |
319
|
|
|
* @param int $value Value |
320
|
|
|
* |
321
|
|
|
* @throws InvalidArgumentException |
322
|
|
|
* @return mixed |
323
|
|
|
*/ |
324
|
|
|
private function whereDate($query, $key, $operator, $value) |
325
|
|
|
{ |
326
|
|
|
if (is_string($value)) { |
327
|
|
|
$value = str_replace("_", '', $value); // Caso vier com a mascara __/__/____ |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
if (! empty($value)) { |
331
|
|
|
$date = asDateTime($value); |
332
|
|
|
|
333
|
|
|
if ($date instanceof Datetime) { |
|
|
|
|
334
|
|
|
$query = $query->whereRaw( |
335
|
|
|
$this->dateFormatDb($query, $key, $operator), |
336
|
|
|
[$date->format('Y-m-d')] |
337
|
|
|
); |
338
|
|
|
} else { |
339
|
|
|
if ($operator == '!=' || $operator == '<>') { |
340
|
|
|
$query = $query->whereNotNull($key); |
341
|
|
|
} else { |
342
|
|
|
$query = $query->whereNull($key); |
343
|
|
|
} |
344
|
|
|
} |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
return $query; |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* |
352
|
|
|
* @param Builder $query Builder Query |
353
|
|
|
* @param string $key String Key |
354
|
|
|
* @param int $value Value |
355
|
|
|
* |
356
|
|
|
*@return mixed |
357
|
|
|
*/ |
358
|
|
|
private function whereBetweenColumn($query, $key, $value) |
359
|
|
|
{ |
360
|
|
|
$table = $this->table; |
361
|
|
|
$column = $key; |
362
|
|
|
if (preg_match('/^(.+\.)(.+)/', $key, $matches)) { |
363
|
|
|
$table = $matches[1]; |
364
|
|
|
$column = $matches[2]; |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
if (preg_match('/^(.+)(_ini|_fim)$/', $column, $match) && in_array($match[1], $this->columns)) { |
368
|
|
|
$field = $match[1]; |
369
|
|
|
$operator = ($match[2]=='_ini')? '>=' : '<='; |
370
|
|
|
if (in_array($field, $this->dates)) { |
371
|
|
|
$query = $this->whereDate($query, $table.$field, $operator, $value); |
372
|
|
|
} else { |
373
|
|
|
$query = $query->where($table.$field, $operator, $value); |
374
|
|
|
} |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
return $query; |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
/** |
381
|
|
|
* Date Formate Database |
382
|
|
|
* |
383
|
|
|
* @param Builder $query Builder |
384
|
|
|
* @param string $key Column |
385
|
|
|
* @param string $operator String Operator |
386
|
|
|
* |
387
|
|
|
* @return string |
388
|
|
|
*/ |
389
|
|
|
private function dateFormatDb($query, $key, $operator) |
390
|
|
|
{ |
391
|
|
|
if (!$this->grammar) { |
392
|
|
|
$this->grammar = $query->getQuery()->getGrammar(); |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
$key = $this->grammar->wrap($key); |
396
|
|
|
|
397
|
|
|
$formatDb = sprintf("%s %s ?", $key, $operator); |
398
|
|
|
|
399
|
|
|
switch (true) { |
400
|
|
|
case $this->grammar instanceof \Illuminate\Database\Query\Grammars\MySqlGrammar: |
401
|
|
|
$formatDb = sprintf("DATE(%s) %s ?", $key, $operator); |
402
|
|
|
break; |
403
|
|
|
|
404
|
|
|
case $this->grammar instanceof \Illuminate\Database\Query\Grammars\PostgresGrammar: |
405
|
|
|
$formatDb = sprintf("DATE_TRUNC('day', %s) %s ?", $key, $operator); |
406
|
|
|
break; |
407
|
|
|
|
408
|
|
|
case $this->grammar instanceof \Illuminate\Database\Query\Grammars\SQLiteGrammar: |
409
|
|
|
$formatDb = sprintf("strftime('%%Y-%%m-%%d', %s) %s ?", $key, $operator); |
410
|
|
|
break; |
411
|
|
|
|
412
|
|
|
case $this->grammar instanceof \Illuminate\Database\Query\Grammars\SqlServerGrammar: |
413
|
|
|
$formatDb = sprintf("CAST(%s AS DATE) %s ?", $key, $operator); |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
return $formatDb; |
417
|
|
|
} |
418
|
|
|
} |
419
|
|
|
|
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.json
file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.json
to be in the root folder of your repository.Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the
require
orrequire-dev
section?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceof
checks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.