Enhancing Enum Constants in Laravel with Description and Label Attributes

realrashid

Rashid Ali

Posted on June 19, 2024

Enhancing Enum Constants in Laravel with Description and Label Attributes

PHP attributes provide a powerful way to add metadata to classes and constants, enhancing readability and organization in frameworks like Laravel. Let's explore how to use Description and Label attributes to annotate enum constants in Laravel, specifically with an OrderStatus example.

Understanding PHP Attributes in Enums

PHP attributes allow us to attach metadata to classes, methods, properties, and constants. In Laravel, this feature can streamline the management of descriptive metadata for enum constants such as status codes or types.

Implementing Description and Label Attributes

Step 1: Define Attribute Classes

Create attribute classes that extend a base AttributeProperty class to encapsulate metadata values:

<?php

namespace App\Attributes;

use Attribute;

/* Base class for attribute properties */
#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
class AttributeProperty
{
    public const ATTRIBUTE_PATH = 'App\Attributes\\';

    public function __construct(
        protected mixed $value,
    ) {
    }

    public function get(): mixed
    {
        return $this->value;
    }
}

/* Attribute for describing enum constants */
#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
class Description extends AttributeProperty
{
}

/* Attribute for labeling enum constants */
#[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
class Label extends AttributeProperty
{
}

<?php

namespace App\Traits;

use App\Attributes\AttributeProperty;
use BadMethodCallException;
use Illuminate\Support\Str;
use ReflectionAttribute;
use ReflectionEnum;

trait AttributableEnum
{
    /**
     * Call the given method on the enum case
     *
     */
    public function __call(string $method, array $arguments): mixed
    {
        // Get attributes of the enum case with reflection API
        $reflection = new ReflectionEnum(static::class);
        $attributes = $reflection->getCase($this->name)->getAttributes();

        // Check if attribute exists in our attributes list
        $filtered_attributes = array_filter($attributes, fn (ReflectionAttribute $attribute) => $attribute->getName() === AttributeProperty::ATTRIBUTE_PATH . Str::ucfirst($method));

        // If not, throw an exception
        if (empty($filtered_attributes)) {
            throw new BadMethodCallException(sprintf('Call to undefined method %s::%s()', static::class, $method));
        }

        return array_shift($filtered_attributes)->newInstance()->get();
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Create the Enum Using Attributes

Define an enum OrderStatus that uses Label and Description attributes to annotate its constants:

<?php

namespace App\Enums;

use App\Attributes\Label;
use App\Attributes\Description;
use App\Attributes\AttributeProperty;
use App\Traits\AttributableEnum;

enum OrderStatus: string
{
    use AttributableEnum;

    #[Label('Pending')]
    #[Description('Order is pending')]
    case Pending = 'pending';

    #[Label('Confirmed')]
    #[Description('Order is confirmed')]
    case Confirmed = 'confirmed';

    #[Label('Canceled')]
    #[Description('Order has been canceled')]
    case Canceled = 'canceled';

    #[Label('Completed')]
    #[Description('Order has been completed')]
    case Completed = 'completed';
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Accessing Enum Attributes

With the defined Description and Label attributes, you can access their values through methods defined in AttributeProperty or directly within your Laravel application's logic. For example, to retrieve the description of an enum constant:

<?php

$statusDescription = OrderStatus::Pending()->getDescription();
// Output: 'Order is pending'
Enter fullscreen mode Exit fullscreen mode

Conclusion

Using PHP attributes such as Label and Description with enums in Laravel enables you to centralize and manage descriptive metadata for enum constants effectively. This approach improves code clarity, simplifies maintenance, and enhances the readability of your Laravel applications.

By leveraging attributes in enums, you can streamline how you define and use status codes, types, or any other constant values that require additional descriptive information.

Start using PHP attributes in enums today to enhance your Laravel projects and maintain a clean, organized codebase!

💖 💪 🙅 🚩
realrashid
Rashid Ali

Posted on June 19, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related