Package Data | |
---|---|
Maintainer Username: | mohammad-fouladgar |
Maintainer Contact: | mohammadfouladgarphp@gmail.com (Mohammad Fouladgar) |
Package Create Date: | 2018-08-11 |
Package Last Update: | 2024-04-06 |
Home Page: | https://medium.com/@mohammadfouladgarphp/laravel-eloquent-filter-all-in-one-d903ededbd19 |
Language: | PHP |
License: | MIT |
Last Refreshed: | 2024-12-15 15:10:47 |
Package Statistics | |
---|---|
Total Downloads: | 145,030 |
Monthly Downloads: | 2,294 |
Daily Downloads: | 18 |
Total Stars: | 519 |
Total Watchers: | 16 |
Total Forks: | 42 |
Total Open Issues: | 0 |
This package allows you to build eloquent queries, based on request parameters. It greatly reduces the complexity of the queries and conditions, which will make your code cleaner.
Suppose we want to get the list of the users with the requested parameters as follows:
//Get api/user/search?age_more_than=25&gender=male&has_published_post=true
[
'age_more_than' => '25',
'gender' => 'male',
'has_published_post' => 'true',
]
In the legacy code the method written below was followed:
<?php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index(Request $request)
{
$users = User::where('is_active', true);
if ($request->has('age_more_than')) {
$users->where('age', '>', $request->age_more_than);
}
if ($request->has('gender')) {
$users->where('gender', $request->gender);
}
if ($request->has('has_published_post')) {
$users->where(function ($query) use ($request) {
$query->whereHas('posts', function ($query) use ($request) {
$query->where('is_published', $request->has_published_post);
});
});
}
return $users->get();
}
}
But the new method with EloquentBuilder follows the steps below:
<?php
namespace App\Http\Controllers;
use App\User;
use EloquentBuilder;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index(Request $request)
{
$users = EloquentBuilder::to(User::class, $request->all());
return $users->get();
}
}
Note: It's recommended validates the incoming requests before sending to filters.
You can install the package via composer:
composer require mohammad-fouladgar/eloquent-builder
Laravel 5.5 uses Package Auto-Discovery, so you are not required to add ServiceProvider manually.
If you don't use Auto-Discovery, add the ServiceProvider to the providers array in config/app.php
file
'providers' => [
/*
* Package Service Providers...
*/
Fouladgar\EloquentBuilder\ServiceProvider::class,
],
And add the facade to your config/app.php
file
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
*/
'aliases' => [
"EloquentBuilder" => Fouladgar\EloquentBuilder\Facade::class,
]
You can install the package via composer:
composer require mohammad-fouladgar/eloquent-builder
For Lumen, add the LumenServiceProvider
to the bootstrap/app.php
file
/*
|--------------------------------------------------------------------------
| Register Service Providers...
|--------------------------------------------------------------------------
*/
$app->register(\Fouladgar\EloquentBuilder\LumenServiceProvider::class);
For using the facade you have to uncomment the line $app->withFacades();
in the bootstrap/app.php
file
After uncommenting this line you have the EloquentBuilder
facade enabled
$app->withFacades();
Publish the configuration file
php artisan eloquent-builder:publish
and add the configuration to the bootstrap/app.php
file
$app->configure('eloquent-builder');
...
$app->register(\Fouladgar\EloquentBuilder\LumenServiceProvider::class);
Important : this needs to be before the registration of the service provider.
The default namespace for all filters is App\EloquentFilters\
with the base name of the Model.
For example:
Suppose we have a User model with an AgeMoreThan filter.As a result, the namespace filter must be as follows:
App\EloquentFilters\User\AgeMoreThanFilter
You can optionally publish the config file with:
php artisan vendor:publish --provider="Fouladgar\EloquentBuilder\ServiceProvider" --tag="config"
And set the namespace for your model filters which will reside in:
return [
/*
|--------------------------------------------------------------------------
| Eloquent Filter Settings
|--------------------------------------------------------------------------
|
| This is the namespace all you Eloquent Model Filters will reside
|
*/
'namespace' => 'App\\EloquentFilters\\',
];
Writing a filter is simple. Define a class that implements the Fouladgar\EloquentBuilder\Support\Foundation\Contracts\IFilter
interface. This interface requires you to implement one method: apply
. The apply
method may add where constraints to the query as needed:
<?php
namespace App\EloquentFilters\User;
use Fouladgar\EloquentBuilder\Support\Foundation\Contracts\IFilter as Filter;
use Illuminate\Database\Eloquent\Builder;
class AgeMoreThanFilter implements Filter
{
/**
* Apply the age condition to the query.
*
* @param Builder $builder
* @param mixed $value
*
* @return Builder
*/
public function apply(Builder $builder, $value): Builder
{
return $builder->where('age', '>', $value);
}
}
Filter parameters are ignored if contain empty values or null.
Suppose we have a request something like:
//Get api/user/search?name&gender=null&age_more_than=''&published_post=true
// Request result will be:
$filters = [
'published_post' => true
];
Only the "published_post" filter will be applied on your query.
You may also want to work with existing queries. For example, consider the following code:
<?php
namespace App\Http\Controllers;
use App\User;
use EloquentBuilder;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index(Request $request)
{
$query = User::where('is_active', true);
$users = EloquentBuilder::to($query, $request->all())
->where('city', 'london')
->paginate();
return $users;
}
}
Suppose you want use the EloquentBuilder
as DependencyInjection
in a Repository
.
Let's have an example.We have a sample UserRepository
as follows:
<?php
namespace App\Repositories;
use App\User;
use Fouladgar\EloquentBuilder\EloquentBuilder;
class UserRepository extends BaseRepository
{
public function __construct(EloquentBuilder $eloquentBuilder)
{
$this->eloquentBuilder = $eloquentBuilder;
$this->makeModel();
}
public function makeModel()
{
return $this->setModel($this->model());
}
public function setModel($model)
{
$this->model = app()->make($model);
return $this;
}
public function model()
{
return User::class;
}
public function all($columns = ['*'])
{
return $this->model->get($columns);
}
// other methods ...
public function filters(array $filters)
{
$this->model = $this->eloquentBuilder->to($this->model(), $filters);
return $this;
}
}
The filters
method applies the requested filters to the query by using EloquentBuilder
injected.
Now,we can simply "type-hint" it in the constructor of our UserController
:
<?php
namespace App\Http\Controllers;
use App\Repositories\UserRepository;
use Illuminate\Http\Request;
class UserController extends Controller
{
protected $users;
public function __construct(UserRepository $users)
{
$this->users = $users;
}
public function index(Request $request)
{
return $this->users->filters($request->all())->get();
}
}
composer test
Please see CONTRIBUTING for details.
If you discover any security related issues, please email fouladgar.dev@gmail.com instead of using the issue tracker.
Eloquent-Builder is released under the MIT License. See the bundled LICENSE file for details.
Built with :heart: for you.