Spatie Enum

repository·main·Indexed 21 days ago

https://github.com/spatie/enum

A PHP package providing strongly typed enums as objects to improve static analysis, IDE autocompletion, and refactoring. It allows for custom underlying values and human-readable labels, provides an equals() method for comparison, and includes integration tools such as EnumAssertions for PHPUnit and a FakerEnumProvider for generating random enum data.

Tokens
4.2K
Snippets
21
Records
24
Agent score
73%

What's inside spatie/enum

  1. Features of the spatie/laravel-enum wrapper

    main

    The Laravel wrapper package provides several specialized features for seamless integration with the Laravel framework:

    • Model Attribute casting: Automatically cast database columns to Enum instances.
    • Request Validation Rule: Use Enums directly within Laravel validation rules.
    • Request Data Transformation: Automatically transform incoming request data into Enum instances.
    • Artisan Make Command: Generate new Enum classes via the CLI.
    • Faker Provider: Integrate Enums with Faker for testing.
  2. Best practices for using enums

    main

    The core philosophy of this package is to treat enums as objects rather than primitive values.

    • Do not use the raw enum value directly in your application logic.
    • Always use the enum object itself.
    • The only recommended use case for converting a value into an enum is during unserialization (e.g., converting a stored database string into an enum object).
  3. Define an Enum

    main

    To create an enum, extend the Spatie\Enum\Enum class. You must use PHPDoc @method static self annotations for each enum case to enable IDE autocompletion and static analysis. Each method name represents an enum case.

    use \Spatie\Enum\Enum;
    
    /**
     * @method static self draft()
     * @method static self published()
     * @method static self archived()
     */
    class StatusEnum extends Enum
    {
    }
  4. Compare enums using the equals() method

    main

    You can compare an enum instance against another enum instance using the equals() method. This method returns true if the current enum matches the provided value(s).

    Single comparison

    To check if an enum matches a specific value:

    $status->equals(StatusEnum::draft());

    Multiple comparisons

    The equals() method accepts multiple arguments. It will return true if the current enum matches any of the provided enum values:

    $status->equals(StatusEnum::draft(), StatusEnum::archived());

    Important Restriction

    Only enum objects are allowed as arguments to the equals() method. You cannot compare an enum object directly to a serialized value (like a string or integer).

    $status->equals(StatusEnum::draft());
    
    // Or with multiple values
    $status->equals(StatusEnum::draft(), StatusEnum::archived());
  5. Create strongly typed enums with Spatie Enum

    main

    To create an enum, define a class that extends Spatie\Enum\Enum. Use PHPDoc @method static self annotations for each enum case to enable IDE autocompletion and proper type hinting. This approach ensures you work with enum objects rather than simple scalar values, facilitating safer refactoring and better developer experience.

    use \Spatie\Enum\Enum;
    
    /**
     * @method static self draft()
     * @method static self published()
     * @method static self archived()
     */
    class StatusEnum extends Enum
    {
    }
  6. Use a Closure to dynamically generate enum labels

    main

    Instead of a static array, you can override the labels() method to return a Closure. This allows you to derive labels dynamically from the enum's method name. The closure receives the method name as a string argument.

    /**
     * @method static self issue()
     * @method static self pullRequest()
     */
    class EventEnum extends Enum
    {
        protected static function labels(): Closure
        {
            return fn (string $name) => str_replace('_', ' ', snake_case($name));
        }
    }
  7. Override enum labels for user-friendly display

    main

    By default, an enum's label is its value. You can provide custom, user-friendly labels (e.g., for dropdown menus) by overriding the protected static function labels(): array method in your Enum class. You only need to define labels for the specific values you wish to customize; others will fall back to their default values.

    /**
     * @method static self draft()
     * @method static self published()
     * @method static self archived()
     */
    class StatusEnum extends Enum
    {
        protected static function labels(): array
        {
            return [
                'draft' => 'my draft label',
            ];
        }
    }
    
    // Accessing the label:
    $status->label;
  8. Derive enum values from method names using a Closure

    main

    If you want to transform the method name into a specific format (e.g., converting camelCase method names to snake_case values), you can return a Closure from the values() method. The closure receives the method name as a string and should return the desired value.

    /**
     * @method static self issue()
     * @method static self pullRequest()
     */
    class EventEnum extends Enum
    {
        protected static function values(): Closure
        {
            return fn (string $name) => snake_case($name);
        }
    }
  9. Create an enum instance from a value

    main

    To instantiate an enum object from a serialized value (for example, when retrieving a value from a database), pass the value to the constructor of your Enum class.

    Warning: If the provided value does not correspond to an existing enum value, an error will be thrown.

    $status = new StatusEnum('draft');
  10. Override enum values with static values

    main

    By default, an enum's value is its method name. To use different values (such as integers for database storage), override the values() method in your Enum class and return an associative array where the keys are the method names and the values are the desired enum values.

    Note that enum values do not have to be strings.

    /**
     * @method static self draft()
     * @method static self published()
     * @method static self archived()
     */
    class StatusEnum extends Enum
    {
        protected static function values(): array
        {
            return [
                'draft' => 1,
                'published' => 2,
                'archived' => 3,
            ];
        }
    }