esign/laravel-query-filters

应用过滤器到Laravel的查询构建器。

1.2.0 2024-03-12 21:09 UTC

This package is auto-updated.

Last update: 2024-09-12 22:14:49 UTC


README

Latest Version on Packagist Total Downloads GitHub Actions

此包允许您通过将过滤器逻辑抽象到专用类中来轻松地将过滤器应用到Laravel的查询构建器。

安装

您可以通过composer安装此包

composer require esign/laravel-query-filters

该包将自动注册服务提供者。

用法

准备您的模型

要为您的模型应用过滤器,您可以使用 Esign\QueryFilters\Concerns\Filterable 特性

use Esign\QueryFilters\Concerns\Filterable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use Filterable;
}

应用过滤器

将特性应用到您的模型后,将有一个名为 filter 的查询作用域可用,该作用域接受一个可能的过滤器数组

use App\Models\Filters\TitleFilter;
use App\Models\Filters\BodyFilter;

Post::filter([
    TitleFilter::class,
    BodyFilter::class,
])->get();

filter 作用域将通过一个过滤器数组将查询构建器传递给下一个过滤器。要将查询构建器传递给下一个过滤器,您应该使用 $query 调用 $next 回调。

您不仅限于仅使用基于字符串的类作为过滤器,您还可以传递实际实例、回调或与您的基于类的字符串一起传递参数

use App\Models\Filters\TitleFilter;
use Closure;
use Illuminate\Database\Eloquent\Builder;

Post::filter([
    // Class strings
    TitleFilter::class,
    // Class strings that pass a parameter to the handle method
    TitleFilter::class . ':dogs',
    // Class instance with a constructor parameter
    new TitleFilter('dogs'),
    // Use a callback
    function (Builder $query, Closure $next): Builder {
        $query->where('title', 'like', '%dogs%');

        return $next($query);
    },
])->get();

定义默认过滤器

如果您没有提供过滤器项数组,您可以在模型上定义一组默认过滤器

use App\Models\Filters\TitleFilter;
use Esign\QueryFilters\Concerns\Filterable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use Filterable;

    public function getFilters(): array
    {
        return [
            TitleFilter::class,
        ];
    }
}

现在您可以调用 filter 作用域而不传递数组

Post::filter()->get();

创建过滤器

要创建一个过滤器类,您可以使用 make:filter Artisan命令

php artisan make:filter TitleFilter
namespace App\Models\Filters;

use Closure;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;

class TitleFilter
{
    public function __construct(protected Request $request)
    {}

    public function handle(Builder $query, Closure $next): Builder
    {
        $query->where('title', 'like', '%' . $this->request->query('search') . '%');

        return $next($query);
    }
}

方法过滤器

此包还提供了一个方便的 MethodFilter 类,允许您定义将查询字符串参数作为方法的过滤器。想象一下,我们有一个请求,它使用以下查询字符串来过滤帖子列表:?published_at=2022-01-01&title=dogs。我们可以创建一个扩展 MethodFilter 类并具有驼峰命名方法的 PostFilter

use Esign\QueryFilters\Filters\MethodFilter;
use Illuminate\Database\Eloquent\Builder;

class PostFilter extends MethodFilter
{
    public function title(mixed $value): Builder
    {
        return $this->query->where('title', 'like', "%$value%");
    }

    public function publishedAt(mixed $value): Builder
    {
        return $this->query->where('published_at', '=', $value);
    }
}

默认情况下,包含空值的查询字符串参数不会被调用。

测试

composer test

许可证

MIT许可证(MIT)。请参阅许可证文件以获取更多信息。