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

Entity Translation Bundle Laravel Package

hostnet/entity-translation-bundle

A Symfony bundle for translating Doctrine entity fields per locale. Store and retrieve localized entity content with minimal setup, making multilingual applications easier to build and maintain.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Unchanged in substance. The package solves a real, recurring problem — enum-like domain values (OrderStatus::PENDING, Role constants) leaking raw storage values into UI, emails, exports, and admin tables — via a convention-driven mapping from class constant → translation key → human label.

That is a conceptual fit for any Laravel codebase. The mechanical fit remains poor: this is a Symfony bundle whose value is delivered through a DependencyInjection extension, service definitions, and a Twig extension. Laravel has no bundle loader, uses Illuminate\Translation rather than symfony/translation, and Blade rather than Twig. None of the wiring survives the trip. What survives — if the core is not tightly coupled — is a small label-resolution service and a naming convention.

Integration feasibility. Release 1.0.11 does not change the calculus. It is a hygiene release: removes an unused doctrine/annotations dependency, drops Symfony < 6.4, drops PHP < 8.3. No new features, no API surface change, no new capability that would move this from "reference implementation" to "dependency." Required spike and effort estimates stand:

  • Best case (core is framework-agnostic): ~1–2 engineer-days to vendor the resolver, adapt to __(), add a Blade directive, and write tests.
  • Likely case (core coupled to Symfony contracts): ~3–5 engineer-days to reimplement the convention from scratch, at which point the package is a specification, not a dependency.
  • Worst case: the API surface is trivial enough that reading it and writing 80 lines of Laravel-native code is cheaper than either.

The new PHP 8.3 floor is a genuine constraint on the best case: any Laravel service still on PHP 8.2 cannot even install the package to inspect runtime behavior. Vendoring the resolver file sidesteps this, but the vendored code must then be reviewed for 8.3-only syntax before it lands in an 8.2 app.

Technical risk.

  • Adoption signal is still near-zero. 5 stars, 0 dependents. One release does not create community validation, third-party bug reports, or a fork ecosystem. Opportunity score of 34.87 still reads as narrow utility, not platform bet.
  • Semver hygiene concern (new). A patch release (1.0.11) that drops PHP 8.2 and Symfony < 6.4 is a platform-breaking change shipped under a non-breaking version number. That is a concrete signal that the maintainer does not treat the version number as a compatibility contract. For a package we would only read, it is cosmetic. For anything we depended on, it would mean pinning exact versions and auditing every bump — which is exactly the kind of operational tax we are trying to avoid.
  • PHP 8.1+ enum support is still unconfirmed, but now more likely. Raising the floor to PHP 8.3 is consistent with a maintainer tracking a modern baseline, which makes native backed-enum support more probable than before. "More probable" is not "confirmed" — the original question stands and is still the first thing the spike must answer.
  • Single-maintainer / single-vendor risk. Unchanged. One release is evidence of activity, not of depth; a portfolio publisher's attention to an individual bundle still cannot be inferred from outside.
  • License is the mitigant. MIT means fork-and-own is unconditionally available, and the code surface is small. Lock-in cost is close to zero — which remains the strongest argument against adding it as a Composer dependency.
  • Metadata anomaly, partially resolved. The earlier future-dated release (2026-08-25) is now joined by a real, dated 1.0.11 with concrete changelog content. Treat the package as live, but verify tag history against Packagist before writing "actively maintained" into a decision record.

Key questions for the maintainers / spike.

  1. Is the resolver framework-agnostic, or does it require symfony/translation contracts?
  2. Does it support PHP 8.1 backed enums natively, or only class constants? (Now more likely yes given the 8.3 floor — still unverified.)
  3. Is the translation key convention configurable, or hardcoded (e.g., Entity.field.value)?
  4. What is the placeholder syntax — Symfony %name% or Laravel :name?
  5. Does it ship tests, and what is the CI matrix (now presumably PHP 8.3/8.4 × Symfony 6.4/7.x)?
  6. What happens on a missing key: exception, fallback to raw value, or fallback to key?
  7. Is there any caching of reflection or constant enumeration, or is it re-derived per call?
  8. (New) What is the maintainer's stated compatibility policy — does 1.0.11 signal that future platform floors will also land in patch releases?

Integration Approach

Stack fit. Unchanged. Treat this as a reference implementation rather than a dependency. Laravel already has lang/ files, the __() helper, pluralization, locale switching, and Illuminate\Translation. The only missing piece is the convention mapping a domain value to a translation key — a naming decision, not a library.

Recommended shape:

  • Convention: enums.{snake_case_class}.{value} — e.g., enums.order_status.pending.
  • Resolver: a small EnumLabel service with label(BackedEnum|string $value, ?string $locale = null): string, falling back to Str::headline() when the key is absent.
  • Presentation: a Blade directive or @lang usage plus a casts.php config, so domain models are not touched to render labels.
  • Validation: reuse the same keys for Rule::enum() messages, keeping API and UI consistent.

