1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Encore\Admin\Grid; |
4
|
|
|
|
5
|
|
|
use Encore\Admin\Grid\Filter\AbstractFilter; |
6
|
|
|
use Encore\Admin\Grid\Filter\Layout\Layout; |
7
|
|
|
use Encore\Admin\Grid\Filter\Scope; |
8
|
|
|
use Illuminate\Contracts\Support\Arrayable; |
9
|
|
|
use Illuminate\Contracts\Support\Renderable; |
10
|
|
|
use Illuminate\Support\Arr; |
11
|
|
|
use Illuminate\Support\Collection; |
12
|
|
|
use Illuminate\Support\Str; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Class Filter. |
16
|
|
|
* |
17
|
|
|
* @method AbstractFilter equal($column, $label = '') |
18
|
|
|
* @method AbstractFilter notEqual($column, $label = '') |
19
|
|
|
* @method AbstractFilter leftLike($column, $label = '') |
20
|
|
|
* @method AbstractFilter like($column, $label = '') |
21
|
|
|
* @method AbstractFilter contains($column, $label = '') |
22
|
|
|
* @method AbstractFilter startsWith($column, $label = '') |
23
|
|
|
* @method AbstractFilter endsWith($column, $label = '') |
24
|
|
|
* @method AbstractFilter ilike($column, $label = '') |
25
|
|
|
* @method AbstractFilter gt($column, $label = '') |
26
|
|
|
* @method AbstractFilter lt($column, $label = '') |
27
|
|
|
* @method AbstractFilter between($column, $label = '') |
28
|
|
|
* @method AbstractFilter in($column, $label = '') |
29
|
|
|
* @method AbstractFilter notIn($column, $label = '') |
30
|
|
|
* @method AbstractFilter where($callback, $label = '', $column = null) |
31
|
|
|
* @method AbstractFilter date($column, $label = '') |
32
|
|
|
* @method AbstractFilter day($column, $label = '') |
33
|
|
|
* @method AbstractFilter month($column, $label = '') |
34
|
|
|
* @method AbstractFilter year($column, $label = '') |
35
|
|
|
* @method AbstractFilter hidden($name, $value) |
36
|
|
|
* @method AbstractFilter group($column, $label = '', $builder = null) |
37
|
|
|
*/ |
38
|
|
|
class Filter implements Renderable |
39
|
|
|
{ |
40
|
|
|
/** |
41
|
|
|
* @var Model |
42
|
|
|
*/ |
43
|
|
|
protected $model; |
44
|
|
|
|
45
|
|
|
/** |
46
|
|
|
* @var array |
47
|
|
|
*/ |
48
|
|
|
protected $filters = []; |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* @var array |
52
|
|
|
*/ |
53
|
|
|
protected static $supports = [ |
54
|
|
|
'equal' => Filter\Equal::class, |
55
|
|
|
'notEqual' => Filter\NotEqual::class, |
56
|
|
|
'ilike' => Filter\Ilike::class, |
57
|
|
|
'like' => Filter\Like::class, |
58
|
|
|
'gt' => Filter\Gt::class, |
59
|
|
|
'lt' => Filter\Lt::class, |
60
|
|
|
'between' => Filter\Between::class, |
61
|
|
|
'group' => Filter\Group::class, |
62
|
|
|
'where' => Filter\Where::class, |
63
|
|
|
'in' => Filter\In::class, |
64
|
|
|
'notIn' => Filter\NotIn::class, |
65
|
|
|
'date' => Filter\Date::class, |
66
|
|
|
'day' => Filter\Day::class, |
67
|
|
|
'month' => Filter\Month::class, |
68
|
|
|
'year' => Filter\Year::class, |
69
|
|
|
'hidden' => Filter\Hidden::class, |
70
|
|
|
'contains' => Filter\Like::class, |
71
|
|
|
'startsWith' => Filter\StartsWith::class, |
72
|
|
|
'endsWith' => Filter\EndsWith::class, |
73
|
|
|
]; |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* If use id filter. |
77
|
|
|
* |
78
|
|
|
* @var bool |
79
|
|
|
*/ |
80
|
|
|
protected $useIdFilter = true; |
81
|
|
|
|
82
|
|
|
/** |
83
|
|
|
* Id filter was removed. |
84
|
|
|
* |
85
|
|
|
* @var bool |
86
|
|
|
*/ |
87
|
|
|
protected $idFilterRemoved = false; |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Action of search form. |
91
|
|
|
* |
92
|
|
|
* @var string |
93
|
|
|
*/ |
94
|
|
|
protected $action; |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* @var string |
98
|
|
|
*/ |
99
|
|
|
protected $view = 'admin::filter.container'; |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* @var string |
103
|
|
|
*/ |
104
|
|
|
protected $filterID = 'filter-box'; |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @var string |
108
|
|
|
*/ |
109
|
|
|
protected $name = ''; |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @var bool |
113
|
|
|
*/ |
114
|
|
|
public $expand = false; |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* @var Collection |
118
|
|
|
*/ |
119
|
|
|
protected $scopes; |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* @var Layout |
123
|
|
|
*/ |
124
|
|
|
protected $layout; |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* Set this filter only in the layout. |
128
|
|
|
* |
129
|
|
|
* @var bool |
130
|
|
|
*/ |
131
|
|
|
protected $thisFilterLayoutOnly = false; |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Columns of filter that are layout-only. |
135
|
|
|
* |
136
|
|
|
* @var array |
137
|
|
|
*/ |
138
|
|
|
protected $layoutOnlyFilterColumns = []; |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Primary key of giving model. |
142
|
|
|
* |
143
|
|
|
* @var mixed |
144
|
|
|
*/ |
145
|
|
|
protected $primaryKey; |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* Create a new filter instance. |
149
|
|
|
* |
150
|
|
|
* @param Model $model |
151
|
|
|
*/ |
152
|
|
|
public function __construct(Model $model) |
153
|
|
|
{ |
154
|
|
|
$this->model = $model; |
155
|
|
|
|
156
|
|
|
$this->primaryKey = $this->model->eloquent()->getKeyName(); |
157
|
|
|
|
158
|
|
|
$this->initLayout(); |
159
|
|
|
|
160
|
|
|
$this->equal($this->primaryKey, strtoupper($this->primaryKey)); |
161
|
|
|
$this->scopes = new Collection(); |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* Initialize filter layout. |
166
|
|
|
*/ |
167
|
|
|
protected function initLayout() |
168
|
|
|
{ |
169
|
|
|
$this->layout = new Filter\Layout\Layout($this); |
170
|
|
|
} |
171
|
|
|
|
172
|
|
|
/** |
173
|
|
|
* Set action of search form. |
174
|
|
|
* |
175
|
|
|
* @param string $action |
176
|
|
|
* |
177
|
|
|
* @return $this |
178
|
|
|
*/ |
179
|
|
|
public function setAction($action) |
180
|
|
|
{ |
181
|
|
|
$this->action = $action; |
182
|
|
|
|
183
|
|
|
return $this; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Get grid model. |
188
|
|
|
* |
189
|
|
|
* @return Model |
190
|
|
|
*/ |
191
|
|
|
public function getModel() |
192
|
|
|
{ |
193
|
|
|
$conditions = array_merge( |
194
|
|
|
$this->conditions(), |
195
|
|
|
$this->scopeConditions() |
196
|
|
|
); |
197
|
|
|
|
198
|
|
|
return $this->model->addConditions($conditions); |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* Set ID of search form. |
203
|
|
|
* |
204
|
|
|
* @param string $filterID |
205
|
|
|
* |
206
|
|
|
* @return $this |
207
|
|
|
*/ |
208
|
|
|
public function setFilterID($filterID) |
209
|
|
|
{ |
210
|
|
|
$this->filterID = $filterID; |
211
|
|
|
|
212
|
|
|
return $this; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
/** |
216
|
|
|
* Get filter ID. |
217
|
|
|
* |
218
|
|
|
* @return string |
219
|
|
|
*/ |
220
|
|
|
public function getFilterID() |
221
|
|
|
{ |
222
|
|
|
return $this->filterID; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* @param $name |
227
|
|
|
* |
228
|
|
|
* @return $this |
229
|
|
|
*/ |
230
|
|
|
public function setName($name) |
231
|
|
|
{ |
232
|
|
|
$this->name = $name; |
233
|
|
|
|
234
|
|
|
$this->setFilterID("{$this->name}-{$this->filterID}"); |
235
|
|
|
|
236
|
|
|
return $this; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* @return string |
241
|
|
|
*/ |
242
|
|
|
public function getName() |
243
|
|
|
{ |
244
|
|
|
return $this->name; |
245
|
|
|
} |
246
|
|
|
|
247
|
|
|
/** |
248
|
|
|
* Disable Id filter. |
249
|
|
|
* |
250
|
|
|
* @return $this |
251
|
|
|
*/ |
252
|
|
|
public function disableIdFilter(bool $disable = true) |
253
|
|
|
{ |
254
|
|
|
$this->useIdFilter = !$disable; |
255
|
|
|
|
256
|
|
|
return $this; |
257
|
|
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* Remove ID filter if needed. |
261
|
|
|
*/ |
262
|
|
|
public function removeIDFilterIfNeeded() |
263
|
|
|
{ |
264
|
|
|
if (!$this->useIdFilter && !$this->idFilterRemoved) { |
265
|
|
|
$this->removeDefaultIDFilter(); |
266
|
|
|
|
267
|
|
|
$this->layout->removeDefaultIDFilter(); |
268
|
|
|
|
269
|
|
|
$this->idFilterRemoved = true; |
270
|
|
|
} |
271
|
|
|
} |
272
|
|
|
|
273
|
|
|
/** |
274
|
|
|
* Remove the default ID filter. |
275
|
|
|
*/ |
276
|
|
|
protected function removeDefaultIDFilter() |
277
|
|
|
{ |
278
|
|
|
array_shift($this->filters); |
279
|
|
|
} |
280
|
|
|
|
281
|
|
|
/** |
282
|
|
|
* Remove filter by filter id. |
283
|
|
|
* |
284
|
|
|
* @param mixed $id |
285
|
|
|
*/ |
286
|
|
|
public function removeFilterByID($id) |
287
|
|
|
{ |
288
|
|
|
$this->filters = array_filter($this->filters, function (AbstractFilter $filter) use ($id) { |
289
|
|
|
return $filter->getId() != $id; |
290
|
|
|
}); |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
/** |
294
|
|
|
* Get all conditions of the filters. |
295
|
|
|
* |
296
|
|
|
* @return array |
297
|
|
|
*/ |
298
|
|
|
public function conditions() |
299
|
|
|
{ |
300
|
|
|
$inputs = Arr::dot(request()->all()); |
301
|
|
|
|
302
|
|
|
$inputs = array_filter($inputs, function ($input) { |
303
|
|
|
return $input !== '' && !is_null($input); |
304
|
|
|
}); |
305
|
|
|
|
306
|
|
|
$this->sanitizeInputs($inputs); |
307
|
|
|
|
308
|
|
|
if (empty($inputs)) { |
309
|
|
|
return []; |
310
|
|
|
} |
311
|
|
|
|
312
|
|
|
$params = []; |
313
|
|
|
|
314
|
|
|
foreach ($inputs as $key => $value) { |
315
|
|
|
Arr::set($params, $key, $value); |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
$conditions = []; |
319
|
|
|
|
320
|
|
|
$this->removeIDFilterIfNeeded(); |
321
|
|
|
|
322
|
|
|
foreach ($this->filters() as $filter) { |
323
|
|
|
if (in_array($column = $filter->getColumn(), $this->layoutOnlyFilterColumns)) { |
324
|
|
|
$filter->default(Arr::get($params, $column)); |
325
|
|
|
} else { |
326
|
|
|
$conditions[] = $filter->condition($params); |
327
|
|
|
} |
328
|
|
|
} |
329
|
|
|
|
330
|
|
|
return tap(array_filter($conditions), function ($conditions) { |
331
|
|
|
if (!empty($conditions)) { |
332
|
|
|
$this->expand(); |
333
|
|
|
} |
334
|
|
|
}); |
335
|
|
|
} |
336
|
|
|
|
337
|
|
|
/** |
338
|
|
|
* @param $inputs |
339
|
|
|
* |
340
|
|
|
* @return array |
341
|
|
|
*/ |
342
|
|
|
protected function sanitizeInputs(&$inputs) |
343
|
|
|
{ |
344
|
|
|
if (!$this->name) { |
345
|
|
|
return $inputs; |
346
|
|
|
} |
347
|
|
|
|
348
|
|
|
$inputs = collect($inputs)->filter(function ($input, $key) { |
349
|
|
|
return Str::startsWith($key, "{$this->name}_"); |
350
|
|
|
})->mapWithKeys(function ($val, $key) { |
351
|
|
|
$key = str_replace("{$this->name}_", '', $key); |
352
|
|
|
|
353
|
|
|
return [$key => $val]; |
354
|
|
|
})->toArray(); |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
/** |
358
|
|
|
* Set this filter layout only. |
359
|
|
|
* |
360
|
|
|
* @return $this |
361
|
|
|
*/ |
362
|
|
|
public function layoutOnly() |
363
|
|
|
{ |
364
|
|
|
$this->thisFilterLayoutOnly = true; |
365
|
|
|
|
366
|
|
|
return $this; |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* Add a filter to grid. |
371
|
|
|
* |
372
|
|
|
* @param AbstractFilter $filter |
373
|
|
|
* |
374
|
|
|
* @return AbstractFilter |
375
|
|
|
*/ |
376
|
|
|
protected function addFilter(AbstractFilter $filter) |
377
|
|
|
{ |
378
|
|
|
$this->layout->addFilter($filter); |
379
|
|
|
|
380
|
|
|
$filter->setParent($this); |
381
|
|
|
|
382
|
|
|
if ($this->thisFilterLayoutOnly) { |
383
|
|
|
$this->thisFilterLayoutOnly = false; |
384
|
|
|
$this->layoutOnlyFilterColumns[] = $filter->getColumn(); |
385
|
|
|
} |
386
|
|
|
|
387
|
|
|
return $this->filters[] = $filter; |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
/** |
391
|
|
|
* Use a custom filter. |
392
|
|
|
* |
393
|
|
|
* @param AbstractFilter $filter |
394
|
|
|
* |
395
|
|
|
* @return AbstractFilter |
396
|
|
|
*/ |
397
|
|
|
public function use(AbstractFilter $filter) |
398
|
|
|
{ |
399
|
|
|
return $this->addFilter($filter); |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
/** |
403
|
|
|
* Get all filters. |
404
|
|
|
* |
405
|
|
|
* @return AbstractFilter[] |
406
|
|
|
*/ |
407
|
|
|
public function filters() |
408
|
|
|
{ |
409
|
|
|
return $this->filters; |
410
|
|
|
} |
411
|
|
|
|
412
|
|
|
/** |
413
|
|
|
* @param string $key |
414
|
|
|
* @param string $label |
415
|
|
|
* |
416
|
|
|
* @return mixed |
417
|
|
|
*/ |
418
|
|
|
public function scope($key, $label = '') |
419
|
|
|
{ |
420
|
|
|
return tap(new Scope($key, $label), function (Scope $scope) { |
421
|
|
|
return $this->scopes->push($scope); |
422
|
|
|
}); |
423
|
|
|
} |
424
|
|
|
|
425
|
|
|
/** |
426
|
|
|
* Add separator in filter scope. |
427
|
|
|
* |
428
|
|
|
* @return mixed |
429
|
|
|
*/ |
430
|
|
|
public function scopeSeparator() |
431
|
|
|
{ |
432
|
|
|
return $this->scope(Scope::SEPARATOR); |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
/** |
436
|
|
|
* Get all filter scopes. |
437
|
|
|
* |
438
|
|
|
* @return Collection |
439
|
|
|
*/ |
440
|
|
|
public function getScopes() |
441
|
|
|
{ |
442
|
|
|
return $this->scopes; |
443
|
|
|
} |
444
|
|
|
|
445
|
|
|
/** |
446
|
|
|
* Get current scope. |
447
|
|
|
* |
448
|
|
|
* @return Scope|null |
449
|
|
|
*/ |
450
|
|
|
public function getCurrentScope() |
451
|
|
|
{ |
452
|
|
|
$key = request(Scope::QUERY_NAME); |
453
|
|
|
|
454
|
|
|
return $this->scopes->first(function ($scope) use ($key) { |
455
|
|
|
return $scope->key == $key; |
456
|
|
|
}); |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
/** |
460
|
|
|
* Get scope conditions. |
461
|
|
|
* |
462
|
|
|
* @return array |
463
|
|
|
*/ |
464
|
|
|
protected function scopeConditions() |
465
|
|
|
{ |
466
|
|
|
if ($scope = $this->getCurrentScope()) { |
467
|
|
|
return $scope->condition(); |
468
|
|
|
} |
469
|
|
|
|
470
|
|
|
return []; |
471
|
|
|
} |
472
|
|
|
|
473
|
|
|
/** |
474
|
|
|
* Add a new layout column. |
475
|
|
|
* |
476
|
|
|
* @param int $width |
477
|
|
|
* @param \Closure $closure |
478
|
|
|
* |
479
|
|
|
* @return $this |
480
|
|
|
*/ |
481
|
|
View Code Duplication |
public function column($width, \Closure $closure) |
|
|
|
|
482
|
|
|
{ |
483
|
|
|
$width = $width < 1 ? round(12 * $width) : $width; |
484
|
|
|
|
485
|
|
|
$this->layout->column($width, $closure); |
486
|
|
|
|
487
|
|
|
return $this; |
488
|
|
|
} |
489
|
|
|
|
490
|
|
|
/** |
491
|
|
|
* Expand filter container. |
492
|
|
|
* |
493
|
|
|
* @return $this |
494
|
|
|
*/ |
495
|
|
|
public function expand() |
496
|
|
|
{ |
497
|
|
|
$this->expand = true; |
498
|
|
|
|
499
|
|
|
return $this; |
500
|
|
|
} |
501
|
|
|
|
502
|
|
|
/** |
503
|
|
|
* Execute the filter with conditions. |
504
|
|
|
* |
505
|
|
|
* @param bool $toArray |
506
|
|
|
* |
507
|
|
|
* @return array|Collection|mixed |
508
|
|
|
*/ |
509
|
|
|
public function execute($toArray = true) |
510
|
|
|
{ |
511
|
|
|
if (method_exists($this->model->eloquent(), 'paginate')) { |
512
|
|
|
$this->model->usePaginate(true); |
513
|
|
|
|
514
|
|
|
return $this->model->buildData($toArray); |
515
|
|
|
} |
516
|
|
|
$conditions = array_merge( |
517
|
|
|
$this->conditions(), |
518
|
|
|
$this->scopeConditions() |
519
|
|
|
); |
520
|
|
|
|
521
|
|
|
return $this->model->addConditions($conditions)->buildData($toArray); |
522
|
|
|
} |
523
|
|
|
|
524
|
|
|
/** |
525
|
|
|
* @param callable $callback |
526
|
|
|
* @param int $count |
527
|
|
|
* |
528
|
|
|
* @return bool |
529
|
|
|
*/ |
530
|
|
|
public function chunk(callable $callback, $count = 100) |
531
|
|
|
{ |
532
|
|
|
$conditions = array_merge( |
533
|
|
|
$this->conditions(), |
534
|
|
|
$this->scopeConditions() |
535
|
|
|
); |
536
|
|
|
|
537
|
|
|
return $this->model->addConditions($conditions)->chunk($callback, $count); |
538
|
|
|
} |
539
|
|
|
|
540
|
|
|
/** |
541
|
|
|
* Get the string contents of the filter view. |
542
|
|
|
* |
543
|
|
|
* @return \Illuminate\View\View|string |
544
|
|
|
*/ |
545
|
|
|
public function render() |
546
|
|
|
{ |
547
|
|
|
$this->removeIDFilterIfNeeded(); |
548
|
|
|
|
549
|
|
|
if (empty($this->filters)) { |
550
|
|
|
return ''; |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
return view($this->view)->with([ |
|
|
|
|
554
|
|
|
'action' => $this->action ?: $this->urlWithoutFilters(), |
555
|
|
|
'layout' => $this->layout, |
556
|
|
|
'filterID' => $this->filterID, |
557
|
|
|
'expand' => $this->expand, |
558
|
|
|
])->render(); |
559
|
|
|
} |
560
|
|
|
|
561
|
|
|
/** |
562
|
|
|
* Get url without filter queryString. |
563
|
|
|
* |
564
|
|
|
* @return string |
565
|
|
|
*/ |
566
|
|
|
public function urlWithoutFilters() |
567
|
|
|
{ |
568
|
|
|
/** @var Collection $columns */ |
569
|
|
|
$columns = collect($this->filters)->map->getColumn()->flatten(); |
570
|
|
|
|
571
|
|
|
$pageKey = 'page'; |
572
|
|
|
|
573
|
|
|
if ($gridName = $this->model->getGrid()->getName()) { |
574
|
|
|
$pageKey = "{$gridName}_{$pageKey}"; |
575
|
|
|
} |
576
|
|
|
|
577
|
|
|
$columns->push($pageKey); |
578
|
|
|
|
579
|
|
|
$groupNames = collect($this->filters)->filter(function ($filter) { |
580
|
|
|
return $filter instanceof Filter\Group; |
581
|
|
|
})->map(function (AbstractFilter $filter) { |
582
|
|
|
return "{$filter->getId()}_group"; |
583
|
|
|
}); |
584
|
|
|
|
585
|
|
|
return $this->fullUrlWithoutQuery( |
586
|
|
|
$columns->merge($groupNames) |
587
|
|
|
); |
588
|
|
|
} |
589
|
|
|
|
590
|
|
|
/** |
591
|
|
|
* Get url without scope queryString. |
592
|
|
|
* |
593
|
|
|
* @return string |
594
|
|
|
*/ |
595
|
|
|
public function urlWithoutScopes() |
596
|
|
|
{ |
597
|
|
|
return $this->fullUrlWithoutQuery(Scope::QUERY_NAME); |
598
|
|
|
} |
599
|
|
|
|
600
|
|
|
/** |
601
|
|
|
* Get full url without query strings. |
602
|
|
|
* |
603
|
|
|
* @param Arrayable|array|string $keys |
604
|
|
|
* |
605
|
|
|
* @return string |
606
|
|
|
*/ |
607
|
|
|
protected function fullUrlWithoutQuery($keys) |
608
|
|
|
{ |
609
|
|
|
if ($keys instanceof Arrayable) { |
610
|
|
|
$keys = $keys->toArray(); |
611
|
|
|
} |
612
|
|
|
|
613
|
|
|
$keys = (array) $keys; |
614
|
|
|
|
615
|
|
|
$request = request(); |
616
|
|
|
|
617
|
|
|
$query = $request->query(); |
618
|
|
|
Arr::forget($query, $keys); |
619
|
|
|
|
620
|
|
|
$question = $request->getBaseUrl().$request->getPathInfo() == '/' ? '/?' : '?'; |
621
|
|
|
|
622
|
|
|
return count($request->query()) > 0 |
623
|
|
|
? $request->url().$question.http_build_query($query) |
624
|
|
|
: $request->fullUrl(); |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
/** |
628
|
|
|
* @param string $name |
629
|
|
|
* @param string $filterClass |
630
|
|
|
*/ |
631
|
|
|
public static function extend($name, $filterClass) |
632
|
|
|
{ |
633
|
|
|
if (!is_subclass_of($filterClass, AbstractFilter::class)) { |
|
|
|
|
634
|
|
|
throw new \InvalidArgumentException("The class [$filterClass] must be a type of ".AbstractFilter::class.'.'); |
635
|
|
|
} |
636
|
|
|
|
637
|
|
|
static::$supports[$name] = $filterClass; |
638
|
|
|
} |
639
|
|
|
|
640
|
|
|
/** |
641
|
|
|
* @param string $abstract |
642
|
|
|
* @param array $arguments |
643
|
|
|
* |
644
|
|
|
* @return AbstractFilter |
645
|
|
|
*/ |
646
|
|
|
public function resolveFilter($abstract, $arguments) |
647
|
|
|
{ |
648
|
|
|
if (isset(static::$supports[$abstract])) { |
649
|
|
|
return new static::$supports[$abstract](...$arguments); |
650
|
|
|
} |
651
|
|
|
} |
652
|
|
|
|
653
|
|
|
/** |
654
|
|
|
* Generate a filter object and add to grid. |
655
|
|
|
* |
656
|
|
|
* @param string $method |
657
|
|
|
* @param array $arguments |
658
|
|
|
* |
659
|
|
|
* @return AbstractFilter|$this |
660
|
|
|
*/ |
661
|
|
|
public function __call($method, $arguments) |
662
|
|
|
{ |
663
|
|
|
if ($filter = $this->resolveFilter($method, $arguments)) { |
664
|
|
|
return $this->addFilter($filter); |
665
|
|
|
} |
666
|
|
|
|
667
|
|
|
return $this; |
668
|
|
|
} |
669
|
|
|
} |
670
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.