exenjer/laravel-filters

为您的Laravel Eloquent应用程序提供简单方便的过滤器

此包的规范存储库似乎已丢失,因此包已被冻结。

2.2.0 2020-01-19 13:28 UTC

This package is auto-updated.

Last update: 2021-10-19 19:43:00 UTC


README

为您的 Laravel Eloquent 应用程序提供简单方便的过滤器

安装

使用此包所需的最小 php 版本:7.1
使用composer要求此包。

composer require exenjer/laravel-filters

使用

public function index(Request $request, UserFilter $userFilter)
{
    $users = $userFilter->filter($request->all())
        ->get();
    // OR
    $users = $userFilter->filter($request->all())
        ->paginate();
    // OR
    $users = $userFilter->filter($request->all())
        ->simplePaginate();
        
    // OR
    $users = (new UserFilter())->filter($request->all())
        ->get();
    // ...
}

配置

基本配置

创建一个新的类并扩展从 Filter

class UserFilter extends Filter
{

}

添加过滤器方法

class UserFilter extends Filter
{
    public function filter(array $request): Filter
    {
        $this->setFilter($this); // Set this class as filter
    
        return $this->apply($request); // Apply filter
    }
}

或使用特性以使用默认的过滤器方法

class UserFilter extends Filter
{
    use DefaultFilterSetUp;
}

指定过滤器将工作的模型

class UserFilter extends Filter
{
    use DefaultFilterSetUp;
    
    protected $model = User::class;
}

指定将响应过滤的字段

class UserFilter extends Filter
{
    use DefaultFilterSetUp;
    
    protected $model = User::class;
    
    protected $fields = ['name', 'age'];
}

您已准备好编写过滤器!

编写过滤器的以下方案:创建具有以下名称的方法:'fieldName' + 'Filter'用于处理除数组外的所有请求值,以及用于处理数组的'fieldName' + 'ArrayFilter'

您不能创建用于过滤特定字段的特定方法。然后将调用标准方法,其详细信息如下。

在蛇形命名(例如 price_from)的情况下,方法的名称必须是驼峰命名法(priceFromFilter)。

示例:

class UserFilter extends Filter
{
    use DefaultFilterSetUp;
    
    protected $model = User::class;
    
    protected $fields = ['name', 'age', 'age_from'];
    
    protected function nameFilter(string $value): void
    {
        $this()->where('name', $value);
    }

    protected function nameArrayFilter(array $value): void
    {
        $this()->whereIn('name', $value);
    }

    protected function ageFromFilter(string $value): void 
    {
        $this()->where('age', '>=', $value);
    }
}

是的,为了访问构建器,您需要引用$this()

附加配置

排除特定字段

要排除查询中对特定字段的默认过滤器触发,请使用数组$exclude

protected $exclude = ['id', 'email'];

With trashed

要使用所有过滤器withTrashed,将$withDeletions属性设置为true

protected $withDeletions = true;

Casts

您还可以通过$casts属性对结果值进行类型转换

注意:支持类型:int(整数)、bool(布尔值)、float、double、real、array、object。

在获取数组时不工作

protected $casts = [
    'age' => 'int'
];

自定义构建器

如果您需要使用预定义的eloquent参数进行过滤,可以使用setModelBuilder函数

public function index(Request $request, UserFilter $userFilter)
{
    $modelBuilder = User::where(...)->with(...);

    $users = $userFilter->setModelBuilder($modelBuilder)
        ->filter($request->all())
        ->get();
}

动态过滤器

您可以通过两种方式动态添加过滤器

  1. 使用方法addFilter()
  2. 使用接口FilterRule和方法addFilterClass()

第一个方法的示例实现(在UserFilter上下文中)

$this->addFilter('name', function (string $name): void {
    $this()->where('name', $name);
}, function (array $values): void { // For arrays
    $this()->whereIn('name', $values);
});

第二个方法的实现

创建一个类并实现FilterRule接口

class UserNameRuleFilter implements FilterRule
{
    public function handle($value, Builder $builder): void
    {
        $builder->where('name', $value);
    }
 
    public function handleArray(array $values, Builder $builder): void
    {
        $builder->whereIn('name', $values);
    }
}

使用addFilterClass()方法将类添加到UserFilter实例

$userFilter->addFilterClass('name', new UserNameRuleFilter());

默认过滤器

如果您还没有为特定字段编写过滤器,那么将调用默认数据处理方法

它们的默认实现

protected function defaultFilterCall(string $field, $value): void
{
    $this()->where($field, $value);
}

protected function defaultArrayFilterCall(string $field, array $values): void
{
    $this()->whereIn($field, $values);
}

您可以在过滤器中覆盖它们

class UserFilter extends Filter
{
    use DefaultFilterSetUp;
    
    protected $model = User::class;
    
    protected $fields = ['name', 'age'];
    
    protected function defaultFilterCall(string $field, $value): void
    {
        // Some logic...
    }
    
    protected function defaultArrayFilterCall(string $field, array $values): void
    {
        // Some logic...
    }
}

感谢

欢迎任何pull requests和suggestions(建议)!