From cf45eeccfc48bee212ab014f68e9807ba02501ec Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 7 Dec 2019 16:49:34 +0100 Subject: [PATCH] [FrameworkBundle] Allow using a ContainerConfigurator in MicroKernelTrait::configureContainer() --- UPGRADE-5.1.md | 3 +- UPGRADE-6.0.md | 3 +- .../Bundle/FrameworkBundle/CHANGELOG.md | 4 +- .../Kernel/MicroKernelTrait.php | 78 +++++++++++-------- .../Tests/Kernel/ConcreteMicroKernel.php | 2 +- .../Tests/Kernel/MicroKernelTraitTest.php | 12 --- .../Kernel/MicroKernelWithConfigureRoutes.php | 74 ------------------ .../Bundle/FrameworkBundle/composer.json | 2 +- src/Symfony/Component/Routing/CHANGELOG.md | 1 - .../Configurator/RoutingConfigurator.php | 40 ++-------- .../Routing/RouteCollectionBuilder.php | 3 + 11 files changed, 61 insertions(+), 161 deletions(-) delete mode 100644 src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelWithConfigureRoutes.php diff --git a/UPGRADE-5.1.md b/UPGRADE-5.1.md index 128cc50613..ea110ecc66 100644 --- a/UPGRADE-5.1.md +++ b/UPGRADE-5.1.md @@ -4,8 +4,7 @@ UPGRADE FROM 5.0 to 5.1 FrameworkBundle --------------- - * Marked `MicroKernelTrait::configureRoutes()` as `@internal` and `@final`. - * Deprecated not overriding `MicroKernelTrait::configureRouting()`. + * Deprecated passing a `RouteCollectionBuiler` to `MicroKernelTrait::configureRoutes()`, type-hint `RoutingConfigurator` instead HttpFoundation -------------- diff --git a/UPGRADE-6.0.md b/UPGRADE-6.0.md index c279d8bfe6..1b97c43d9b 100644 --- a/UPGRADE-6.0.md +++ b/UPGRADE-6.0.md @@ -4,8 +4,7 @@ UPGRADE FROM 5.x to 6.0 FrameworkBundle --------------- - * Removed `MicroKernelTrait::configureRoutes()`. - * Made `MicroKernelTrait::configureRouting()` abstract. + * `MicroKernelTrait::configureRoutes()` is now always called with a `RoutingConfigurator` HttpFoundation -------------- diff --git a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md index 44107bcd6c..7f1b87dc46 100644 --- a/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md +++ b/src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md @@ -4,10 +4,10 @@ CHANGELOG 5.1.0 ----- - * Marked `MicroKernelTrait::configureRoutes()` as `@internal` and `@final`. - * Deprecated not overriding `MicroKernelTrait::configureRouting()`. + * Made `MicroKernelTrait::configureContainer()` compatible with `ContainerConfigurator` * Added a new `mailer.message_bus` option to configure or disable the message bus to use to send mails. * Added flex-compatible default implementations for `MicroKernelTrait::registerBundles()` and `getProjectDir()` + * Deprecated passing a `RouteCollectionBuiler` to `MicroKernelTrait::configureRoutes()`, type-hint `RoutingConfigurator` instead 5.0.0 ----- diff --git a/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php b/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php index f462fb6ace..f4ac7e4b16 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php +++ b/src/Symfony/Bundle/FrameworkBundle/Kernel/MicroKernelTrait.php @@ -13,8 +13,10 @@ namespace Symfony\Bundle\FrameworkBundle\Kernel; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; +use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\RouteCollectionBuilder; /** @@ -25,20 +27,6 @@ use Symfony\Component\Routing\RouteCollectionBuilder; */ trait MicroKernelTrait { - /** - * Add or import routes into your application. - * - * $routes->import('config/routing.yml'); - * $routes->add('/admin', 'App\Controller\AdminController::dashboard', 'admin_dashboard'); - * - * @final since Symfony 5.1, override configureRouting() instead - * - * @internal since Symfony 5.1, use configureRouting() instead - */ - protected function configureRoutes(RouteCollectionBuilder $routes) - { - } - /** * Adds or imports routes into your application. * @@ -48,29 +36,26 @@ trait MicroKernelTrait * ->controller('App\Controller\AdminController::dashboard') * ; */ - protected function configureRouting(RoutingConfigurator $routes): void - { - @trigger_error(sprintf('Not overriding the "%s()" method is deprecated since Symfony 5.1 and will trigger a fatal error in 6.0.', __METHOD__), E_USER_DEPRECATED); - } + abstract protected function configureRoutes(RoutingConfigurator $routes); /** * Configures the container. * * You can register extensions: * - * $c->loadFromExtension('framework', [ + * $c->extension('framework', [ * 'secret' => '%secret%' * ]); * * Or services: * - * $c->register('halloween', 'FooBundle\HalloweenProvider'); + * $c->services()->set('halloween', 'FooBundle\HalloweenProvider'); * * Or parameters: * - * $c->setParameter('halloween', 'lot of fun'); + * $c->parameters()->set('halloween', 'lot of fun'); */ - abstract protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader); + abstract protected function configureContainer(ContainerConfigurator $c); /** * {@inheritdoc} @@ -120,9 +105,31 @@ trait MicroKernelTrait $kernelDefinition->addTag('kernel.event_subscriber'); } - $this->configureContainer($container, $loader); $container->addObjectResource($this); $container->fileExists($this->getProjectDir().'/config/bundles.php'); + + try { + $this->configureContainer($container, $loader); + + return; + } catch (\TypeError $e) { + $file = $e->getFile(); + + if (0 !== strpos($e->getMessage(), sprintf('Argument 1 passed to %s::configureContainer() must be an instance of %s,', static::class, ContainerConfigurator::class))) { + throw $e; + } + } + + $kernelLoader = $loader->getResolver()->resolve($file); + $kernelLoader->setCurrentDir(\dirname($file)); + $instanceof = &\Closure::bind(function &() { return $this->instanceof; }, $kernelLoader, $kernelLoader)(); + + try { + $this->configureContainer(new ContainerConfigurator($container, $kernelLoader, $instanceof, $file, $file), $loader); + } finally { + $instanceof = []; + $kernelLoader->registerAliasesForSinglyImplementedInterfaces(); + } }); } @@ -131,17 +138,26 @@ trait MicroKernelTrait */ public function loadRoutes(LoaderInterface $loader) { - $routes = new RouteCollectionBuilder($loader); - $this->configureRoutes($routes); - $collection = $routes->build(); + $file = (new \ReflectionObject($this))->getFileName(); + $kernelLoader = $loader->getResolver()->resolve($file); + $kernelLoader->setCurrentDir(\dirname($file)); + $collection = new RouteCollection(); - if (0 !== \count($collection)) { - @trigger_error(sprintf('Adding routes via the "%s:configureRoutes()" method is deprecated since Symfony 5.1 and will have no effect in 6.0; use "configureRouting()" instead.', self::class), E_USER_DEPRECATED); + try { + $this->configureRoutes(new RoutingConfigurator($collection, $kernelLoader, $file, $file)); + + return $collection; + } catch (\TypeError $e) { + if (0 !== strpos($e->getMessage(), sprintf('Argument 1 passed to %s::configureRoutes() must be an instance of %s,', static::class, RouteCollectionBuilder::class))) { + throw $e; + } } - $file = (new \ReflectionObject($this))->getFileName(); - $this->configureRouting(new RoutingConfigurator($collection, $loader, null, $file)); + @trigger_error(sprintf('Using type "%s" for argument 1 of method "%s:configureRoutes()" is deprecated since Symfony 5.1, use "%s" instead.', RouteCollectionBuilder::class, self::class, RoutingConfigurator::class), E_USER_DEPRECATED); - return $collection; + $routes = new RouteCollectionBuilder($loader); + $this->configureRoutes($routes); + + return $routes->build(); } } diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php index 3759b32973..c5da350a27 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php @@ -80,7 +80,7 @@ class ConcreteMicroKernel extends Kernel implements EventSubscriberInterface $fs->remove($this->cacheDir); } - protected function configureRouting(RoutingConfigurator $routes): void + protected function configureRoutes(RoutingConfigurator $routes): void { $routes->add('halloween', '/')->controller('kernel::halloweenAction'); $routes->add('danger', '/danger')->controller('kernel::dangerousAction'); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelTraitTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelTraitTest.php index a66ebeffdc..dd909ea6fc 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelTraitTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelTraitTest.php @@ -19,18 +19,6 @@ use Symfony\Component\HttpFoundation\Request; class MicroKernelTraitTest extends TestCase { - /** - * @group legacy - * @expectedDeprecation Adding routes via the "Symfony\Bundle\FrameworkBundle\Tests\Kernel\MicroKernelWithConfigureRoutes:configureRoutes()" method is deprecated since Symfony 5.1 and will have no effect in 6.0; use "configureRouting()" instead. - * @expectedDeprecation Not overriding the "Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait::configureRouting()" method is deprecated since Symfony 5.1 and will trigger a fatal error in 6.0. - */ - public function testConfigureRoutingDeprecated() - { - $kernel = new MicroKernelWithConfigureRoutes('test', false); - $kernel->boot(); - $kernel->handle(Request::create('/')); - } - public function test() { $kernel = new ConcreteMicroKernel('test', false); diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelWithConfigureRoutes.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelWithConfigureRoutes.php deleted file mode 100644 index b57f301ee6..0000000000 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/MicroKernelWithConfigureRoutes.php +++ /dev/null @@ -1,74 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Bundle\FrameworkBundle\Tests\Kernel; - -use Psr\Log\NullLogger; -use Symfony\Bundle\FrameworkBundle\FrameworkBundle; -use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait; -use Symfony\Component\Config\Loader\LoaderInterface; -use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\Filesystem\Filesystem; -use Symfony\Component\HttpKernel\Kernel; -use Symfony\Component\Routing\RouteCollectionBuilder; - -class MicroKernelWithConfigureRoutes extends Kernel -{ - use MicroKernelTrait; - - private $cacheDir; - - public function registerBundles(): iterable - { - return [ - new FrameworkBundle(), - ]; - } - - public function getCacheDir(): string - { - return $this->cacheDir = sys_get_temp_dir().'/sf_micro_kernel_with_configured_routes'; - } - - public function getLogDir(): string - { - return $this->cacheDir; - } - - public function __sleep(): array - { - throw new \BadMethodCallException('Cannot serialize '.__CLASS__); - } - - public function __wakeup() - { - throw new \BadMethodCallException('Cannot unserialize '.__CLASS__); - } - - public function __destruct() - { - $fs = new Filesystem(); - $fs->remove($this->cacheDir); - } - - protected function configureRoutes(RouteCollectionBuilder $routes) - { - $routes->add('/', 'kernel::halloweenAction'); - } - - protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader) - { - $c->register('logger', NullLogger::class); - $c->loadFromExtension('framework', [ - 'secret' => '$ecret', - ]); - } -} diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index e244b682d7..46183969a8 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -27,7 +27,7 @@ "symfony/polyfill-mbstring": "~1.0", "symfony/filesystem": "^4.4|^5.0", "symfony/finder": "^4.4|^5.0", - "symfony/routing": "^5.1" + "symfony/routing": "^5.0" }, "require-dev": { "doctrine/annotations": "~1.7", diff --git a/src/Symfony/Component/Routing/CHANGELOG.md b/src/Symfony/Component/Routing/CHANGELOG.md index bf52e1c355..0ed447d6fe 100644 --- a/src/Symfony/Component/Routing/CHANGELOG.md +++ b/src/Symfony/Component/Routing/CHANGELOG.md @@ -5,7 +5,6 @@ CHANGELOG ----- * Deprecated `RouteCollectionBuilder` in favor of `RoutingConfigurator`. - * Added support for a generic loader to `RoutingConfigurator`. 5.0.0 ----- diff --git a/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php b/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php index 737320bd2e..8ed06f307c 100644 --- a/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php +++ b/src/Symfony/Component/Routing/Loader/Configurator/RoutingConfigurator.php @@ -11,9 +11,7 @@ namespace Symfony\Component\Routing\Loader\Configurator; -use Symfony\Component\Config\Exception\LoaderLoadException; -use Symfony\Component\Config\Loader\FileLoader; -use Symfony\Component\Config\Loader\LoaderInterface; +use Symfony\Component\Routing\Loader\PhpFileLoader; use Symfony\Component\Routing\RouteCollection; /** @@ -27,7 +25,7 @@ class RoutingConfigurator private $path; private $file; - public function __construct(RouteCollection $collection, LoaderInterface $loader, ?string $path, string $file) + public function __construct(RouteCollection $collection, PhpFileLoader $loader, string $path, string $file) { $this->collection = $collection; $this->loader = $loader; @@ -40,7 +38,9 @@ class RoutingConfigurator */ final public function import($resource, string $type = null, bool $ignoreErrors = false, $exclude = null): ImportConfigurator { - $imported = $this->load($resource, $type, $ignoreErrors, $exclude) ?: []; + $this->loader->setCurrentDir(\dirname($this->path)); + + $imported = $this->loader->import($resource, $type, $ignoreErrors, $this->file, $exclude) ?: []; if (!\is_array($imported)) { return new ImportConfigurator($this->collection, $imported); } @@ -57,34 +57,4 @@ class RoutingConfigurator { return new CollectionConfigurator($this->collection, $name); } - - /** - * @param string|string[]|null $exclude - * - * @return RouteCollection|RouteCollection[]|null - */ - private function load($resource, ?string $type, bool $ignoreErrors, $exclude) - { - $loader = $this->loader; - - if (!$loader->supports($resource, $type)) { - if (null === $resolver = $loader->getResolver()) { - throw new LoaderLoadException($resource, $this->file, null, null, $type); - } - - if (false === $loader = $resolver->resolve($resource, $type)) { - throw new LoaderLoadException($resource, $this->file, null, null, $type); - } - } - - if (!$loader instanceof FileLoader) { - return $loader->load($resource, $type); - } - - if (null !== $this->path) { - $this->loader->setCurrentDir(\dirname($this->path)); - } - - return $this->loader->import($resource, $type, $ignoreErrors, $this->file, $exclude); - } } diff --git a/src/Symfony/Component/Routing/RouteCollectionBuilder.php b/src/Symfony/Component/Routing/RouteCollectionBuilder.php index 4bbcf795a1..2cf5f23ae1 100644 --- a/src/Symfony/Component/Routing/RouteCollectionBuilder.php +++ b/src/Symfony/Component/Routing/RouteCollectionBuilder.php @@ -14,6 +14,9 @@ namespace Symfony\Component\Routing; use Symfony\Component\Config\Exception\LoaderLoadException; use Symfony\Component\Config\Loader\LoaderInterface; use Symfony\Component\Config\Resource\ResourceInterface; +use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; + +@trigger_error(sprintf('The "%s" class is deprecated since Symfony 5.1, use "%s" instead.', RouteCollectionBuilder::class, RoutingConfigurator::class), E_USER_DEPRECATED); /** * Helps add and import routes into a RouteCollection.