biiiiiigmonster / laravel-enum
laravel enum helper base php version 8.1
Requires
- laminas/laminas-code: ^4.10
- laravel/framework: >=10
Requires (Dev)
- laravel/pint: ^1.0
- nunomaduro/larastan: ^2.0.1
- orchestra/testbench: ^8.0
- pestphp/pest: ^2.0
- pestphp/pest-plugin-laravel: ^2.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
This package is auto-updated.
Last update: 2025-01-10 00:01:23 UTC
README
Enum helper for laravel10 based on the enum feature of php 8.1.
Installation
You can install the package via composer:
composer require biiiiiigmonster/laravel-enum
Usage
To get started, enums typically live in the app\Enums
directory. You may use the make:enum
Artisan command to generate a new enum:
php artisan make:enum TaskStatus
if you want to generate a backed enum, you may use the make:enum
Artisan command with --type
options:
php artisan make:enum TaskStatus --type=int
and also you can apply the trait on your exists enum:
use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; // pure enum. enum Role { use EnumTraits; case ADMINISTRATOR; case SUBSCRIBER; case GUEST; } // backed enum. enum TaskStatus: int { use EnumTraits; case INCOMPLETE = 0; case COMPLETED = 1; case CANCELED = 2; }
Invokable
This helper lets you get the primitive value of a backed enum, or the name of a pure enum, by "invoking" it — either statically (MyEnum::FOO()
instead of MyEnum::FOO
), or as an instance ($enum()
).
That way, you can use enums as array keys:
'statuses' => [ TaskStatus::INCOMPLETE() => ['some configuration'], TaskStatus::COMPLETED() => ['other configuration'], ],
Or access the underlying primitives for any other use cases:
public function updateStatus(int $status): void; $task->updateStatus(TaskStatus::COMPLETED());
The main point: this is all without having to append ->value
to everything:
TaskStatus::CANCELED; // => TaskStatus instance TaskStatus::CANCELED(); // => 2
Use static calls to get the primitive value
TaskStatus::INCOMPLETE(); // 0 TaskStatus::COMPLETED(); // 1 TaskStatus::CANCELED(); // 2 Role::ADMINISTRATOR(); // 'ADMINISTRATOR' Role::SUBSCRIBER(); // 'SUBSCRIBER' Role::GUEST(); // 'GUEST'
Invoke instances to get the primitive value
public function updateStatus(TaskStatus $status, Role $role) { $this->record->setStatus($status(), $role()); }
Enhancement
Helper provide many static methods for you to enhance experience with enums.
Names
This helper returns a list of case names in the enum.
TaskStatus::names(); // ['INCOMPLETE', 'COMPLETED', 'CANCELED'] Role::names(); // ['ADMINISTRATOR', 'SUBSCRIBER', 'GUEST']
Values
This helper returns a list of case values for backed enums, or a list of case names for pure enums (making this functionally equivalent to ::names()
for pure Enums)
TaskStatus::values(); // [0, 1, 2] Role::values(); // ['ADMINISTRATOR', 'SUBSCRIBER', 'GUEST']
Options
This helper returns an array, that key is each instance invoke ()
return, and value is instance ->label()
returns.
TaskStatus::options(); /* [ 0 => 'Incomplete', 1 => 'Completed', 2 => 'Canceled' ] */ Role::options(); /* [ 'ADMINISTRATOR' => 'Administrator', 'SUBSCRIBER' => 'Subscriber', 'GUEST' => 'Guest' ] */
Tables
This helper returns a list of case map array that each instance, if instance append attributes that extended Meta
, the map array including more.
TaskStatus::tables(); /* [ ['name' => 'INCOMPLETE', 'value' => 0], ['name' => 'COMPLETED', 'value' => 1], ['name' => 'CANCELED', 'value' => 2] ] */ Role::tables(); /* [ ['name' => 'ADMINISTRATOR'], ['name' => 'SUBSCRIBER'], ['name' => 'GUEST'] ] */
From
This helper adds from()
and tryFrom()
to pure enums, and adds fromName()
and tryFromName()
to all enums.
Important Notes:
BackedEnum
instances already implement their ownfrom()
andtryFrom()
methods, which will not be overridden by this trait. Attempting to override those methods in aBackedEnum
causes a fatal error.- Pure enums only have named cases and not values, so the
from()
andtryFrom()
methods are functionally equivalent tofromName()
andtryFromName()
Use the from()
method
Role::from('ADMINISTRATOR'); // Role::ADMINISTRATOR Role::from('NOBODY'); // Error: ValueError
Use the tryFrom()
method
Role::tryFrom('GUEST'); // Role::GUEST Role::tryFrom('NEVER'); // null
Use the fromName()
method
TaskStatus::fromName('INCOMPLETE'); // TaskStatus::INCOMPLETE TaskStatus::fromName('MISSING'); // Error: ValueError Role::fromName('SUBSCRIBER'); // Role::SUBSCRIBER Role::fromName('HACKER'); // Error: ValueError
Use the tryFromName()
method
TaskStatus::tryFromName('COMPLETED'); // TaskStatus::COMPLETED TaskStatus::tryFromName('NOTHING'); // null Role::tryFromName('GUEST'); // Role::GUEST Role::tryFromName('TESTER'); // null
Random
This helper returns an instance of case by random.
TaskStatus::random(); // TaskStatus::COMPLETED Role::random(); // Role::GUEST
Default Case
Sometimes you may need to specify default case for your enum, which is easy as below: simply append the #[DefaultCase]
attribute to the case:
use BiiiiiigMonster\LaravelEnum\Attributes\DefaultCase; use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; enum Role { use EnumTraits; #[DefaultCase] case ADMIN; case GUEST; }
Then use the ::default()
static method to get this case instance:
Role::default(); // Role::ADMIN Role::ADMIN->isDefault(); // true
Meta
This feature lets you add metadata to enum cases, it's used by way of attributes.
use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; use App\Enums\Metas\{Description, Color}; enum TaskStatus: int { use EnumTraits; #[Description('Incomplete Task')] #[Color('red')] case INCOMPLETE = 0; #[Description('Completed Task')] #[Color('green')] case COMPLETED = 1; #[Description('Canceled Task')] #[Color('gray')] case CANCELED = 2; }
Creating meta attributes
To generate a new meta attributes, you may use the make:enumMeta
Artisan command:
php artisan make:enumMeta Color
meta attribute needs to exist as an Attribute.
use BiiiiiigMonster\LaravelEnum\Concerns\Meta; use Attribute; #[Attribute] class Color extends Meta {} #[Attribute] class Description extends Meta {}
Inside the attribute, you can customize a few things. For instance, you may want to use a different method name than the one derived from the class name (Description
becomes description()
by default). To do that, define the alias
static property on the meta:
#[Attribute] class Description extends Meta { public static string $alias = 'note'; }
With the code above, the ->description()
of a case will be accessible as ->note()
.
Another thing you can customize is the passed value. For instance, to wrap a color name like text-{$color}-500
, you'd add the following transform()
method:
#[Attribute] class Color extends Meta { protected function transform(mixed $value): string { return "text-{$value}-500"; } }
And now the returned color will be correctly transformed:
TaskStatus::COMPLETED->color(); // 'text-green-500'
Access the metadata
By accessing the attribute method name, you can get the meta value:
TaskStatus::INCOMPLETE->description(); // 'Incomplete Task' TaskStatus::COMPLETED->color(); // 'green'
Also, ::tables()
static method can return all meta attribute maps on each instance.
$tables = TaskStatus::tables(); // $tables [ [ 'name' => 'INCOMPLETE', 'value' => 0, 'description' => 'Incomplete Task', 'color' => 'red' ], [ 'name' => 'COMPLETED', 'value' => 1, 'description' => 'Completed Task', 'color' => 'green' ], [ 'name' => 'CANCELED', 'value' => 2, 'description' => 'Canceled Task', 'color' => 'gray' ] ]
Use the fromMeta()
method
Similarly, you can also get the enum case instance through the meta instance.
$green = Color::make('green');// new Color('green'); $blue = Color::make('blue');// new Color('blue'); TaskStatus::fromMeta($green); // TaskStatus::COMPLETED TaskStatus::fromMeta($blue); // Error: ValueError
Use the tryFromMeta()
method
TaskStatus::tryFromMeta($green); // TaskStatus::COMPLETED TaskStatus::tryFromMeta($blue); // null
Validation
Usually, we need limit your application's incoming data to a specified enums, laravel provides the basic rule, but here we have perfected it.
Array Validation
You can use the 'array' syntax for rules.
Enum
Validate that a parameter is an instance of a given enum, it's similar to Enum Rules
and can support pure enums.
use BiiiiiigMonster\LaravelEnum\Rules\Enum; public function store(Request $request) { $this->validate($request, [ 'status' => ['required', new Enum(TaskStatus::class)], 'role' => ['required', new Enum(Role::class)], ]); }
EnumMeta
Additionally, validate that a parameter is an instance of the given meta in the given enum.
use BiiiiiigMonster\LaravelEnum\Rules\EnumMeta; public function store(Request $request) { $this->validate($request, [ 'color' => ['required', new EnumMeta(TaskStatus::class, Color::class)], ]); }
EnumMeta
rule takes two parameters, the first is given enum, the second is given meta, if parameter name is same of meta method name, you can omit it:
'color' => ['required', new EnumMeta(TaskStatus::class)],
Pipe Validation
You can also use the 'pipe' syntax for rules.
- enumerate: enum_class
- enum_meta: enum_class,[meta_attribute]
'status' => 'required|enumerate:' . TaskStatus::class, 'color' => 'required|enum_meta:' . TaskStatus::class . ',' . Color::class,
Validation messages
If needed, you can modify the error message when validated fails.
Run the following command to publish the language files to your lang
folder:
php artisan vendor:publish --provider="BiiiiiigMonster\LaravelEnum\EnumServiceProvider" --tag="translations"
Localization
Labels
The enum instances are descriptive, and we have added translation capabilities for this.
You can translate the strings returned by the enum instance's ->label()
method using Laravel's built-in localization features.
Add a new enums.php
keys file for each of your supported languages. In this example there is one for English and one for Spanish:
// lang/en/enums.php <?php declare(strict_types=1); use App\Enums\TaskStatus; return [ TaskStatus::class => [ TaskStatus::INCOMPLETE() => 'Incomplete', TaskStatus::COMPLETED() => 'Completed', TaskStatus::CANCELED() => 'Canceled', ], ];
// lang/es/enums.php <?php declare(strict_types=1); use App\Enums\TaskStatus; return [ TaskStatus::class => [ TaskStatus::INCOMPLETE() => 'Incompleto', TaskStatus::COMPLETED() => 'Completo', TaskStatus::CANCELED() => 'Cancelación', ], ];
Now, you just need to make sure that your enum implements the Localizable
interface as demonstrated below:
use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; use BiiiiiigMonster\LaravelEnum\Contracts\Localizable; enum TaskStatus: int implements Localizable { use EnumTraits; // ... }
Alternatively, when creating with the make:enum
Artisan command, add the --local
option:
php artisan make:enum TaskStatus --local
The ->label()
method will now look for the value in your localization files:
// en/enums.php TaskStatus::CANCELED->label();// 'Canceled' // es/enums.php TaskStatus::CANCELED->label();// 'Cancelación'
and the ::options()
static method returned array's value also be localized:
// en/enums.php TaskStatus::options();// [0 => 'Incomplete', 1 => 'Completed', 2 => 'Canceled'] // es/enums.php TaskStatus::options();// [0 => 'Incompleto', 1 => 'Completo', 2 => 'Cancelación']
Artisan Command
If you want your IDE to autocomplete the static instantiation helpers, you can generate PHPDoc annotations through an artisan command.
By default, all Enums in app/Enums
will be annotated (you can change the folder by passing a path to --folder
)
php artisan enum:phpdoc
Also, you can annotate a single class by specifying the class name
php artisan enum:phpdoc "App\Enums\TaskStatus"
use BiiiiiigMonster\LaravelEnum\Concerns\EnumTraits; use App\Enums\Metas\{Description, Color}; /** * @method static int INCOMPLETE() * @method static int COMPLETED() * @method static int CANCELED() * @method mixed description() * @method mixed color() */ enum TaskStatus: int { use EnumTraits; // ... }
Testing
composer test
Changelog
Please see CHANGELOG for more information on what has changed recently.
References
License
The MIT License (MIT). Please see License File for more information.