bakhadyrovf/easy-filter

此包允许您使用自己的方法过滤查询。

v3.0.1 2022-10-05 07:46 UTC

This package is auto-updated.

Last update: 2024-09-05 11:57:44 UTC


README

这是一个通过用户自定义方法过滤查询的包。

依赖项

  • PHP >= 8.0
  • Laravel >= 9.0

安装

composer require bakhadyrovf/easy-filter

Laravel使用包自动发现,因此不需要您手动添加ServiceProvider。

使用发布命令将包配置复制到本地配置。

php artisan vendor:publish --tag=easy-filter-config

用法

重要

默认情况下,过滤器的命名空间为App\Filters,每个过滤器类在创建之前都期望您已经有一个遵循以下命名空间标准的强类型Eloquent模型

首先,您必须创建一个过滤器类

php artisan make:filter ArticleFilter

此命令将在您项目的app/Filters文件夹中创建ArticleFilter类。
此命令还将把Filterable特质添加到您的Eloquent Model

您可以在配置文件中更改基本文件夹的名称(命名空间也会相应更改)

<?php

return [

    /**
     * Base folder's name in app directory.
     * Default: Filters
     */
    'base-folder' => 'Filters'

];

此外,您还可以使用子文件夹生成过滤器类

php artisan make:filter Dashboard/ArticleFilter

过滤器类将位于app/Filters/Dashboard文件夹。

新创建的类将如下所示

<?php 

namespace App\Filters\ArticleFilter;

use Bakhadyrovf\EasyFilter\QueryFilter;

class ArticleFilter extends QueryFilter
{
    
}

如果您的ModelFilter的命名空间与上述不匹配,您可以使用--model选项:例如,我们有一个命名空间为App\Models\Article的模型,我们希望创建一个命名空间为App\Filters\Dashboard\ArticleFilter的过滤器类

php artisan make:filter Dashboard/ArticleFilter --model=App\\Models\\Article

为了使不与模型命名空间匹配的过滤器,您必须在您的App\Models\Article类中添加方法

<?php

namespace App\Models\Admin;

use Bakhadyrovf\EasyFilter\Traits\Filterable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use App\Filters\Dashboard\ArticleFilter;

class Discount extends Model
{
    use HasFactory, Filterable;
    
    public function provideFilter()
    {
        return ArticleFilter::class;
    }
}

此方法将指向特定的过滤器类。

现在,您可以在过滤器类中编写自己的方法。让我们添加第一个方法并尝试过滤我们的查询。在app/Filters/ArticleFilter

class ArticleFilter extends QueryFilter
{
    public function title(Builder $builder, $value)
    {
        return $builder->where('title', 'LIKE', $value . '%');           
    }
}

方法参数

  • $builder - Illuminate\Database\Eloquent\Builder
  • $value - 从请求中获取的值

您可以使用您Eloquent Model上的filter()方法尝试过滤查询。这是基本的Eloquent Scope,因此您可以像通常一样使用它。在app\Http\Controllers\ArticleController

use App\Models\Article;
use Illuminate\Http\Request;

class ArticleController extends Controller
{
    public function index(Request $request)
    {
        $articles = Article::filter()
            ->orderByDesc('id')
            ->get();
            
        return $articles;
    }
}

所有负责过滤的参数都必须在查询中

example.com/articles?title=some-title

如果您的参数是蛇形命名,您不需要创建相同命名的参数的方法,因为它不匹配php标准。包本身会将参数转换为驼峰式命名。

例如,如果您的参数是first_name

example.com/articles?first_name=some-value

方法将如下所示

Class ArticleFilter extends QueryFilter 
{
    public function firstName(Builder $builder, $value)
    {
        return $builder->where('first_name', 'LIKE', $value . '%');
    }
}

多个值
如果您的参数可以接受多个值,您可以使用括号

example.com/articles?category_ids=[1,2,3,4,5]

通常,这些值将在方法的第二个参数中

Class ArticleFilter extends QueryFilter 
{
    public function categoryIds(Builder $builder, $values)
    {
        return $builder->whereHas('categories', function ($query) use ($values) {
            return $query->whereIn('id', $values);
        });
    }
}

忽略参数
例如,如果您想忽略post_ids参数的过滤

https://example.com/users?name=Firuzbek&post_ids=[1,10,25]

您可以将方法名称或查询参数的异常数组作为filter()方法的参数提供

use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index(Request $request)
    {
        $users = User::active()
            ->filter(['postIds']) // Or post_ids
            ->orderByDesc('created_at')
            ->get();
            
        return $users;
    }
}

多个过滤器
如果您有一个模型的多个过滤器类,您可以提供特定的过滤器类作为第二个参数。即使您在模型上有一个provideFilter()方法,也会使用此过滤器类

use App\Models\Post;
use App\Filters\Dashboard\PostFilter;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index(Request $request)
    {
        $posts = Post::active()
            ->filter(['sort_by'], PostFilter::class)  
            ->orderByDesc('created_at')
            ->get();
            
        return $posts;
    }
}