-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Describe the bug
When implementing multiple Dashboards intended for different subdomains (e.g., admin.site.com and aff.site.com), the AdminRouteLoader using type: easyadmin.routes creates a global collision.
Despite the dashboards being located in separate physical directories and namespaces, the loader performs a global discovery of all AbstractDashboardController instances. This causes the routes for the Admin dashboard to "leak" and be generated for the Affiliate subdomain host context, and vice versa.
Environment
PHP: 8.5
Symfony: 8.0
EasyAdmin Bundle: 4.28.0
To Reproduce
Project Structure
I have organized the controllers into separate directories to maintain strict isolation,
but the automatic route loader ignores these boundaries:
src/
└── Controller/
├── Admin/
│ └── AdminDashboardController.php --> (Target: admin.site.com)
└── Aff/
└── AffDashboardController.php --> (Target: aff.site.com)
routes.yaml
easyadmin:
resource: .
type: easyadmin.routes
AdminDashboardController.php:
#[AdminDashboard(
routePath: '/dashboard',
routeName: 'admin',
routeOptions: ['host' => 'admin.%site_url%'],
routes: [
'index' => ['routeName' => 'index', 'routePath' => '/'],
// ...
]
)]
final class AdminDashboardController extends AbstractDashboardController { ... }
AffDashboardController.php
#[AdminDashboard(
routePath: '/panel',
routeName: 'affiliate',
routeOptions: ['host' => 'aff.%site_url%'],
routes: []
)]
class AffDashboardController extends AbstractDashboardController { ... }
The Issue:
In EasyCorp\Bundle\EasyAdminBundle\Router\AdminRouteLoader, the load() method executes:
public function load(mixed $resource, ?string $type = null): RouteCollection
{
// ...
return $this->adminRouteGenerator->generateAll();
}
Currently, there is no way to tell the loader to "Only generate routes for Dashboards found in this specific resource/path."
Expected Behavior
The route loader should respect the resource path provided in routes.yaml or allow an option to filter discovery by namespace/directory so that:
admin.site.com only contains routes belonging to AdminDashboardController.
aff.site.com only contains routes belonging to AffDashboardController.
Actual Behavior
The loader aggregates all Dashboards and CRUD controllers into a single collection, causing Admin CRUDs to be mounted onto the Affiliate Dashboard.
For example, running bin/console debug:router shows Admin password reset routes appearing under the Affiliate URL prefix (/panel):
admin_admin_reset_admin_password GET|POST /dashboard/admin/reset (Correct)
affiliate_admin_reset_admin_password GET|POST /panel/admin/reset (BUG: Admin controller leaked to Affiliate host)
Proposed Solution
Update AdminRouteLoader to respect the $resource parameter or an optional dashboard_controller configuration. This would allow for separate definitions in routes.yaml:
admin_panel_routes:
resource: 'App\Controller\Admin'
type: easyadmin.routes
affiliate_panel_routes:
resource: 'App\Controller\Aff'
type: easyadmin.routes
or filter the routes by namespace.