agog/osmose

为 Laravel 的 Eloquent 模型提供优雅的过滤功能

2.1.1 2020-07-28 14:01 UTC

README

Build Status Latest Stable Version Total Downloads License

优雅地过滤你的 Eloquent 集合

入门

要将 osmose 拉入您的项目,请使用以下命令

composer require agog/osmose

定义 Osmose 过滤器

Osmose 提供了一个 artisan 命令 make-filter,它接受要生成的过滤器的名称,可以快速生成一个过滤器类

php artisan osmose:make-filter CharacterFilter

将在 App\Http\Filters 命名空间中创建一个 CharacterFilter.php 文件。

注意:如果不存在,则会自动创建 Filters 文件夹。

过滤器类扩展了 Agog\Osmose\Library\OsmoseFilter 模板,并实现了 Agog\Osmose\Library\Services\Contracts\OsmoseFilterInterface 接口。

它必须定义一个 residue 方法,该方法返回一个定义过滤规则的数组

<?php

namespace App\Http\Filters;

use Agog\Osmose\Library\OsmoseFilter;
use Agog\Osmose\Library\Services\Contracts\OsmoseFilterInterface;

class CharacterFilter extends OsmoseFilter implements OsmoseFilterInterface
{
    /**
     * defines the form elements that are to be sieved
     * @return array
     */
    public function residue() : array
    {
        return [
            //
        ];
    }
}

用法

为了使用 osmose 过滤器,您在 residue 方法的数组中定义规则

规则定义为由键 => 值对组成,其中键表示作为请求传递的参数,值表示规则构造。

规则根据预期的过滤驱动类型定义。Osmose 提供了三个内部过滤驱动

1. Agog\Osmose\Library\Drivers\DirectFilter
2. Agog\Osmose\Library\Drivers\CallbackFilter
3. Agog\Osmose\Library\Drivers\RelationshipFilter

在我们的业务逻辑中,我们在过滤器对象上调用 Osmose 的 sieve 方法,并传递我们打算过滤的 Eloquent 类。sieve 方法将返回 Eloquent 的构建器。

CharacterController.php

public function index (CharacterFilter $filter)
{
    $characters = $filter->sieve(Character::class)->get();
}

考虑以下表及其相关的 Eloquent 模型

Character.php

Role.php

CharacterRole.php

DirectFilter

要使用 DirectFilter 驱动程序,我们定义规则,以单词 'column' 为前缀

public function residue () : array
{
    return [
        'character_id' => 'column:id'
    ]
}

Osmose 将然后在请求对象中查找 'character_id' 键,并且只返回与传递的值匹配的 id 的结果

/characters?character_id=1 将返回 id 为 '1' 的角色记录

RelationshipFilter

要使用 RelationshipFilter 驱动程序,我们定义规则,以单词 'relationship' 为前缀,给出关系的名称和应在相关表中检查的列

public function residue () : array
{
    return [
        'role' => 'relationship:roles,name'
    ]
}

注意:假设在 Character 模型中存在 roles (belongsToMany) 关系。

Osmose 将然后在请求对象中查找 'role' 键,并且只返回基于规则定义的结果

/characters?role=god 将返回所有角色为 'god' 的角色

CallbackFilter

要使用 CallbackFilter 驱动程序,我们传递一个回调函数,该函数接受查询构建器和请求值作为参数。回调必须返回构建器的结果

public function residue () : array
{
    return [
        'gender' => function ($query, $value) {

            return $query->where('gender', $value);

        }
    ]
}

Osmose 将然后在请求对象中查找 'gender' 键,并且只返回基于回调的结果

/characters?gender=male 将返回所有男性角色

过滤日期

从 2.0.0 版本开始,osmose 引入了三个新方法来协助日期过滤。这些方法是;

public function column () : string
{
    return 'created_at';
}

public function range ()
{
    return 'range';
}

public function limits () : array
{
    return [
        'from'  => 'from',
        'to'    => 'to'
    ];
}

column() 方法

column() 方法返回一个字符串,指示执行过滤器类的 sieve 方法后要过滤的列。默认为 created_at 列。只需在您的过滤器类中覆盖该方法,返回您所需的列。

range() 方法

要使用此功能,您必须通过运行以下命令发布 osmose 的配置文件;

此方法替代了在旧版本中可用的 range 属性。它具有类似的 API,返回要检查的查询参数,给定 osmose 配置文件中的预定义范围。覆盖此方法以返回适当的范围字符串。

如果定义的范围在 GET 参数中不存在,则 osmose 不会执行范围功能。

limits() 方法

limits 方法通过允许配置请求选项来细化 osmose 中的日期筛选。此方法返回一个包含两个键 fromto 的数组,这些键指示请求参数。

bound() 方法

osmose 2.0.0 版本引入了 bound() 方法。此方法与 residue 方法一样,返回一个规则定义的数组。在此方法中定义的规则 始终 执行,不依赖于 URL 中传递的查询参数。因此,这些规则不是作为键 => 值对定义的,而是简单地作为数组中的值。

注意:目前仅支持直接和回调过滤器。

在定义规则时必须显式传递 bound() 方法中的值。因此,CallbackFilter 驱动程序只接受一个参数,即查询构建器。

public function bound () : array
{
    return [
        'column:id,1,2,3,4', // will always return records with the IDs defined whenever the route is visited,
        function ($query) {
            return $query->orWhere('id', 5); // adds record where id=5
        }
    ];
}

您可以通过在创建 osmose 过滤器时传递 bound 选项来自动创建 bound 方法。

php artisan osmose:make-filter ExampleFilter --boundphp artisan osmose:make-filter ExampleFilter -b

全局 Osmose 函数

1.2.0 版本引入了一个全局函数 osmose(),可以自动检测过滤器中的模型类。

要使用此功能,您必须通过运行以下命令发布 osmose 的配置文件;

php artisan vendor:publish --provider="Agog\Osmose\Providers\OsmoseServiceProvider"

要自动检测模型,创建过滤器时应遵循 ${ModelName}Filter 的约定。例如,名为 CharacterFilter 的过滤器将自动查找并加载名为 Character 的模型。

默认情况下,osmose 在 App 命名空间中查找模型,但可以通过更改 osmose 配置文件中的 namespace keyfrom 进行配置。

osmose() 函数接收过滤器的完全限定类名和一个可选的模型名。

它返回 Eloquent 的构建器,就像 sieve() 方法一样。

public function index ()
{
    $characters = osmose(CharacterFilter::class)->get();
}

如果模型名与过滤器完全不同,或者如果模型不在单个命名空间下,例如在微服务架构中,则可以将模型的完全限定名作为第二个参数传递给 osmose 函数。

public function index ()
{
    $characters = osmose(UserSieve::class, Character::class)->get();
}

功能请求

如果您有任何功能请求、安全漏洞或只是简单的点赞,请随时发送电子邮件至 franciskisiara@gmail.com

灵感

本项目受到 Laravel 请求验证的启发。名称 osmose 来自生物学术语渗透压,以及粒子如何能够通过 过滤 半透膜。 :)

Osmose 作者

Kisiara Francis