If the spike confirms a framework-agnostic core, vendor the resolver file with attribution and a header comment citing the upstream repo, the MIT license, and the specific version read (currently 1.0.11) so future readers know which snapshot informed the code. Do not add it to composer.json — a hard dependency on a Symfony bundle in a Laravel app invites autoload and service-provider confusion for no benefit, and now also imposes a PHP 8.3 floor we do not control.

Migration path.

  1. Spike (0.5 day). Read the 1.0.11 source; answer the eight questions; write a one-page ADR with a build-vs-vendor recommendation.
  2. Prototype (1 day). Implement the convention for the two highest-traffic enums (typically OrderStatus, UserRole). Cover every case in tests.
  3. Rollout (2–3 days). Replace ad-hoc match/switch label logic and hardcoded string maps across Blade views, mail templates, and API resources. Highest value first: customer-facing surfaces where raw enum values are currently visible.
  4. Guardrail (0.5 day). CI check that every case of every enum in app/Enums has a corresponding translation key in lang/en/. Still the single highest-leverage piece of the effort.

Compatibility. Two friction points persist if we ever consume upstream code directly: Symfony's %placeholder% syntax versus Laravel's :placeholder, and Symfony's translations/ directory layout versus Laravel's lang/. Release 1.0.11 adds a third: a hard PHP >= 8.3 requirement. Since the recommended path is vendoring a single file rather than installing the package, the version floor is advisory — but it must be checked line by line if any consuming app is still on 8.2.

Sequencing. Unchanged. Do not schedule this as a standalone initiative; it does not justify its own sprint slot. Attach it to the next piece of work touching domain-value presentation (a status-display refactor, an admin table, an export feature). Land the guardrail CI check first — it prevents regression regardless of which implementation we choose.

Operational Impact

Maintenance. Fork-and-own remains the operating model; ownership sits with the application team, not platform. Ongoing cost is low — the resolver is a handful of lines, and the real burden is the translation corpus, not the code. Budget roughly one hour per new enum, mostly translation review across supported locales. The 1.0.11 release does not change this number, because we are not tracking upstream.

Support. No vendor SLA, no commercial backing, GitHub issues with a 5-star project's typical latency. The 1.0.11 changelog is terse and undated in prose, which is characteristic of a small maintained-in-spare-time project — competent, but not a support relationship. Assume we write our own fixes. Acceptable precisely because the code surface is small enough to fully understand, but it must be a conscious acceptance recorded in the ADR.

Scaling. Runtime impact remains negligible: label resolution is a hash lookup against a loaded translation array. Two watch items persist: (a) if the implementation enumerates constants or reflects on each call, memoize it — this matters in list endpoints serializing hundreds of models; (b) keep the enum namespace in a dedicated translation group rather than the general messages file, allowing per-group lazy loading across locales.

Failure modes.

  • Missing key → raw value in the UI. Depending on fallback behavior, customers see PENDING or enums.order_status.pending. Silent and customer-visible; the CI guardrail is the mitigation.
  • Renamed or removed enum cases leave orphaned keys. Harmless but accumulates; add a reverse check (keys with no matching case) as a warning, not a failure.
  • Locale gaps. A key present in en but absent in de degrades quality silently. Requires a locale-parity check in CI, not just a key-existence check.
  • Placeholder syntax mismatch if upstream files are reused — renders literal %name% in output.
  • Unhandled enum case in a match statement during migration throws UnhandledMatchError — a hard 500 rather than a cosmetic defect. Migrate with explicit default branches during the transition.
  • Platform-floor drift (new). If we had taken the dependency, 1.0.11 would have landed as an unreviewed composer update that silently raised our PHP requirement and could break CI or a deploy target mid-sprint. Vendoring removes this failure mode entirely — another point in favour of the current recommendation.

Ramp-up. Low and unchanged. A mid-level engineer can own this after reading the ADR and the convention doc — half a day. The larger onboarding task is transmitting the convention so new enums are not added with inline match statements out of habit. Enforce it at review plus the CI check, not through documentation alone.

Verdict. Unchanged: conceptually valuable, mechanically mismatched, too low-adoption to adopt as a dependency. Release 1.0.11 is maintenance hygiene that improves the package's modernity (PHP 8.3, Symfony 6.4 floor, dead dependency removed) without adding capability — and its shipment as a patch release is a mild negative signal about upstream's compatibility discipline, which reinforces rather than weakens the case for reading it and reimplementing natively in roughly a day. The package's real contribution remains validating that the problem is worth solving systematically — not the code we would ship.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager