8000 feature #24738 [FrameworkBundle][Routing] Use a PSR-11 container in F… · symfony/symfony@74106c2 · GitHub
[go: up one dir, main page]

Skip to content

Commit 74106c2

Browse files
committed
feature #24738 [FrameworkBundle][Routing] Use a PSR-11 container in FrameworkBundle Router (ogizanagi)
This PR was merged into the 4.1-dev branch. Discussion ---------- [FrameworkBundle][Routing] Use a PSR-11 container in FrameworkBundle Router | Q | A | ------------- | --- | Branch? | 4.1 <!-- see comment below --> | Bug fix? | no | New feature? | yes <!-- don't forget to update src/**/CHANGELOG.md files --> | BC breaks? | no | Deprecations? | not yet <!-- don't forget to update UPGRADE-*.md files --> | Tests pass? | yes | Fixed tickets | N/A <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | N/A ~3.4 because~ it allows to make the `routing.loader` service private and add sense into implementing the `ServiceSubscriberInterface` in the `Router` by injecting a ServiceLocator instead of the DI container. Should we deprecate passing a DI `ContainerInterface` instance without providing the `$paramFetcher` argument? Move the whole `Router::resolve()` method into a dedicated `callable $paramResolver` ? Commits ------- 5a2f295 [FrameworkBundle][Routing] Use a PSR-11 container & parameter bag in FrameworkBundle Router
2 parents 2677109 + 5a2f295 commit 74106c2

File tree

5 files changed

+282
-14
lines changed

5 files changed

+282
-14
lines changed

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Allowed to pass an optional `LoggerInterface $logger` instance to the `Router`
88
* Added a new `parameter_bag` service with related autowiring aliases to access parameters as-a-service
9+
* Allowed the `Router` to work with any PSR-11 container
910

1011
4.0.0
1112
-----

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,13 @@ private function registerRouterConfiguration(array $config, ContainerBuilder $co
619619

620620
$loader->load('routing.xml');
621621

622+
if (!interface_exists(ContainerBagInterface::class)) {
623+
$container->getDefinition('router.default')
624+
->replaceArgument(0, new Reference('service_container'))
625+
->clearTag('container.service_subscriber')
626+
;
627+
}
628+
622629
$container->setParameter('router.resource', $config['resource']);
623630
$container->setParameter('router.cache_class_prefix', $container->getParameter('kernel.container_class'));
624631
$router = $container->findDefinition('router.default');

src/Symfony/Bundle/FrameworkBundle/Resources/config/routing.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@
5252

5353
<service id="router.default" class="Symfony\Bundle\FrameworkBundle\Routing\Router">
5454
<tag name="monolog.logger" channel="router" />
55-
<argument type="service" id="service_container" />
55+
<tag name="container.service_subscriber" id="routing.loader" />
56+
<argument type="service" id="Psr\Container\ContainerInterface" />
5657
<argument>%router.resource%</argument>
5758
<argument type="collection">
5859
<argument key="cache_dir">%kernel.cache_dir%</argument>
@@ -67,6 +68,7 @@
6768
<argument key="matcher_cache_class">%router.cache_class_prefix%UrlMatcher</argument>
6869
</argument>
6970
<argument type="service" id="router.request_context" on-invalid="ignore" />
71+
<argument type="service" id="parameter_bag" on-invalid="ignore" />
7072
<argument type="service" id="logger" on-invalid="ignore" />
7173
<call method="setConfigCacheFactory">
7274
<argument type="service" id="config_cache_factory" />

src/Symfony/Bundle/FrameworkBundle/Routing/Router.php

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Routing;
1313

14+
use Psr\Container\ContainerInterface;
1415
use Psr\Log\LoggerInterface;
1516
use Symfony\Component\Config\Loader\LoaderInterface;
1617
use Symfony\Component\DependencyInjection\Config\ContainerParametersResource;
18+
use Symfony\Component\DependencyInjection\ContainerInterface as SymfonyContainerInterface;
1719
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
1820
use Symfony\Component\Routing\Router as BaseRouter;
1921
use Symfony\Component\Routing\RequestContext;
20-
use Symfony\Component\DependencyInjection\ContainerInterface;
2122
use Symfony\Component\Routing\RouteCollection;
2223
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
2324
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
@@ -32,22 +33,31 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI
3233
{
3334
private $container;
3435
private $collectedParameters = array();
36+
private $paramFetcher;
3537

3638
/**
37-
* @param ContainerInterface $container A ContainerInterface instance
38-
* @param mixed $resource The main resource to load
39-
* @param array $options An array of options
40-
* @param RequestContext $context The context
41-
* @param LoggerInterface|null $logger
39+
* @param ContainerInterface $container A ContainerInterface instance
40+
* @param mixed $resource The main resource to load
41+
* @param array $options An array of options
42+
* @param RequestContext $context The context
43+
* @param ContainerInterface|null $parameters A ContainerInterface instance allowing to fetch parameters
44+
* @param LoggerInterface|null $logger
4245
*/
43-
public function __construct(ContainerInterface $container, $resource, array $options = array(), RequestContext $context = null, LoggerInterface $logger = null)
46+
public function __construct(ContainerInterface $container, $resource, array $options = array(), RequestContext $context = null, ContainerInterface $parameters = null, LoggerInterface $logger = null)
4447
{
4548
$this->container = $container;
46-
4749
$this->resource = $resource;
4850
$this->context = $context ?: new RequestContext();
4951
$this->logger = $logger;
5052
$this->setOptions($options);
53+
54+
if ($parameters) {
55+
$this->paramFetcher = array($parameters, 'get');
56+
} elseif ($container instanceof SymfonyContainerInterface) {
57+
$this->paramFetcher = array($container, 'getParameter');
58+
} else {
59+
throw new \LogicException(sprintf('You should either pass a "%s" instance or provide the $parameters argument of the "%s" method.', SymfonyContainerInterface::class, __METHOD__));
60+
}
5161
}
5262

5363
/**
@@ -142,9 +152,7 @@ private function resolve($value)
142152
return $value;
143153
}
144154

145-
$container = $this->container;
146-
147-
$escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($container, $value) {
155+
$escapedValue = preg_replace_callback('/%%|%([^%\s]++)%/', function ($match) use ($value) {
148156
// skip %%
149157
if (!isset($match[1])) {
150158
return '%%';
@@ -154,7 +162,7 @@ private function resolve($value)
154162
throw new RuntimeException(sprintf('Using "%%%s%%" is not allowed in routing configuration.', $match[1]));
155163
}
156164

157-
$resolved = $container->getParameter($match[1]);
165+
$resolved = ($this->paramFetcher)($match[1]);
158166

159167
if (is_string($resolved) || is_numeric($resolved)) {
160168
$this->collectedParameters[$match[1]] = $resolved;

0 commit comments

Comments
 (0)
0