Add an url EnvProcessor

This commit is contained in:
Jérémy Derussé 2018-10-25 08:43:38 +02:00
parent a96308f0ba
commit f253c9b7ca
No known key found for this signature in database
GPG Key ID: 2083FA5758C473D2
6 changed files with 331 additions and 0 deletions

View File

@ -6,6 +6,8 @@ CHANGELOG
* added `%env(trim:...)%` processor to trim a string value
* added `%env(default:param_name:...)%` processor to fallback to a parameter or to null when using `%env(default::...)%`
* added `%env(url:...)%` processor to convert an URL or DNS into an array of components
* added `%env(query_string:...)%` processor to convert a query string into an array of key values
* added support for deprecating aliases
* made `ContainerParametersResource` final and not implement `Serializable` anymore
* added ability to define an index for a tagged collection

View File

@ -41,6 +41,8 @@ class EnvVarProcessor implements EnvVarProcessorInterface
'int' => 'int',
'json' => 'array',
'key' => 'bool|int|float|string|array',
'url' => 'array',
'query_string' => 'array',
'resolve' => 'string',
'default' => 'bool|int|float|string|array',
'string' => 'string',
@ -183,6 +185,37 @@ class EnvVarProcessor implements EnvVarProcessorInterface
return $env;
}
if ('url' === $prefix) {
$parsedEnv = parse_url($env);
if (false === $parsedEnv) {
throw new RuntimeException(sprintf('Invalid URL in env var "%s"', $name));
}
if (!isset($parsedEnv['scheme'], $parsedEnv['host'])) {
throw new RuntimeException(sprintf('Invalid URL env var "%s": schema and host expected, %s given.', $name, $env));
}
$parsedEnv += [
'port' => null,
'user' => null,
'pass' => null,
'path' => null,
'query' => null,
'fragment' => null,
];
// remove the '/' separator
$parsedEnv['path'] = '/' === $parsedEnv['path'] ? null : substr($parsedEnv['path'], 1);
return $parsedEnv;
}
if ('query_string' === $prefix) {
$queryString = parse_url($env, PHP_URL_QUERY) ?: $env;
parse_str($queryString, $result);
return $result;
}
if ('resolve' === $prefix) {
return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($name) {
if (!isset($match[1])) {

View File

@ -39,6 +39,8 @@ class RegisterEnvVarProcessorsPassTest extends TestCase
'int' => ['int'],
'json' => ['array'],
'key' => ['bool', 'int', 'float', 'string', 'array'],
'url' => ['array'],
'query_string' => ['array'],
'resolve' => ['string'],
'default' => ['bool', 'int', 'float', 'string', 'array'],
'string' => ['string'],

View File

@ -497,6 +497,52 @@ class PhpDumperTest extends TestCase
$this->assertSame('foobaz', $container->getParameter('hello-bar'));
}
public function testDumpedUrlEnvParameters()
{
$container = new ContainerBuilder();
$container->setParameter('env(foo)', 'postgres://user@localhost:5432/database?sslmode=disable');
$container->setParameter('hello', '%env(url:foo)%');
$container->compile();
$dumper = new PhpDumper($container);
$dumper->dump();
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_url_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_UrlParameters']));
require self::$fixturesPath.'/php/services_url_env.php';
$container = new \Symfony_DI_PhpDumper_Test_UrlParameters();
$this->assertSame([
'scheme' => 'postgres',
'host' => 'localhost',
'port' => 5432,
'user' => 'user',
'path' => 'database',
'query' => 'sslmode=disable',
'pass' => null,
'fragment' => null,
], $container->getParameter('hello'));
}
public function testDumpedQueryEnvParameters()
{
$container = new ContainerBuilder();
$container->setParameter('env(foo)', 'foo=bar&baz[]=qux');
$container->setParameter('hello', '%env(query_string:foo)%');
$container->compile();
$dumper = new PhpDumper($container);
$dumper->dump();
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services_query_string_env.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_QueryStringParameters']));
require self::$fixturesPath.'/php/services_query_string_env.php';
$container = new \Symfony_DI_PhpDumper_Test_QueryStringParameters();
$this->assertSame([
'foo' => 'bar',
'baz' => ['qux'],
], $container->getParameter('hello'));
}
public function testDumpedJsonEnvParameters()
{
$container = new ContainerBuilder();

View File

@ -0,0 +1,124 @@
<?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_QueryStringParameters extends Container
{
private $parameters;
private $targetDirs = [];
public function __construct()
{
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = [];
$this->aliases = [];
}
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 [
'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 = [
'hello' => false,
];
private $dynamicParameters = [];
/**
* Computes a dynamic parameter.
*
* @param string $name 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('query_string:foo'); 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 [
'env(foo)' => 'foo=bar&baz[]=qux',
];
}
}

View File

@ -0,0 +1,124 @@
<?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_UrlParameters extends Container
{
private $parameters;
private $targetDirs = [];
public function __construct()
{
$this->parameters = $this->getDefaultParameters();
$this->services = $this->privates = [];
$this->aliases = [];
}
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 [
'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 = [
'hello' => false,
];
private $dynamicParameters = [];
/**
* Computes a dynamic parameter.
*
* @param string $name 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('url:foo'); 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 [
'env(foo)' => 'postgres://user@localhost:5432/database?sslmode=disable',
];
}
}