Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Enum Laravel Package

cerbero/laravel-enum

Cerbero Laravel Enum adds type-safe enum classes to Laravel, with validation rules, model casting, and helper methods for labels and values. A clean way to replace scattered constants with organized, reusable enum objects.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install with Composer:

    composer require cerbero/laravel-enum
    

    There is nothing to publish and no service provider to register — it's a trait-only package. Check composer.json for the PHP/Laravel constraint of the version you install; enums require PHP 8.1+, so older projects will need to upgrade first.

  2. Where to look first:

    • README.md — canonical, versioned list of what the trait exposes.
    • src/Concerns/LaravelEnum.php — the trait you add to your enums.
    • src/Concerns/Metable.php — metadata helpers for labels/colors/icons.
    • tests/ — executable examples of every helper. When in doubt, the tests are more reliable than blog posts.
  3. First use case — a <select> in five minutes:

    use Cerbero\LaravelEnum\Concerns\LaravelEnum;
    
    enum Status: string
    {
        use LaravelEnum;
    
        case Draft     = 'draft';
        case Published = 'published';
        case Archived  = 'archived';
    }
    
    Status::names();   // ['Draft', 'Published', 'Archived']
    Status::values();  // ['draft', 'published', 'archived']
    Status::options(); // name => value map, designed for form select generation
    
    <select name="status">
        @foreach (Status::options() as $name => $value)
            <option value="{{ $value }}">{{ $name }}</option>
        @endforeach
    </select>
    

    Verify the direction of options() in the README for your version — it is built for <select> generation but the map direction has been flipped in some helper packages. If your template expects value => label, wrap it in array_flip().

Implementation Patterns

Validation and form requests

  • Use Laravel's native Rule::enum(Status::class) for value validation. The package does not replace it.
  • When your API accepts the case name ("Published") rather than the value, normalize in prepareForValidation():
    protected function prepareForValidation(): void
    {
        $this->merge([
            'status' => Status::fromName($this->input('status'))->value,
        ]);
    }
    
  • For multi-select or "allowed values" rules, generate a list from Status::values() or Status::names() and feed it into Rule::in(...).

Eloquent integration

  • Keep declaring the native enum cast: protected $casts = ['status' => Status::class];. The trait doesn't replace it — it only adds helpers around the enum.
  • Query scopes can pass the enum directly (where('status', Status::Published) works on backed enums), or use ->value if you want explicit scalars.
  • In inbound filters, cast defensively: Status::tryFrom($request->input('status')) for values, tryFromName() for names. Never call the throwing variants on user input.

Guard clauses and comparison helpers

Replace growing === chains with collection-style comparisons:

if ($post->status->is(Status::Draft, Status::Archived)) { /* ... */ }
if ($post->status->in([Status::Draft, Status::Archived])) { /* ... */ }
if (! $post->status->isNot(Status::Published)) { /* ... */ }

Keep a plain === when there are only two cases — the helpers earn their keep as lists grow.

API resources and JSON

  • Backed enums serialize to their scalar value automatically; don't rely on toArray() shape inside a resource or you'll get a map {Name: value} instead of the scalar.
  • If the frontend needs both the value and a label, return them explicitly from the resource:
    return [
        'status' => $this->status->value,
        'status_label' => $this->status->name,
    ];
    
  • Use Status::options() for lookup endpoints / config dumps instead of building them ad hoc.

Metadata for UI concerns

Metable keeps presentation data (colors, icons, badge classes) out of the enum's core semantics:

public function meta(): array
{
    return match ($this) {
        self::Draft     => ['color' => 'gray',  'icon' => 'pencil'],
        self::Published => ['color' => 'green', 'icon' => 'check'],
        self::Archived  => ['color' => 'slate', 'icon' => 'archive'],
    };
}

Then resolve metadata in your Blade component or API transformer. This is the right place for UI-only attributes — not business logic.

Extending the enum itself

Add your own static convenience methods (default(), fromRequest(), forAdminPanel()). If you need to override a trait helper, alias it:

use LaravelEnum { options as frameworkOptions; }

public static function options(): array
{
    return self::frameworkOptions();
}

Testing

$this->assertSame(Status::Published, Status::fromName('Published'));
$this->assertNull(Status::tryFromName('Nope'));
$this->assertTrue(Status::Published->is(Status::Published, Status::Draft));

Gotchas and Tips

  • Backed vs. pure enums. Anything value-based (values(), from(), tryFrom(), option maps) only makes sense on backed enums. Pure enums still get name-based helpers, but don't expect scalars.
  • fromName() throws; tryFromName() returns null. Always use the try* variant on request input and validate the null case.
  • Names are case-sensitive. fromName('published') will not match case Published. Normalize input (ucfirst, Str::studly) before calling, or add a small wrapper.
  • Trait method collisions are fatal. Defining values(), options(), or is() yourself causes a compile-time error. Alias the trait method and call through the alias.
  • Enums cannot hold instance properties. Metadata must live in a method or static array; it isn't per-case state you can mutate freely. Treat returned arrays as read-only.
  • Queue and cache payloads. Enums serialize with the case name, so renaming a case breaks already-queued jobs. Store the scalar ->value in job payloads and rehydrate with tryFrom() on consume. Same rule applies to cache entries and signed URLs.
  • $casts is still your job. The trait does not register casts automatically. Hydration is native Eloquent behavior; the package only adds convenience methods.
  • Don't inject services into enums. Enums aren't resolved by the container. Keep dependencies (translators, repositories) in services and pass the enum across the boundary.
  • Version drift. The method surface has grown across minor releases (metadata, matching helpers, comparisons). Pin a version, read the changelog before upgrading, and confirm helper names against src/Concerns/ rather than assuming. If IDE autocompletion feels incomplete on a large enum, add @method docblocks — the trait methods are real, but static analysis sometimes needs help.
  • Debugging "method doesn't exist." Run composer show cerbero/laravel-enum to confirm the installed version, then cross-reference src/Concerns/LaravelEnum.php. A quick Status::cases() sanity check tells you whether the problem is the package or the enum definition itself.
  • Static metadata caches persist in long-running processes. If you memoize metadata (or the package does internally), mutations leak between Pest/PHPUnit tests in the same process. Reset in tearDown if a test asserts on metadata, and clear on Octane workers when underlying data changes.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console