elao/enum
Opinionated extensions for PHP 8.1+ native enums with readable labels, flag/bitmask enums, and extra values. Includes integrations for Symfony (Forms, HTTP Kernel arg resolver, Translation, VarDumper), Doctrine ORM/ODM, and Faker.
Installation
composer require elao/enum
Ensure your project uses PHP 8.4+ and Symfony 6.4+ (if applicable).
First Use Case: Basic Enum Define an enum with traits for extended functionality:
use Elao\Enum\ReadableEnumInterface;
use Elao\Enum\ReadableEnumTrait;
#[ReadableEnum(prefix: 'user.role.')]
enum UserRole: string implements ReadableEnumInterface
{
use ReadableEnumTrait;
case ADMIN = 'admin';
case EDITOR = 'editor';
case USER = 'user';
}
#[ReadableEnum] attribute enables human-readable string representations (e.g., UserRole::ADMIN->getReadable() returns 'user.role.admin').Where to Look First
tests/ for real-world usage patterns.src/Symfony/ for form/validator integrations.EnumType for form fields:
use Elao\Enum\Bridge\Symfony\Form\EnumType;
$builder->add('role', EnumType::class, [
'enum' => UserRole::class,
'placeholder' => 'Select a role',
]);
ChoiceType for custom labels:
'choices' => UserRole::ADMIN->getReadable() => 'Administrator',
use Elao\Enum\Bridge\Symfony\Validator\Constraints\Enum;
#[Assert\All([
new Enum(UserRole::class),
])]
public array $roles;
Stringable enums (e.g., Suit: string) for database columns.public function getRoleAttribute(string $value): UserRole
{
return UserRole::from($value);
}
public function scopeWithRole(Builder $query, UserRole $role)
{
return $query->where('role', $role->value);
}
#[AsArray]
public function toArray(): array
{
return ['role' => $this->role->getReadable()];
}
#[JsonSerializable] for automatic conversion:
use Elao\Enum\JsonSerializableEnumInterface;
enum UserRole implements JsonSerializableEnumInterface { ... }
#[ReadableEnum(prefix: 'user.role.', translations: [
'en' => ['ADMIN' => 'Admin'],
'fr' => ['ADMIN' => 'Administrateur'],
])]
enum UserRole { ... }
$this->translator->trans($role->getReadable());
$this->assertEquals('user.role.admin', UserRole::ADMIN->getReadable());
$mockRole = $this->createMock(UserRole::class);
$mockRole->method('getReadable')->willReturn('mock.role');
Backward Compatibility
#[ReadableEnum] with #[Enum\ReadableEnum] if using namespaced attributes.Attribute Overrides
#[ReadableEnum].#[Attribute\Target('CLASS')] explicitly or merge attributes:
#[ReadableEnum(prefix: 'user.role.')]
#[SomeCustomAttribute]
enum UserRole { ... }
Database Migrations
string backings require TEXT/VARCHAR columns, not ENUM (MySQL).Stringable enums for consistency:
Schema::table('users', function (Blueprint $table) {
$table->string('role')->comment('UserRole enum value');
});
Caching Readable Values
getReadable() is cached per instance, but translations may not be.UserRole::ADMIN->getReadable('fr'); // Forces locale reload
Enum Not Found Errors
use statement or incorrect enum class reference.composer dump-autoload
Symfony Form Errors
EnumType fails with "Invalid enum value."Stringable or use value directly:
'enum' => UserRole::class,
'choice_value' => fn(UserRole $role) => $role->value,
Validation Failures
Enum constraint expects exact matches (case-sensitive).$this->assertThat(strtoupper($input), new Enum(UserRole::class));
Custom Traits
trait SortableEnum
{
public function getSortValue(): int { return $this->value === 'ADMIN' ? 3 : 1; }
}
enum UserRole implements SortableEnum { ... }
Dynamic Enums
#[ReadableEnum(dynamic: true)]
enum DynamicRole: string
{
use DynamicEnumTrait;
public static function cases(): array
{
return config('roles.available');
}
}
Event Dispatching
use Elao\Enum\Event\EnumEvent;
enum UserRole
{
public function __toString(): string
{
$event = new EnumEvent($this);
$this->dispatcher->dispatch($event);
return $this->getReadable();
}
}
API Platform
# config/packages/api_platform.yaml
api_platform.metadata.enums:
UserRole: { openapi_type: string, description: 'User roles' }
How can I help you explore Laravel packages today?