Skip to content

Commit

Permalink
feat: add support for POST advanced filters
Browse files Browse the repository at this point in the history
  • Loading branch information
binaryk committed Jul 2, 2024
1 parent 7145785 commit a9ebec0
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 11 deletions.
5 changes: 5 additions & 0 deletions src/Bootstrap/RoutesDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ public function __invoke(?string $uriKey = null)
\Binaryk\LaravelRestify\Http\Controllers\RepositoryFilterController::class
)->name('filters.index');

Route::post(
$prefix.'/apply-restify-advanced-filters',
\Binaryk\LaravelRestify\Http\Controllers\RepositoryApplyFiltersController::class
)->name('filters.apply');

// Actions
Route::get(
$prefix.'/actions',
Expand Down
2 changes: 1 addition & 1 deletion src/Events/AdvancedFiltersApplied.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ class AdvancedFiltersApplied
public function __construct(
public Repository $repository,
public AdvancedFiltersCollection $advancedFiltersCollection,
public ?string $rawFilters = null,
public array $rawFilters = [],
) {}
}
11 changes: 5 additions & 6 deletions src/Filters/AdvancedFiltersCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Binaryk\LaravelRestify\Filters;

use Binaryk\LaravelRestify\Http\Requests\RepositoryApplyFiltersRequest;
use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
use Binaryk\LaravelRestify\Repositories\Repository;
use Illuminate\Support\Collection;
Expand All @@ -16,28 +17,26 @@ class AdvancedFiltersCollection extends Collection
{
public function authorized(RestifyRequest $request): self
{
return $this->filter(fn (Filter $filter) => $filter->authorizedToSee($request))->values();
return $this->filter(fn(Filter $filter) => $filter->authorizedToSee($request))->values();
}

public function apply(RestifyRequest $request, $query): self
{
return $this->each(fn (AdvancedFilter $filter) => $filter->filter($request, $query, $filter->dataObject->value));
return $this->each(fn(AdvancedFilter $filter) => $filter->filter($request, $query, $filter->dataObject->value));
}

public static function collectQueryFilters(RestifyRequest $request, Repository $repository): self
{
if (! $request->input('filters')) {
if (! $filters = $request->filters()) {
return static::make([]);
}

$filters = json_decode(base64_decode($request->input('filters')), true);

$allowedFilters = $repository->collectAdvancedFilters($request);

return static::make($filters)
->map(function (array $queryFilter) use ($allowedFilters, $request) {
/** * @var AdvancedFilter $advancedFilter */
$advancedFilter = $allowedFilters->first(fn (
$advancedFilter = $allowedFilters->first(fn(
AdvancedFilter $filter
) => $filter::uriKey() === data_get($queryFilter, 'key'));

Expand Down
13 changes: 13 additions & 0 deletions src/Http/Controllers/RepositoryApplyFiltersController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Binaryk\LaravelRestify\Http\Controllers;

use Binaryk\LaravelRestify\Http\Requests\RepositoryApplyFiltersRequest;

class RepositoryApplyFiltersController extends RepositoryController
{
public function __invoke(RepositoryApplyFiltersRequest $request)
{
return $request->repository()->index($request);
}
}
5 changes: 5 additions & 0 deletions src/Http/Requests/RepositoryApplyFiltersRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Binaryk\LaravelRestify\Http\Requests;

class RepositoryApplyFiltersRequest extends RestifyRequest {}
7 changes: 7 additions & 0 deletions src/Http/Requests/RestifyRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,11 @@ public function related(): RelatedDto
return app(RelatedDto::class);
}
}

public function filters(): array
{
return $this instanceof RepositoryApplyFiltersRequest
? $this->input('filters', [])
: json_decode(base64_decode($this->input('filters', [])), true);
}
}
2 changes: 1 addition & 1 deletion src/Services/Search/RepositorySearchService.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ protected function applyFilters(RestifyRequest $request, Repository $repository,
$repository,
AdvancedFiltersCollection::collectQueryFilters($request, $repository)
->apply($request, $query),
$request->input('filters'),
$request->filters(),
)
);

Expand Down
32 changes: 29 additions & 3 deletions tests/Feature/Filters/AdvancedFilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function test_filters_can_have_definition(): void
$this->getJson(PostRepository::route('filters', query: [
'only' => 'matches,searchables,sortables',
]))->assertJson(
fn (AssertableJson $json) => $json
fn(AssertableJson $json) => $json
->where('data.1.repository.key', 'users')
->where('data.1.repository.label', 'Users')
->where('data.1.repository.display_key', 'id')
Expand Down Expand Up @@ -73,7 +73,7 @@ public function test_value_filter_doesnt_require_value(): void
'filters' => $filters,
]))
->assertJson(
fn (AssertableJson $json) => $json
fn(AssertableJson $json) => $json
->where('data.0.attributes.title', $expectedTitle)
->etc()
)
Expand Down Expand Up @@ -197,7 +197,7 @@ public function test_the_timestamp_filter_is_applied(): void
]))
->assertOk()
->assertJson(
fn (AssertableJson $json) => $json
fn(AssertableJson $json) => $json
->where('data.0.attributes.title', 'Valid post')
->count('data', 1)
->etc()
Expand Down Expand Up @@ -242,4 +242,30 @@ public function test_filter_can_send_meta(): void
'filters' => $filters,
]))->assertJsonCount(0, 'data');
}

public function test_filter_can_be_sent_in_post_requests(): void
{
Post::factory()->create([
'title' => 'Valid post',
'description' => 'Zoo bar post',
]);

Post::factory()->create([
'title' => 'Active post',
'description' => 'Foo bar post',
]);

$filters = [
[
'key' => ValueFilter::uriKey(),
'value' => 'Valid%',
'operator' => 'like',
'column' => 'title',
],
];

$this->post(PostRepository::route('apply-restify-advanced-filters'), [
'filters' => $filters,
])->assertJsonCount(1, 'data');
}
}

0 comments on commit a9ebec0

Please sign in to comment.