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

Skip to content

Commit e1f164c

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

File tree

14 files changed

+304
-56
lines changed

14 files changed

+304
-56
lines changed

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
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="service" id="Symfony\Component\Routing\Matcher\EnvVarResolverInterface" />
7172
<call method="setConfigCacheFactory">
7273
<argument type="service" id="config_cache_factory" />
7374
</call>
@@ -115,5 +116,18 @@
115116
<service id="Symfony\Bundle\FrameworkBundle\Controller\TemplateController" public="true">
116117
<argument type="service" id="twig" on-invalid="ignore" />
117118
</service>
119+
120+
<service id="Symfony\Bundle\FrameworkBundle\Routing\Matcher\EnvVarResolverAdapter" public="false">
121+
<argument type="service" id="container.env_var_resolver" />
122+
</service>
123+
124+
<service id="Symfony\Component\Routing\Matcher\EnvVarResolverInterface" alias="Symfony\Bundle\FrameworkBundle\Routing\Matcher\EnvVarResolverAdapter" />
125+
126+
<service id="Symfony\Component\Routing\Matcher\ExpressionLanguageProvider" public="false">
127+
<tag name="routing.expression_language_provider" />
128+
<call method="setEnvVarResolver">
129+
<argument type="service" id="Symfony\Component\Routing\Matcher\EnvVarResolverInterface" on-invalid="ignore" />
130+
</call>
131+
</service>
118132
</services>
119133
</container>

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@
120120

121121
<service id="container.env_var_processor" class="Symfony\Component\DependencyInjection\EnvVarProcessor">
122122
<tag name="container.env_var_processor" />
123-
<argument type="service" id="service_container" />
123+
<argument type="service" id="parameter_bag" />
124124
<argument type="tagged_iterator" tag="container.env_var_loader" />
125125
</service>
126126

