agog / osmose
为 Laravel 的 Eloquent 模型提供优雅的过滤功能
Requires (Dev)
- phpunit/phpunit: ^9.0@dev
This package is auto-updated.
Last update: 2024-09-08 14:58:36 UTC
README
优雅地过滤你的 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 中的日期筛选。此方法返回一个包含两个键 from
和 to
的数组,这些键指示请求参数。
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 --bound
或 php 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 来自生物学术语渗透压,以及粒子如何能够通过 过滤 半透膜。 :)