amirhshokri / laravel-filterable
为Laravel查询构建器添加过滤功能的更好解决方案。
Requires
- php: ^8.1
- illuminate/console: ^10.0
- illuminate/database: ^10.0
- illuminate/support: ^10.0
This package is auto-updated.
Last update: 2024-09-12 09:21:08 UTC
README
简介
Laravel Filterable 帮助您将高效的过滤逻辑添加到Laravel查询构建器。您可以使用默认的过滤逻辑,手动定义自定义过滤逻辑,或使用提供的命令在任何路径下创建它。通过启用自动发现模式,该包将自动为您定位所需的过滤类。
安装
您可以通过composer安装此包
composer require amirhshokri/laravel-filterable
您可以使用以下命令发布配置文件
php artisan vendor:publish --tag="laravel-filterable-config"
这是已发布的配置文件的内容
return [ 'auto_discovery' => false, 'namespace' => 'App\\Filterable\\Custom', 'suffix' => 'Filter', ];
这些参数的用法将在下面讨论。
基本用法
步骤 1: 将 Filterable 特性添加到您的模型中
use Amirhshokri\LaravelFilterable\Main\Filterable; class User extends Authenticatable { use Filterable; }
您还可以使用 $allowedFilterParameters
数组指定允许过滤的字段
use Amirhshokri\LaravelFilterable\Main\Filterable; class User extends Authenticatable { use Filterable; protected array $allowedFilterParameters = ["id", "email"]; }
如果未定义 $allowedFilterParameters
,则所有参数都将允许进行过滤。
步骤 2: 将 filter()
方法添加到您的查询构建器中
$users = \App\Models\User::query() ->filter() ->get();
步骤 3: 提交请求
{ "filters": [ { "name": "id", "operator": "isEqualTo", "value": 1 }, { "name": "email", "operator": "contains", "value": "@gmail" } ] }
支持的运算符
可用的运算符有
- isEqualTo
- isNotEqualTo
- greaterThan
- lessThan
- greaterThanOrEqualTo
- lessThanOrEqualTo
- between
- in
- contains
深入探讨 filter()
方法
使用 filter()
方法有几种方法
方法 1: 传递自定义过滤类
您可以将自定义过滤类传递给 filter()
方法,为您的模型强制执行特定的过滤逻辑
$users = \App\Models\User::query() ->filter(new UserFilter()) ->get();
如何创建自定义过滤类?
您可以选择手动创建自定义过滤类,或使用以下命令生成
php artisan make:filter <FilterName> --path=Path\To\Filter\Class
注意
-
此命令使用配置文件中的
suffix
参数来创建过滤类。文件名必须以指定的后缀结尾(例如,MyNewUserFilter)。 -
如果没有提供
--path
选项,则将使用配置文件中的namespace
参数作为默认路径。
生成自定义过滤类的示例
use Amirhshokri\LaravelFilterable\Main\Filter\Custom\CustomFilter; class UserFilter extends CustomFilter { //TODO: Add your custom filter logic here. }
一旦您创建了自定义过滤类,您可以为希望过滤的每个字段扩展过滤逻辑。在自定义过滤类中添加一个与请求体中的 name
字段对应的函数
use Amirhshokri\LaravelFilterable\Main\Filter\Custom\CustomFilter; class UserFilter extends CustomFilter { public function id($value, string $operator): void { //Custom filter logic for 'id' column } public function email($value, string $operator): void { //Custom filter logic for 'email' column } }
注意
-
每个函数可以接受
$value
和$operator
参数。$value
代表请求中的值,$operator
代表运算符。 -
使用
operatorMapper()
方法将运算符映射到数据库等效项,例如
$eloquentBuilder
属性在自定义过滤类中提供,允许更易于阅读的查询。它本质上是对Laravel默认查询构建器的副本。
use Amirhshokri\LaravelFilterable\Main\Filter\Custom\CustomFilter; class UserFilter extends CustomFilter { public function id($value): void { $this->eloquentBuilder->where('id', $value); } public function mobile($value, string $operator): void { $this->eloquentBuilder->where('mobile', $this->operatorMapper($operator), $value); } }
嵌套过滤
对于更复杂的过滤场景,您可以在另一个 filter()
调用内部调用 filter()
,以应用多个条件,例如根据帖子标题过滤用户。
注意
- 此外,请确保已将 Filterable 特性添加到
Post
模型中。
use Amirhshokri\LaravelFilterable\Main\Filter\Custom\CustomFilter; class UserFilter extends CustomFilter { public function title($value, string $operator): void { $this->eloquentBuilder->whereHas('posts', function ($query) use ($value, $operator) { $query->setFilterParameters([ ["title", $operator, $value] ])->filter(); }); } }
然后,提交请求
{ "filters": [ { "name": "title", "operator": "contains", "value": "pizza" } ] }
注意
- 您可以使用
OperatorEnum
添加多个条件,如下所示
use Amirhshokri\LaravelFilterable\Main\Filter\Custom\CustomFilter; use Amirhshokri\LaravelFilterable\Main\Filter\Enum\OperatorEnum; class UserFilter extends CustomFilter { public function title($value, string $operator): void { $this->eloquentBuilder->whereHas('posts', function ($query) use ($value, $operator) { $query->setFilterParameters([ ["id", OperatorEnum::IS_NOT_EQUAL_TO, 10], ["title", $operator, $value], ["slug", OperatorEnum::CONTAINS, 'another pizza'] ])->filter(); }); } }
方法 2: 使用自动发现
该包包含一个自动发现功能,根据配置文件中定义的 namespace
和 suffix
参数自动检测自定义过滤类。此功能在您希望不将自定义过滤类传递给 filter()
方法时很有用。
当启用 自动发现
时,它将搜索名为 {ModelName}{Suffix}.php
的过滤器类(例如,在 App\Filterable\Custom 中的 UserFilter.php)。如果自定义过滤器类未在预期位置找到,将抛出异常。
注意
- 在本地启用或禁用自动发现:想象一下这样的场景,全局启用了自动发现,但你不想为某些
filter()
调用使用它,反之亦然。在这种情况下,你可以在调用filter()
方法之前简单地调用setFilterAutoDiscovery()
方法,传递一个布尔值。
use Amirhshokri\LaravelFilterable\Main\Filter\Custom\CustomFilter; class UserFilter extends CustomFilter { public function title($value, string $operator): void { $this->eloquentBuilder->whereHas('posts', function ($query) use ($value, $operator) { $query->setFilterParameters([ ["title", $operator, $value] ]) ->setFilterAutoDiscovery(false) ->filter(); }); } }
- 如果你更喜欢使用
make:filter
命令创建自定义过滤器类,并且该类在自动发现模式下可被发现,你可以省略--path
选项,自动在指定的namespace
中生成文件。
方法 3:使用默认过滤器
如果你没有为 filter()
方法提供自定义过滤器类,并且自动发现被关闭,该包将使用之前在 基本用法 部分中解释的默认过滤器功能为你提供模型。
致谢
许可协议
MIT 许可协议(MIT)。有关更多信息,请参阅 许可文件。