mjahn / eloquent-builder
Requires
- php: ^7.1
- illuminate/database: ~5.5.0|~5.6.0|~5.7.0|~5.8.0|~6.0
- illuminate/http: ~5.5.0|~5.6.0|~5.7.0|~5.8.0|~6.0
- illuminate/support: ~5.5.0|~5.6.0|~5.7.0|~5.8.0|~6.0
Requires (Dev)
- mockery/mockery: ^1.0.0
- orchestra/testbench: ~3.5.0|~3.6.0|~3.7.0|~3.8.0
- php-coveralls/php-coveralls: ^2.1
- phpunit/phpunit: ^7.1
This package is auto-updated.
Last update: 2024-09-29 05:55:23 UTC
README
此包允许您基于请求参数构建优雅的查询。它极大地降低了查询和条件的复杂性,从而使您的代码更加清晰。
基本用法
假设您想获取具有以下请求参数的用户列表
//Get api/user/search?age_more_than=25&gender=male&has_published_post=true [ 'age_more_than' => '25', 'gender' => 'male', 'has_published_post' => 'true', ]
在 旧版 代码中,遵循以下方法
<?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); } // A User model may have an infinite numbers of Post(One-To-Many). 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(); } }
但是 在使用 EloquentBuilder 之后,上述代码重构如下
<?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(); } }
您只需为要添加到查询中的每个参数定义 过滤器。
提示:建议在发送到过滤器之前验证传入的请求。
提示:建议将过滤器放在查询字符串的
filter
键内部,如下所示:user/search?filter[age_more_than]=25&filter[gender]=male
然后以这种方式获取它们:$request->only('filter')
。
安装
Laravel
您可以通过 composer 安装此包
composer require mohammad-fouladgar/eloquent-builder
Laravel 5.5 使用包自动发现,因此您无需手动添加 ServiceProvider。
Laravel <= 5.4.x
如果您不使用自动发现,请将 ServiceProvider 添加到 config/app.php
文件中的 providers 数组
'providers' => [ /* * Package Service Providers... */ Fouladgar\EloquentBuilder\ServiceProvider::class, ],
并将 外观 添加到您的 config/app.php
文件
/* |-------------------------------------------------------------------------- | Class Aliases |-------------------------------------------------------------------------- */ 'aliases' => [ "EloquentBuilder" => Fouladgar\EloquentBuilder\Facade::class, ]
Lumen
您可以通过 composer 安装此包
composer require mohammad-fouladgar/eloquent-builder
对于 Lumen,请将 LumenServiceProvider
添加到 bootstrap/app.php
文件
/* |-------------------------------------------------------------------------- | Register Service Providers... |-------------------------------------------------------------------------- */ $app->register(\Fouladgar\EloquentBuilder\LumenServiceProvider::class);
要使用外观,您必须在 bootstrap/app.php
文件中取消注释 $app->withFacades();
行
取消注释此行后,您将启用 EloquentBuilder
外观
$app->withFacades();
发布配置文件
php artisan eloquent-builder:publish
并将配置添加到 bootstrap/app.php
文件
$app->configure('eloquent-builder'); ... $app->register(\Fouladgar\EloquentBuilder\LumenServiceProvider::class);
重要:这需要在注册服务提供商之前完成。
默认过滤器命名空间
所有过滤器的默认命名空间为 App\EloquentFilters
,其基名为模型。例如,对于 User
模型,过滤器命名空间将是 App\EloquentFilters\User
。
使用配置文件
您可以选择使用以下方式发布配置文件
php artisan vendor:publish --provider="Fouladgar\EloquentBuilder\ServiceProvider" --tag="config"
并设置您模型过滤器所在的命名空间,该过滤器将位于
return [ /* |-------------------------------------------------------------------------- | Eloquent Filter Settings |-------------------------------------------------------------------------- | | This is the namespace all you Eloquent Model Filters will reside | */ 'namespace' => 'App\\EloquentFilters\\', ];
定义一个过滤器
编写过滤器很简单。定义一个继承自 Fouladgar\EloquentBuilder\Support\Foundation\Contracts\Filter
抽象类的类。该类要求您实现一个方法: apply
。根据需要,apply
方法可以添加 where 约束到查询。每个过滤器类都应该以单词 Filter
结尾。
例如,看一下下面定义的过滤器
<?php namespace App\EloquentFilters\User; use Fouladgar\EloquentBuilder\Support\Foundation\Contracts\Filter; use Illuminate\Database\Eloquent\Builder; class AgeMoreThanFilter extends 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); } }
提示:您还可以在过滤器中轻松使用 局部作用域。因为它们是查询构建器的实例。
授权过滤器
过滤器类还包含一个 authorize
方法。在此方法内,您可以检查认证用户是否有权应用给定的过滤器。例如,您可以确定用户是否有高级账户,可以应用 StatusFilter
以列出在线或离线人员
/** * Determine if the user is authorized to make this filter. * * @return bool */ public function authorize(): bool { if(auth()->user()->hasPremiumAccount()){ return true; } return false }
默认情况下,您无需实现 authorize
方法,并且过滤器将应用于您的查询构建器。如果 authorize
方法返回 false
,将自动返回一个具有 403 状态码的 HTTP 响应。
忽略空值上的过滤器
如果过滤器参数包含 空 或 空值,则忽略过滤器。
假设您有一个这样的请求
//Get api/user/search?filter[name]&filter[gender]=null&filter[age_more_than]=''&filter[published_post]=true EloquentBuilder::to(User::class,$request->only('filter')); // filters result will be: $filters = [ 'published_post' => true ];
只有 "published_post" 过滤器会被应用于您的查询。
处理现有查询
您也可以选择处理现有查询。例如,考虑以下代码
<?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; } }
作为依赖注入使用
假设您想将 EloquentBuilder
作为 DependencyInjection
用于 Repository
。
让我们举一个例子。我们有一个如下的示例 UserRepository
:
<?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; } }
filters
方法通过注入的 EloquentBuilder
将请求的过滤器应用于查询。
注入仓库
现在,我们可以在 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
贡献
有关详细信息,请参阅CONTRIBUTING。
安全
如果您发现任何与安全相关的问题,请通过电子邮件 fouladgar.dev@gmail.com 联系,而不是使用问题跟踪器。
许可协议
Eloquent-Builder 在 MIT 许可协议下发布。有关详细信息,请参阅附带的 LICENSE 文件。
用 ❤️ 为您打造。