forci/menu-builder-client-bundle
A Symfony bundle that integrates the Forci menu builder client into your application, providing ready-made services, dependency injection wiring and configuration options for building, managing and rendering menus within the Symfony framework.
Architecture fit. Poor as catalogued, conditional as engineered. The package is a Symfony bundle — the -bundle suffix is a hard signal. It plugs into Symfony's Kernel, bundles.php, and DependencyInjection/Extension pipeline, none of which exist in Laravel. Our stack (Laravel, Eloquent, Blade/Livewire, queue workers) has no bundle concept, so the package cannot be "installed" in the intended sense. What is potentially reusable is only the inner layer: the PSR-18/PSR-7 HTTP client, auth handling, request/response DTOs, and serialization. The outer layer — service definitions, configuration tree, Twig helpers, compiler passes — is dead weight or actively conflicting. Treat the artifact as "a ~200-line HTTP client with a Symfony delivery vehicle," and plan accordingly.
Integration feasibility. Feasible but unproven, and only after source review. There are two possible outcomes:
Client/ (or equivalent) does not use Symfony kernel, Twig, or Doctrine classes, we can extract it, wrap it in a Laravel ServiceProvider, and be productive in one to two days. This is the favourable case.The decision between these two paths is a single afternoon of reading composer.json and DependencyInjection/. Do that before committing anything to a roadmap.
Technical risk. High, and mostly non-technical:
NOASSERTION. No asserted license means no granted rights to copy, modify, or distribute. This is a hard blocker until counsel or the maintainer resolves it. It is the critical path for every other activity.Key questions for the vendor or repo owner.
composer.json? Until answered, this is a no-go.Verdict. Do not adopt as a production dependency on current evidence. Run a two-day spike: confirm the license, read the source, and decide between "extract and wrap" versus "reimplement." Both outcomes are cheap; the expensive mistake is depending on the bundle as-is.
Stack fit. Partial. Laravel and Symfony share enough surface — PSR-18 HTTP clients, symfony/serializer, PSR-7 messages, and Laravel's own Http facade built on Guzzle — that a well-factored client should port without heroics. The seam is a Laravel ServiceProvider binding a MenuClient singleton, a config/menu-builder.php for base URI, credentials, timeouts, and cache TTL, and a typed interface (MenuRepository) that controllers and Blade components consume. Everything the Symfony bundle would have done via its Configuration tree and compiler passes gets replaced by Laravel config and environment variables. Twig helpers are not reusable; the rendering layer is reimplemented in Blade or a view component.
Migration path.
NOASSERTION before any code lands in a product repo. If the vendor will not assert a license, plan on reimplementation and skip the rest of this list.composer.json constraints, and classify every class as portable, replaceable, or blocking. Record the result in the spike ticket.Compatibility. Confirm PHP 8.1+ and PSR-18 support. The specific tell is whether the package requires symfony/framework-bundle: if it does, we reimplement rather than integrate. If it pins symfony/http-client to a major that our Laravel version already resolves transitively, we are likely fine; if it pins an older Symfony major, expect Composer conflict resolution or a fork. Check for a CI workflow or phpunit.xml — absence means we are the test suite.
Sequencing and ownership. If we proceed, vendor the code rather than pulling from Packagist: fork it into our org, pin a VCS repository in composer.json, and assign a named engineer as owner. This makes the license and audit trail explicit and decouples us from upstream abandonment. Regardless of path, define the MenuRepository interface internally so a future vendor-supported Laravel package, or a full reimplementation, swaps in without touching call sites. Sequence: legal → source audit → contract capture → wrapper PoC → resilience → flagged rollout. Do not parallelize past the legal gate.
Maintenance. With zero dependents and zero stars we are the maintainer from day one. Budget a quarterly dependency review and a named owner for upgrades, security patches, and the fork. Assume upstream will not fix PHP or Symfony compatibility breaks, and will not respond to issues. Version-pin aggressively and treat any upstream change as unreviewed code.
Support. No community channel, no visible SLA. If Forci is a commercial counterparty, negotiate support terms and a deprecation notice window before adoption — not after. If it is not, the support plan is "internal engineer reads the source under incident pressure," which must be written into the on-call runbook and reflected in the escalation matrix.
Scaling. A remote menu service in the render path is a latency and availability coupling on every page. Mitigations:
Failure modes and mitigations.
Cache::lock or a single-flight pattern for the first fetch per node.Ramp-up. One to two sprints for the spike plus wrapper, plus ongoing ownership. The team cost is not Symfony familiarity — the portable slice is small — it is owning an unmaintained dependency and building the operational machinery around a remote menu service: caching, fallback, alerting, contract tests. Those are non-negotiable if menus sit in the critical rendering path, and they are the real budget line. Any estimate that quotes only integration hours is wrong by a factor of three.
How can I help you explore Laravel packages today?