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

Skip to content

Commit a40e319

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

File tree

8 files changed

+145
-3
lines changed

8 files changed

+145
-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: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,19 @@
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="collection" key="functions">
73+
<argument type="service" key="env">
74+
<service class="Closure">
75+
<factory class="Closure" method="fromCallable" />
76+
<argument type="collection">
77+
<argument type="service" id="service_container" />
78+
<argument>getEnv</argument>
79+
</argument>
80+
</service>
81+
</argument>
82+
</argument>
83+
</argument>
7184
<call method="setConfigCacheFactory">
7285
<argument type="service" id="config_cache_factory" />
7386
</call>
@@ -115,5 +128,10 @@
115128
<service id="Symfony\Bundle\FrameworkBundle\Controller\TemplateController" public="true">
116129
<argument type="service" id="twig" on-invalid="ignore" />
117130
</service>
131+
132+
<service id="Symfony\Component\Routing\Matcher\ExpressionLanguageProvider">
133+
<tag name="routing.expression_language_provider" />
134+
<argument type="service" id="router" />
135+
</service>
118136
</services>
119137
</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->setParameters($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`
1112

1213
5.0.0
1314
-----
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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\RequestContextAwareInterface;
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(RequestContextAwareInterface $contextAware)
30+
{
31+
$this->context = $contextAware->getContext();
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function getFunctions()
38+
{
39+
foreach ($this->context->getParameter('functions') ?? [] as $function => $callable) {
40+
if (!\is_callable($callable)) {
41+
throw new \InvalidArgumentException(sprintf('The value of the function "%s" must be a valid callable ("%s" given).', $function, \is_object($callable) ? \get_class($callable) : \gettype($callable)));
42+
}
43+
44+
yield new ExpressionFunction(
45+
$function,
46+
static function ($str) use ($function) {
47+
return sprintf('(($context->getParameter(\'functions\')[\'%s\'])(%s))', $function, $str);
48+
},
49+
function ($arguments, $str) use ($function) {
50+
return ($this->context->getParameter('functions')[$function])($str);
51+
}
52+
);
53+
}
54+
}
55+
}

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->setParameters($defaultParameters);
106107
$this->setOptions($options);
107108
$this->defaultLocale = $defaultLocale;
108109
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potenc F438 ier <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('functions', [
29+
'env' => static function (string $name) {
30+
return [
31+
'APP_ENV' => 'test',
32+
'PHP_VERSION' => '7.2',
33+
][$name] ?? null;
34+
},
35+
]);
36+
37+
$this->router->method('getContext')->willReturn($context);
38+
}
39+
40+
/**
41+
* @dataProvider provider
42+
*/
43+
public function testEnv(string $expression, $expected): void
44+
{
45+
$expressionLanguage = new ExpressionLanguage();
46+
$expressionLanguageProvider = new ExpressionLanguageProvider($this->router);
47+
$expressionLanguage->registerProvider($expressionLanguageProvider);
48+
49+
$this->assertEquals($expected, $expressionLanguage->evaluate($expression));
50+
}
51+
52+
public function provider(): array
53+
{
54+
return [
55+
['env("APP_ENV")', 'test'],
56+
['env("PHP_VERSION")', '7.2'],
57+
['env("unknown_env_variable")', null],
58+
];
59+
}
60+
}

0 commit comments

Comments
 (0)
0