Skip to content

Latest commit

 

History

History
71 lines (61 loc) · 2.82 KB

File metadata and controls

71 lines (61 loc) · 2.82 KB

Implementation Plan

Critical Path

  1. EnumUtilsTrait (core) → 2. EnumCollection → 3. Validation → 4. Laravel Integration → 5. Doctrine Integration

Tasks

1. Core: EnumUtilsTrait

The main trait for BackedEnum. All methods are static.

  • cases() — already provided by PHP
  • values(): array — return all backing values
  • labels(): array — return [value => label] map
  • toSelectArray(): array — alias for labels(), returns [value => label]
  • toRadioOptions(): array — returns array of {value, label, name} objects
  • fromLabel(string): static — find case by label, throw on miss
  • tryFromLabel(string): ?static — find case by label, null on miss
  • randomCase(): static — random case
  • toJsonValue(): string|int — instance method, returns backing value
  • fromJsonValue(string|int): static — static, wraps from()
  • Label resolution: if enum has label(): string method, use it; otherwise humanize case name (SCREAMING_SNAKE → Title Case)

2. EnumCollection

Wraps an array of enum cases with collection operations.

  • __construct(array $cases)
  • filter(callable): self
  • map(callable): array
  • contains(BackedEnum): bool
  • diff(self): self
  • toArray(): array
  • count(): int (Countable)
  • Static from(string $enumClass): self — creates collection of all cases

3. HasLabels Contract

Interface: Contracts\HasLabels with label(): string method.

4. Validation: EnumValidationRule

Standalone validation rule (no framework dependency).

  • __construct(string $enumClass)
  • validate(mixed $value): bool
  • message(): string

5. Integration: Laravel EnumCast

  • Kexxt\EnumUtils\Integration\Laravel\EnumCast
  • Implements CastsAttributes (interface check only, no Laravel dependency)
  • get() / set() methods using from() / ->value

6. Integration: Doctrine AbstractEnumType

  • Kexxt\EnumUtils\Integration\Doctrine\AbstractEnumType
  • Abstract class users extend per enum
  • convertToPHPValue() / convertToDatabaseValue()

Architectural Decisions

  • Zero runtime dependencies: Framework integrations reference interfaces by string, no imports
  • Label convention: humanize SCREAMING_SNAKE case names as default
  • PHPStan level 9: Use generics/templates where needed for type safety
  • Trait over base class: PHP enums can't extend classes, trait is the only option

API Surface

All public methods on EnumUtilsTrait:

static values(): array<int, string|int>
static labels(): array<string|int, string>
static toSelectArray(): array<string|int, string>
static toRadioOptions(): array<int, array{value: string|int, label: string, name: string}>
static fromLabel(string $label): static
static tryFromLabel(string $label): ?static
static randomCase(): static
static fromJsonValue(string|int $value): static
toJsonValue(): string|int
static collect(): EnumCollection