feature #26498 Allow "json:" env var processor to accept null value (mcfedr)
This PR was merged into the 4.1-dev branch.
Discussion
----------
Allow "json:" env var processor to accept null value
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR | Currently no docs for this feature
Edits the EnvVarProcessor so that it allows any type of variable in JSON encoded vars.
Previously it was only possible to use `%env(json:ENV)%` for array types, but this seems to be an arbitrary restriction, when I could have any other data type in that JSON.
Valid JSON that was previously rejected:
- `1`
- `null`
- `"string"`
Commits
-------
abc7480828
Allow "json:" env var processor to parse null values
This commit is contained in:
commit
2e47edc4a5
@ -129,8 +129,8 @@ class EnvVarProcessor implements EnvVarProcessorInterface
|
|||||||
throw new RuntimeException(sprintf('Invalid JSON in env var "%s": '.json_last_error_msg(), $name));
|
throw new RuntimeException(sprintf('Invalid JSON in env var "%s": '.json_last_error_msg(), $name));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_array($env)) {
|
if (null !== $env && !is_array($env)) {
|
||||||
throw new RuntimeException(sprintf('Invalid JSON env var "%s": array expected, %s given.', $name, gettype($env)));
|
throw new RuntimeException(sprintf('Invalid JSON env var "%s": array or null expected, %s given.', $name, gettype($env)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $env;
|
return $env;
|
||||||
|
@ -432,6 +432,27 @@ class PhpDumperTest extends TestCase
|
|||||||
$this->assertSame(array('foo', 'bar'), $container->getParameter('hello'));
|
$this->assertSame(array('foo', 'bar'), $container->getParameter('hello'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testDumpedJsonEnvParameters()
|
||||||
|
{
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
$container->setParameter('env(foo)', '["foo","bar"]');
|
||||||
|
$container->setParameter('env(bar)', 'null');
|
||||||
|
$container->setParameter('hello', '%env(json:foo)%');
|
||||||
|
$container->setParameter('hello-bar', '%env(json:bar)%');
|
||||||
|
$container->compile();
|
||||||
|
|
||||||
|
$dumper = new PhpDumper($container);
|
||||||
|
$dumper->dump();
|
||||||
|
|
||||||
|
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_json_env.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_JsonParameters')));
|
||||||
|
|
||||||
|
putenv('foobar="hello"');
|
||||||
|
require self::$fixturesPath.'/php/services_json_env.php';
|
||||||
|
$container = new \Symfony_DI_PhpDumper_Test_JsonParameters();
|
||||||
|
$this->assertSame(array('foo', 'bar'), $container->getParameter('hello'));
|
||||||
|
$this->assertNull($container->getParameter('hello-bar'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testCustomEnvParameters()
|
public function testCustomEnvParameters()
|
||||||
{
|
{
|
||||||
$container = new ContainerBuilder();
|
$container = new ContainerBuilder();
|
||||||
|
@ -233,17 +233,29 @@ class EnvVarProcessorTest extends TestCase
|
|||||||
$this->assertSame('hello', $result);
|
$this->assertSame('hello', $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetEnvJson()
|
/**
|
||||||
|
* @dataProvider validJson
|
||||||
|
*/
|
||||||
|
public function testGetEnvJson($value, $processed)
|
||||||
{
|
{
|
||||||
$processor = new EnvVarProcessor(new Container());
|
$processor = new EnvVarProcessor(new Container());
|
||||||
|
|
||||||
$result = $processor->getEnv('json', 'foo', function ($name) {
|
$result = $processor->getEnv('json', 'foo', function ($name) use ($value) {
|
||||||
$this->assertSame('foo', $name);
|
$this->assertSame('foo', $name);
|
||||||
|
|
||||||
return json_encode(array(1));
|
return $value;
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->assertSame(array(1), $result);
|
$this->assertSame($processed, $result);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function validJson()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
array('[1]', array(1)),
|
||||||
|
array('{"key": "value"}', array('key' => 'value')),
|
||||||
|
array(null, null),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -284,6 +296,7 @@ class EnvVarProcessorTest extends TestCase
|
|||||||
array(1.1),
|
array(1.1),
|
||||||
array(true),
|
array(true),
|
||||||
array(false),
|
array(false),
|
||||||
|
array('foo'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,138 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\Container;
|
||||||
|
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||||
|
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||||
|
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||||
|
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class has been auto-generated
|
||||||
|
* by the Symfony Dependency Injection Component.
|
||||||
|
*
|
||||||
|
* @final since Symfony 3.3
|
||||||
|
*/
|
||||||
|
class Symfony_DI_PhpDumper_Test_JsonParameters extends Container
|
||||||
|
{
|
||||||
|
private $parameters;
|
||||||
|
private $targetDirs = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal but protected for BC on cache:clear
|
||||||
|
*/
|
||||||
|
protected $privates = array();
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->parameters = $this->getDefaultParameters();
|
||||||
|
|
||||||
|
$this->services = $this->privates = array();
|
||||||
|
|
||||||
|
$this->aliases = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reset()
|
||||||
|
{
|
||||||
|
$this->privates = array();
|
||||||
|
parent::reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function compile()
|
||||||
|
{
|
||||||
|
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isCompiled()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getRemovedIds()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'Psr\\Container\\ContainerInterface' => true,
|
||||||
|
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParameter($name)
|
||||||
|
{
|
||||||
|
$name = (string) $name;
|
||||||
|
|
||||||
|
if (!(isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters))) {
|
||||||
|
throw new InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
|
||||||
|
}
|
||||||
|
if (isset($this->loadedDynamicParameters[$name])) {
|
||||||
|
return $this->loadedDynamicParameters[$name] ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parameters[$name];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasParameter($name)
|
||||||
|
{
|
||||||
|
$name = (string) $name;
|
||||||
|
|
||||||
|
return isset($this->parameters[$name]) || isset($this->loadedDynamicParameters[$name]) || array_key_exists($name, $this->parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setParameter($name, $value)
|
||||||
|
{
|
||||||
|
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParameterBag()
|
||||||
|
{
|
||||||
|
if (null === $this->parameterBag) {
|
||||||
|
$parameters = $this->parameters;
|
||||||
|
foreach ($this->loadedDynamicParameters as $name => $loaded) {
|
||||||
|
$parameters[$name] = $loaded ? $this->dynamicParameters[$name] : $this->getDynamicParameter($name);
|
||||||
|
}
|
||||||
|
$this->parameterBag = new FrozenParameterBag($parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parameterBag;
|
||||||
|
}
|
||||||
|
|
||||||
|
private $loadedDynamicParameters = array(
|
||||||
|
'hello' => false,
|
||||||
|
'hello-bar' => false,
|
||||||
|
);
|
||||||
|
private $dynamicParameters = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes a dynamic parameter.
|
||||||
|
*
|
||||||
|
* @param string The name of the dynamic parameter to load
|
||||||
|
*
|
||||||
|
* @return mixed The value of the dynamic parameter
|
||||||
|
*
|
||||||
|
* @throws InvalidArgumentException When the dynamic parameter does not exist
|
||||||
|
*/
|
||||||
|
private function getDynamicParameter($name)
|
||||||
|
{
|
||||||
|
switch ($name) {
|
||||||
|
case 'hello': $value = $this->getEnv('json:foo'); break;
|
||||||
|
case 'hello-bar': $value = $this->getEnv('json:bar'); break;
|
||||||
|
default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
|
||||||
|
}
|
||||||
|
$this->loadedDynamicParameters[$name] = true;
|
||||||
|
|
||||||
|
return $this->dynamicParameters[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the default parameters.
|
||||||
|
*
|
||||||
|
* @return array An array of the default parameters
|
||||||
|
*/
|
||||||
|
protected function getDefaultParameters()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'env(foo)' => '["foo","bar"]',
|
||||||
|
'env(bar)' => 'null',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user