spatie/laravel-enum

Laravel enum support

1.4.0 2020-03-11 10:26 UTC

This package is auto-updated.

Last update: 2020-03-23 12:03:12 UTC


README

Latest Version on Packagist GitHub Workflow Status Quality Score Code Coverage StyleCI Total Downloads

This package provides extended support for our spatie/enum package in Laravel.

Installation

You can install the package via composer:

composer require spatie/laravel-enum

Usage

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',
];

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 attribute
  • value - the actual value that's validated
  • enum - the full class name of the wanted enumerable
  • other - a comma separated list of all possible values - they are translated via the enums array 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 StatusEnum

You 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-coverage

Changelog

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, Samberstraat 69D, 2060 Antwerp, Belgium.

We publish all received postcards on our company website.

Credits

Support us

Spatie is a webdesign agency based in Antwerp, Belgium. You'll find an overview of all our open source projects on our website.

Does your business depend on our contributions? Reach out and support us on Patreon. All pledges will be dedicated to allocating workforce on maintenance and new awesome stuff.

License

The MIT License (MIT). Please see License File for more information.