[DependencyInjection] moved ContainerBuilder::resolveValue() to ParameterBag

This commit is contained in:
Fabien Potencier 2010-07-15 20:15:49 +02:00
parent 7796eb213c
commit 6bad58012f
5 changed files with 88 additions and 91 deletions

View File

@ -234,7 +234,7 @@ class ContainerBuilder extends Container implements AnnotatedContainerInterface
$this->parameterBag->add($parameters);
foreach ($this->parameterBag->all() as $key => $value) {
$this->parameterBag->set($key, self::resolveValue($value, $this->getParameterBag()->all()));
$this->parameterBag->set($key, $this->getParameterBag()->resolveValue($value));
}
}
@ -449,21 +449,21 @@ class ContainerBuilder extends Container implements AnnotatedContainerInterface
protected function createService(Definition $definition, $id)
{
if (null !== $definition->getFile()) {
require_once self::resolveValue($definition->getFile(), $this->getParameterBag()->all());
require_once $this->getParameterBag()->resolveValue($definition->getFile());
}
$arguments = $this->resolveServices(self::resolveValue($definition->getArguments(), $this->getParameterBag()->all()));
$arguments = $this->resolveServices($this->getParameterBag()->resolveValue($definition->getArguments()));
if (null !== $definition->getFactoryMethod()) {
if (null !== $definition->getFactoryService()) {
$factory = $this->get(self::resolveValue($definition->getFactoryService(), $this->getParameterBag()->all()));
$factory = $this->get($this->getParameterBag()->resolveValue($definition->getFactoryService()));
} else {
$factory = self::resolveValue($definition->getClass(), $this->getParameterBag()->all());
$factory = $this->getParameterBag()->resolveValue($definition->getClass());
}
$service = call_user_func_array(array($factory, $definition->getFactoryMethod()), $arguments);
} else {
$r = new \ReflectionClass(self::resolveValue($definition->getClass(), $this->getParameterBag()->all()));
$r = new \ReflectionClass($this->getParameterBag()->resolveValue($definition->getClass()));
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
}
@ -484,7 +484,7 @@ class ContainerBuilder extends Container implements AnnotatedContainerInterface
}
if ($ok) {
call_user_func_array(array($service, $call[0]), $this->resolveServices(self::resolveValue($call[1], $this->getParameterBag()->all())));
call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->resolveValue($call[1])));
}
}
@ -492,7 +492,7 @@ class ContainerBuilder extends Container implements AnnotatedContainerInterface
if (is_array($callable) && is_object($callable[0]) && $callable[0] instanceof Reference) {
$callable[0] = $this->get((string) $callable[0]);
} elseif (is_array($callable)) {
$callable[0] = self::resolveValue($callable[0], $this->getParameterBag()->all());
$callable[0] = $this->getParameterBag()->resolveValue($callable[0]);
}
if (!is_callable($callable)) {
@ -505,50 +505,6 @@ class ContainerBuilder extends Container implements AnnotatedContainerInterface
return $service;
}
/**
* Replaces parameter placeholders (%name%) by their values.
*
* @param mixed $value A value
*
* @return mixed The same value with all placeholders replaced by their values
*
* @throws \RuntimeException if a placeholder references a parameter that does not exist
*/
static public function resolveValue($value, $parameters)
{
if (is_array($value)) {
$args = array();
foreach ($value as $k => $v) {
$args[self::resolveValue($k, $parameters)] = self::resolveValue($v, $parameters);
}
$value = $args;
} else if (is_string($value)) {
if (preg_match('/^%([^%]+)%$/', $value, $match)) {
// we do this to deal with non string values (boolean, integer, ...)
// the preg_replace_callback converts them to strings
if (!array_key_exists($name = strtolower($match[1]), $parameters)) {
throw new \RuntimeException(sprintf('The parameter "%s" must be defined.', $name));
}
$value = $parameters[$name];
} else {
$replaceParameter = function ($match) use ($parameters, $value)
{
if (!array_key_exists($name = strtolower($match[2]), $parameters)) {
throw new \RuntimeException(sprintf('The parameter "%s" must be defined (used in the following expression: "%s").', $name, $value));
}
return $parameters[$name];
};
$value = str_replace('%%', '%', preg_replace_callback('/(?<!%)(%)([^%]+)\1/', $replaceParameter, $value));
}
}
return $value;
}
/**
* Replaces service references by the real service instance.
*

View File

@ -137,7 +137,7 @@ class GraphvizDumper extends Dumper
$container = clone $this->container;
foreach ($container->getDefinitions() as $id => $definition) {
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $this->getValue($definition->getClass())), 'attributes' => array_merge($this->options['node.definition'], array('style' => $definition->isShared() ? 'filled' : 'dotted')));
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $this->container->getParameterBag()->resolveValue($definition->getClass())), 'attributes' => array_merge($this->options['node.definition'], array('style' => $definition->isShared() ? 'filled' : 'dotted')));
$container->setDefinition($id, new Definition('stdClass'));
}
@ -157,11 +157,6 @@ class GraphvizDumper extends Dumper
return $nodes;
}
protected function getValue($value, $default = '')
{
return ContainerBuilder::resolveValue($value, $this->container->getParameterBag()->all());
}
protected function startDot()
{
$parameters = var_export($this->container->getParameterBag()->all(), true);

View File

@ -104,4 +104,47 @@ class ParameterBag implements ParameterBagInterface
{
return array_key_exists(strtolower($name), $this->parameters);
}
/**
* Replaces parameter placeholders (%name%) by their values.
*
* @param mixed $value A value
*
* @throws \RuntimeException if a placeholder references a parameter that does not exist
*/
public function resolveValue($value)
{
if (is_array($value)) {
$args = array();
foreach ($value as $k => $v) {
$args[$this->resolveValue($k)] = $this->resolveValue($v);
}
$value = $args;
} else if (is_string($value)) {
if (preg_match('/^%([^%]+)%$/', $value, $match)) {
// we do this to deal with non string values (boolean, integer, ...)
// the preg_replace_callback converts them to strings
if (!array_key_exists($name = strtolower($match[1]), $this->parameters)) {
throw new \RuntimeException(sprintf('The parameter "%s" must be defined.', $name));
}
$value = $this->parameters[$name];
} else {
$parameters = $this->parameters;
$replaceParameter = function ($match) use ($parameters, $value)
{
if (!array_key_exists($name = strtolower($match[2]), $parameters)) {
throw new \RuntimeException(sprintf('The parameter "%s" must be defined (used in the following expression: "%s").', $name, $value));
}
return $parameters[$name];
};
$value = str_replace('%%', '%', preg_replace_callback('/(?<!%)(%)([^%]+)\1/', $replaceParameter, $value));
}
}
return $value;
}
}

