8000 [Routing] Use env() in route condition · symfony/symfony@2d30cf3 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2d30cf3

Browse files
committed
[Routing] Use env() in route condition
1 parent f46ab58 commit 2d30cf3

File tree

9 files changed

+160
-3
lines changed

9 files changed

+160
-3
lines changed

src/Symfony/Bundle/FrameworkBundle/Command/RouterMatchCommand.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ class RouterMatchCommand extends Command
3333
protected static $defaultName = 'router:match';
3434

3535
private $router;
36+
private $expressionLanguageProviders;
3637

37-
public function __construct(RouterInterface $router)
38+
public function __construct(RouterInterface $router, iterable $expressionLanguageProviders)
3839
{
3940
parent::__construct();
4041

4142
$this->router = $router;
43+
$this->expressionLanguageProviders = $expressionLanguageProviders;
4244
}
4345

4446
/**
@@ -87,6 +89,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int
8789
}
8890

8991
$matcher = new TraceableUrlMatcher($this->router->getRouteCollection(), $context);
92+
foreach ($this->expressionLanguageProviders as $provider) {
93+
$matcher->addExpressionLanguageProvider($provider);
94+
}
9095

9196
$traces = $matcher->getTraces($input->getArgument('path_info'));
9297

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

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

146146
<service id="console.command.router_match" class="Symfony\Bundle\FrameworkBundle\Command\RouterMatchCommand">
147147
<argument type="service" id="router" />
148+
<argument type="tagged_iterator" tag="routing.expression_language_provider"/>
148149
<tag name="console.command" command="router:match" />
149150
</service>
150151

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,17 @@
6868
<argument type="service" id="parameter_bag" on-invalid="ignore" />
6969
<argument type="service" id="logger" on-invalid="ignore" />
7070
<argument>%kernel.default_locale%</argument>
71+
<argument type="collection">
72+
<argument type="service" key="get_env">
73+
<service class="Closure">
74+
<factory class="Closure" method="fromCallable" />
75+
<argument type="collection">
76+
<argument type="service" id="service_container" />
77+
<argument>getEnv</argument>
78+
</argument>
79+
</service>
80+
</argument>
81+
</argument>
7182
<call method="setConfigCacheFactory">
7283
<argument type="service" id="config_cache_factory" />
7384
</call>
@@ -115,5 +126,10 @@
115126
<service id="Symfony\Bundle\FrameworkBundle\Controller\TemplateController" public="true">
116127
<argument type="service" id="twig" on-invalid="ignore" />
117128
</service>
129+
130+
<service id="Symfony\Component\Routing\Matcher\ExpressionLanguageProvider" public="false">
131+
<tag name="routing.expression_language_provider" />
132+
<argument type="service" id="router" />
133+
</service>
118134
</services>
119135
</container>

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI
3838
/**
3939
* @param mixed $resource The main resource to load
4040
*/
41-
public function __construct(ContainerInterface $container, $resource, array $options = [], RequestContext $context = null, ContainerInterface $parameters = null, LoggerInterface $logger = null, string $defaultLocale = null)
41+
public function __construct(ContainerInterface $container, $resource, array $options = [], RequestContext $context = null, ContainerInterface $parameters = null, LoggerInterface $logger = null, string $defaultLocale = null, array $defaultParameters = [])
4242
{
4343
$this->container = $container;
4444
$this->resource = $resource;
4545
$this->context = $context ?: new RequestContext();
46+
$this->context->addParameters($defaultParameters);
4647
$this->logger = $logger;
4748
$this->setOptions($options);
4849

src/Symfony/Component/Routing/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* deprecated `RouteCollectionBuilder` in favor of `RoutingConfigurator`.
99
* added "priority" option to annotated routes
1010
* added argument `$priority` to `RouteCollection::add()`
11+
* added `ExpressionLanguageProvider` that provides `env` function.
1112

1213
5.0.0
1314
-----
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Routing\Matcher;
13+
14+
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
15+
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
16+
use Symfony\Component\Routing\RequestContext;
17+
use Symfony\Component\Routing\RouterInterface;
18+
19+
/**
20+
* Defines some ExpressionLanguage functions.
21+
*
22+
* @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>
23+
*/
24+
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
25+
{
26+
/** @var RequestContext */
27+
private $context;
28+
29+
public function __construct(RouterInterface $router)
30+
{
31+
$this->context = $router->getContext();
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function getFunctions()
38+
{
39+
return [
40+
new ExpressionFunction(
41+
'env',
42+
function ($str, $default = 'null') {
43+
if (false === $this->context->hasParameter('get_env')) {
44+
throw new \LogicException('You cannot use function "env" as no "get_env" is not available.');
45+
}
46+
47+
return sprintf('(($context->getParameter(\'get_env\'))(%s) ?? %s)', $str, $default);
48+
},
49+
function ($arguments, $str, $default = null) {
50+
if (false === $this->context->hasParameter('get_env')) {
51+
throw new \LogicException('You cannot use function "env" as no "get_env" is not available.');
52+
}
53+
54+
return ($this->context->getParameter('get_env'))($str) ?? $default;
55+
}
56+
),
57+
];
58+
}
59+
}

src/Symfony/Component/Routing/RequestContext.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,20 @@ public function setParameters(array $parameters)
269269
return $this;
270270
}
271271

272+
/**
273+
* Adds some parameters.
274+
*
275+
* @param array $parameters The parameters
276+
*
277+
* @return $this
278+
*/
279+
public function addParameters(array $parameters)
280+
{
281+
$this->parameters = array_merge($parameters, $this->parameters);
282+
283+
return $this;
284+
}
285+
272286
/**
273287
* Gets a parameter value.
274288
*

src/Symfony/Component/Routing/Router.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,13 @@ class Router implements RouterInterface, RequestMatcherInterface
9797
/**
9898
* @param mixed $resource The main resource to load
9999
*/
100-
public function __construct(LoaderInterface $loader, $resource, array $options = [], RequestContext $context = null, LoggerInterface $logger = null, string $defaultLocale = null)
100+
public function __construct(LoaderInterface $loader, $resource, array $options = [], RequestContext $context = null, LoggerInterface $logger = null, string $defaultLocale = null, array $defaultParameters = [])
101101
{
102102
$this->loader = $loader;
103103
$this->resource = $resource;
104104
$this->logger = $logger;
105105
$this->context = $context ?: new RequestContext();
106+
$this->context->addParameters($defaultParameters);
106107
$this->setOptions($options);
107108
$this->defaultLocale = $defaultLocale;
108109
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Routing\Tests\Matcher;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
16+
use Symfony\Component\Routing\Matcher\ExpressionLanguageProvider;
17+
use Symfony\Component\Routing\RequestContext;
18+
use Symfony\Component\Routing\Router;
19+
20+
class ExpressionLanguageTest extends TestCase
21+
{
22+
private $router;
23+
24+
public function setUp(): void
25+
{
26+
$this->router = $this->getMockBuilder(Router::class)->disableOriginalConstructor()->getMock();
27+
$context = new RequestContext();
28+
$context->setParameter('get_env', static function (string $name) {
29+
return [
30+
'APP_ENV' => 'test',
31+
'PHP_VERSION' => '7.2',
32+
][$name] ?? null;
33+
});
34+
35+
$this->router->method('getContext')->willReturn($context);
36+
}
37+
38+
/**
39+
* @dataProvider provider
40+
*/
41+
public function testEnv(string $expression, $expected): void
42+
{
43+
$expressionLanguage = new ExpressionLanguage();
44+
$expressionLanguageProvider = new ExpressionLanguageProvider($this->router);
45+
$expressionLanguage->registerProvider($expressionLanguageProvider);
46+
47+
$this->assertEquals($expected, $expressionLanguage->evaluate($expression));
48+
}
49+
50+
public function provider(): array
51+
{
52+
return [
53+
['env("APP_ENV")', 'test'],
54+
['env("PHP_VERSION")', '7.2'],
55+
['env("unknown_env_variable")', null],
56+
['env("unknown_env_variable", "default")', 'default'],
57+
];
58+
}
59+
}

0 commit comments

Comments
 (0)
0