diff --git a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
index 0dc715bd6c..18251f064c 100644
--- a/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+++ b/src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
@@ -201,7 +201,7 @@ class PhpDumper extends Dumper
$nbOccurrences->offsetSet($definition, 1);
} else {
$i = $nbOccurrences->offsetGet($definition);
- $nbOccurrences->offsetSet($definition, $i+1);
+ $nbOccurrences->offsetSet($definition, $i + 1);
}
}
@@ -212,7 +212,7 @@ class PhpDumper extends Dumper
$processed->offsetSet($sDefinition);
$class = $this->dumpValue($sDefinition->getClass());
- if ($nbOccurrences->offsetGet($sDefinition) > 1 || count($sDefinition->getMethodCalls()) > 0 || $sDefinition->getProperties() || null !== $sDefinition->getConfigurator() || false !== strpos($class, '$')) {
+ if ($nbOccurrences->offsetGet($sDefinition) > 1 || $sDefinition->getMethodCalls() || $sDefinition->getProperties() || null !== $sDefinition->getConfigurator() || false !== strpos($class, '$')) {
$name = $this->getNextVariableName();
$variableMap->offsetSet($sDefinition, new Variable($name));
@@ -246,7 +246,7 @@ class PhpDumper extends Dumper
$code .= sprintf(" \$%s = new \\%s(%s);\n", $name, substr(str_replace('\\\\', '\\', $class), 1, -1), implode(', ', $arguments));
}
- if (!$this->hasReference($id, $sDefinition->getMethodCalls()) && !$this->hasReference($id, $sDefinition->getProperties())) {
+ if (!$this->hasReference($id, $sDefinition->getMethodCalls(), true) && !$this->hasReference($id, $sDefinition->getProperties(), true)) {
$code .= $this->addServiceMethodCalls(null, $sDefinition, $name);
$code .= $this->addServiceProperties(null, $sDefinition, $name);
$code .= $this->addServiceConfigurator(null, $sDefinition, $name);
@@ -415,16 +415,14 @@ class PhpDumper extends Dumper
}
$processed->offsetSet($iDefinition);
- if (!$this->hasReference($id, $iDefinition->getMethodCalls())) {
+ if (!$this->hasReference($id, $iDefinition->getMethodCalls(), true) && !$this->hasReference($id, $iDefinition->getProperties(), true)) {
continue;
}
- if ($iDefinition->getMethodCalls()) {
- $code .= $this->addServiceMethodCalls(null, $iDefinition, (string) $this->definitionVariables->offsetGet($iDefinition));
- }
- if ($iDefinition->getConfigurator()) {
- $code .= $this->addServiceConfigurator(null, $iDefinition, (string) $this->definitionVariables->offsetGet($iDefinition));
- }
+ $name = (string) $this->definitionVariables->offsetGet($iDefinition);
+ $code .= $this->addServiceMethodCalls(null, $iDefinition, $name);
+ $code .= $this->addServiceProperties(null, $iDefinition, $name);
+ $code .= $this->addServiceConfigurator(null, $iDefinition, $name);
}
if ('' !== $code) {
@@ -960,17 +958,26 @@ EOF;
*
* @return Boolean
*/
- private function hasReference($id, array $arguments)
+ private function hasReference($id, array $arguments, $deep = false)
{
foreach ($arguments as $argument) {
if (is_array($argument)) {
- if ($this->hasReference($id, $argument)) {
+ if ($this->hasReference($id, $argument, $deep)) {
return true;
}
} elseif ($argument instanceof Reference) {
if ($id === (string) $argument) {
return true;
}
+
+ if ($deep) {
+ $service = $this->container->getDefinition((string) $argument);
+ $arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());
+
+ if ($this->hasReference($id, $arguments, $deep)) {
+ return true;
+ }
+ }
}
}
diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Dumper/PhpDumperTest.php b/tests/Symfony/Tests/Component/DependencyInjection/Dumper/PhpDumperTest.php
index ed2228a523..ad5270f5de 100644
--- a/tests/Symfony/Tests/Component/DependencyInjection/Dumper/PhpDumperTest.php
+++ b/tests/Symfony/Tests/Component/DependencyInjection/Dumper/PhpDumperTest.php
@@ -96,10 +96,17 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
public function testAddService()
{
+ // without compilation
$container = include self::$fixturesPath.'/containers/container9.php';
$dumper = new PhpDumper($container);
$this->assertEquals(str_replace('%path%', str_replace('\\','\\\\',self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9.php')), $dumper->dump(), '->dump() dumps services');
+ // with compilation
+ $container = include self::$fixturesPath.'/containers/container9.php';
+ $container->compile();
+ $dumper = new PhpDumper($container);
+ $this->assertEquals(str_replace('%path%', str_replace('\\','\\\\',self::$fixturesPath.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR), file_get_contents(self::$fixturesPath.'/php/services9_compiled.php')), $dumper->dump(), '->dump() dumps services');
+
$dumper = new PhpDumper($container = new ContainerBuilder());
$container->register('foo', 'FooClass')->addArgument(new \stdClass());
try {
diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/containers/container9.php b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/containers/container9.php
index 663f2a7fd9..71d29f209b 100644
--- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/containers/container9.php
+++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/containers/container9.php
@@ -14,9 +14,8 @@ $container->
addTag('foo', array('bar' => 'bar'))->
setFactoryClass('FooClass')->
setFactoryMethod('getInstance')->
- setArguments(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'bar' => '%foo%'), true, new Reference('service_container')))->
+ setArguments(array('foo', new Reference('foo.baz'), array('%foo%' => 'foo is %foo%', 'foobar' => '%foo%'), true, new Reference('service_container')))->
setProperties(array('foo' => 'bar', 'moo' => new Reference('foo.baz')))->
- setScope('prototype')->
addMethodCall('setBar', array(new Reference('bar')))->
addMethodCall('initialize')->
setConfigurator('sc_configure')
@@ -33,7 +32,10 @@ $container->
setFactoryMethod('getInstance')->
setConfigurator(array('%baz_class%', 'configureStatic1'))
;
-$container->register('foo_bar', '%foo_class%');
+$container->
+ register('foo_bar', '%foo_class%')->
+ setScope('prototype')
+;
$container->getParameterBag()->clear();
$container->getParameterBag()->add(array(
'baz_class' => 'BazClass',
@@ -50,9 +52,24 @@ $container->
addMethodCall('setBar', array(new Reference('foobaz', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)))
;
$container->
- register('factory_service')->
+ register('factory_service', 'Bar')->
setFactoryService('foo.baz')->
setFactoryMethod('getInstance')
;
+$container
+ ->register('foo_with_inline', 'Foo')
+ ->addMethodCall('setBar', array(new Reference('inlined')))
+;
+$container
+ ->register('inlined', 'Bar')
+ ->setProperty('pub', 'pub')
+ ->addMethodCall('setBaz', array(new Reference('baz')))
+ ->setPublic(false)
+;
+$container
+ ->register('baz', 'Baz')
+ ->addMethodCall('setFoo', array(new Reference('foo_with_inline')))
+;
+
return $container;
diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/graphviz/services9.dot b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/graphviz/services9.dot
index fdff2219ef..73608e27fc 100644
--- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/graphviz/services9.dot
+++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/graphviz/services9.dot
@@ -3,12 +3,15 @@ digraph sc {
node [fontsize="11" fontname="Arial" shape="record"];
edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"];
- node_foo [label="foo (alias_for_foo)\nFooClass\n", shape=record, fillcolor="#eeeeee", style="dotted"];
+ node_foo [label="foo (alias_for_foo)\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_bar [label="bar\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_foo_baz [label="foo.baz\nBazClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
- node_foo_bar [label="foo_bar\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
+ node_foo_bar [label="foo_bar\nFooClass\n", shape=record, fillcolor="#eeeeee", style="dotted"];
node_method_call1 [label="method_call1\nFooClass\n", shape=record, fillcolor="#eeeeee", style="filled"];
- node_factory_service [label="factory_service\n\n", shape=record, fillcolor="#eeeeee", style="filled"];
+ node_factory_service [label="factory_service\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
+ node_foo_with_inline [label="foo_with_inline\nFoo\n", shape=record, fillcolor="#eeeeee", style="filled"];
+ node_inlined [label="inlined\nBar\n", shape=record, fillcolor="#eeeeee", style="filled"];
+ node_baz [label="baz\nBaz\n", shape=record, fillcolor="#eeeeee", style="filled"];
node_service_container [label="service_container\nSymfony\\Component\\DependencyInjection\\ContainerBuilder\n", shape=record, fillcolor="#9999ff", style="filled"];
node_foo2 [label="foo2\n\n", shape=record, fillcolor="#ff9999", style="filled"];
node_foo3 [label="foo3\n\n", shape=record, fillcolor="#ff9999", style="filled"];
@@ -22,4 +25,7 @@ digraph sc {
node_method_call1 -> node_foo2 [label="setBar()" style="dashed"];
node_method_call1 -> node_foo3 [label="setBar()" style="dashed"];
node_method_call1 -> node_foobaz [label="setBar()" style="dashed"];
+ node_foo_with_inline -> node_inlined [label="setBar()" style="dashed"];
+ node_inlined -> node_baz [label="setBaz()" style="dashed"];
+ node_baz -> node_foo_with_inline [label="setFoo()" style="dashed"];
}
diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/includes/classes.php b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/includes/classes.php
index 514df23e51..fb6d4cf19d 100644
--- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/includes/classes.php
+++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/includes/classes.php
@@ -7,10 +7,23 @@ function sc_configure($instance)
class BarClass
{
+ protected $baz;
+
+ public function setBaz(BazClass $baz)
+ {
+ $this->baz = $baz;
+ }
}
class BazClass
{
+ protected $foo;
+
+ public function setFoo(Foo $foo)
+ {
+ $this->foo = $foo;
+ }
+
public function configure($instance)
{
$instance->configure();
diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9.php b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9.php
index dc62d54ffd..0d4008583e 100644
--- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9.php
+++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9.php
@@ -40,13 +40,30 @@ class ProjectServiceContainer extends Container
return $instance;
}
+ /**
+ * Gets the 'baz' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return Baz A Baz instance.
+ */
+ protected function getBazService()
+ {
+ $this->services['baz'] = $instance = new \Baz();
+
+ $instance->setFoo($this->get('foo_with_inline'));
+
+ return $instance;
+ }
+
/**
* Gets the 'factory_service' service.
*
* This service is shared.
* This method always returns the same instance of the service.
*
- * @return Object An instance returned by foo.baz::getInstance().
+ * @return Bar A Bar instance.
*/
protected function getFactoryServiceService()
{
@@ -56,13 +73,16 @@ class ProjectServiceContainer extends Container
/**
* Gets the 'foo' service.
*
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
* @return FooClass A FooClass instance.
*/
protected function getFooService()
{
$a = $this->get('foo.baz');
- $instance = call_user_func(array('FooClass', 'getInstance'), 'foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo'), 'bar' => $this->getParameter('foo')), true, $this);
+ $this->services['foo'] = $instance = call_user_func(array('FooClass', 'getInstance'), 'foo', $a, array($this->getParameter('foo') => 'foo is '.$this->getParameter('foo'), 'foobar' => $this->getParameter('foo')), true, $this);
$instance->setBar($this->get('bar'));
$instance->initialize();
@@ -93,15 +113,29 @@ class ProjectServiceContainer extends Container
/**
* Gets the 'foo_bar' service.
*
- * This service is shared.
- * This method always returns the same instance of the service.
- *
* @return Object A %foo_class% instance.
*/
protected function getFooBarService()
{
$class = $this->getParameter('foo_class');
- return $this->services['foo_bar'] = new $class();
+ return new $class();
+ }
+
+ /**
+ * Gets the 'foo_with_inline' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return Foo A Foo instance.
+ */
+ protected function getFooWithInlineService()
+ {
+ $this->services['foo_with_inline'] = $instance = new \Foo();
+
+ $instance->setBar($this->get('inlined'));
+
+ return $instance;
}
/**
@@ -140,6 +174,28 @@ class ProjectServiceContainer extends Container
return $this->get('foo');
}
+ /**
+ * Gets the 'inlined' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * This service is private.
+ * If you want to be able to request this service from the container directly,
+ * make it public, otherwise you might end up with broken code.
+ *
+ * @return Bar A Bar instance.
+ */
+ protected function getInlinedService()
+ {
+ $this->services['inlined'] = $instance = new \Bar();
+
+ $instance->setBaz($this->get('baz'));
+ $instance->pub = 'pub';
+
+ return $instance;
+ }
+
/**
* Gets the default parameters.
*
diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9_compiled.php b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9_compiled.php
new file mode 100644
index 0000000000..f41d4b23d8
--- /dev/null
+++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/php/services9_compiled.php
@@ -0,0 +1,238 @@
+parameters = $this->getDefaultParameters();
+
+ $this->services =
+ $this->scopedServices =
+ $this->scopeStacks = array();
+
+ $this->set('service_container', $this);
+
+ $this->scopes = array();
+ $this->scopeChildren = array();
+ }
+
+ /**
+ * Gets the 'bar' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return FooClass A FooClass instance.
+ */
+ protected function getBarService()
+ {
+ $this->services['bar'] = $instance = new \FooClass('foo', $this->get('foo.baz'), $this->getParameter('foo_bar'));
+
+ $this->get('foo.baz')->configure($instance);
+
+ return $instance;
+ }
+
+ /**
+ * Gets the 'baz' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return Baz A Baz instance.
+ */
+ protected function getBazService()
+ {
+ $this->services['baz'] = $instance = new \Baz();
+
+ $instance->setFoo($this->get('foo_with_inline'));
+
+ return $instance;
+ }
+
+ /**
+ * Gets the 'factory_service' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return Bar A Bar instance.
+ */
+ protected function getFactoryServiceService()
+ {
+ return $this->services['factory_service'] = $this->get('foo.baz')->getInstance();
+ }
+
+ /**
+ * Gets the 'foo' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return FooClass A FooClass instance.
+ */
+ protected function getFooService()
+ {
+ $a = $this->get('foo.baz');
+
+ $this->services['foo'] = $instance = call_user_func(array('FooClass', 'getInstance'), 'foo', $a, array('bar' => 'foo is bar', 'foobar' => 'bar'), true, $this);
+
+ $instance->setBar($this->get('bar'));
+ $instance->initialize();
+ $instance->foo = 'bar';
+ $instance->moo = $a;
+ sc_configure($instance);
+
+ return $instance;
+ }
+
+ /**
+ * Gets the 'foo.baz' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return BazClass A BazClass instance.
+ */
+ protected function getFoo_BazService()
+ {
+ $this->services['foo.baz'] = $instance = call_user_func(array('BazClass', 'getInstance'));
+
+ call_user_func(array('BazClass', 'configureStatic1'), $instance);
+
+ return $instance;
+ }
+
+ /**
+ * Gets the 'foo_bar' service.
+ *
+ * @return FooClass A FooClass instance.
+ */
+ protected function getFooBarService()
+ {
+ return new \FooClass();
+ }
+
+ /**
+ * Gets the 'foo_with_inline' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return Foo A Foo instance.
+ */
+ protected function getFooWithInlineService()
+ {
+ $a = new \Bar();
+
+ $this->services['foo_with_inline'] = $instance = new \Foo();
+
+ $a->setBaz($this->get('baz'));
+ $a->pub = 'pub';
+
+ $instance->setBar($a);
+
+ return $instance;
+ }
+
+ /**
+ * Gets the 'method_call1' service.
+ *
+ * This service is shared.
+ * This method always returns the same instance of the service.
+ *
+ * @return FooClass A FooClass instance.
+ */
+ protected function getMethodCall1Service()
+ {
+ require_once '%path%foo.php';
+
+ $this->services['method_call1'] = $instance = new \FooClass();
+
+ $instance->setBar($this->get('foo'));
+ $instance->setBar(NULL);
+
+ return $instance;
+ }
+
+ /**
+ * Gets the alias_for_foo service alias.
+ *
+ * @return FooClass An instance of the foo service
+ */
+ protected function getAliasForFooService()
+ {
+ return $this->get('foo');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getParameter($name)
+ {
+ $name = strtolower($name);
+
+ if (!array_key_exists($name, $this->parameters)) {
+ throw new \InvalidArgumentException(sprintf('The parameter "%s" must be defined.', $name));
+ }
+
+ return $this->parameters[$name];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasParameter($name)
+ {
+ return array_key_exists(strtolower($name), $this->parameters);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setParameter($name, $value)
+ {
+ throw new \LogicException('Impossible to call set() on a frozen ParameterBag.');
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getParameterBag()
+ {
+ if (null === $this->parameterBag) {
+ $this->parameterBag = new FrozenParameterBag($this->parameters);
+ }
+
+ return $this->parameterBag;
+ }
+ /**
+ * Gets the default parameters.
+ *
+ * @return array An array of the default parameters
+ */
+ protected function getDefaultParameters()
+ {
+ return array(
+ 'baz_class' => 'BazClass',
+ 'foo_class' => 'FooClass',
+ 'foo' => 'bar',
+ );
+ }
+}
diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/services9.xml b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/services9.xml
index a73fb3e7d1..58eb6d79a3 100644
--- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/services9.xml
+++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/xml/services9.xml
@@ -6,14 +6,14 @@
bar
-
+
foo
foo is %foo%
- %foo%
+ %foo%
true
@@ -34,7 +34,7 @@
-
+
%path%foo.php
@@ -50,7 +50,23 @@
-
+
+
+
+
+
+
+
+ pub
+
+
+
+
+
+
+
+
+
diff --git a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/yaml/services9.yml b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/yaml/services9.yml
index 6f0eca9038..d0085536ac 100644
--- a/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/yaml/services9.yml
+++ b/tests/Symfony/Tests/Component/DependencyInjection/Fixtures/yaml/services9.yml
@@ -10,13 +10,12 @@ services:
- { name: foo, foo: foo }
- { name: foo, bar: bar }
factory_method: getInstance
- arguments: [foo, '@foo.baz', { '%foo%': 'foo is %foo%', bar: '%foo%' }, true, '@service_container']
+ arguments: [foo, '@foo.baz', { '%foo%': 'foo is %foo%', foobar: '%foo%' }, true, '@service_container']
properties: { foo: bar, moo: '@foo.baz' }
calls:
- [setBar, ['@bar']]
- [initialize, { }]
- scope: prototype
configurator: sc_configure
bar:
class: FooClass
@@ -28,6 +27,7 @@ services:
configurator: ['%baz_class%', configureStatic1]
foo_bar:
class: %foo_class%
+ scope: prototype
method_call1:
class: FooClass
file: %path%foo.php
@@ -38,6 +38,23 @@ services:
- [setBar, ['@?foobaz']]
factory_service:
+ class: Bar
factory_method: getInstance
factory_service: foo.baz
+ foo_with_inline:
+ class: Foo
+ calls:
+ - [setBar, ['@inlined']]
+
+ inlined:
+ class: Bar
+ properties: { pub: pub }
+ calls:
+ - [setBaz, ['@baz']]
+
+ baz:
+ class: Baz
+ calls:
+ - [setFoo, ['@foo_with_inline']]
+
alias_for_foo: @foo