Skip to content

Commit ac2beed

Browse files
committed
feat: add conditionable allowed filter
1 parent 1818565 commit ac2beed

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed

src/AllowedFilter.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Spatie\QueryBuilder;
44

5+
use Closure;
56
use Illuminate\Support\Collection;
67
use Spatie\QueryBuilder\Enums\FilterOperator;
78
use Spatie\QueryBuilder\Filters\Filter;
@@ -27,6 +28,8 @@ class AllowedFilter
2728

2829
protected bool $nullable = false;
2930

31+
protected ?Closure $condition = null;
32+
3033
public function __construct(
3134
protected string $name,
3235
protected Filter $filterClass,
@@ -39,6 +42,10 @@ public function __construct(
3942

4043
public function filter(QueryBuilder $query, $value): void
4144
{
45+
if ($this->condition && ! value($this->condition, $this)) {
46+
return;
47+
}
48+
4249
$valueToFilter = $this->resolveValueForFiltering($value);
4350

4451
if (! $this->nullable && is_null($valueToFilter)) {
@@ -204,4 +211,11 @@ protected function resolveValueForFiltering($value)
204211

205212
return ! $this->ignored->contains($value) ? $value : null;
206213
}
214+
215+
public function when(Closure $callback): static
216+
{
217+
$this->condition = $callback;
218+
219+
return $this;
220+
}
207221
}

tests/FilterTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,3 +894,33 @@ public function __invoke(Builder $query, $value, string $property): Builder
894894

895895
expect($results)->toHaveCount(2);
896896
});
897+
898+
it('can filter models by partial property when the condition return true', function () {
899+
$models = createQueryFromFilterRequest([
900+
'name' => $this->models->first()->name,
901+
])
902+
->allowedFilters(AllowedFilter::partial('name')->when(fn () => true))
903+
->get();
904+
905+
expect($models)->toHaveCount(1);
906+
});
907+
908+
it('cannot filter models by partial property when the condition return false', function () {
909+
$models = createQueryFromFilterRequest([
910+
'name' => $this->models->first()->name,
911+
])
912+
->allowedFilters(AllowedFilter::partial('name')->when(fn () => false))
913+
->get();
914+
915+
expect($models)->toHaveCount(5);
916+
});
917+
918+
it('can filter only trashed passing the class as a parameter to evaluate the condition', function () {
919+
$models = createQueryFromFilterRequest([
920+
'name' => $this->models->first()->name,
921+
])
922+
->allowedFilters(AllowedFilter::partial('name')->when(fn (AllowedFilter $filter) => $filter->getName() === 'name'))
923+
->get();
924+
925+
expect($models)->toHaveCount(1);
926+
});

tests/FiltersTrashedTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,33 @@
5151

5252
expect($models)->toHaveCount(3);
5353
});
54+
55+
it('can filter only trashed when the condition return true', function () {
56+
$models = createQueryFromFilterRequest([
57+
'trashed' => 'only',
58+
], SoftDeleteModel::class)
59+
->allowedFilters(AllowedFilter::trashed()->when(fn () => true))
60+
->get();
61+
62+
expect($models)->toHaveCount(1);
63+
});
64+
65+
it('cannot filter only trashed when the condition return false', function () {
66+
$models = createQueryFromFilterRequest([
67+
'trashed' => 'only',
68+
], SoftDeleteModel::class)
69+
->allowedFilters(AllowedFilter::trashed()->when(fn () => false))
70+
->get();
71+
72+
expect($models)->toHaveCount(2);
73+
});
74+
75+
it('can filter only trashed passing the class as a parameter to evaluate the condition', function () {
76+
$models = createQueryFromFilterRequest([
77+
'trashed' => 'only',
78+
], SoftDeleteModel::class)
79+
->allowedFilters(AllowedFilter::trashed()->when(fn (AllowedFilter $filter) => $filter->getName() === 'trashed'))
80+
->get();
81+
82+
expect($models)->toHaveCount(1);
83+
});

0 commit comments

Comments
 (0)