[FrameworkBundle][Routing] Private service route loaders

This commit is contained in:
Thomas Calvet 2019-07-18 08:35:24 +02:00
parent f64d3fc23e
commit 64aa2c8529
11 changed files with 177 additions and 3 deletions

View File

@ -94,6 +94,7 @@ FrameworkBundle
* The `ControllerResolver` and `DelegatingLoader` classes have been marked as `final`.
* The `controller_name_converter` and `resolve_controller_name_subscriber` services have been deprecated.
* Deprecated `routing.loader.service`, use `routing.loader.container` instead.
* Not tagging service route loaders with `routing.route_loader` has been deprecated.
HttpClient
----------

View File

@ -373,6 +373,7 @@ Routing
Instead of overwriting them, use `__serialize` and `__unserialize` as extension points which are forward compatible
with the new serialization methods in PHP 7.4.
* Removed `ServiceRouterLoader` and `ObjectRouteLoader`.
* Service route loaders must be tagged with `routing.route_loader`.
Security
--------

View File

@ -11,6 +11,7 @@ CHANGELOG
* Added support for configuring chained cache pools
* Deprecated booting the kernel before running `WebTestCase::createClient()`
* Deprecated `routing.loader.service`, use `routing.loader.container` instead.
* Not tagging service route loaders with `routing.route_loader` has been deprecated.
4.3.0
-----

View File

@ -49,6 +49,7 @@ class UnusedTagsPass implements CompilerPassInterface
'proxy',
'routing.expression_language_provider',
'routing.loader',
'routing.route_loader',
'security.expression_language_provider',
'security.remember_me_aware',
'security.voter',

View File

@ -24,6 +24,7 @@ use Symfony\Bridge\Twig\Extension\CsrfExtension;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Bundle\FrameworkBundle\Routing\AnnotatedRouteControllerLoader;
use Symfony\Bundle\FrameworkBundle\Routing\RedirectableUrlMatcher;
use Symfony\Bundle\FrameworkBundle\Routing\RouteLoaderInterface;
use Symfony\Bundle\FullStack;
use Symfony\Component\Asset\PackageInterface;
use Symfony\Component\BrowserKit\AbstractBrowser;
@ -446,6 +447,9 @@ class FrameworkExtension extends Extension
if (!$config['disallow_search_engine_index'] ?? false) {
$container->removeDefinition('disallow_search_engine_index_response_listener');
}
$container->registerForAutoconfiguration(RouteLoaderInterface::class)
->addTag('routing.route_loader');
}
/**

View File

@ -69,14 +69,20 @@ trait MicroKernelTrait
],
]);
if ($this instanceof EventSubscriberInterface) {
if (!$container->hasDefinition('kernel')) {
$container->register('kernel', static::class)
->setSynthetic(true)
->setPublic(true)
->addTag('kernel.event_subscriber')
;
}
$kernelDefinition = $container->getDefinition('kernel');
$kernelDefinition->addTag('routing.route_loader');
if ($this instanceof EventSubscriberInterface) {
$kernelDefinition->addTag('kernel.event_subscriber');
}
$this->configureContainer($container, $loader);
$container->addObjectResource($this);

View File

@ -47,7 +47,12 @@
<service id="routing.loader.container" class="Symfony\Component\Routing\Loader\ContainerLoader">
<tag name="routing.loader" />
<argument type="service" id="service_container" />
<argument type="service">
<service class="Symfony\Bundle\FrameworkBundle\Routing\LegacyRouteLoaderContainer">
<argument type="service" id="service_container" />
<argument type="tagged_locator" tag="routing.route_loader" />
</service>
</argument>
</service>
<service id="routing.loader" class="Symfony\Bundle\FrameworkBundle\Routing\DelegatingLoader" public="true">

View File

@ -0,0 +1,51 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Routing;
use Psr\Container\ContainerInterface;
/**
* @internal to be removed in Symfony 5.0
*/
class LegacyRouteLoaderContainer implements ContainerInterface
{
private $container;
private $serviceLocator;
public function __construct(ContainerInterface $container, ContainerInterface $serviceLocator)
{
$this->container = $container;
$this->serviceLocator = $serviceLocator;
}
/**
* {@inheritdoc}
*/
public function get($id)
{
if ($this->serviceLocator->has($id)) {
return $this->serviceLocator->get($id);
}
@trigger_error(sprintf('Registering the service route loader "%s" without tagging it with the "routing.route_loader" tag is deprecated since Symfony 4.4 and will be required in Symfony 5.0.', $id), E_USER_DEPRECATED);
return $this->container->get($id);
}
/**
* {@inheritdoc}
*/
public function has($id)
{
return $this->serviceLocator->has($id) || $this->container->has($id);
}
}

View File

@ -0,0 +1,19 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Routing;
/**
* Marker interface for service route loaders.
*/
interface RouteLoaderInterface
{
}

View File

@ -12,6 +12,9 @@
namespace Symfony\Bundle\FrameworkBundle\Tests\Kernel;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
use Symfony\Component\HttpFoundation\Request;
class MicroKernelTraitTest extends TestCase
@ -39,4 +42,18 @@ class MicroKernelTraitTest extends TestCase
$this->assertSame('It\'s dangerous to go alone. Take this ⚔', $response->getContent());
}
public function testRoutingRouteLoaderTagIsAdded()
{
$frameworkExtension = $this->createMock(ExtensionInterface::class);
$frameworkExtension
->expects($this->atLeastOnce())
->method('getAlias')
->willReturn('framework');
$container = new ContainerBuilder();
$container->registerExtension($frameworkExtension);
$kernel = new ConcreteMicroKernel('test', false);
$kernel->registerContainerConfiguration(new ClosureLoader($container));
$this->assertTrue($container->getDefinition('kernel')->hasTag('routing.route_loader'));
}
}

View File

@ -0,0 +1,68 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Tests\Routing;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Routing\LegacyRouteLoaderContainer;
use Symfony\Component\DependencyInjection\Container;
/**
* @group legacy
*/
class LegacyRouteLoaderContainerTest extends TestCase
{
/**
* @var ContainerInterface
*/
private $container;
/**
* @var ContainerInterface
*/
private $serviceLocator;
/**
* @var LegacyRouteLoaderContainer
*/
private $legacyRouteLoaderContainer;
/**
* {@inheritdoc}
*/
protected function setUp()
{
$this->container = new Container();
$this->container->set('foo', new \stdClass());
$this->serviceLocator = new Container();
$this->serviceLocator->set('bar', new \stdClass());
$this->legacyRouteLoaderContainer = new LegacyRouteLoaderContainer($this->container, $this->serviceLocator);
}
/**
* @expectedDeprecation Registering the service route loader "foo" without tagging it with the "routing.route_loader" tag is deprecated since Symfony 4.4 and will be required in Symfony 5.0.
*/
public function testGet()
{
$this->assertSame($this->container->get('foo'), $this->legacyRouteLoaderContainer->get('foo'));
$this->assertSame($this->serviceLocator->get('bar'), $this->legacyRouteLoaderContainer->get('bar'));
}
public function testHas()
{
$this->assertTrue($this->legacyRouteLoaderContainer->has('foo'));
$this->assertTrue($this->legacyRouteLoaderContainer->has('bar'));
$this->assertFalse($this->legacyRouteLoaderContainer->has('ccc'));
}
}