Working with Enums

Tips and handy utilities for working with enums in your Laravel project

Making your Enum invokable

When working with enums, its handy to reference them statically such as when authorizing access to a controller method using a role name.

Personally, I find it clumsy to have to access the Enum static method such as

$this->authorize(Role::MANAGER->name);

With a tiny function we can simplify this to

$this->authorize(Role::MANAGER());

This is because we can make the enum invokable using the magic __callStatic() method on the enum. This method is called when a static method is requested but does not exist. Using this we can return an instance of the Enum being used.

An example of an enum class for expenses, using this method;

App\Enums\Expenses.php
<?php

namespace App\Enums;

use Illuminate\Support\Arr;

enum Expenses
{
  case CREATE_EXPENSE;
  case DELETE_EXPENSE;
  case APPROVE_EXPENSE;

  public static function __callStatic($name, $args)
  {
    $case = Arr::first(static::cases(), fn($case) => $case->name === $name);

    throw_unless($case, sprintf('Undefined Enum Case %s::%s',static::class,$name));
    
    return empty($case->value) ? $case->name : $case->value;
  }
}

Now

Invokable Enum with Backed Enums

The method shown supports both plain Enums and Backed Enums

A Backed Enum returns a value (string or int) rather than the enum name

For instance, if we wanted to just work with ints in the database, our Enum might be declared as

Now;

The method returns the name or the value, depending on whether your enum is backed.

Make a Trait

Since the function is not dedicated to any specific enum, you can create a trait and include it in every enum class.

And then use in every enum

Enum methods

Enums are not like normal classes, but they do still allow public methods which may be called against a given Enum case.

For Instance;

Returning an icon component for a case

The match statement is very useful for this type of thing and allows an easy way to return different data for each case.

Returning a long block of text

And then use it in blade like

Or if you are already working with an instance of an enum

If you are having problems with using enum classes directly in your blade files, dont forget that you can import the class at the top of your blade file with @use('\App\Enums\Expenses')

Last updated

Was this helpful?