Search by

ekramhossain / laravel-query-filter

ekrambd

A flexible query filtering package for Laravel with operators, date ranges, relational filters, and sorting.

Package info

github.com/ekrambd/laravel-query-filter-package

pkg:composer/ekramhossain/laravel-query-filter

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.0.0 2026-08-08 08:23 UTC

This package is auto-updated.

Last update: 2026-09-08 08:44:28 UTC


README

A flexible and lightweight query filtering package for Laravel Eloquent with support for:

  • Allowed filters
  • String search
  • Comparison operators
  • Date range filtering
  • Relational filtering
  • Multiple sorting
  • Ascending and descending sorting

Requirements

  • PHP ^8.1
  • Laravel 9.x
  • Laravel 10.x
  • Laravel 11.x
  • Laravel 12.x

Installation

Install the package via Composer:

composer require ekramhossain/laravel-query-filter

The package automatically registers its service provider and Filter facade.

Configuration

Publish the configuration file:

php artisan vendor:publish --tag=query-filter-config

This will publish:

config/query-filter.php

Basic Usage

Suppose you have a Product model:

use App\Models\Product;
use EkramHossain\LaravelQueryFilter\Facades\Filter;

public function index(Request $request)
{
    $products = Filter::query(Product::query())
        ->allowedFilters([
            'name',
            'status',
            'price',
            'created_at',
        ])
        ->allowedSorts([
            'name',
            'price',
            'created_at',
        ])
        ->apply($request)
        ->paginate();

    return response()->json($products);
}

Basic Filtering

Request:

/api/products?filter[status]=active

Equivalent query:

WHERE status = 'active'

String Filtering

String values are automatically treated as a LIKE search.

Request:

/api/products?filter[name]=phone

Equivalent query:

WHERE name LIKE '%phone%'

Comparison Operators

The following operators are supported:

Operator Meaning
eq Equal
gt Greater than
gte Greater than or equal
lt Less than
lte Less than or equal

Equal

/api/products?filter[price][eq]=1000

Greater Than

/api/products?filter[price][gt]=1000

Greater Than Or Equal

/api/products?filter[price][gte]=1000

Less Than

/api/products?filter[price][lt]=1000

Less Than Or Equal

/api/products?filter[price][lte]=1000

Date Range Filtering

Date range filtering is supported using from and to.

Example:

/api/leaves?filter[issue_date][from]=2026-08-01&filter[issue_date][to]=2026-08-08

This produces a query equivalent to:

WHERE DATE(issue_date) >= '2026-08-01'
AND DATE(issue_date) <= '2026-08-08'

You can use the same syntax with any allowed date column:

filter[created_at][from]=2026-01-01
filter[created_at][to]=2026-01-31

Relational Filtering

You can filter records through Eloquent relationships using dot notation.

Example:

->allowedFilters([
    'name',
    'category.name',
])

Request:

/api/products?filter[category.name]=electronics

This will use Eloquent's whereHas() internally.

For example:

Product::query()
    ->whereHas('category', function ($query) {
        $query->where(
            'name',
            'like',
            '%electronics%'
        );
    });

Nested relationships are also supported:

->allowedFilters([
    'category.parent.name',
])

Sorting

Define allowed sorting columns:

->allowedSorts([
    'name',
    'price',
    'created_at',
])

Ascending

/api/products?sort=price

Equivalent to:

ORDER BY price ASC

Descending

Prefix the column with -:

/api/products?sort=-price

Equivalent to:

ORDER BY price DESC

Multiple Sorting

Multiple sorting columns can be passed using commas:

/api/products?sort=-created_at,price

Equivalent to:

ORDER BY created_at DESC, price ASC

Multiple Filters

Multiple filters can be combined:

/api/products?filter[status]=active&filter[price][gte]=500&filter[price][lte]=2000

Security

Only fields explicitly defined through allowedFilters() can be filtered.

->allowedFilters([
    'name',
    'status',
    'price',
])

Only fields defined through allowedSorts() can be sorted.

->allowedSorts([
    'name',
    'price',
])

Unknown filters and sorting fields are ignored.

This prevents users from arbitrarily controlling which database columns are queried.

Complete Example

use App\Models\Product;
use Illuminate\Http\Request;
use EkramHossain\LaravelQueryFilter\Facades\Filter;

public function index(Request $request)
{
    $products = Filter::query(Product::query())
        ->allowedFilters([
            'name',
            'status',
            'price',
            'manufacture_date',
            'category.name',
        ])
        ->allowedSorts([
            'name',
            'price',
            'manufacture_date',
            'created_at',
        ])
        ->apply($request)
        ->paginate(20);

    return response()->json([
        'success' => true,
        'data' => $products,
    ]);
}

Example request:

/api/products?filter[status]=active&filter[price][gte]=500&filter[manufacture_date][from]=2026-01-01&filter[manufacture_date][to]=2026-01-31&filter[category.name]=electronics&sort=-created_at,price

Supported Features

Feature Supported
Basic filtering ✅
String LIKE search ✅
eq ✅
gt ✅
gte ✅
lt ✅
lte ✅
Date range ✅
Relationship filtering ✅
Nested relationship filtering ✅
Ascending sorting ✅
Descending sorting ✅
Multiple sorting ✅
Allowed filters ✅
Allowed sorts ✅

License

This package is open-sourced software licensed under the MIT License.

Author

Md. Ekram Hossain

GitHub: https://github.com/ekrambd/