webfox/laravel-backed-enums

Supercharge your PHP8 backed enums with superpowers like localization support and fluent comparison methods.

v2.3.1 2024-03-15 01:13 UTC

README

Banner Image

Latest Version on Packagist Total Downloads

This package supercharges your PHP8 backed enums with superpowers like localization support and fluent comparison methods.

Installation

composer require webfox/laravel-backed-enums

Usage

Setup your enum

The enum you create must implement the BackedEnum interface and also use the IsBackedEnum trait. The interface is required for Laravel to cast your enum correctly and the trait is what gives your enum its superpowers.

use Webfox\LaravelBackedEnums\BackedEnum;
use Webfox\LaravelBackedEnums\IsBackedEnum;

enum VolumeUnitEnum: string implements BackedEnum
{
    use IsBackedEnum;

    case MILLIGRAMS = "milligrams";
    case GRAMS = "grams";
    case KILOGRAMS = "kilograms";
    case TONNE = "tonne";
}

Enum value labels (Localization)

Create enums.php lang file and create labels for your enum values.

// resources/lang/en/enums.php

return [
     VolumeUnitEnum::class => [
        VolumeUnitEnum::MILLIGRAMS->value => "mg",
        VolumeUnitEnum::GRAMS->value      => "g",
        VolumeUnitEnum::KILOGRAMS->value  => "kg",
        VolumeUnitEnum::TONNE->value      => "t"
     ]
];

You may then access these localized values using the ->label() or ::labelFor() methods.
Additionally rendering the enum in a blade template will render the label.

VolumeUnitEnum::MILLIGRAMS->label(); // "mg"
VolumeUnitEnum::labelFor(VolumeUnitEnum::TONNE); // "t"
// in blade
{{ VolumeUnitEnum::KILOGRAMS }} // "kg"

If you do not specify a label in the lang file these methods will return the value assigned to the enum inside the enum file. e.g MILLIGRAMS label will be MILLIGRAMS

Meta data

Adding metadata allows you to return additional values alongside the label and values.

Create a withMeta method on your enum to add metadata.

public function withMeta(): array
{
    return match ($this) {
        self::MILLIGRAMS                => [
            'background_color' => 'bg-green-100',
            'text_color'       => 'text-green-800',
        ],
        self::GRAMS                     => [
            'background_color' => 'bg-red-100',
            'text_color'       => 'text-red-800',
        ],
        self::KILOGRAMS, self::TONNE    => [
            'background_color' => 'bg-gray-100',
            'text_color'       => 'text-gray-800',
        ],
        default                         => [
            'background_color' => 'bg-blue-100',
            'text_color'       => 'text-blue-800',
        ],
    };
}

If you do not specify a withMeta method, meta will be an empty array.

Other methods

options

Returns an array of all enum values with their labels and metadata.

Usage

VolumeUnitEnum::options();

returns

[
    [
        'name'  => 'MILLIGRAMS'
        'value' => 'milligrams',
        'label' => 'mg',
        'meta'  => [
            'background_color' => 'bg-green-100',
            'text_color'       => 'text-green-800',
        ],
    ],
    [
        'name'  => 'GRAMS',
        'value' => 'grams',
        'label' => 'g',
        'meta'  => [
            'background_color' => 'bg-red-100',
            'text_color'       => 'text-red-800',
        ],
        ...
    ]
]

names

Returns an array of all enum values.

Usage

VolumeUnitEnum::names();

returns

[
    'MILLIGRAMS',
    'GRAMS',
    'KILOGRAMS',
    'TONNE',
]

values

Returns an array of all enum values.

Usage

VolumeUnitEnum::values();

returns

[
    'milligrams',
    'grams',
    'killograms',
    'tonne',
]

labels

Returns an array of all enum labels.

Usage

VolumeUnitEnum::labels();

returns

[
    'mg',
    'g',
    'kg',
    't',
]

map

Returns an array of all enum values mapping to their label.

Usage

VolumeUnitEnum::map();

returns

[
    'MILLIGRAMS' => 'mg',
    'GRAMS'      => 'g',
    'KILOGRAMS'  => 'kg',
    'TONNE'      => 't',
]

toArray

Returns an array of a single enum value with its label and metadata.

Usage

VolumeUnitEnum::MILLIGRAMS->toArray();

returns

[
    'name'  => 'MILLIGRAMS'
    'value' => 'milligrams',
    'label' => 'mg',
    'meta'  => [
        'color'      => 'bg-green-100',
        'text_color' => 'text-green-800',
    ],
]

toHtml

An alias of ::label(). Used to satisfy Laravel's Htmlable interface.

Usage

VolumeUnitEnum::MILLIGRAMS->toHtml();

returns

mg

toJson

Returns a json string represention of the toArray return value.

is/isA/isAn

Allows you to check if an enum is a given value. Returns a boolean.

Note isA, isAn are just aliases for is.

Usage

VolumeUnitEnum::MILLIGRAMS->is(VolumeUnitEnum::MILLIGRAMS); //true
VolumeUnitEnum::MILLIGRAMS->is('MILLIGRAMS');               //true
VolumeUnitEnum::MILLIGRAMS->is('invalid');                  //exception

isNot/isNotA/isNotAn

Allows you to check if an enum is not a given value. Returns a boolean.

Note isNotA and isNotAn are just aliases for isNot.

Usage

VolumeUnitEnum::MILLIGRAMS->isNot(VolumeUnitEnum::GRAMS); //true
VolumeUnitEnum::MILLIGRAMS->isNot('GRAMS');               //true
VolumeUnitEnum::MILLIGRAMS->isNot('invalid');             //exception

isAny

Allows you to check if an enum is contained in an array. Returns a boolean.

Usage

VolumeUnitEnum::MILLIGRAMS->isAny(['GRAMS', VolumeUnitEnum::TONNE]);                    // false
VolumeUnitEnum::MILLIGRAMS->isAny([VolumeUnitEnum::GRAMS, VolumeUnitEnum::MILLIGRAMS]); // true

isNotAny

Allows you to check if an enum is not contained in an array. Returns a boolean.

Usage

VolumeUnitEnum::MILLIGRAMS->isNotAny(['GRAMS', VolumeUnitEnum::TONNE]);                    // true
VolumeUnitEnum::MILLIGRAMS->isNotAny([VolumeUnitEnum::GRAMS, VolumeUnitEnum::MILLIGRAMS]); // false

rule

The backed enums may be validated using Laravel's standard Enum validation rule - new Illuminate\Validation\Rules\Enum(VolumeUnitEnum::class).
This method a shortcut for the validation rule.

Usage

public function rules(): array
{
    return [
        'volume_unit' => [VolumeUnitEnum::rule()],
    ];
}

Other Classes

AsFullEnumCollection

This cast is similar to the Laravel built in AsEnumCollection cast but unlike the built-in will maintain the full toArray structure when converting to json.

E.g. the Laravel built in AsEnumCollection cast will return the following json:

["MILLIGRAMS", "GRAMS"]

This cast will return

[
  {
    "name": "MILLIGRAMS",
    "value": "MILLIGRAMS",
    "label": "mg",
    "meta": {
      "background_color": "bg-green-100",
      "text_color": "text-green-800"
    }
  },
  {
    "name": "GRAMS",
    "value": "GRAMS",
    "label": "g",
    "meta": {
      "background_color": "bg-red-100",
      "text_color": "text-red-800"
    }
  }
]

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

We welcome all contributors to the project.

License

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