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

Skip to content

Commit 6177069

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

File tree

8 files changed

+168
-3
lines changed

8 files changed

+168
-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: 20 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,12 @@
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+
<argument type="collection">
134+
<argument>env</argument>
135+
</argument>
136+
<tag name="routing.expression_language_provider" />
137+
</service>
118138
</services>
119139
</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: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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+
17+
/**
18+
* Defines some ExpressionLanguage functions.
19+
*
20+
* @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>
21+
*/
22+
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
23+
{
24+
private $functions;
25+
26+
/**
27+
* @param string[] $functions
28+
*/
29+
public function __construct(array $functions)
30+
{
31+
$this->functions = $functions;
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
public function getFunctions()
38+
{
39+
foreach ($this->functions as $function) {
40+
yield new ExpressionFunction(
41+
$function,
42+
static function (...$args) use ($function) {
43+
return sprintf('(($context->getParameter(\'_functions\')[%s])(%s))', var_export($function, true), implode(', ', $args));
44+
},
45+
function ($values, ...$args) use ($function) {
46+
$context = $values['context'];
47+
48+
return ($context->getParameter('_functions')[$function])(...$args);
49+
}
50+
);
51+
}
52+
}
53+
}

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: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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+
19+
class ExpressionLanguageTest extends TestCase
20+
{
21+
private $context;
22+
private $expressionLanguage;
23+
24+
public function setUp(): void
25+
{
26+
$this->context = new RequestContext();
27+
$this->context->setParameter('_functions', [
28+
// function with one arg
29+
'env' => static function (string $arg) {
30+
return [
31+
'APP_ENV' => 'test',
32+
'PHP_VERSION' => '7.2',
33+
][$arg] ?? null;
34+
},
35+
// function with multiple args
36+
'sum' => static function ($a, $b) {
37+
return $a + $b;
38+
},
39+
'foo' => static function () {
40+
return 'bar';
41+
},
42+
]);
43+
44+
$this->expressionLanguage = new ExpressionLanguage();
45+
$this->expressionLanguage->registerProvider(new ExpressionLanguageProvider(['env', 'sum', 'foo']));
46+
}
47+
48+
/**
49+
* @dataProvider compileProvider
50+
*/
51+
public function testCompile(string $expression, string $expected): void
52+
{
53+
$this->assertEquals($expected, $this->expressionLanguage->compile($expression));
54+
}
55+
56+
public function compileProvider(): iterable
57+
{
58+
return [
59+
['env("APP_ENV")', '(($context->getParameter(\'_functions\')[\'env\'])("APP_ENV"))'],
60+
['sum(1, 2)', '(($context->getParameter(\'_functions\')[\'sum\'])(1, 2))'],
61+
['foo()', '(($context->getParameter(\'_functions\')[\'foo\'])())'],
62+
];
63+
}
64+
65+
/**
66+
* @dataProvider evaluateProvider
67+
*/
68+
public function testEvaluate(string $expression, $expected): void
69+
{
70+
$this->assertEquals($expected, $this->expressionLanguage->evaluate($expression, ['context' => $this->context]));
71+
}
72+
73+
public function evaluateProvider(): array
74+
{
75+
return [
76+
['env("APP_ENV")', 'test'],
77+
['env("PHP_VERSION")', '7.2'],
78+
['env("unknown_env_variable")', null],
79+
['sum(1, 2)', 3],
80+
['foo()', 'bar'],
81+
];
82+
}
83+
}

0 commit comments

Comments
 (0)
0