Helpers for PHP backed enums, including BenSampo-style APIs (fromValue, hasValue, getInstances, descriptions, select arrays) and an EnumValue validation rule for Laravel.
composer require langleyfoxall/backed-enum-helpersRequires PHP 8.4+ and Laravel 11+.
use LangleyFoxall\BackedEnumHelpers\Concerns\BackedEnumHelpers;
enum Status: string
{
use BackedEnumHelpers;
case Active = 'active';
case On_Hold = 'on_hold';
case Archived = 'archived';
}
Status::Active(); // Status::Active
Status::hasValue('active'); // true
Status::fromValue('on_hold'); // Status::On_Hold
Status::getDescription('on_hold'); // "On Hold"
Status::getInstances(); // Status::cases()
Status::getValues(); // ['active', 'on_hold', 'archived']
Status::getKeys(); // ['Active', 'On_Hold', 'Archived']
Status::asArray(); // ['Active' => 'active', ...]
Status::asSelectArray(); // ['active' => 'Active', 'on_hold' => 'On Hold', ...]
Status::asSelectOptions(); // [['value' => 'active', 'label' => 'Active'], ...]
Status::fromDescription('On Hold'); // Status::On_Hold (case-insensitive)
Status::asDescriptionMap(); // ['active' => Status::Active, 'on hold' => Status::On_Hold, ...]
Status::getRandomInstance();
Status::getRandomValue(['active']); // random value excluding 'active'
Status::toLabel('on_hold'); // alias of getDescription()Optional extra helpers for apps that relied on BenSampo instance/key APIs (is, isNot, in, hasKey, fromKey, getValue, getRandomKey). Use alongside BackedEnumHelpers — getValue() needs fromValue() from that trait:
use LangleyFoxall\BackedEnumHelpers\Concerns\BackedEnumHelpers;
use LangleyFoxall\BackedEnumHelpers\Concerns\HasEnumMembers;
enum Status: string
{
use BackedEnumHelpers;
use HasEnumMembers;
case Active = 'active';
case Archived = 'archived';
}
Status::Active->is('active'); // true
Status::Active->isNot('Archived'); // true
Status::Active->in(['archived']); // false
Status::hasKey('Active'); // true
Status::fromKey('Active'); // Status::Active
Status::getValue('Active'); // 'active'
Status::getRandomKey(['Active']);Custom labels via a DESCRIPTIONS map (case name → label). Unmapped cases still use the default ucwords fallback. Prefer this over repeating instanceof BackedEnum checks in each enum:
enum QuoteStatuses: string
{
use BackedEnumHelpers;
case ReadyToSend = 'ready_to_send';
case Sent = 'sent';
private const DESCRIPTIONS = [
'ReadyToSend' => 'Ready To Send',
'Sent' => 'Sent',
];
}
QuoteStatuses::toLabel('ready_to_send'); // "Ready To Send"
QuoteStatuses::toLabel(QuoteStatuses::Sent); // "Sent"
QuoteStatuses::fromDescription('ready to send'); // QuoteStatuses::ReadyToSend
QuoteStatuses::asDescriptionMap(); // ['ready to send' => QuoteStatuses::ReadyToSend, 'sent' => QuoteStatuses::Sent]fromDescription() / asDescriptionMap() invert toLabel() / asSelectArray(): CSV cells and other label input resolve to enum instances. Matching is case-insensitive by default (fromDescription('On Hold', caseInsensitive: false) for an exact match). Duplicate descriptions throw rather than silently overwriting.
Or override description() when a map is not enough:
public function description(): string
{
return match ($this) {
self::Active => 'Currently active',
default => ucwords(str_replace('_', ' ', strtolower($this->name))),
};
}Drop-in replacements for BenSampo's EnumValue and EnumKey rules — including the same failure messages (The value you have entered is invalid. / The key you have entered is invalid.):
use LangleyFoxall\BackedEnumHelpers\Rules\EnumKey;
use LangleyFoxall\BackedEnumHelpers\Rules\EnumValue;
$request->validate([
'status' => ['required', new EnumValue(Status::class)],
'status_key' => ['required', new EnumKey(Status::class)],
// or as string rules:
'status' => ['required', 'enum_value:'.Status::class.',true'],
'status_key' => ['required', 'enum_key:'.Status::class.',true'],
]);Override globally by defining enum_value / enum_key in your app's lang/{locale}/validation.php (same as BenSampo). Otherwise the package defaults apply. No app wrapper rule is needed for message parity.
- Convert enum classes to native PHP backed enums.
- Add
use LangleyFoxall\BackedEnumHelpers\Concerns\BackedEnumHelpers;on each enum. - Where call sites use
is/isNot/in/hasKey/fromKey/getValue/getRandomKey, alsouse LangleyFoxall\BackedEnumHelpers\Concerns\HasEnumMembers;. - Replace
use BenSampo\Enum\Rules\EnumValue;/EnumKeywith the package rules (LangleyFoxall\BackedEnumHelpers\Rules\...). Failure messages match BenSampo by default. - Remove
bensampo/laravel-enumand any app-levelEnumValue/EnumKeyshims that only existed to restore the old message text.
Common method names are preserved so most call sites can stay unchanged.
composer testPlease see CHANGELOG for more information on what has changed recently.
The GNU LGPL v3.0. Please see License File for more information.