Skip to content

Commit d1659b9

Browse files
[DI][FrameworkBundle] add EnvVarLoaderInterface - remove SecretEnvVarProcessor
1 parent 4f493e1 commit d1659b9

File tree

4 files changed

+94
-6
lines changed

4 files changed

+94
-6
lines changed

Compiler/CheckTypeDeclarationsPass.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ private function checkType(Definition $checkedDefinition, $value, \ReflectionPar
188188
$checkFunction = sprintf('is_%s', $parameter->getType()->getName());
189189

190190
if (!$parameter->getType()->isBuiltin() || !$checkFunction($value)) {
191-
throw new InvalidParameterTypeException($this->currentId, \gettype($value), $parameter);
191+
throw new InvalidParameterTypeException($this->currentId, \is_object($value) ? \get_class($value) : \gettype($value), $parameter);
192192
}
193193
}
194194
}

EnvVarLoaderInterface.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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+
/**
15+
* EnvVarLoaderInterface objects return key/value pairs that are added to the list of available env vars.
16+
*
17+
* @author Nicolas Grekas <[email protected]>
18+
*/
19+
interface EnvVarLoaderInterface
20+
{
21+
/**
22+
* @return string[] Key/value pairs that can be accessed using the regular "%env()%" syntax
23+
*/
24+
public function loadEnvVars(): array;
25+
}

EnvVarProcessor.php

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\DependencyInjection;
1313

1414
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
15+
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
1516
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
1617

1718
/**
@@ -20,10 +21,17 @@
2021
class EnvVarProcessor implements EnvVarProcessorInterface
2122
{
2223
private $container;
24+
private $loaders;
25+
private $loadedVars = [];
2326

24-
public function __construct(ContainerInterface $container)
27+
/**
28+
* @param EnvVarLoaderInterface[] $loaders
29+
*/
30+
public function __construct(ContainerInterface $container, \Traversable $loaders = null)
2531
{
2632
$this->container = $container;
33+
$this->loaders = new \IteratorIterator($loaders ?? new \ArrayIterator());
34+
$this->loaders = $this->loaders->getInnerIterator();
2735
}
2836

2937
/**
@@ -127,12 +135,31 @@ public function getEnv($prefix, $name, \Closure $getEnv)
127135
} elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) {
128136
$env = $_SERVER[$name];
129137
} elseif (false === ($env = getenv($name)) || null === $env) { // null is a possible value because of thread safety issues
130-
if (!$this->container->hasParameter("env($name)")) {
131-
throw new EnvNotFoundException(sprintf('Environment variable not found: "%s".', $name));
138+
foreach ($this->loadedVars as $vars) {
139+
if (false !== $env = ($vars[$name] ?? false)) {
140+
break;
141+
}
132142
}
133143

134-
if (null === $env = $this->container->getParameter("env($name)")) {
135-
return null;
144+
try {
145+
while ((false === $env || null === $env) && $this->loaders->valid()) {
146+
$loader = $this->loaders->current();
147+
$this->loaders->next();
148+
$this->loadedVars[] = $vars = $loader->loadEnvVars();
149+
$env = $vars[$name] ?? false;
150+
}
151+
} catch (ParameterCircularReferenceException $e) {
152+
// skip loaders that need an env var that is not defined
153+
}
154+
155+
if (false === $env || null === $env) {
156+
if (!$this->container->hasParameter("env($name)")) {
157+
throw new EnvNotFoundException(sprintf('Environment variable not found: "%s".', $name));
158+
}
159+
160+
if (null === $env = $this->container->getParameter("env($name)")) {
161+
return null;
162+
}
136163
}
137164
}
138165

Tests/EnvVarProcessorTest.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PHPUnit\Framework\TestCase;
66
use Symfony\Component\DependencyInjection\Container;
77
use Symfony\Component\DependencyInjection\ContainerBuilder;
8+
use Symfony\Component\DependencyInjection\EnvVarLoaderInterface;
89
use Symfony\Component\DependencyInjection\EnvVarProcessor;
910

1011
class EnvVarProcessorTest extends TestCase
@@ -517,4 +518,39 @@ public function validCsv()
517518
[null, null],
518519
];
519520
}
521+
522+
public function testEnvLoader()
523+
{
524+
$loaders = function () {
525+
yield new class() implements EnvVarLoaderInterface {
526+
public function loadEnvVars(): array
527+
{
528+
return [
529+
'FOO_ENV_LOADER' => '123',
530+
];
531+
}
532+
};
533+
534+
yield new class() implements EnvVarLoaderInterface {
535+
public function loadEnvVars(): array
536+
{
537+
return [
538+
'FOO_ENV_LOADER' => '234',
539+
'BAR_ENV_LOADER' => '456',
540+
];
541+
}
542+
};
543+
};
544+
545+
$processor = new EnvVarProcessor(new Container(), $loaders());
546+
547+
$result = $processor->getEnv('string', 'FOO_ENV_LOADER', function () {});
548+
$this->assertSame('123', $result);
549+
550+
$result = $processor->getEnv('string', 'BAR_ENV_LOADER', function () {});
551+
$this->assertSame('456', $result);
552+
553+
$result = $processor->getEnv('string', 'FOO_ENV_LOADER', function () {});
554+
$this->assertSame('123', $result); // check twice
555+
}
520556
}

0 commit comments

Comments
 (0)