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 Bundle Laravel Package

yethee/enum-bundle

Symfony bundle that integrates PHP 8.1 enums into your app: autowire enum instances, use enum-aware form types and validator constraints, map enums with Doctrine types, and simplify enum choices in configuration and templates.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and register. composer require yethee/enum-bundle (or the yethee/biplane-enum library if you only want the core). Check the bundle's composer.json first: this is a Symfony 2-era bundle, so its symfony/symfony constraint will likely block installation on Symfony 4+. Then register it manually in AppKernel::registerBundles() — there is no Flex recipe.
  2. Read these files first, in order:
    • vendor/yethee/enum-bundle/README.md
    • The base enum class in the bundle and the underlying Biplane\Enum\AbstractEnum — this is where getValues(), getReadableValues(), isValid(), and create() live.
    • Form/Type/EnumType.php and Validator/Constraints/Enum.php — the two integration points you will actually touch day to day.
    • Command/ — the enum generator, if it ships in your version.
  3. Define your first enum. Either scaffold with the console command (app/console biplane:enum:generate ...) or hand-write a class extending the bundle's enum base, defining one constant per member and overriding the readable-label method (e.g. getReadable() / getReadableValues()).
  4. First real use case: a status/code field on an entity stored as a scalar (string or int), rendered as a <select> via EnumType, validated with the Enum constraint, with the enum class as the single source of truth for both allowed codes and display labels. That end-to-end slice is the fastest way to see whether the package earns its place.

Implementation Patterns

  • Enum as the single source of truth. Keep codes and readable labels in one class. The entity stores the scalar; the enum class is used at the boundaries (forms, validation, rendering, API input/output). Don't scatter raw 1/'active' literals through templates and services.
  • Form integration. Add fields via the bundle's enum form type, passing the enum class (either as the class option or the type's constructor, depending on the version). Populate choices from getReadableValues() so the select shows labels while submitting values. For a multi-select, use the same type with multiple => true.
  • Validation. Attach the bundle's Enum constraint to the scalar property (or to request DTOs) so tampered POSTs are rejected before conversion. Validate the raw scalar, not the enum object.
  • Doctrine mapping. Map the column as string/integer. On hydrate, wrap with the enum's static factory (create()/createByValue()); on persist, write ->getValue(). Do this in the entity accessor/mutator or a lifecycle callback rather than a custom Doctrine type — it keeps the mapping portable and avoids surprises in DQL.
  • Twig / view layer. If entities hold scalars, expose a small Twig extension or lookup filter that maps a value to its readable label via Enum::getReadableValues(). If entities hold enum objects, rely on __toString()/readable getter. Either way, centralise it so label changes are one edit.
  • Services and DI. Register enum class names as container parameters (or services) and inject them, so form types and validators don't hardcode FQCNs. This also makes swapping an enum class in tests trivial.
  • Request/API boundaries. Accept the scalar, reject with a 400 if Enum::isValid($input) fails, then construct the enum. Serialize back out as ->getValue(), never as the object, so your JSON contract survives refactors.
  • Generation workflow. Use the generator command to scaffold from a values list, then hand-edit readable labels in the generated class and commit it. Treat generated enums like migrations: generated once, edited afterwards.
  • Testing. Data providers that iterate getValues() catch coverage gaps; add an assertion that every constant has a readable label so new members can't ship with a raw value as their display name.

Gotchas and Tips

  • Symfony-version lock. This is Symfony 2 scaffolding: manual bundle registration, old DI conventions, old PHPUnit. On Symfony 4/5+ expect composer conflicts and missing autoload entries (PSR-0 vs PSR-4). The pragmatic path is a fork or vendoring the handful of classes you use rather than fighting the constraint.
  • Native PHP 8.1 enums supersede it. For new code, use backed enums. Migration is mechanical: keep the same backing values (integer or string) as the old constants so existing DB rows and serialized payloads stay valid, and keep a getReadable()-equivalent method on the enum for labels.
  • The reflection cache. AbstractEnum caches reflected constants statically. Constants must be declared on the class — you cannot register enum members at runtime, and dynamic or conditionally-defined subclasses will behave unpredictably. If you run APC/opcache and change enum classes on deploy, clear caches.
  • Silent missing labels. If you forget to override the readable method, labels fall back to raw values and nothing errors — you just get ugly selects. Add the "every constant has a label" test above.
  • Type strictness. isValid(1) and isValid('1') are not necessarily interchangeable depending on the version; request data always arrives as strings. Cast explicitly at the boundary before validating, or you will reject valid input or accept invalid input depending on the enum's value type.
  • Form type configuration drift. Older versions use setDefaultOptions() and a constructor argument; newer ones use configureOptions() and a class option. Passing the wrong one throws an InvalidConfigurationException that doesn't clearly point at the cause. Read the type's option configuration before wiring it.
  • Constraint target. The validator expects the scalar form of the value. Applying it to an enum object (or to a property that's already been converted) produces confusing "not valid" failures.
  • Doctrine pitfalls. Don't map the enum object directly to a column; conversion in DQL, findBy, and ORDER BY becomes painful. Also avoid keeping enum objects in session or queued messages — a class refactor or removed constant turns stored data into an unserializable blob. Persist scalars.
  • Ecosystem risk. 31 stars, zero dependents, and no active community means no StackOverflow answers and no upstream fixes. Pin the exact version, read the source (it's small), and be prepared to fork. Budget the fork as a likely cost, not a contingency.
  • Extension points worth knowing: subclass the base enum for shared behaviour (e.g. a translated label lookup), extend the bundle's form type to preset class/choices, and write your own constraint if you need richer error messages than the bundled one. These are all small classes — copying them into your app is often cleaner than depending on them.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core