View File

@ -288,39 +288,6 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
}
}
/**
* @covers Symfony\Components\DependencyInjection\ContainerBuilder::resolveValue
*/
public function testResolveValue()
{
$this->assertEquals('foo', ContainerBuilder::resolveValue('foo', array()), '->resolveValue() returns its argument unmodified if no placeholders are found');
$this->assertEquals('I\'m a bar', ContainerBuilder::resolveValue('I\'m a %foo%', array('foo' => 'bar')), '->resolveValue() replaces placeholders by their values');
$this->assertTrue(ContainerBuilder::resolveValue('%foo%', array('foo' => true)) === true, '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');
$this->assertEquals(array('bar' => 'bar'), ContainerBuilder::resolveValue(array('%foo%' => '%foo%'), array('foo' => 'bar')), '->resolveValue() replaces placeholders in keys and values of arrays');
$this->assertEquals(array('bar' => array('bar' => array('bar' => 'bar'))), ContainerBuilder::resolveValue(array('%foo%' => array('%foo%' => array('%foo%' => '%foo%'))), array('foo' => 'bar')), '->resolveValue() replaces placeholders in nested arrays');
$this->assertEquals('I\'m a %foo%', ContainerBuilder::resolveValue('I\'m a %%foo%%', array('foo' => 'bar')), '->resolveValue() supports % escaping by doubling it');
$this->assertEquals('I\'m a bar %foo bar', ContainerBuilder::resolveValue('I\'m a %foo% %%foo %foo%', array('foo' => 'bar')), '->resolveValue() supports % escaping by doubling it');
try {
ContainerBuilder::resolveValue('%foobar%', array());
$this->fail('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
} catch (\Exception $e) {
$this->assertInstanceOf('\RuntimeException', $e, '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
$this->assertEquals('The parameter "foobar" must be defined.', $e->getMessage(), '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
}
try {
ContainerBuilder::resolveValue('foo %foobar% bar', array());
$this->fail('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
} catch (\Exception $e) {
$this->assertInstanceOf('\RuntimeException', $e, '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
$this->assertEquals('The parameter "foobar" must be defined (used in the following expression: "foo %foobar% bar").', $e->getMessage(), '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
}
}
/**
* @covers Symfony\Components\DependencyInjection\ContainerBuilder::resolveServices
*/

View File

@ -75,4 +75,40 @@ class ParameterBagTest extends \PHPUnit_Framework_TestCase
$this->assertTrue($bag->has('Foo'), '->has() converts the key to lowercase');
$this->assertFalse($bag->has('bar'), '->has() returns false if a parameter is not defined');
}
/**
* @covers Symfony\Components\DependencyInjection\ParameterBag\ParameterBag::resolveValue
*/
public function testResolveValue()
{
$bag = new ParameterBag(array());
$this->assertEquals('foo', $bag->resolveValue('foo'), '->resolveValue() returns its argument unmodified if no placeholders are found');
$bag = new ParameterBag(array('foo' => 'bar'));
$this->assertEquals('I\'m a bar', $bag->resolveValue('I\'m a %foo%'), '->resolveValue() replaces placeholders by their values');
$this->assertEquals(array('bar' => 'bar'), $bag->resolveValue(array('%foo%' => '%foo%')), '->resolveValue() replaces placeholders in keys and values of arrays');
$this->assertEquals(array('bar' => array('bar' => array('bar' => 'bar'))), $bag->resolveValue(array('%foo%' => array('%foo%' => array('%foo%' => '%foo%')))), '->resolveValue() replaces placeholders in nested arrays');
$this->assertEquals('I\'m a %foo%', $bag->resolveValue('I\'m a %%foo%%'), '->resolveValue() supports % escaping by doubling it');
$this->assertEquals('I\'m a bar %foo bar', $bag->resolveValue('I\'m a %foo% %%foo %foo%'), '->resolveValue() supports % escaping by doubling it');
$bag = new ParameterBag(array('foo' => true));
$this->assertTrue($bag->resolveValue('%foo%') === true, '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');
$bag = new ParameterBag(array());
try {
$bag->resolveValue('%foobar%', array());
$this->fail('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
} catch (\Exception $e) {
$this->assertInstanceOf('\RuntimeException', $e, '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
$this->assertEquals('The parameter "foobar" must be defined.', $e->getMessage(), '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
}
try {
$bag->resolveValue('foo %foobar% bar', array());
$this->fail('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
} catch (\Exception $e) {
$this->assertInstanceOf('\RuntimeException', $e, '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
$this->assertEquals('The parameter "foobar" must be defined (used in the following expression: "foo %foobar% bar").', $e->getMessage(), '->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
}
}
}