acodingproject/laravel-filterable

使用URL查询字符串来过滤Eloquent查询。

v1.0.6 2023-06-20 14:09 UTC

This package is auto-updated.

Last update: 2024-09-20 16:50:49 UTC


README

Laravel Filterable

Latest Version on Packagist Build Status Total Downloads

此包允许您通过查询字符串轻松处理数据库过滤。该想法来自Jeffrey的视频之一(付费墙后)Jeffrey's videos (behind the paywall)。一个简单的示例可能如下所示:/users?filter-username=~joe 将生成SQL查询 select * from users where "username" like '%joe%'

安装

您可以通过composer安装此包

composer require kyslik/laravel-filterable

Laravel将自动发现此包。如果您想使用老式方法,请禁用自动发现,并将Kyslik\LaravelFilterable\FilterableServiceProvider::class添加到您的config/app.php文件中的提供者数组中。

开始之前

该包允许我们创建并应用两种类型的过滤器:自定义通用

自定义过滤器

自定义过滤器与Jeffrey的视频中的类似。我们在构建器实例上定义我们的逻辑,然后包将通过局部作用域应用它。
假设我们想显示最近创建的记录。我们在过滤器类中创建方法recent($minutes = null),此方法返回Builder实例

public function recent($minutes = null)
{
    $minutes = (is_numeric($minutes)) ? $minutes : 30;

    return $this->builder->where('created_at', '>=', Carbon\Carbon::now()->subMinutes($minutes));
}

完整示例稍后展示later on

通用过滤器

通用过滤器是在配置文件中定义的。默认情况下,该包支持过滤timestampsrangesinsbooleansstrings

/?filter-created_at=t>=1510952444
/?filter-id=><1,19
/?filter-id=i=1,5,10,12
/?filter-admin=b=yes
/?filter-username=joe
/?filter-username=~joe
/?filter-username=~joe&filter-admin=b=yes&filter-created_at=t=1510952444

通用过滤器的默认操作矩阵

使用方法

在使用两种过滤器时(自定义或通用)

  1. 模型上有具有签名scopeFilter(Builder $query, FILTERNAME $filters)的局部作用域
  2. 具有特定(FILTERNAME)过滤器类,该类扩展了以下之一
    • Kyslik\LaravelFilterable\GenericFilterable类 - 允许我们使用自定义和通用过滤器
    • Kyslik\LaravelFilterable\Filterable类 - 只允许我们使用自定义过滤器
  3. 在控制器中调用作用域

使用自定义过滤器的示例

假设我们想在用户模型上使用filterable。我们将必须创建过滤器类App/Filters/UserFilter.php,指定filterMap()和具有我们自定义逻辑的方法。

<?php
namespace App\Filters;

use Kyslik\LaravelFilterable\Filterable;

class UserFilters extends Filterable
{
    public function filterMap()
    {
        return ['recent' => ['recently', 'recent']];
    }
	
    public function recent($minutes = null)
    {
        $minutes = (is_numeric($minutes)) ? $minutes : 30;

        return $this->builder->where('created_at', '>=', \Carbon\Carbon::now()->subMinutes($minutes)->toDateTimeString());
    }
}

注意filterMap()必须定义,并且它应该返回一个关联数组,其中key是方法名,value是别名或别名数组

其次,我们必须通过特质将局部作用域添加到我们的用户模型中

use Kyslik\LaravelFilterable\FilterableTrait;

...
class User extends Model 
{
    use FilterableTrait;
    ...
}

最后,在用户控制器中,我们必须调用模型的作用域

public function index(User $user, UserFilters $filters) 
{
    return $user->filter($filters)->paginate();
}

现在我们可以访问users?recentusers?recentlyusers?recent=25,结果将通过在UserFilters类中定义的recent()方法进行过滤。

使用通用过滤器的示例

假设我们想要在用户模型上使用可过滤功能。我们需要创建一个过滤类 App/Filters/UserFilter.php 并指定 $filterables

<?php
namespace App\Filters;

use Kyslik\LaravelFilterable\GenericFilterable;

class UserFilters extends GenericFilterable
{
    protected $filterables = ['id', 'username', 'email', 'created_at', 'updated_at'];
}

其次,我们必须通过特质将局部作用域添加到我们的用户模型中

use Kyslik\LaravelFilterable\FilterableTrait;

...
class User extends Model 
{
    use FilterableTrait;
    ...
}

最后,在我们的用户控制器中,我们需要调用模型的范围。

public function index(User $user, UserFilters $filters) 
{
	return $user->filter($filters)->paginate();
}

我们已经准备好过滤用户模型了。

注意:在幕后,GenericFilterable 类继承自 Filterable 类,因此使用 GenericFilterable 也允许我们应用过滤类中定义的自定义过滤器

额外配置

在使用通用过滤器时,我们可以定义允许哪些泛型。在我们的过滤类中,我们定义了一个 settings() 方法来指定设置。

...
class UserFilters extends GenericFilterable
{
    protected $filterables = ['id', 'username', 'email', 'created_at', 'updated_at'];
    
    protected function settings()
    {
        // global settings for this filter, pick either "except" or "only" logic
        $this->only(['=', '~', '!~']);
        // $this->except(['!=']);

        // settings applied only to some columns, these settings ignore settings above
        $this->for(['username', 'id'])->only(['!=', '>=', '=', '~']);
        $this->for(['id'])->only(['=', '!=', '~']); //settings for "id" will be re-written
    }
}

测试

composer test

变更日志

有关最近更改的更多信息,请参阅 变更日志

贡献

有关详细信息,请参阅 贡献指南

安全

如果您发现任何安全问题,请通过电子邮件 martin.kiesel@gmail.com 联系我们,而不是使用问题跟踪器。

致谢

许可证

MIT许可(MIT)。有关更多信息,请参阅 许可文件