@@ -143,5 +143,10 @@
143143
</service>
144144
</argument>
145145
</service>
146+
147+
<service id="container.env_var_resolver" class="Symfony\Component\DependencyInjection\EnvVarResolver" public="true">
148+
<argument type="service" id="parameter_bag" />
149+
<argument type="service" id="container.env_var_processors_locator" on-invalid="null" />
150+
</service>
146151
</services>
147152
</container>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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\Bundle\FrameworkBundle\Routing\Matcher;
13+
14+
use Symfony\Component\DependencyInjection\EnvVarResolver;
15+
use Symfony\Component\Routing\Matcher\EnvVarResolverInterface;
16+
17+
/**
18+
* @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>
19+
*/
20+
class EnvVarResolverAdapter implements EnvVarResolverInterface
21+
{
22+
private $resolver;
23+
24+
public function __construct(EnvVarResolver $resolver)
25+
{
26+
$this->resolver = $resolver;
27+
}
28+
29+
public function getEnv(string $name)
30+
{
31+
return $this->resolver->getEnv($name);
32+
}
33+
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
2020
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
2121
use Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
22+
use Symfony\Component\Routing\Matcher\EnvVarResolverInterface;
2223
use Symfony\Component\Routing\RequestContext;
2324
use Symfony\Component\Routing\RouteCollection;
2425
use Symfony\Component\Routing\Router as BaseRouter;
@@ -38,11 +39,12 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI
3839
/**
3940
* @param mixed $resource The main resource to load
4041
*/
41-
public function __construct(ContainerInterface $container, $resource, array $options = [], RequestContext $context = null, ContainerInterface $parameters = null, LoggerInterface $logger = null, string $defaultLocale = null)
42+
public function __construct(ContainerInterface $container, $resource, array $options = [], RequestContext $context = null, ContainerInterface $parameters = null, LoggerInterface $logger = null, string $defaultLocale = null, EnvVarResolverInterface $envVarResolver)
4243
{
4344
$this->container = $container;
4445
$this->resource = $resource;
4546
$this->context = $context ?: new RequestContext() F987 ;
47+
$this->context->setEnvVarResolver($envVarResolver);
4648
$this->logger = $logger;
4749
$this->setOptions($options);
4850

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ CHANGELOG
77
* added support to autowire public typed properties in php 7.4
88
* added support for defining method calls, a configurator, and property setters in `InlineServiceConfigurator`
99
* added possibility to define abstract service arguments
10+
* Moved `Container::getEnv` to a new class `EnvVarResolver`
1011

1112
5.0.0
1213
-----

src/Symfony/Component/DependencyInjection/Container.php

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection;
1313

14-
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
1514
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
16-
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
1715
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
1816
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
1917
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
@@ -49,12 +47,9 @@ class Container implements ContainerInterface, ResetInterface
4947
protected $factories = [];
5048
protected $aliases = [];
5149
protected $loading = [];
52-
protected $resolving = [];
5350
protected $syntheticIds = [];
5451

55-
private $envCache = [];
5652
private $compiled = false;
57-
private $getEnv;
5853

5954
public function __construct(ParameterBagInterface $parameterBag = null)
6055
{
@@ -368,48 +363,9 @@ protected function load($file)
368363
return require $file;
369364
}
370365

371-
/**
372-
* Fetches a variable from the environment.
373-
*
374-
* @param string $name The name of the environment variable
375-
*
376-
* @return mixed The value to use for the provided environment variable name
377-
*
378-
* @throws EnvNotFoundException When the environment variable is not found and has no default value
379-
*/
380366
protected function getEnv($name)
381367
{
382-
if (isset($this->resolving[$envName = "env($name)"])) {
383-
throw new ParameterCircularReferenceException(array_keys($this->resolving));
384-
}
385-
if (isset($this->envCache[$name]) || \array_key_exists($name, $this->envCache)) {
386-
return $this->envCache[$name];
387-
}
388-
if (!$this->has($id = 'container.env_var_processors_locator')) {
389-
$this->set($id, new ServiceLocator([]));
390-
}
391-
if (!$this->getEnv) {
392-
$this->getEnv = new \ReflectionMethod($this, __FUNCTION__);
393-
$this->getEnv->setAccessible(true);
394-
$this->getEnv = $this->getEnv->getClosure($this);
395-
}
396-
$processors = $this->get($id);
397-
398-
if (false !== $i = strpos($name, ':')) {
399-
$prefix = substr($name, 0, $i);
400-
$localName = substr($name, 1 + $i);
401-
} else {
402-
$prefix = 'string';
403-
$localName = $name;
404-
}
405-
$processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this);
406-
407-
$this->resolving[$envName] = true;
408-
try {
409-
return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv);
410-
} finally {
411-
unset($this->resolving[$envName]);
412-
}
368+
return $this->get('container.env_var_resolver')->getEnv($name);
413369
}
414370

415371
/**

src/Symfony/Component/DependencyInjection/EnvVarProcessor.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,23 @@
1414
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
1515
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
1616
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
17+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
1718

1819
/**
1920
* @author Nicolas Grekas <p@tchwork.com>
2021
*/
2122
class EnvVarProcessor implements EnvVarProcessorInterface
2223
{
23-
private $container;
24+
private $parameterBag;
2425
private $loaders;
2526
private $loadedVars = [];
2627

2728
/**
2829
* @param EnvVarLoaderInterface[] $loaders
2930
*/
30-
public function __construct(ContainerInterface $container, \Traversable $loaders = null)
31+
public function __construct(ParameterBagInterface $parameterBag, \Traversable $loaders = null)
3132
{
32-
$this->container = $container;
33+
$this->parameterBag = $parameterBag;
3334
$this->loaders = $loaders ?? new \ArrayIterator();
3435
}
3536

@@ -93,7 +94,7 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv)
9394
$next = substr($name, $i + 1);
9495
$default = substr($name, 0, $i);
9596

