Created
May 11, 2023 22:43
-
-
Save cesurapp/9636ae6cd5928940cb68ff92240ed4aa to your computer and use it in GitHub Desktop.
Laravel Filtered JsonResource
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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