diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 4e30aa5394084..5e29298a6a3ff 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -8,9 +8,9 @@ CHANGELOG * Deprecate the `AdapterInterface` autowiring alias, use `CacheItemPoolInterface` instead * Deprecate the public `profiler` service to private * Deprecate `get()`, `has()`, `getDoctrine()`, and `dispatchMessage()` in `AbstractController`, use method/constructor injection instead - * Add `MicroKernelTrait::getBundlesPath` method to get bundles config path * Deprecate the `cache.adapter.doctrine` service - * Add support for resetting container services after each messenger message. + * Add support for resetting container services after each messenger message + * Add `configureContainer()`, `configureRoutes()`, `getConfigDir()` and `getBundlesPath()` to `MicroKernelTrait` 5.3 --- diff --git a/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php b/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php index 7d0b54652b273..c25f90d63c9ca 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php @@ -27,41 +27,79 @@ * * @author Ryan Weaver * @author Fabien Potencier - * - * @method void configureRoutes(RoutingConfigurator $routes) - * @method void configureContainer(ContainerConfigurator $container) */ trait MicroKernelTrait { - /** - * Adds or imports routes into your application. - * - * $routes->import($this->getProjectDir().'/config/*.{yaml,php}'); - * $routes - * ->add('admin_dashboard', '/admin') - * ->controller('App\Controller\AdminController::dashboard') - * ; - */ - //abstract protected function configureRoutes(RoutingConfigurator $routes): void; - /** * Configures the container. * * You can register extensions: * - * $c->extension('framework', [ + * $container->extension('framework', [ * 'secret' => '%secret%' * ]); * * Or services: * - * $c->services()->set('halloween', 'FooBundle\HalloweenProvider'); + * $container->services()->set('halloween', 'FooBundle\HalloweenProvider'); * * Or parameters: * - * $c->parameters()->set('halloween', 'lot of fun'); + * $container->parameters()->set('halloween', 'lot of fun'); */ - //abstract protected function configureContainer(ContainerConfigurator $container): void; + private function configureContainer(ContainerConfigurator $container, LoaderInterface $loader, ContainerBuilder $builder): void + { + $configDir = $this->getConfigDir(); + + $container->import($configDir.'/{packages}/*.yaml'); + $container->import($configDir.'/{packages}/'.$this->environment.'/*.yaml'); + + if (is_file($configDir.'/services.yaml')) { + $container->import($configDir.'/services.yaml'); + $container->import($configDir.'/{services}_'.$this->environment.'.yaml'); + } else { + $container->import($configDir.'/{services}.php'); + } + } + + /** + * Adds or imports routes into your application. + * + * $routes->import($this->getConfigDir().'/*.{yaml,php}'); + * $routes + * ->add('admin_dashboard', '/admin') + * ->controller('App\Controller\AdminController::dashboard') + * ; + */ + private function configureRoutes(RoutingConfigurator $routes): void + { + $configDir = $this->getConfigDir(); + + $routes->import($configDir.'/{routes}/'.$this->environment.'/*.yaml'); + $routes->import($configDir.'/{routes}/*.yaml'); + + if (is_file($configDir.'/routes.yaml')) { + $routes->import($configDir.'/routes.yaml'); + } else { + $routes->import($configDir.'/{routes}.php'); + } + } + + /** + * Gets the path to the configuration directory. + */ + private function getConfigDir(): string + { + return $this->getProjectDir().'/config'; + } + + /** + * Gets the path to the bundles configuration file. + */ + private function getBundlesPath(): string + { + return $this->getConfigDir().'/bundles.php'; + } /** * {@inheritdoc} @@ -126,23 +164,18 @@ public function registerContainerConfiguration(LoaderInterface $loader) $container->addObjectResource($this); $container->fileExists($this->getBundlesPath()); - try { - $configureContainer = new \ReflectionMethod($this, 'configureContainer'); - } catch (\ReflectionException $e) { - throw new \LogicException(sprintf('"%s" uses "%s", but does not implement the required method "protected function configureContainer(ContainerConfigurator $container): void".', get_debug_type($this), MicroKernelTrait::class), 0, $e); - } - + $configureContainer = new \ReflectionMethod($this, 'configureContainer'); $configuratorClass = $configureContainer->getNumberOfParameters() > 0 && ($type = $configureContainer->getParameters()[0]->getType()) instanceof \ReflectionNamedType && !$type->isBuiltin() ? $type->getName() : null; if ($configuratorClass && !is_a(ContainerConfigurator::class, $configuratorClass, true)) { - $this->configureContainer($container, $loader); + $configureContainer->getClosure($this)($container, $loader); return; } - // the user has opted into using the ContainerConfigurator + $file = (new \ReflectionObject($this))->getFileName(); /* @var ContainerPhpFileLoader $kernelLoader */ - $kernelLoader = $loader->getResolver()->resolve($file = $configureContainer->getFileName()); + $kernelLoader = $loader->getResolver()->resolve($file); $kernelLoader->setCurrentDir(\dirname($file)); $instanceof = &\Closure::bind(function &() { return $this->instanceof; }, $kernelLoader, $kernelLoader)(); @@ -152,7 +185,7 @@ public function registerContainerConfiguration(LoaderInterface $loader) }; try { - $this->configureContainer(new ContainerConfigurator($container, $kernelLoader, $instanceof, $file, $file, $this->getEnvironment()), $loader); + $configureContainer->getClosure($this)(new ContainerConfigurator($container, $kernelLoader, $instanceof, $file, $file, $this->getEnvironment()), $loader, $container); } finally { $instanceof = []; $kernelLoader->registerAliasesForSinglyImplementedInterfaces(); @@ -174,12 +207,7 @@ public function loadRoutes(LoaderInterface $loader): RouteCollection $kernelLoader->setCurrentDir(\dirname($file)); $collection = new RouteCollection(); - try { - $configureRoutes = new \ReflectionMethod($this, 'configureRoutes'); - } catch (\ReflectionException $e) { - throw new \LogicException(sprintf('"%s" uses "%s", but does not implement the required method "protected function configureRoutes(RoutingConfigurator $routes): void".', get_debug_type($this), MicroKernelTrait::class), 0, $e); - } - + $configureRoutes = new \ReflectionMethod($this, 'configureRoutes'); $configuratorClass = $configureRoutes->getNumberOfParameters() > 0 && ($type = $configureRoutes->getParameters()[0]->getType()) instanceof \ReflectionNamedType && !$type->isBuiltin() ? $type->getName() : null; if ($configuratorClass && !is_a(RoutingConfigurator::class, $configuratorClass, true)) { @@ -191,7 +219,7 @@ public function loadRoutes(LoaderInterface $loader): RouteCollection return $routes->build(); } - $this->configureRoutes(new RoutingConfigurator($collection, $kernelLoader, $file, $file, $this->getEnvironment())); + $configureRoutes->getClosure($this)(new RoutingConfigurator($collection, $kernelLoader, $file, $file, $this->getEnvironment())); foreach ($collection as $route) { $controller = $route->getDefault('_controller'); @@ -203,12 +231,4 @@ public function loadRoutes(LoaderInterface $loader): RouteCollection return $collection; } - - /** - * Gets the path to the bundles configuration file. - */ - private function getBundlesPath(): string - { - return $this->getProjectDir().'/config/bundles.php'; - } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelTraitTest.php index 8bce44e96fb34..d47ca5a822139 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelTraitTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelTraitTest.php @@ -126,38 +126,6 @@ protected function configureRoutes(RoutingConfigurator $routes): void $this->assertSame('Hello World!', $response->getContent()); } - - public function testMissingConfigureContainer() - { - $kernel = new class('missing_configure_container') extends MinimalKernel { - protected function configureRoutes(RoutingConfigurator $routes): void - { - } - }; - - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('"Symfony\Bundle\FrameworkBundle\Tests\Kernel\MinimalKernel@anonymous" uses "Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait", but does not implement the required method "protected function configureContainer(ContainerConfigurator $container): void".'); - - $kernel->boot(); - } - - public function testMissingConfigureRoutes() - { - $kernel = new class('missing_configure_routes') extends MinimalKernel { - protected function configureContainer(ContainerConfigurator $c): void - { - $c->extension('framework', [ - 'router' => ['utf8' => true], - ]); - } - }; - - $this->expectException(\LogicException::class); - $this->expectExceptionMessage('"Symfony\Bundle\FrameworkBundle\Tests\Kernel\MinimalKernel@anonymous" uses "Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait", but does not implement the required method "protected function configureRoutes(RoutingConfigurator $routes): void".'); - - $request = Request::create('/'); - $kernel->handle($request, HttpKernelInterface::MAIN_REQUEST, false); - } } abstract class MinimalKernel extends Kernel