LaravelFilter is a package designed to simplify the process of filtering table fields in a Laravel project. It provides a straightforward way to implement custom query filters for your models.
Please check the official laravel installation guide for server requirements before you start. Official Documentation
You can install the package via composer:
composer require baraadark/laravel-filter
Next, publish the configuration file:
php artisan vendor:publish --tag=config
Use the Filterable trait in your models to enable filtering.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use BaraaDark\LaravelFilter\Traits\Filterable;
class YourModel extends Model
{
use Filterable;
}
You should override the filtersKeys method to return an array of filter keys and their corresponding filter classes.
Example:
use BaraaDark\LaravelFilter\Traits\Filterable;
class YourModel extends Model
{
use Filterable;
public function filtersKeys(): array
{
return [
// 'filter-key' => FilterClass::class
];
}
}
The filtersKeys method returns an associative array where the keys are the names of the filter keys expected from the request, and the values are the filter classes that contain the query logic.
To create a Filter class, run the command:
php artisan make:filter
You will be prompted to enter the class name and the related model name. The generated file will be located at App\Http\Filters\ModelName.
namespace App\Http\Filters\ModelName;
use BaraaDark\LaravelFilter\Filter;
class FilterClass extends Filter
{
/**
* Get the validation rules that apply to the filter request.
*
* @return array
*/
public static function rules(): array
{
return [];
}
/**
* Apply filter query on the related model.
*
* @param \Illuminate\Database\Eloquent\Builder &$query
*/
public function apply(&$query)
{
return $query;
}
}
Example Filter Class:
use BaraaDark\LaravelFilter\Filter;
class ProductPriceRangeFilter extends Filter
{
/**
* Get the validation rules that apply to the filter request.
*
* @return array
*/
public static function rules(): array
{
return [
'min' => ['required', 'numeric', 'min:0'],
'max' => ['required', 'numeric']
];
}
/**
* Apply filter query on related model.
* @param \Illuminate\Database\Eloquent\Builder &$query
*/
public function apply(&$query)
{
return $query->where('price', '>=', $this->min)
->where('price', '<=', $this->max);
}
}
Note: You can easily access the values associated with each filter key by using $this->key.
Product model:
use BaraaDark\LaravelFilter\Traits\Filterable;
use App\Http\Filters\Product\ProductPriceRangeFilter;
class Product extends Model
{
use HasFactory, Filterable;
protected $guarded = [];
public function filtersKeys(): array
{
return [
'price-range' => ProductPriceRangeFilter::class
];
}
}
Filters can be applied by sending a request with the following structure in the body:
{
"filters": {
"filter_key": {
"filter_class_key": "value",
"filter_class_key": "value"
}
}
}
Example:
{
"filters": {
"price-range": {
"min": 500000,
"max": 1000000
}
}
}
If apply_global_scope is set to true in the configuration file, filters will be applied globally to all models when the filters are included in the request. This is not recommended as a general setting since multiple models might be used in the same function, and you might want to apply the filter only to the main model manually.
To configure global scope:
// config/laravel-filter.php
return [
'apply_global_scope' => false, // Set to true to enable global scope
];
If apply_global_scope is set to false, you can manually apply the filter in your controller:
use App\Models\SubjectCategory;
public function index(): LengthAwarePaginator
{
return SubjectCategory::applyFilter()->paginate();
}
Remember to make routes that use filtering either POST or match(['post', 'get']) since the request contains data.