[DependencyInjection] Fixed unescaping of class arguments

This commit is contained in:
avorobiev 2012-06-26 21:33:57 +04:00
parent 81fe2ff8e2
commit 19bdae1b90
5 changed files with 27 additions and 11 deletions

View File

@ -10,3 +10,6 @@ CHANGELOG
* added Definition::clearTag() * added Definition::clearTag()
* component exceptions that inherit base SPL classes are now used exclusively * component exceptions that inherit base SPL classes are now used exclusively
(this includes dumped containers) (this includes dumped containers)
* [BC BREAK] fixed unescaping of class arguments, method ParameterBag::unescapeValue() was made
public

View File

@ -728,24 +728,28 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
*/ */
private function createService(Definition $definition, $id) private function createService(Definition $definition, $id)
{ {
$parameterBag = $this->getParameterBag();
if (null !== $definition->getFile()) { if (null !== $definition->getFile()) {
require_once $this->getParameterBag()->resolveValue($definition->getFile()); require_once $parameterBag->resolveValue($definition->getFile());
} }
$arguments = $this->resolveServices($this->getParameterBag()->resolveValue($definition->getArguments())); $arguments = $this->resolveServices(
$parameterBag->unescapeValue($parameterBag->resolveValue($definition->getArguments()))
);
if (null !== $definition->getFactoryMethod()) { if (null !== $definition->getFactoryMethod()) {
if (null !== $definition->getFactoryClass()) { if (null !== $definition->getFactoryClass()) {
$factory = $this->getParameterBag()->resolveValue($definition->getFactoryClass()); $factory = $parameterBag->resolveValue($definition->getFactoryClass());
} elseif (null !== $definition->getFactoryService()) { } elseif (null !== $definition->getFactoryService()) {
$factory = $this->get($this->getParameterBag()->resolveValue($definition->getFactoryService())); $factory = $this->get($parameterBag->resolveValue($definition->getFactoryService()));
} else { } else {
throw new RuntimeException('Cannot create service from factory method without a factory service or factory class.'); throw new RuntimeException('Cannot create service from factory method without a factory service or factory class.');
} }
$service = call_user_func_array(array($factory, $definition->getFactoryMethod()), $arguments); $service = call_user_func_array(array($factory, $definition->getFactoryMethod()), $arguments);
} else { } else {
$r = new \ReflectionClass($this->getParameterBag()->resolveValue($definition->getClass())); $r = new \ReflectionClass($parameterBag->resolveValue($definition->getClass()));
$service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments); $service = null === $r->getConstructor() ? $r->newInstance() : $r->newInstanceArgs($arguments);
} }
@ -774,11 +778,11 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
} }
if ($ok) { if ($ok) {
call_user_func_array(array($service, $call[0]), $this->resolveServices($this->getParameterBag()->resolveValue($call[1]))); call_user_func_array(array($service, $call[0]), $this->resolveServices($parameterBag->resolveValue($call[1])));
} }
} }
$properties = $this->resolveServices($this->getParameterBag()->resolveValue($definition->getProperties())); $properties = $this->resolveServices($parameterBag->resolveValue($definition->getProperties()));
foreach ($properties as $name => $value) { foreach ($properties as $name => $value) {
$service->$name = $value; $service->$name = $value;
} }
@ -787,7 +791,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
if (is_array($callable) && is_object($callable[0]) && $callable[0] instanceof Reference) { if (is_array($callable) && is_object($callable[0]) && $callable[0] instanceof Reference) {
$callable[0] = $this->get((string) $callable[0]); $callable[0] = $this->get((string) $callable[0]);
} elseif (is_array($callable)) { } elseif (is_array($callable)) {
$callable[0] = $this->getParameterBag()->resolveValue($callable[0]); $callable[0] = $parameterBag->resolveValue($callable[0]);
} }
if (!is_callable($callable)) { if (!is_callable($callable)) {

View File

@ -274,7 +274,7 @@ class ParameterBag implements ParameterBagInterface
return $value; return $value;
} }
private function unescapeValue($value) public function unescapeValue($value)
{ {
if (is_string($value)) { if (is_string($value)) {
return str_replace('%%', '%', $value); return str_replace('%%', '%', $value);

View File

@ -103,4 +103,13 @@ interface ParameterBagInterface
* @return mixed * @return mixed
*/ */
function escapeValue($value); function escapeValue($value);
/**
* Unescape parameter placeholders %
*
* @param mixed $value
*
* @return mixed
*/
function unescapeValue($value);
} }

View File

@ -251,9 +251,9 @@ class ContainerBuilderTest extends \PHPUnit_Framework_TestCase
{ {
$builder = new ContainerBuilder(); $builder = new ContainerBuilder();
$builder->register('bar', 'stdClass'); $builder->register('bar', 'stdClass');
$builder->register('foo1', 'FooClass')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar'))); $builder->register('foo1', 'FooClass')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar'), '%%unescape_it%%'));
$builder->setParameter('value', 'bar'); $builder->setParameter('value', 'bar');
$this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar')), $builder->get('foo1')->arguments, '->createService() replaces parameters and service references in the arguments provided by the service definition'); $this->assertEquals(array('foo' => 'bar', 'bar' => 'foo', $builder->get('bar'), '%unescape_it%'), $builder->get('foo1')->arguments, '->createService() replaces parameters and service references in the arguments provided by the service definition');
} }
/** /**