PHPackages                             asemalalami/laravel-advanced-filter - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. asemalalami/laravel-advanced-filter

ActiveProject[Search &amp; Filtering](/categories/search)

asemalalami/laravel-advanced-filter
===================================

Laravel Advanced Filter

v0.7(5y ago)328162MITPHP

Since Nov 14Pushed 3y ago2 watchersCompare

[ Source](https://github.com/AsemAlalami/Laravel-Advanced-Filter)[ Packagist](https://packagist.org/packages/asemalalami/laravel-advanced-filter)[ RSS](/packages/asemalalami-laravel-advanced-filter/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (6)Dependencies (4)Versions (7)Used By (0)

Laravel Advanced Filter
=======================

[](#laravel-advanced-filter)

This package allows you to filter on laravel models

You can choose fields to filtering and customize its data-types, aliases and excepted operators, you can add/customize your request format, and you add new operators or overwrite the existed operators

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require asemalalami/laravel-advanced-filter

```

The package will automatically register its service provider.

You can optionally publish the config file with:

```
php artisan vendor:publish --provider="AsemAlalami\LaravelAdvancedFilter\AdvancedFilterServiceProvider" --tag="config"

```

These default config file that will be published: [Config File](https://github.com/AsemAlalami/Laravel-Advanced-Filter/blob/master/config/advanced_filter.php)

Usage
-----

[](#usage)

- use `HasFilter` trait in the model
- add fields in the implementation of the abstract function `setupFilter`
- call the `filter` scope in your controller

```
class Order extends Model
{
    use HasFilter;

    protected $casts = [
        'void' => 'boolean',
    ];

    public function channel()
    {
        return $this->belongsTo(Channel::class);
    }

    public function orderLines()
    {
        return $this->hasMany(OrderLine::class);
    }

    public function setupFilter()
    {
        $this->addField('void'); // will cast to 'boolean' from the model casts
        $this->addField('total')->setDatatype('numeric');
        $this->addFields(['source', 'subsource', 'order_date']);
        // field from relation
        $this->addFields(['channel.created_at' => 'channel_create'])->setDatatype('date');
        $this->addField('orderLines.product.sku', 'product_sku');
        // field from relation count
        $this->addCountField('orderLines');
        // custom field (raw sql)
        $this->addCustomField('my_total', '(shipping_cost + subtotal)');
        // enable general search
        $this->addGeneralSearch(['source', 'orderLines.product.sku'], 'startsWith');
    }

    // customize field filter by custom scope
    public function scopeWhereSource(Builder $builder, Field $field, string $operator, $value, $conjunction = 'and')
    {
        if ($operator == 'Equal') {
            return $builder->where(function (Builder $builder) use ($value) {
                $builder->where('source', $value)
                    ->orWhere('subsource', $value);
            });
        }

        // default behavior
        return $builder->applyOperator($operator, $field, $value, $conjunction);
    }
}

...

class OrderController extends Controller
{
    public function index()
    {
        return Order::filter()->paginate(); // you can pass your custom request
    }
}
```

Query Format
------------

[](#query-format)

Query format is the shape that you want to send your query(filters) in the request. the package support 3 formats, and you can create a new format.

- `json` (default): the filters will send as json in the request

    ```
    filters=[{"field":"email","operator":"equal","value":"abc"}]
    ```
- `array`: the filters will send as array in the request

    ```
    filters[email][value]=abc&filters[email][operator]=equal

    ```
- `separator`: the filters will send as well as in the `array` format, but separated by a separator(`^` default)

    the format sets with a separator symbol `separator:^`

    ```
    filters^email^value=abc&filters^email^operator=equal

    ```

> set the default query format in the config file `query_format` attribute

#### Create a new query format:

[](#create-a-new-query-format)

- create a new class and extends it from `QueryFormat`: `class MyFormat extends QueryFormat`
- implement the abstract function `format` that returns `FilterRequest` object
- add the class to the config file in `custom_query_format` attribute: `'custom_query_format' => MyFormat::class,`

Fields
------

[](#fields)

Normal Field options:

- field name is the column name
- alias is the key that you want to send in the request
- data-type: by default it set from model `casts`, if you want to set custom data-type, use `setDatatype`
- operators: the field will accept all operators unless you use `setExceptedOperators` to exclude some operators
- a relational field: only set the field name by `.` separator `channel.name`, `channel.type.name`

    > you can define field name by `.` separator, but you want to consider it as a non relational field by pass `false` for `inRelation` parameter (used in NoSQL DB or join between tables)

    ```
    $this->addField('channels.name', 'channel_name', false);
    ```
- customize a field query, you can make a scope for the field to customize the filter behavior. scope name must be combined 3 sections :

    - scope
    - the value of `prefix_scope_function` key in config file (`where` is the default)
    - field name(or relation name) for example `email`

    ```
    public function scopeWhereEmail(Builder $builder, Field $field, string $operator, $value, $conjunction = 'and')
    ```

    > you can customize a relational field by define the scope in the relation model OR define scope by relation name

    ```
    OrderLine.php

    public function scopeWherePrice(Builder $builder, Field $field, string $operator, $value, $conjunction = 'and')

    OR

    Order.php

    public function scopeWhereOrderLines(Builder $builder, Field $field, string $operator, $value, $conjunction = 'and')
    ```

    > you can use `applyOperator` function to use the default behavior `$builder->applyOperator($operator, $field, $value, $conjunction);`

You can add fields to a model by using 4 functions:

- `addField`(string $field, string $alias = null, ?bool $inRelation = null): by default alias value same as field name value ```
    $this->addField('total')->setDatatype('numeric');
    ```
- `addFields`($fields): accept an array of field and aliases: ```
    $this->addFields(['created_at' => 'create_date', 'order_date'])->setDatatype('date');
    ```
- `addCountField`(string $relation, string $alias = null, callable $callback = null): add a field from count of relation, use can customize the count query and alias(by default is concat relation name(snake case) and `_count`) ```
    $this->addCountField('orderLines');

    $this->addCountField('orderLines', 'lines_count', function (Builder $builder) {
        $builder->where('quantity', '>', 1);
    });
    ```

    >
- `addCustomField`(string $alias, string $sqlRaw, $relation = null): add a field from raw sql query ```
    $this->addCustomField('my_total', '(`shipping_cost` + `subtotal`)');
    $this->addCustomField('line_subtotal', '(`price` + `quantity`)', 'orderLines'); // inside "orderLines" relation
    ```

General Search
--------------

[](#general-search)

You can enable general search on some fields, and you can specify the operator (`startsWith` is the default operator)

```
$this->addGeneralSearch(['source', 'orderLines.product.sku'], 'startsWith');
```

Conjunction
-----------

[](#conjunction)

Currently, the package support one conjunction between all fields `and` | `or`, default conjunction attribute in the config file `default_conjunction`

Operators
---------

[](#operators)

The package has many operators, you can create new operators, and you can customize the operators aliases that you want to send in the request

- Equals (`=`, `equals`)
- NotEquals (`!=`, `notEquals`)
- GreaterThan (`>` , `greater`)
- GreaterThanOrEqual (`>=`, `greaterOrEqual`)
- LessThan (` ['my-op', '*']],`

Data Types:
-----------

[](#data-types)

- boolean
- date
- datetime
- numeric
- string

Config
------

[](#config)

[Config File](https://github.com/AsemAlalami/Laravel-Advanced-Filter/blob/master/config/advanced_filter.php)

###  Health Score

28

—

LowBetter than 54% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity24

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 98.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~12 days

Total

6

Last Release

1943d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/8d21e83470971b4d9f81d0af9111429d390430ed47aaee9816172b6764719cc8?d=identicon)[Asem Alalami](/maintainers/Asem%20Alalami)

---

Top Contributors

[![AsemAlalami](https://avatars.githubusercontent.com/u/11025503?v=4)](https://github.com/AsemAlalami "AsemAlalami (62 commits)")[![nelutihon](https://avatars.githubusercontent.com/u/8122262?v=4)](https://github.com/nelutihon "nelutihon (1 commits)")

---

Tags

elequentfilterslaravellaravelfilterfilters

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/asemalalami-laravel-advanced-filter/health.svg)

```
[![Health](https://phpackages.com/badges/asemalalami-laravel-advanced-filter/health.svg)](https://phpackages.com/packages/asemalalami-laravel-advanced-filter)
```

###  Alternatives

[kyslik/laravel-filterable

Using URL query strings to filter Eloquent queries.

11539.0k](/packages/kyslik-laravel-filterable)[czim/laravel-filter

Filter for Laravel Eloquent queries, with support for modular filter building

8973.0k3](/packages/czim-laravel-filter)[millat/laravel-hooks

The WordPress filter, action system in Laravel

5715.1k](/packages/millat-laravel-hooks)[hashemi/queryfilter

A simple &amp; dynamic package for your eloquent query in laravel. It will help you to write query logic individual for each parameter.

391.1k](/packages/hashemi-queryfilter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
