Laravel support for spatie/enum
This package provides extended support for our spatie/enum package in Laravel.
Support us
Learn how to create a package like this one, by watching our premium video course:
We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.
Installation
You can install the package via composer:
composer require spatie/laravel-enumUsage
Model Attribute casting
Chances are that if you're working in a Laravel project, you'll want to use enums within your models. This package provides a trait you can use in these models, to allow allow automatic casting between stored enum values and enum objects.
use Illuminate\Database\Eloquent\Model;
use Spatie\Enum\Laravel\HasEnums;
class TestModel extends Model
{
use HasEnums;
protected $enums = [
'status' => StatusEnum::class,
];
}You can also define enum as nullable:
protected $enums = [
'status' => StatusEnum::class.':nullable',
];You can also define attribute as array of enums:
protected $enums = [
'status' => StatusEnum::class.':array',
];By using the HasEnums trait, you'll be able to work with the status field like so:
$model = new TestModel();
$model->status = StatusEnum::DRAFT();You can set the value of an enum field with its textual value:
$model->status = 'published';This can be useful when filling data from a validated request:
$model->fill($request->validated());
// …
$model->status->isEqual(StatusEnum::ARCHIVED());In some cases, enums should be stored as integer (index) in the database.
By using the $casts property you can cast your status attribute to int or integer and the trait will store the index instead of the value.
Model Query Scopes
The HasEnums trait also provides some useful scopes to query your database.
These scopes will also take the optional mapping you provided into account.
Post::whereEnum('status', StatusEnum::DRAFT());
Post::whereNotEnum('status', 'published');
Post::whereEnum('status', StatusEnum::DRAFT())->orWhereEnum('status', StatusEnum::PUBLISHED());You may provide multiple enums as an array:
Post::whereEnum('status', [StatusEnum::DRAFT(), StatusEnum::ARCHIVED()]);
Post::whereNotEnum('status', [StatusEnum::PUBLISHED()]);You may also provide textual input:
Post::whereEnum('status', 'archived');
Post::whereEnum('status', 'legacy archived value');Validation Rules
This package provides some validation rule classes to validate your request data against a given enumerable.
use Spatie\Enum\Laravel\Rules\EnumRule;
$rules = [
'status' => new EnumRule(StatusEnum::class),
];This rule validates that the value of status is any possible representation of the StatusEnum.
If you want to check that the value is a possible name, value or index of StatusEnumyou can use the more specific rules.
use Spatie\Enum\Laravel\Rules\EnumIndexRule;
use Spatie\Enum\Laravel\Rules\EnumNameRule;
use Spatie\Enum\Laravel\Rules\EnumValueRule;
new EnumIndexRule(StatusEnum::class);
new EnumNameRule(StatusEnum::class);
new EnumValueRule(StatusEnum::class);But you can also use the simple string validation rule definition:
$rules = [
'status' => [
'enum:'.StatusEnum::class,
'enum_index:'.StatusEnum::class,
'enum_name:'.StatusEnum::class,
'enum_value:'.StatusEnum::class,
],
];If you want to customize the failed validation messages you can publish the translation file.
php artisan vendor:publish --provider="Spatie\Enum\Laravel\EnumServiceProvider" --tag="translation"We pass several replacements to the translation key which you can use.
attribute- the name of the validated attributevalue- the actual value that's validatedenum- the full class name of the wanted enumerableother- a comma separated list of all possible values - they are translated via theenumsarray in the translation file
Request Data Transformation
A common scenario is that you receive an enumerable value as part of yor request data. To let you work with it as a real enum object you can transform request data to an enum in a similar way to the model attribute casting.
Request macro
There is a request macro available which is the base for the other possible ways to cast request data to an enumerable.
$request->transformEnums($enumCastRules);This is an example definition of all possible request enum castings.
There are three predefined keys available as constants on Spatie\Enum\Laravel\Http\EnumRequest to cast enums only in specific request data sets.
All other keys will be treated as independent enum casts and are applied to the combined request data set.
$enums = [
// cast the status key independent of it's data set
'status' => StatusEnum::class,
// cast the status only in the request query params
EnumRequest::REQUEST_QUERY => [
'status' => StatusEnum::class,
],
// cast the status only in the request post data
EnumRequest::REQUEST_REQUEST => [
'status' => StatusEnum::class,
],
// cast the status only in the request route params
EnumRequest::REQUEST_ROUTE => [
'status' => StatusEnum::class,
],
];You can call this macro yourself in every part of your code with access to a request instance. Most commonly you will do this in your controller action if you don't want to use one of the other two ways.
Form Requests
Form requests are the easiest way to cast the data to an enum.
use Illuminate\Foundation\Http\FormRequest;
use Spatie\Enum\Laravel\Http\Requests\TransformsEnums;
class StatusFormRequest extends FormRequest
{
use TransformsEnums;
public function rules(): array
{
return [];
}
public function enums(): array
{
return [
'status' => StatusEnum::class,
];
}
}The request data transformation is done after validation via the FormRequest::passedValidation() method. If you define your own passedValidation() method you have to call the request macro transformEnums() yourself.
protected function passedValidation()
{
$this->transformEnums($this->enums());
// ...
}Middleware
You can also use the middleware to transform enums in a more general way and for requests without a form request.
use Spatie\Enum\Laravel\Http\Middleware\TransformEnums;
new TransformEnums([
'status' => StatusEnum::class,
]);Enum Make Command
We provide an artisan make command which allows you to quickly create new enumerables.
php artisan make:enum StatusEnumYou can use --method or --value options to predefine some enum names or values - you can use them several times.
The --formatter option is used to let you define the used conversion from value to method.
Testing
composer test
composer test-coverageChangelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security
If you discover any security related issues, please email freek@spatie.be instead of using the issue tracker.
Postcardware
You're free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.
Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.
We publish all received postcards on our company website.
Credits
License
The MIT License (MIT). Please see License File for more information.
