Skip to content

Instantly share code, notes, and snippets.

@cesurapp
Created May 11, 2023 22:43
Show Gist options
  • Save cesurapp/9636ae6cd5928940cb68ff92240ed4aa to your computer and use it in GitHub Desktop.
Save cesurapp/9636ae6cd5928940cb68ff92240ed4aa to your computer and use it in GitHub Desktop.
Laravel Filtered JsonResource
<?php
namespace App\Resources;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Resources\Json\JsonResource;
class FilteredJsonResource extends JsonResource
{
public static function collection($resource)
{
static::applyFilter($resource);
static::applySorting($resource);
return parent::collection($resource->paginate());
}
/**
* Filter QueryBuilder.
*/
private static function applyFilter(Builder $builder): void
{
$filter = request()?->query('filter');
if (! $filter) {
return;
}
// İnit Filter
$current = array_intersect_key(static::toFilter(), $filter);
foreach ($current as $columnId => $config) {
if (! isset($config['filter'])) {
continue;
}
// Single
if (! is_array($config['filter'])) {
$config['filter']($builder, $filter[$columnId]);
continue;
}
// Multiple
foreach ($config['filter'] as $subColumnId => $subConfig) {
if (isset($filter[$columnId][$subColumnId])) {
$subConfig($builder, $filter[$columnId][$subColumnId]);
}
}
}
}
/**
* Sort Query Builder.
*
* sort=ASC
* sort-by=id
*/
private static function applySorting(Builder $builder): void
{
$sortBy = request()?->query('sort_by');
$toFilter = static::toFilter()[$sortBy ?? 'id'];
if (! $sortBy || empty($toFilter['sortable'])) {
return;
}
// Generate Direction
$direction = match (strtolower(request()->query->get('sort', ''))) {
'asc' => 'asc',
default => 'desc'
};
if (is_callable($toFilter['sortable_field'] ?? '')) {
$toFilter['sortable_field']($builder, $direction);
return;
}
$builder->orderBy($sortBy, $direction);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment