diff --git a/config/services.php b/config/services.php index 63358166bf..edea0245aa 100644 --- a/config/services.php +++ b/config/services.php @@ -211,8 +211,8 @@ ->tag('cache.pool') ->set(AdminRouteGenerator::class) - ->arg(0, tagged_iterator(EasyAdminExtension::TAG_DASHBOARD_CONTROLLER)) - ->arg(1, tagged_iterator(EasyAdminExtension::TAG_CRUD_CONTROLLER)) + ->arg(0, abstract_arg(sprintf('class list of %s tag', EasyAdminExtension::TAG_DASHBOARD_CONTROLLER))) + ->arg(1, abstract_arg(sprintf('class list of %s tag', EasyAdminExtension::TAG_CRUD_CONTROLLER))) ->arg(2, service('cache.easyadmin')) ->arg(3, service('filesystem')) ->arg(4, '%kernel.build_dir%') diff --git a/src/DependencyInjection/AdminRoutePass.php b/src/DependencyInjection/AdminRoutePass.php new file mode 100644 index 0000000000..2134e2d71d --- /dev/null +++ b/src/DependencyInjection/AdminRoutePass.php @@ -0,0 +1,35 @@ + + */ +class AdminRoutePass implements CompilerPassInterface +{ + public function process(ContainerBuilder $container): void + { + $dashboardControllersFqcn = array_map( + static function ($serviceId) use ($container) { + return $container->getDefinition($serviceId)->getClass(); + }, + array_keys($container->findTaggedServiceIds(EasyAdminExtension::TAG_DASHBOARD_CONTROLLER, true)) + ); + + $crudControllersFqcn = array_map( + static function ($serviceId) use ($container) { + return $container->getDefinition($serviceId)->getClass(); + }, + array_keys($container->findTaggedServiceIds(EasyAdminExtension::TAG_CRUD_CONTROLLER, true)) + ); + + $container->getDefinition(AdminRouteGenerator::class) + ->setArgument(0, $dashboardControllersFqcn) + ->setArgument(1, $crudControllersFqcn) + ; + } +} diff --git a/src/EasyAdminBundle.php b/src/EasyAdminBundle.php index 49c267ab36..3fa8f3dd48 100644 --- a/src/EasyAdminBundle.php +++ b/src/EasyAdminBundle.php @@ -2,6 +2,7 @@ namespace EasyCorp\Bundle\EasyAdminBundle; +use EasyCorp\Bundle\EasyAdminBundle\DependencyInjection\AdminRoutePass; use EasyCorp\Bundle\EasyAdminBundle\DependencyInjection\CreateControllerRegistriesPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\HttpKernel\Bundle\Bundle; @@ -16,6 +17,7 @@ class EasyAdminBundle extends Bundle public function build(ContainerBuilder $container): void { $container->addCompilerPass(new CreateControllerRegistriesPass()); + $container->addCompilerPass(new AdminRoutePass()); } public function getPath(): string diff --git a/src/Factory/ControllerFactory.php b/src/Factory/ControllerFactory.php index ddf477fe6c..a85bce6fbf 100644 --- a/src/Factory/ControllerFactory.php +++ b/src/Factory/ControllerFactory.php @@ -54,11 +54,7 @@ private function getController(string $controllerInterface, ?string $controllerF try { $controllerCallable = $this->controllerResolver->getController($newRequest); } catch (\InvalidArgumentException $e) { - $controllerCallable = false; - } - - if (false === $controllerCallable) { - throw new NotFoundHttpException(sprintf('Unable to find the controller "%s::%s".', $controllerFqcn, $controllerAction)); + throw new NotFoundHttpException(sprintf('Unable to find the controller "%s::%s".', $controllerFqcn, $controllerAction), $e); } if (!\is_array($controllerCallable)) { diff --git a/src/Router/AdminRouteGenerator.php b/src/Router/AdminRouteGenerator.php index 5bb2f85275..89356f8397 100644 --- a/src/Router/AdminRouteGenerator.php +++ b/src/Router/AdminRouteGenerator.php @@ -63,8 +63,8 @@ final class AdminRouteGenerator implements AdminRouteGeneratorInterface private ?bool $applicationUsesPrettyUrls = null; public function __construct( - private iterable $dashboardControllers, - private iterable $crudControllers, + private array $dashboardControllersFqcn, + private array $crudControllersFqcn, private CacheItemPoolInterface $cache, private Filesystem $filesystem, private string $buildDir, @@ -100,8 +100,7 @@ public function findRouteName(?string $dashboardFqcn = null, ?string $crudContro $adminRoutes = $this->cache->getItem(self::CACHE_KEY_FQCN_TO_ROUTE)->get(); if (null === $dashboardFqcn) { - $dashboardControllers = iterator_to_array($this->dashboardControllers); - $dashboardFqcn = $dashboardControllers[array_key_first($dashboardControllers)]::class; + $dashboardFqcn = reset($this->dashboardControllersFqcn); } return $adminRoutes[$dashboardFqcn][$crudControllerFqcn ?? ''][$actionName ?? ''] ?? null; @@ -117,8 +116,7 @@ private function generateAdminRoutes(): array /** @var array $addedRouteNames Temporary cache that stores the route names to ensure that we don't add duplicated admin routes */ $addedRouteNames = []; - foreach ($this->dashboardControllers as $dashboardController) { - $dashboardFqcn = $dashboardController::class; + foreach ($this->dashboardControllersFqcn as $dashboardFqcn) { [$allowedCrudControllers, $deniedCrudControllers] = $this->getAllowedAndDeniedControllers($dashboardFqcn); $defaultRoutesConfig = $this->getDefaultRoutesConfig($dashboardFqcn); $dashboardRouteConfig = $this->getDashboardsRouteConfig()[$dashboardFqcn]; @@ -130,9 +128,7 @@ private function generateAdminRoutes(): array } // then, create the routes of the CRUD controllers associated with the dashboard - foreach ($this->crudControllers as $crudController) { - $crudControllerFqcn = $crudController::class; - + foreach ($this->crudControllersFqcn as $crudControllerFqcn) { if (null !== $allowedCrudControllers && !\in_array($crudControllerFqcn, $allowedCrudControllers, true)) { continue; } @@ -231,8 +227,8 @@ private function getDashboardsRouteConfig(): array { $config = []; - foreach ($this->dashboardControllers as $dashboardController) { - $reflectionClass = new \ReflectionClass($dashboardController); + foreach ($this->dashboardControllersFqcn as $dashboardControllerFqcn) { + $reflectionClass = new \ReflectionClass($dashboardControllerFqcn); // first, check if the dashboard uses the #[AdminDashboard] attribute to define its route configuration; // this is the recommended way for modern EasyAdmin applications diff --git a/tests/Router/AdminRouteGeneratorTest.php b/tests/Router/AdminRouteGeneratorTest.php index 25de3702da..d024de50a4 100644 --- a/tests/Router/AdminRouteGeneratorTest.php +++ b/tests/Router/AdminRouteGeneratorTest.php @@ -10,7 +10,6 @@ use Psr\Cache\CacheItemPoolInterface; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\Cache\CacheItem; -use Symfony\Component\DependencyInjection\Argument\RewindableGenerator; use Symfony\Component\Filesystem\Filesystem; class AdminRouteGeneratorTest extends WebTestCase @@ -52,13 +51,13 @@ public function testFindRoute(?string $dashboardControllerFqcn, ?string $crudCon return $item; }); - $dashboardControllers = new RewindableGenerator(function () { - yield DashboardController::class => new DashboardController(); - yield SecondDashboardController::class => new SecondDashboardController(); - }, 2); + $dashboardControllersFqcn = [ + DashboardController::class, + SecondDashboardController::class, + ]; $adminRouteGenerator = new AdminRouteGenerator( - $dashboardControllers, + $dashboardControllersFqcn, [], $cacheMock, new Filesystem(),