Values, names and options
phil/enumsRead the cases of an enum as primitives. The primitive of a case is its value when the enum is backed, its name when it is pure. The examples below use two enums:
enum OrderStatus: string
{
case PENDING = 'pending';
case PAID = 'paid';
case SHIPPED = 'shipped';
}
enum Season
{
case SPRING;
case SUMMER;
case AUTUMN;
case WINTER;
}
Each section names the trait that adds the methods; add a use line for it in the enum.
AsInvocableEnumTrait: a case as its primitive
A case can be called to get its primitive, and the enum can be called by a case's name to get the same thing, so
that code that needs a plain value never writes ->value.
use Phil\Enums\Traits\AsInvocableEnumTrait;
OrderStatus::PAID(); // 'paid'
Season::WINTER(); // 'WINTER'
$status = OrderStatus::SHIPPED;
$status(); // 'shipped'
It helps where PHP takes only primitives, as array keys for instance:
$deliveryDays = [
OrderStatus::PENDING() => 5,
OrderStatus::PAID() => 3,
];
A static call that names no case fails with Exceptions\UndefinedCaseError, an Error worded as PHP words an
undefined constant: Undefined constant App\OrderStatus::REFUNDED. The PHPStan extension knows each case's static
call and its return type (PHPStan).
AsNameableEnumTrait: names()
The case names, in declaration order:
OrderStatus::names(); // ['PENDING', 'PAID', 'SHIPPED']
Season::names(); // ['SPRING', 'SUMMER', 'AUTUMN', 'WINTER']
AsValuableEnumTrait: values()
The case primitives, in declaration order: the values of a backed enum, the names of a pure one.
OrderStatus::values(); // ['pending', 'paid', 'shipped']
Season::values(); // ['SPRING', 'SUMMER', 'AUTUMN', 'WINTER']
AsSelectableEnumTrait: options()
The cases as choices. A backed enum gives each value by name; a pure enum, which has no value, gives the list of its names.
OrderStatus::options(); // ['PENDING' => 'pending', 'PAID' => 'paid', 'SHIPPED' => 'shipped']
Season::options(); // ['SPRING', 'SUMMER', 'AUTUMN', 'WINTER']
AsStringSelectableEnumTrait: stringOptions()
One piece of text per case, joined into one string. The trait includes AsSelectableEnumTrait.
stringOptions(?Closure $callback = null, string $glue = "\n") calls the callback with each case's name and its
primitive as a string — the name twice for a pure enum — and joins what it returns with the glue:
OrderStatus::stringOptions(static fn (string $name, string $value): string => "$value=$name", '&');
// 'pending=PENDING&paid=PAID&shipped=SHIPPED'
Without a callback, each case becomes an HTML <option>, one per line. Its label is the case name as words: a name
with underscores is split on them, a name in mixed case before each capital, and a name all in capitals is one word
(IN_TRANSIT and InTransit read In transit).
echo OrderStatus::stringOptions();
// <option value="pending">Pending</option>
// <option value="paid">Paid</option>
// <option value="shipped">Shipped</option>
echo Season::stringOptions();
// <option value="SPRING">Spring</option>
// …
The default options are escaped for HTML: a quote, <, > or & in a value or a label is written as an
entity, so a value cannot close the attribute or the element. A callback of your own returns text that is printed as
it is, so it escapes what it puts into HTML itself.