holoyan/eloquent-filter

Eloquent filter for laravel models, easy and powerful

Installs: 1 981

Dependents: 0

Suggesters: 0

Security: 0

Stars: 2

Watchers: 1

Forks: 0

Open Issues: 0

pkg:composer/holoyan/eloquent-filter

v1.2.0 2021-09-13 14:39 UTC

This package is auto-updated.

Last update: 2025-12-22 12:27:41 UTC


README

Table of Content

Introduction

An easy way to add custom filters to your eloquent models. Powerful, flexible and fully dynamic

 $users = User::filter($request->all())->get();

Requirement

PHP >= 7.1

Installation

composer require holoyan/eloquent-filter

Basic Usage

Let's say we want to return a list of users filtered by multiple parameters. For example this is our request url: /users?email=jo&categories[]=3&categories[]=4&role=admin

$request->all() will return:

[
   'email'       => 'jo',
   'categories'  => [3, 4],
   'role' => 'admin'
]

To filter by all those parameters we can simply write

 
 namespace App\Http\Controllers;
 
 use Illuminate\Http\Request;
 use App\Models\User;
 
 class UserController extends Controller
 {
     public function index(Request $request)
     {    
         return User::filter($request->all())->get();
     }
 }

In our User model we must import Filterable trait

namespace App\Models;

// import Filterable trait
use holoyan\EloquentFilter\Filterable;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Filterable;
    
    // other stuff here
}

then create class called UserFilter in App\Http\Filters folder

namespace App\Http\Filters;

use holoyan\EloquentFilter\Filter;
use holoyan\EloquentFilter\Rules\SimpleRule;

class UserFilter extends Filter
{

    public function rules()
    {
        return [
            'email' => SimpleRule::make()->startsWith(),
            'categories' => SimpleRule::make(),
            'role' => SimpleRule::make(),
        ];
    }
}

Query returns all users whose name starts with jo, belongs to category 3 or 4 and have role admin.

By default, package will look for filter class in App\Http\Filters folder with name ModelFilter, but if you want ypu can customize this behavior.

add $filterClass static property in model.

namespace App\Models;

use holoyan\EloquentFilter\Filterable;
use Illuminate\Foundation\Auth\User as Authenticatable;

// your custom filter class
use App\Filters\MyFilter;

class User extends Authenticatable
{
    use Filterable;

    public static $filterClass = MyCustomFilter::class;
    // other stuff here
}

Dynamic filter

Sometimes you may want to use a dynamic filter depending on conditions. In this case you can pass second argument to filter method which is the filter class:

$filter = $user->isAdmin() ? AdminFilter::class : BasicFilter::class;

User::filter($request->all(), $filter)->get();

Customize column

You can also customize your column name

    public function rules()
    {
        return [
            'firstName' => SimpleRule::make()->setColumn('first_name'),
        ];
    }

Customize value

    public function rules()
    {
        return [
            'firstName' => SimpleRule::make()->setvalue(function($value){
                return $value . 'test';
}           ),
        ];
    }

Available filters

  • SimpleRule::make() - by default, this will check for exact match
    public function rules()
    {
        return [
            'name' => SimpleRule::make()
        ];
    }

if you want to use like comparison type you can use one of those methods:

        return [
            // where name="value"
            'name' => SimpleRule::make(),
            // where name like "value%"
            'name' => SimpleRule::make()->startsWith(),
            // where name like "%value"
            'name' => SimpleRule::make()->endsWith(),
            // where name like "%value%"
            'name' => SimpleRule::make()->contains()
        ];
  • RawRule::make() - this allows you to specify callback function with your own logic
        return [
            'name' => RawRule::make()->setCallback(function($query, $column, $value){
                $query->where('name', '<>', $value);
            })
        ];
  • RelationRule::class - for relation filter, check bellow for more details

Ordering

To order result use OrderRule rule

    // filter request
    $request = [
        'order' => 'desc'
    ];


    // filter class
    return [
        'name' => SimpleRule::make(),
        // other rules ......
        'order' => OrderRule::make()->setColumn('id'),
    ];

Relation filter

Suppose User has Product relation, and we want to return all users which have product which name starts with 'cook'

        return [
            'name' => SimpleRule::make(),
            'products' => RelationRule::make()->setRelation('products')->setRules([
                'name' => SimpleRule::make()->startsWith(),
            ]),
        ];

This allows you recursively pass any rules you want

Nested filter

To make nested filter we need to use NestedRule::class

        return [
            'b_date' => NestedRule::make()->setRules([
                'from' => SimpleRule::make()->setOperator('>='),
                'to' => SimpleRule::make()->setOperator('<='),
            ])
        ];

Extending filter

You can create your custom rules with custom logic

Custom Rules

For creating custom rules all you need is to create you class extend from use holoyan\EloquentFilter\Rules\FilterRule class and implement handlemethod

namespace App\MyNamespace;

use holoyan\EloquentFilter\Rules\FilterRule;

class DateRule extends FilterRule
{

    /**
     * @param string $filterKey
     * @param $filterValue
     */
    public function handle(string $filterKey, $filterValue): void
    {
        // do something cool
        $this->builder->whereDate($filterKey, $filterValue);
    }
}

Thats all, now you can use custom rule;

        return [
            'name' => SimpleRule::make(),
            'created_at' => DateRule::make(),
        ];

Credits

Inspired by and-m-a

License

MIT