piotrpolak/conditional-routing-bundle
Symfony bundle that adds conditional routing, letting you define routes that match only when configured conditions are met. Useful for feature flags, environment-specific endpoints, and request-aware route selection, with simple routing configuration and integration with Symfony's routing component.
php artisan vendor:publish, no facade, no config file in config/. If you are in a Laravel codebase, you are reading this as a design reference (see the Laravel equivalents below), not as a dependency — Composer may install it, but nothing in Laravel will ever load it.composer.json before anything else. Last release was 2018‑10‑25, so expect PHP 7.x-era constraints and symfony/framework-bundle / symfony/routing constraints in the 2.8–4.x range. Never force it with --ignore-platform-reqs in a real app; pin ^1.0 if you do adopt it.$bundles[] = new PiotrPolak\ConditionalRoutingBundle\...(); in AppKernel.php. Symfony 4+/5+: entry in config/bundles.php. Note the 1.0.0 rename Piotrpolak → PiotrPolak — use the new case everywhere.DependencyInjection/*Extension.php — the real config schema (which condition keys exist).Routing/ — the loader/decorator that decides which route collections get loaded. This is the whole feature.Resources/config/services.yml — service ids and any tags used to collect conditions.if ($this->getEnvironment() === 'dev') { ... } around routing.yml imports. Instead, declare a per-bundle (or per-collection) condition — e.g. environment is dev, host matches *.internal, a feature-flag service returns true — and let the loader skip those routes automatically.bin/console debug:router and bin/console router:match /some/gated/path with the condition satisfied and unsatisfied. If the route list is identical in both runs, your condition is not being wired (usually a missing service tag or a stale cache).src/ for the exact interface name and method signature). It should read the Request and container-provided values and return a boolean — no DB writes, no session mutation, no HTTP calls.IsDevEnvironment, MatchesInternalHost, FeatureFlagEnabled('new-admin'), each registered as a service, with AND/OR applied in config or a thin composite condition. This keeps each predicate unit-testable.access_control/voters for that).debug:router output comprehensible.$urlGenerator->generate('admin_...'), Twig path(), redirects, sitemap builders, mailers) will throw RouteNotFoundException in the environment where it's disabled. Wrap generation in $router->getRouteCollection()->get(...) checks or a helper, and add a smoke test that renders your layout in the "conditions off" environment.HTTP_HOST/server vars and APP_ENV values, asserting the route is 404 vs 200 — that catches loader and cache-layer regressions the unit test cannot.RouteServiceProvider::boot():
if (app()->environment('local') || config('features.admin')) { Route::middleware('web')->group(base_path('routes/admin.php')); } — this is the exact analogue of “skip loading the collection”.Route::domain('{tenant}.app.test')->group(...) plus route-level middleware for host/header predicates.RouteCondition interface with passes(Request $request): bool and a registrar that loops through them before ->group(); that reproduces the bundle's extensibility without the Symfony coupling.config/*.php + mergeConfigFrom; loader decorator → RouteServiceProvider conditional blocks; service tags → container tags/app()->tagged().Piotrpolak → PiotrPolak. Update use statements, config/bundles.php, AppKernel.php, and — easy to miss — YAML/XML service definitions where the class is written as a string (class: PiotrPolak\..., arguments:). PSR-4 path mapping is case-sensitive on Linux/macOS, so one stale reference is a hard Class not found.bin/console cache:clear (and rm -rf var/cache/* if the compiled container is wedged). A stale container will happily keep the old condition wiring and make you debug the wrong file for an hour.debug:container --tag=<condition tag> to confirm your condition service is registered and tagged; (2) debug:router in both condition states; (3) var/log/dev.log for loader exceptions swallowed into a generic routing error; (4) cache:clear; (5) confirm the bundle directory on disk is src/PiotrPolak/, not src/Piotrpolak/.How can I help you explore Laravel packages today?