Package Data | |
---|---|
Maintainer Username: | BenSampo |
Package Create Date: | 2017-09-07 |
Package Last Update: | 2024-08-21 |
Home Page: | https://sampo.co.uk/blog/using-enums-in-laravel |
Language: | PHP |
License: | MIT |
Last Refreshed: | 2024-11-15 15:03:10 |
Package Statistics | |
---|---|
Total Downloads: | 11,254,446 |
Monthly Downloads: | 243,202 |
Daily Downloads: | 12,452 |
Total Stars: | 2,000 |
Total Watchers: | 14 |
Total Forks: | 164 |
Total Open Issues: | 4 |
Simple, extensible and powerful enumeration implementation for Laravel.
Created by Ben Sampson
I wrote a blog post about using laravel-enum: https://sampo.co.uk/blog/using-enums-in-laravel
Laravel 5.4 or newer
PHP 7.1 or newer
Via Composer
$ composer require bensampo/laravel-enum
If you're using Laravel < 5.5 you'll need to add the service provider to config/app.php
'BenSampo\Enum\EnumServiceProvider'
Browse and download from a list of commonly used, community contributed enums.
php artisan make:enum UserType
Given the following enum:
<?php
namespace App\Enums;
use BenSampo\Enum\Enum;
final class UserType extends Enum
{
const Administrator = 0;
const Moderator = 1;
const Subscriber = 2;
const SuperAdministrator = 3;
}
Values can now be accessed like so:
UserType::Moderator // Returns 1
Returns an array of the keys for an enum.
UserType::getKeys(); // Returns ['Administrator', 'Moderator', 'Subscriber', 'SuperAdministrator']
Returns an array of the values for an enum.
UserType::getValues(); // Returns [0, 1, 2, 3]
Returns the key for the given enum value.
UserType::getKey(1); // Returns 'Moderator'
UserType::getKey(UserType::Moderator); // Returns 'Moderator'
Returns the value for the given enum key.
UserType::getValue('Moderator'); // Returns 1
Check if the enum contains a given key.
UserType::hasKey('Moderator'); // Returns 'True'
Check if the enum contains a given value.
UserType::hasValue(1); // Returns 'True'
// It's possible to disable the strict type checking:
UserType::hasValue('1'); // Returns 'False'
UserType::hasValue('1', false); // Returns 'True'
Returns the key in sentence case for the enum value. It's possible to override the getDescription method to return custom descriptions.
UserType::getDescription(3); // Returns 'Super administrator'
UserType::getDescription(UserType::SuperAdministrator); // Returns 'Super administrator'
Returns a random key from the enum. Useful for factories.
UserType::getRandomKey(); // Returns 'Administrator', 'Moderator', 'Subscriber' or 'SuperAdministrator'
Returns a random value from the enum. Useful for factories.
UserType::getRandomValue(); // Returns 0, 1, 2 or 3
Returns the enum key value pairs as an associative array.
UserType::toArray(); // Returns ['Administrator' => 0, 'Moderator' => 1, 'Subscriber' => 2, 'SuperAdministrator' => 3]
Returns the enum for use in a select as value => description.
UserType::toSelectArray(); // Returns [0 => 'Administrator', 1 => 'Moderator', 2 => 'Subscriber', 3 => 'Super administrator']
Returns an instance of the called enum. Read more about enum instantiation.
UserType::getInstance(UserType::Administrator);
It can be useful to instantiate enums in order to pass them between functions with the benefit of type hinting. Additionally, it's impossible to instantiate an enum with an invalid value, therefore you can be certain that the passed value is always valid.
For convenience, enums can be instantiated in multiple ways:
// Standard new PHP class, passing the desired enum value as a parameter
$enumInstance = new UserType(UserType::Administrator);
// Static getInstance method, again passing the desired enum value as a parameter
$enumInstance = UserType::getInstance(UserType::Administrator);
// Statically calling the key name as a method
$enumInstance = UserType::Administrator();
Once you have an enum instance, you can access the key
, value
and description
as properties. This is particularly useful if you're passing an enum instance to a blade view.
$userType = UserType::getInstance(UserType::SuperAdministrator);
$userType->key; // SuperAdministrator
$userType->value; // 0
$userType->description; // Super Administrator
You can check the equality of an instance against a valid enum value by passing it to the is
method.
$userType = UserType::getInstance(UserType::SuperAdministrator);
$userType->is(UserType::SuperAdministrator); // Returns true
$userType->is(UserType::Moderator); // Returns false
$userType->is(UserType::InvalidKey); // Throws InvalidEnumMemberException exception
One of the benefits of enum instances is that it enables you to use type hinting, as shown below.
function canPerformAction(UserType $userType)
{
if ($userType->is(UserType::SuperAdministrator)) {
return true;
}
return false;
}
$userType1 = UserType::getInstance(UserType::SuperAdministrator);
$userType2 = UserType::getInstance(UserType::Moderator);
canPerformAction($userType1); // Returns true
canPerformAction($userType2); // Returns false
You may validate that an enum value passed to a controller is a valid value for a given enum by using the EnumValue
rule.
public function store(Request $request)
{
$this->validate($request, [
'user_type' => ['required', new EnumValue(UserType::class)],
]);
}
By default, type checking is set to strict, but you can bypass this by passing false
to the optional second parameter of the EnumValue class.
new EnumValue(UserType::class, false) // Turn off strict type checking.
You can also validate on keys using the EnumKey
rule. This is useful if you're taking the enum key as a URL parameter for sorting or filtering for example.
public function store(Request $request)
{
$this->validate($request, [
'user_type' => ['required', new EnumKey(UserType::class)],
]);
}
Of course, both of these work on form request classes too.
Make sure to include BenSampo\Enum\Rules\EnumValue
and/or BenSampo\Enum\Rules\EnumKey
and your enum class in the usings.
You can also use the 'pipe' syntax for both the EnumKey and EnumValue rules by using enum_value
and/or enum_key
respectively.
enum_value:enum_class,[strict]
enum_key:enum_class
'user_type' => 'required|enum_value:' . UserType::class,
'user_type' => 'required|enum_key:' . UserType::class,
You can translate the strings returned by the getDescription
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.
// resources/lang/en/enums.php
<?php
use App\Enums\UserType;
return [
UserType::class => [
UserType::Administrator => 'Administrator',
UserType::SuperAdministrator => 'Super administrator',
],
];
// resources/lang/es/enums.php
<?php
use App\Enums\UserType;
return [
UserType::class => [
UserType::Administrator => 'Administrador',
UserType::SuperAdministrator => 'Súper administrador',
],
];
Now, you just need to make sure that your enum implements the LocalizedEnum
interface as demonstrated below:
use BenSampo\Enum\Enum;
use BenSampo\Enum\Contracts\LocalizedEnum;
final class UserType extends Enum implements LocalizedEnum
{
// ...
}
The getDescription
method will now look for the value in your localization files. If a value doesn't exist for a given key, the default description is returned instead.
If you'd like to return a custom value from the getDescription method, you may do so by overriding the method on your enum:
public static function getDescription($value): string
{
if ($value === self::SuperAdministrator) {
return 'Super admin';
}
return parent::getDescription($value);
}
Calling UserType::getDescription(3);
now returns Super admin
instead of Super administator
.
The Enum
base class implements the Laravel Macroable
trait, meaning it's easy to extend it with your own functions. If you have a function that you often add to each of your enums, you can use a macro.
Let's say we want to be able to get a flipped version of the enum toArray
method, we can do this using:
Enum::macro('toFlippedArray', function() {
return array_flip(self::toArray());
});
Now, on each of my enums, I can call it using UserType::toFlippedArray()
.
It's best to register the macro inside of a service providers' boot method.