im-wmkong/laravel-model-filter is a Laravel package for laravel eloquent models filter.
It currently has 1 GitHub stars and 7 downloads on Packagist (latest version 0.03).
Install it with composer require im-wmkong/laravel-model-filter.
Discover more Laravel packages by im-wmkong
or browse all Laravel packages to compare alternatives.
Last updated
A Laravel Eloquent Models filter way
Let say we want to return a list of users filtered by multiple parameters. When we see to:
/users?name=wmkong&age=&client=ios&roles[]=1&roles[]=4&roles[]=7
$request->all() will return:
[
'name' => 'wmkong',
'age' => '',
'mobile_phone' => '12345',
'roles' => ['1','4','7'],
]
To filter by all those parameters we would need to do something like:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\User;
class UserController extends Controller
{
public function index(Request $request)
{
return User::query()
->when($request->has('name'), function ($query) use ($request) {
return $query->where('name', $request->get('name'));
})
->when($request->has('age'), function ($query) use ($request) {
return $query->where('age', $request->get('age'));
})
->when($request->has('mobile_phone'), function ($query) use ($request) {
return $query->where('mobile_phone', 'like', "%{$request->get('mobile_phone')}%");
})
->when($request->has('roles'), function ($query) use ($request) {
return $query->whereIn('roles', $request->get('roles'));
})
->get();
}
}
To filter that same input with model filter:
<?php
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();
}
}
composer require im-wmkong/laravel-model-filter
There are a few ways to define the filter a model will use:
The default namespace for all filters is App\Filters\ and each Model expects the filter classname to follow the {$ModelName}Filter naming convention regardless of the namespace the model is in.
Registering the service provider will give you access to the
php artisan make:filter {model}command as well as allow you to publish the configuration file. Registering the service provider is not required and only needed if you want to change the default namespace or use the artisan command
After installing the Model Filter library, register the ModelFilter\ModelFilterServiceProvider::class in your config/app.php configuration file:
'providers' => [
// Other service providers...
ModelFilter\ModelFilterServiceProvider::class,
],
Copy the package config to your local config with the publish command:
php artisan vendor:publish --provider="ModelFilter\ModelFilterServiceProvider"
In the config/modelfilter.php config file. Set the namespace your model filters will reside in:
'namespace' => "App\\Filters",
The following is optional. If no
modelFiltermethod is found on the model's filter class will be resolved by the default naming conventions
Create a public method modelFilter() that returns Your\Model\Filter::class; in your model.
<?php
namespace App\Models;
use ModelFilter\Traits\Filterable;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use Filterable;
public function modelFilter()
{
return \App\ModelFilters\CustomFilters\CustomUserFilter::class;
}
//User Class
}
Only available if you have registered
ModelFilter\ModelFilterServiceProvider::classin the providers array in yourconfig/app.php
You can create a model filter with the following artisan command:
php artisan make:filter User
Where User is the Eloquent Model you are creating the filter for. This will create app/Filters/UserFilter.php
Define the filter logic based on the camel cased input key passed to the filter() method.
$this context in the model filter class.To define methods for the following input:
[
'name' => 'wmkong',
'age' => '',
'mobile_phone' => '12345',
'roles' => ['1','4','7'],
]
You would use the following methods:
<?php
namespace App\Filters;
use ModelFilter\Filter;
class UserFilter extends Filter
{
/**
* The attributes that equal query is used by default.
*
* @var array
*/
public $filterable = [
'name',
'roles'
];
public function mobilePhone($phone)
{
return $this->where('mobile_phone', 'like', "%{$phone}%");
}
}
Note: In the above example if you do not want equal query you can configure
$filterableattributes
Note: In the above example if you do not want
mobile_phoneto be mapped tomobilePhone()you can set'input_camel' => falseonconfig/eloquentfilter.php. Doing this would allow you to have amobile_phone()filter method instead ofmobilePhone(). By default,mobilePhone()filter method can be called thanks to one of the following input key:mobile_phone,mobilePhone
Implement the ModelFilter\Traits\Filterable trait on any Eloquent model:
<?php
namespace App\Models;
use ModelFilter\Traits\Filterable;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
use Filterable;
//User Class
}
This gives you access to the filter() method that accepts an array of input:
<?php
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();
}
}
Any contributions welcome!