datomatic/laravel-enum-collections

一个用于在Eloquent字段中保存枚举集合并与其交互的包

v2.0.2 2024-04-10 15:45 UTC

This package is auto-updated.

Last update: 2024-08-31 07:43:33 UTC


README

Enum Helper-DarkEnum Helper-Light

Laravel Enum Collections

Latest Version on Packagist Pest Tests number GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

一个Laravel 集合扩展,用于存储枚举,具有有用的Eloquent字段转换和辅助特质。
将您与枚举的交互提升到新水平。
PureEnumBackedEnum以及datomatic/laravel-enum-helper包兼容。

安装

您可以通过composer安装此包

composer require datomatic/laravel-enum-collections

包的主要部分包括

EnumCollection

EnumCollection是基础Laravel 集合的扩展,扩展其功能以添加对

  • 枚举对象实例
  • 枚举情况名称字符串
  • 枚举情况值(仅适用于BackedEnum
  • 枚举情况(字符串)值(仅适用于IntBackedEnum

创建EnumCollection

您可以通过以下4种方式创建枚举集合

use \Datomatic\EnumCollections\EnumCollection;

EnumCollection::of(Enum::class)->from($data);
EnumCollection::of(Enum::class)->tryFrom($data);
EnumCollection::from($data, Enum::class);
EnumCollection::tryFrom($data, Enum::class);

from方法如果$data中的元素错误,则抛出ValueError异常,而tryFrom则跳过错误数据而不引发异常。
$data可以是一个元素、一个collection、一个array...的元素集合。

如果$data只包含枚举元素,您也可以省略EnumClass(集合采用第一个元素的枚举类)。

EnumCollection::from(Enum::CASE1); // ✅ EnumCollection<Enum::CASE1>
EnumCollection::from('CASE1', Enum::class); // ✅ EnumCollection<Enum::CASE1>
EnumCollection::from(1, Enum::class); // ✅ EnumCollection<Enum::CASE1>
EnumCollection::from('1', Enum::class); // ✅ EnumCollection<Enum::CASE1>
EnumCollection::from([Enum::CASE1,Enum::CASE2]); // ✅ EnumCollection<Enum>
EnumCollection::from(collect([Enum::CASE1,Enum::CASE2])); // ✅ EnumCollection<Enum>

包含方法

use \Datomatic\EnumCollections\EnumCollection;

$enumCollection = EnumCollection::from([Enum::CASE1,Enum::CASE2]); // [1,2]

$enumCollection->contains(Enum::CASE1); // true
$enumCollection->contains(Enum::CASE3); // false
$enumCollection->doesntContain(Enum::CASE3); // true
$enumCollection->contains(1); // true
$enumCollection->contains('1'); // true
$enumCollection->contains('PRIVATE'); // true
$enumCollection->doesntContain('PRIVATE'); // false

toValues方法

toValues方法序列化集合内容,如果元素是PureEnum,则传递情况名称,否则传递值。

use \Datomatic\EnumCollections\EnumCollection;

EnumCollection::from([Enum::CASE1,Enum::CASE2,Enum::CASE2])->toValues(); // [1,2,2]
EnumCollection::from(['CASE1','CASE2','CASE2'],Enum::class)->toValues(); // [1,2,2]
EnumCollection::from([1,2,2],Enum::class)->toValues(); // [1,2,2]
EnumCollection::from(['1','2','2'],Enum::class)->toValues(); // [1,2,2]

转换

您可以将字段转换为EnumCollection。要使用此转换选项,您需要正确设置Eloquent模型。

1. 数据库迁移

Schema::table('table', function (Blueprint $table) {
    $table->json('field_name')->nullable()->after('some_field');
});

2. 模型设置

要设置您的模型,您必须

  • 添加自定义转换AsLaravelEnumCollection::class,并将枚举类作为属性
  • 添加可选的HasEnumCollections特质以在枚举集合字段上查询

如果需要,您也可以转换多个字段。

use Datomatic\EnumCollections\Casts\AsLaravelEnumCollection;
use Datomatic\EnumCollections\EnumCollection;
use Illuminate\Database\Eloquent\Model;

class TestModel extends Model
{
    use HasEnumCollections;
    
    //Laravel 9/10
    protected $casts = [
        'field_name' => AsLaravelEnumCollection::class.':'.FieldEnum::class,
    ];
    
    //Laravel 11
    protected function casts(): array
    {
        return [
            'field_name' => AsLaravelEnumCollection::of(FieldEnum::class),
        ];
    }
}

设置枚举集合字段

您可以通过传递单个元素、一个集合或一个元素数组来设置枚举集合字段。字段将变为EnumCollection

enum FieldEnum: int
{
    case PRIVATE = 1;
    case PUBLIC = 2;
    case PROTECTED = 3;
}

$model = new TestModel();
$model->field_name = FieldEnum::PRIVATE; // ✅ EnumCollection<FieldEnum::PRIVATE>
$model->field_name = 'PRIVATE'; // ✅ EnumCollection<FieldEnum::PRIVATE>
$model->field_name = 1; // ✅ EnumCollection<FieldEnum::PRIVATE>
$model->field_name = '1'; // ✅ EnumCollection<FieldEnum::PRIVATE>
$model->field_name = [FieldEnum::PRIVATE,FieldEnum::PUBLIC]; // ✅ EnumCollection<FieldEnum>
$model->field_name = collect([FieldEnum::PRIVATE,FieldEnum::PUBLIC]); // ✅ EnumCollection<FieldEnum>

数据库保存数据

枚举集合序列化存储在数据库中,如果元素是PureEnum,则保存情况名称,否则保存值。

EnumCollection

通过转换,您可以像正常使用之前显示的所有功能一样与field_name交互。

$model = new TestModel();
$model->field_name = [FieldEnum::PRIVATE,FieldEnum::PUBLIC];

$model->field_name->contains(FieldEnum::PRIVATE); // true
$model->field_name->contains(FieldEnum::PROTECTED); // false
$model->field_name->contains(1); // true
$model->field_name->contains('1'); // true
$model->field_name->contains('PRIVATE'); // true
$model->field_name->doesntContain('PRIVATE'); // false
$model->field_name->doesntContain(FieldEnum::PROTECTED); // true

HasEnumCollections特质

如果将HasEnumCollections也包含到模型中,您可以使用新的where函数查询模型,如whereContainsorWhereContainswhereDoesntContainorWhereDoesntContain

TestModel::whereContains('field_name', FieldEnum::PRIVATE)->get()
TestModel::whereDoesntContain('field_name', FieldEnum::PRIVATE)->get()

TestModel::whereContains('field_name', 1)
    ->whereContains('field_name', FieldEnum::PUBLIC)
    ->get()
    
TestModel::whereContains('field_name', [FieldEnum::PRIVATE,FieldEnum::PUBLIC])
    ->get()
TestModel::whereContains('field_name', collect([FieldEnum::PRIVATE,FieldEnum::PUBLIC]))
    ->get()
 TestModel::whereContains('field_name', EnumCollection::make([FieldEnum::PRIVATE,FieldEnum::PUBLIC]))
    ->get()
    
TestModel::whereContains('field_name', [1,2])
    ->get()

TestModel::whereContains('field_name', FieldEnum::PRIVATE)
    ->orWhereContains('field_name', FieldEnum::PUBLIC)
    ->get()

测试

composer test

变更日志

请参阅CHANGELOG以获取有关最近更改的更多信息。

贡献

请参阅CONTRIBUTING以获取详细信息。

安全漏洞

请查阅我们关于如何报告安全漏洞的安全策略:安全策略

致谢

许可证

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