l3aro/pipeline-query-collection

用于Laravel Pipeline的查询数据库集合

v1.4.2 2024-03-03 17:36 UTC

README

Latest Version on Packagist GitHub Tests Action Status Total Downloads

此包包含一组可用于Laravel Pipeline的类。下面是一些查询示例:

// users?name=Baro&is_admin=1&created_at_from=2022-06-01&created_at_to=2022-06-31
$users = User::query()
    ->when($request->name ?? null, function($query, $name) {
        $query->where('name', 'like', "%$name%");
    })
    ->when($request->is_admin ?? null, function($query, $isAdmin) {
        $query->where('is_admin', $isAdmin ? 1 : 0);
    })
    ->when($request->created_at_from ?? null, function($query, $date) {
        $query->where('created_at', '>=', $date);
    })
    ->when($request->created_at_to ?? null, function($query, $date) {
        $query->where('created_at', '<=', $date);
    })
    ->get();

正如大家所看到的,随着过滤条件的增加以及相同过滤条件的重复使用,它显然会持续增长。我们可以使用Laravel Pipeline结合一些预制的查询来重构这个

use Baro\PipelineQueryCollection;

// users?name=Baro&is_admin=1&created_at_from=2022-06-01&created_at_to=2022-06-31
$users = Users::query()->filter([
    PipelineQueryCollection\RelativeFilter::make('name'),
    PipelineQueryCollection\BooleanFilter::make('is_admin'),
    PipelineQueryCollection\DateFromFilter::make('created_at'),
    PipelineQueryCollection\DateToFilter::make('created_at'),
])
->get();

目录

安装

通过composer安装包

composer require l3aro/pipeline-query-collection

可选,您可以使用以下命令发布配置文件:

php artisan vendor:publish --tag="pipeline-query-collection-config"

这是发布配置文件的内容

return [
    // key to detect param to filter
    'detect_key' => env('PIPELINE_QUERY_COLLECTION_DETECT_KEY', ''),

    // type of postfix for date filters
    'date_from_postfix' => env('PIPELINE_QUERY_COLLECTION_DATE_FROM_POSTFIX', 'from'),
    'date_to_postfix' => env('PIPELINE_QUERY_COLLECTION_DATE_TO_POSTFIX', 'to'),

    // default motion for date filters
    'date_motion' => env('PIPELINE_QUERY_COLLECTION_DATE_MOTION', 'find'),
];

用法

准备你的模型

要使用此集合与模型一起使用,您应该实现以下接口和特性

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Baro\PipelineQueryCollection\Concerns\Filterable;
use Baro\PipelineQueryCollection\Contracts\CanFilterContract;

class YourModel extends Model implements CanFilterContract
{
    use Filterable;

    public function getFilters(): array
    {
        return [
            // the filter and sorting that your model need
        ];
    }
}

设置好模型后,您可以在模型上使用作用域过滤,如下所示:

YourModel::query()->filter()->get();

您也可以像这样覆盖模型中的预定义过滤列表:

YourModel::query()->filter([
    // the custom filter and sorting that your model need
])
->paginate();

功能

这里使用集合中的所有过滤和排序

位运算过滤

use Baro\PipelineQueryCollection\BitwiseFilter;

// users?permission[0]=2&permission[1]=4
User::query()->filter([
    BitwiseFilter::make('permission'), // where permission & 6 = 6
]);

布尔过滤

use Baro\PipelineQueryCollection\BooleanFilter;

// users?is_admin=1
User::query()->filter([
    BooleanFilter::make('is_admin'), // where is_admin = 1
]);

日期从过滤

use Baro\PipelineQueryCollection\DateFromFilter;
use Baro\PipelineQueryCollection\Enums\MotionEnum;

// users?updated_at_from=2022-05-31
User::query()->filter([
    DateFromFilter::make('updated_at'), // where updated_at >= 2022-05-31
    DateFromFilter::make('updated_at', MotionEnum::TILL), // where updated_at > 2022-05-31
    // you can config default motion behavior and the postfix `from` in the config file
]);

日期到过滤

use Baro\PipelineQueryCollection\DateToFilter;
use Baro\PipelineQueryCollection\Enums\MotionEnum;

