datomatic / laravel-enum-collections
A package to save a collection of Enums in a Eloquent field and interact with him
Installs: 1 152
Dependents: 0
Suggesters: 0
Security: 0
Stars: 6
Watchers: 1
Forks: 1
Open Issues: 0
Requires
- php: ^8.1
- illuminate/contracts: ^9.0|^10.0|^11.0
- spatie/laravel-package-tools: ^1.13.0
Requires (Dev)
- datomatic/laravel-enum-helper: ^1.0
- laravel/pint: ^1.0
- nunomaduro/collision: ^7.0
- nunomaduro/larastan: ^2.0.1
- orchestra/testbench: ^8.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-laravel: ^2.1
- phpstan/extension-installer: ^1.1
- phpstan/phpstan: ^1.10
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
- phpunit/phpunit: ^10.0
README
Laravel Enum Collections
A Laravel collection extension to store enums with a useful eloquent field cast and a helper trait.
Take your interaction with enums to the next level.
Compatible with PureEnum
, BackedEnum
and datomatic/laravel-enum-helper
package.
Installation
You can install the package via composer:
composer require datomatic/laravel-enum-collections
The main parts of the package are:
EnumCollection
EnumCollection
is an extension of base Laravel collection that expand his functionalities to add the compatibility with:
- enum object instance
- enum case name string
- enum case value (only for
BackedEnum
) - enum case (string) value (only for
IntBackedEnum
)
Creating an EnumCollection
You can make enum collection in 4 ways:
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
method throw an ValueError
Exception if an element in $data
is wrong, instead tryFrom
skips bad data without raise exceptions.
$data
can be a single element or a collection
, array
,... of elements.
If $data
contains only Enum elements you can also omit the EnumClass
(the collection take the EnumClass of the first element).
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>
Contains method
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 method
toValues
method serialize the collection content, if the element is a PureEnum
will be pass the name
of the case, otherwise the value
.
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]
Casting
You can cast a field to be an EnumCollection
.
To use this casting option, you need to set the Eloquent Model properly.
1. Database Migration
Schema::table('table', function (Blueprint $table) { $table->json('field_name')->nullable()->after('some_field'); });
2. Model set up
To set up your model you must:
- add a custom cast
AsLaravelEnumCollection::class
with the enumClass as attribute - add an optional
HasEnumCollections
trait to make query on enum collections fields
You can also cast more than one field if you need.
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), ]; } }
Set the enum collection field
You can set enum collection field passing a single element, a collection or an array of elements.
After the field will become an 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>
Database saved data
A serialization of enumCollection is saved in the database, if the element is a PureEnum
will be saved the name
of the case, otherwise the value
.
EnumCollection
Thanks to casting you can interact with field_name
like a normal EnumCollection
with all functionalities showed before.
$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 trait
If you include also the HasEnumCollections
into the model, you can query the models with the new where functions whereContains
, orWhereContains
, whereDoesntContain
and orWhereDoesntContain
.
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()
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Credits
License
The MIT License (MIT). Please see License File for more information.