laravel-query-filters maintained by joggapp
Introduction
This package makes it easy to sort and filter Eloquent queries via an associative array of options, usually from a FormRequest class.
Installation
Install the package via Composer:
composer require joggapp/laravel-query-filters
Usage
Defining a QueryFilter
Consider a Product model with category, name, and price fields.
We can apply sorting and filtering on these fields by defining a QueryFilter class. To create one, use the following command:
php artisan make:query-filter ProductQueryFilter
This command will create a new QueryFilter class in the App\QueryFilters directory.
Within this class, you can define the fields that can be sorted in ascending or descending order:
protected array $sortableFields = [
'name',
'price',
];
Specify the default sort and filtering options:
protected array $defaultFilters = [
'sort_by' => 'price:asc,name:asc'
];
And define how a filter will be applied:
public function category(string|array $value)
{
if (is_array($value)) {
$query->whereIn('category', $value);
} else {
$query->where('category', $category);
}
}
Using QueryFilter Methods
After defining the QueryFilter, it can be used to apply filter and sorting options:
use App\Model\Product;
use App\QueryFilters\ProductQueryFilter;
$filters = [
'category' => 'Apparel',
'sort_by' => 'price:asc,name:asc',
];
(new ProductQueryFilter())
->set($filters)
->apply(Product::query())
->get();
In this example, we are getting all products in the Apparel category sorted by price from low to high, then alphabetically by name.
SortBy Validation Rule
Included in this package is a SortBy validation rule that can be used to help validate sort-by parameters:
use App\Models\Product;
use App\QueryFilters\ProductQueryFilter;
use Illuminate\Support\Facades\Validator;
use JoggApp\LaravelQueryFilters\Rules\SortBy;
$data = [
'sort_by' => 'price:asc,name:asc',
];
$validator = Validator::make($data, [
'sort_by' => ['sometimes', new SortBy()],
]);
$validated = $validator->validated();
$products = (new ProductQueryFilter())
->set($validated)
->apply(Product::query())
->get();