96-
if ('' !== $default && !$this->container->hasParameter($default)) {
97+
if ('' !== $default && !$this->parameterBag->has($default)) {
9798
throw new RuntimeException(sprintf('Invalid env fallback in "default:%s": parameter "%s" not found.', $name, $default));
9899
}
99100

@@ -107,7 +108,7 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv)
107108
// no-op
108109
}
109110

110-
return '' === $default ? null : $this->container->getParameter($default);
111+
return '' === $default ? null : $this->parameterBag->get($default);
111112
}
112113

113114
if ('file' === $prefix || 'require' === $prefix) {
@@ -167,11 +168,11 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv)
167168
}
168169

169170
if (false === $env || null === $env) {
170-
if (!$this->container->hasParameter("env($name)")) {
171+
if (!$this->parameterBag->has("env($name)")) {
171172
throw new EnvNotFoundException(sprintf('Environment variable not found: "%s".', $name));
172173
}
173174

174-
$env = $this->container->getParameter("env($name)");
175+
$env = $this->parameterBag->get("env($name)");
175176
}
176177
}
177178

@@ -273,7 +274,7 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv)
273274
if (!isset($match[1])) {
274275
return '%';
275276
}
276-
$value = $this->container->getParameter($match[1]);
277+
$value = $this->parameterBag->get($match[1]);
277278
if (!is_scalar($value)) {
278279
throw new RuntimeException(sprintf('Parameter "%s" found when resolving env var "%s" must be scalar, "%s" given.', $match[1], $name, \gettype($value)));
279280
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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\DependencyInjection;
13+
14+
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
15+
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
16+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
17+
18+
/**
19+
* @author Nicolas Grekas <p@tchwork.com>
20+
* @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>
21+
*/
22+
final class EnvVarResolver
23+
{
24+
protected $resolving = [];
25+
private $envCache = [];
26+
private $getEnv;
27+
28+
private $processors;
29+
private $parameterBag;
30+
31+
public function __construct(ParameterBagInterface $parameterBag, $processors = null)
32+
{
33+
$this->parameterBag = $parameterBag;
34+
$this->processors = $processors ?? new ServiceLocator([]);
35+
}
36+
37+
/**
38+
* Fetches a variable from the environment.
39+
*
40+
* @param string $name The name of the environment variable
41+
*
42+
* @return mixed The value to use for the provided environment variable name
43+
*
44+
* @throws EnvNotFoundException When the environment variable is not found and has no default value
45+
*/
46+
public function getEnv($name)
47+
{
48+
if (isset($this->resolving[$envName = "env($name)"])) {
49+
throw new ParameterCircularReferenceException(array_keys($this->resolving));
50+
}
51+
if (isset($this->envCache[$name]) || \array_key_exists($name, $this->envCache)) {
52+
return $this->envCache[$name];
53+
}
54+
55+
if (!$this->getEnv) {
56+
$this->getEnv = new \ReflectionMethod($this, __FUNCTION__);
57+
$this->getEnv->setAccessible(true);
58+
$this->getEnv = $this->getEnv->getClosure($this);
59+
}
60+
61+
if (false !== $i = strpos($name, ':')) {
62+
$prefix = substr($name, 0, $i);
63+
$localName = substr($name, 1 + $i);
64+
} else {
65+
$prefix = 'string';
66+
$localName = $name;
67+
}
68+
69+
$processor = $this->processors->has($prefix) ? $this->processors->get($prefix) : new EnvVarProcessor($this->parameterBag);
70+
71+
$this->resolving[$envName] = true;
72+
try {
73+
return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv);
74+
} finally {
75+
unset($this->resolving[$envName]);
76+
}
77+
}
78+
}

src/Symfony/Component/Routing/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ 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.
12+
* added `EnvVarResolverInterface`
1113

1214
5.0.0
1315
-----
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
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+
/**
15+
* @author Ahmed TAILOULOUTE <ahmed.tailouloute@gmail.com>
16+
*/
17+
interface EnvVarResolverInterface
18+
{
19+
public function getEnv(string $name);
20+
}

0 commit comments

Comments
 (0)
0