// users?updated_at_to=2022-05-31
User::query()->filter([
    DateToFilter::make('updated_at'), // where updated_at <= 2022-05-31
    DateToFilter::make('updated_at', MotionEnum::TILL), // where updated_at < 2022-05-31
    // you can config default motion behavior and the postfix `to` in the config file
]);

精确过滤

use Baro\PipelineQueryCollection\ExactFilter;

// users?id=4
User::query()->filter([
    ExactFilter::make('id'), // where id = 4
]);

关系过滤

use Baro\PipelineQueryCollection\RelationFilter;

// users?roles_id[0]=1&roles_id[1]=4
User::query()->filter([
    RelationFilter::make('roles', 'id'), // where roles.id in(1,4)
]);

相对过滤

use Baro\PipelineQueryCollection\RelativeFilter;
use Baro\PipelineQueryCollection\Enums\WildcardPositionEnum;

// users?name=Baro
User::query()->filter([
    RelativeFilter::make('name'), // where('name', 'like', "%Baro%")
    RelativeFilter::make('name', WildcardPositionEnum::LEFT), // where('name', 'like', "%Baro")
    RelativeFilter::make('name', WildcardPositionEnum::RIGHT), // where('name', 'like', "Baro%")
]);

作用域过滤

// users?search=Baro

// User.php
public function scopeSearch(Builder $query, string $keyword)
{
    return $query->where(function (Builder $query)  use ($keyword) {
        $query->where('id', $keyword)
            ->orWhere('name', 'like', "%{$keyword}%");
    });
}

// Query
use Baro\PipelineQueryCollection\ScopeFilter;

User::query()->filter([
    ScopeFilter::make('search'), // where (`id` = 'Baro' or `name` like '%Baro%')
]);

回收站过滤

当使用Laravel的软删除时,您可以使用管道TrashFilter来查询这些模型。默认查询名称为trashed,并且过滤器响应特定的值

  • with:查询应该是?trashed=with,以便将软删除的记录包含在结果集中
  • only:查询应该是?trashed=only,以便仅将软删除的记录返回到结果集中
  • 任何其他值或完全从请求查询中删除trashed都将返回仅包含未软删除的记录的结果集

您可以通过传递到TrashFilter构造函数的自定义名称来更改查询名称trashed

use Baro\PipelineQueryCollection\TrashFilter;


// ?removed=only
User::query()->filter([
   TrashFilter::make('removed'), // where `deleted_at` is not null
]);

排序

use Baro\PipelineQueryCollection\ScopeFilter;

// users?sort[name]=asc&sort[permission]=desc
User::query()->filter([
    Sort::make(), //  order by `name` asc, `permission` desc
]);

探测器

有时,您想设置带有前缀的请求,例如filter.。您可以配置具有它的每个管道

use Baro\PipelineQueryCollection\ExactFilter;

// users?filter[id]=4&filter[permission][0]=1&filter[permission][1]=4
User::query()->filter([
    ExactFilter::make('id')->detectBy('filter.'), // where id = 4
    BitwiseFilter::make('permission')->detectBy('filter.'), // where permission & 5 = 5
]);

或者,您可以在全局上定义它

// users?filter[id]=4&filter[permission][0]=1&filter[permission][1]=4

// .env
PIPELINE_QUERY_COLLECTION_DETECT_KEY="filter."

// Query
User::query()->filter([
    ExactFilter::make('id'), // where id = 4
    BitwiseFilter::make('permission'), // where permission & 5 = 5
]);

自定义搜索列

有时,您的请求字段与列名不同。例如,在您的数据库中,您有列respond并希望针对它执行一些查询,但出于某种原因,您的请求查询是reply而不是respond

// users?reply=baro

User::query()->filter([
    RelativeFilter::make('reply')->filterOn('respond'), // where respond like '%baro%'
]);

自定义搜索值

您需要搜索的值不是来自您的请求?没问题。您可以使用value()函数来硬设置搜索值!

User::query()->filter([
    RelativeFilter::make('name')->value('Baro'), // where('name', 'like', "%Baro%")
]);

扩展过滤

是的,您可以使用自己的管道。看看我的一些过滤器。所有这些都扩展了BaseFilter以获得一些有用的属性和函数。

测试

composer test

贡献

有关详细信息,请参阅CONTRIBUTING

安全漏洞

请审查我们的安全策略,了解如何报告安全漏洞。

鸣谢

许可

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