Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Enum Helper Laravel Package

datomatic/enum-helper

Laravel helper for PHP enums that adds labels, descriptions, colors, icons, select options, validation rules, and Eloquent casts. Expose enum values and names to build forms, APIs, and admin UIs with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a small, focused package that adds ordering/comparison semantics to PHP 8.1+ enums — it is a language-level helper, not a Laravel service provider you configure. That shapes everything about how you adopt it.

  1. Check your floor: PHP 8.1+ (enums), and a Laravel version already supported by the previous release line. v2.2.0 is an additive feature release, so bumping from v2.1.x should be a composer update with no migration work.
  2. Read the source, not the README, first. The whole surface area is likely one trait (a few dozen lines). Open src/ and note: the trait's fully-qualified namespace, which comparison methods it exposes (greaterThan/lessThan/isAtLeast style vs. operator-like helpers), and whether it compares value, name, or cases() position.
  3. Apply it to one enum and stop. Do not bulk-apply the trait across app/Enums on day one — a single enum where ordering genuinely matters.

The best first use case is a state/severity enum in a domain you already own:

enum OrderStatus: int
{
    use Comparable;

    case Draft     = 10;
    case Placed    = 20;
    case Shipped   = 30;
    case Delivered = 40;
    case Cancelled = 99; // note: not "last" semantically — see Gotchas
}

Then a single guard, e.g. "can't cancel once shipped," expressed in a policy or action class rather than scattered match statements.

Implementation Patterns

Ordering guards in policies and actions. The trait's value is turning match/in_array ladders into one readable expression:

public function cancel(Order $order): bool
{
    return $order->status->lessThan(OrderStatus::Shipped);
}

This is the pattern to standardise on. It reads as intent, works in tests without a database, and survives adding a new case in the middle of the ordering.

Explicit rank values, not declaration order. Prefer integer-backed enums with spaced values (10/20/30) so you can insert a case later without renumbering persisted data. If the trait compares by cases() position, be aware that reordering the case declarations silently changes business logic — that is the single biggest correctness risk with this package.

Keep the trait out of enums that are only categorical. PaymentMethod, Country, Currency — these should never be comparable. A comparable enum is a claim that there is a total order, and reviewers should push back on the trait appearing on enums where that claim is false.

State-machine transitions. Pair the trait with a transition map so comparisons control guards while an explicit map controls allowed edges; don't let comparisons become the transition table. Cancelled = 99 above is a good example: it sorts last numerically but isn't "further along" — model it as a terminal state, not a rank.

Sorting collections. Use the trait's comparison inside sort()/sortBy() callbacks rather than relying on ->value directly, so the ordering rule stays in one place:

$orders->sort(fn ($a, $b) => $a->status->compareTo($b->status));

Testing. Comparison logic is pure and cheap — cover it with a small matrix of enum pairs in a unit test, not feature tests. Assert both directions (a ≥ b and b ≤ a) since trait-based comparators frequently get the operand order inverted in one branch.

Blade and API layers. Expose ->value or a labelled string, not the enum comparison API. The trait is for server-side decision-making; the front end should receive a stable scalar and, if it needs ordering, the integer rank explicitly.

Gotchas and Tips

  • Backed vs. pure enums. String-backed enums compare alphabetically by value unless the package does something smarter — almost always the wrong semantics ('shipped' < 'delivered' is false). Use integer backing for anything orderable, or confirm exactly what the trait compares before shipping.
  • The trait cannot carry state. Enums can't have properties, so any implementation that adds a $rank property will fail at class-load time. If you need a custom rank, use a method or a match inside your own enum.
  • Method name collisions are fatal. Enums can't inherit conflicting methods; if your enum already defines compareTo or the trait adds value()-adjacent helpers, you'll get a fatal error. Grep your enums before applying the trait.
  • Comparisons don't cross enum classes. Comparing OrderStatus to TicketStatus should throw — don't wrap the call in a try/catch to "make it work." Type the parameters tightly instead.
  • The database is unaware of this. where('status', '>', $x) still uses raw column values. Convert to whereIn('status', $allowedValues) built from a filtered cases() list; never assume the trait influences query building.
  • Eloquent casts return enum instances. After $order->status, you have the enum, so the trait applies directly — but $order->status->value is what you persist. Don't pass the enum object into update() on a non-enum-cast column.
  • Serialisation and API contracts. Enums serialise to value in JSON; adding comparison methods doesn't change payloads. But if you switch an enum from string- to int-backed to get sane ordering, that is a breaking API change — plan it as a migration with a cast/accessor, not a rename.
  • Upgrade note for v2.2.0. Purely additive: new capability on top of existing behaviour, no deprecations signalled. Pin to ^2.2 and let the lockfile prove it; there is no reason to hold back the bump. Contributed features in small packages can be less battle-tested than the maintainer's own code, though — worth a quick source read of the comparison implementation and one extra test on your own ordering assumptions before relying on it in a payment or fulfilment path.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib