[DI] Fix the "almost-circular refs" fix
This commit is contained in:
parent
e81005ed5e
commit
db12a9872d
@ -1490,29 +1490,37 @@ EOF;
|
||||
if ($this->hasReference($id, $argument, $deep, $visited)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
continue;
|
||||
} elseif ($argument instanceof Reference) {
|
||||
$argumentId = (string) $argument;
|
||||
if ($id === $argumentId) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($deep && !isset($visited[$argumentId]) && 'service_container' !== $argumentId) {
|
||||
$visited[$argumentId] = true;
|
||||
|
||||
$service = $this->container->getDefinition($argumentId);
|
||||
|
||||
// if the proxy manager is enabled, disable searching for references in lazy services,
|
||||
// as these services will be instantiated lazily and don't have direct related references.
|
||||
if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());
|
||||
|
||||
if ($this->hasReference($id, $arguments, $deep, $visited)) {
|
||||
return true;
|
||||
}
|
||||
if (!$deep || isset($visited[$argumentId]) || 'service_container' === $argumentId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$visited[$argumentId] = true;
|
||||
|
||||
$service = $this->container->getDefinition($argumentId);
|
||||
} elseif ($argument instanceof Definition) {
|
||||
$service = $argument;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if the proxy manager is enabled, disable searching for references in lazy services,
|
||||
// as these services will be instantiated lazily and don't have direct related references.
|
||||
if ($service->isLazy() && !$this->getProxyDumper() instanceof NullDumper) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());
|
||||
|
||||
if ($this->hasReference($id, $arguments, $deep, $visited)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1203,8 +1203,19 @@ class ContainerBuilderTest extends TestCase
|
||||
$this->assertEquals(array('foo1' => new \stdClass(), 'foo3' => new \stdClass()), iterator_to_array($bar->iter));
|
||||
}
|
||||
|
||||
public function testAlmostCircular()
|
||||
public function testAlmostCircularPrivate()
|
||||
{
|
||||
$public = false;
|
||||
$container = include __DIR__.'/Fixtures/containers/container_almost_circular.php';
|
||||
|
||||
$foo = $container->get('foo');
|
||||
|
||||
$this->assertSame($foo, $foo->bar->foobar->foo);
|
||||
}
|
||||
|
||||
public function testAlmostCircularPublic()
|
||||
{
|
||||
$public = true;
|
||||
$container = include __DIR__.'/Fixtures/containers/container_almost_circular.php';
|
||||
|
||||
$foo = $container->get('foo');
|
||||
|
@ -764,17 +764,35 @@ class PhpDumperTest extends TestCase
|
||||
$this->assertEquals(array('foo1' => new \stdClass(), 'foo3' => new \stdClass()), iterator_to_array($bar->iter));
|
||||
}
|
||||
|
||||
public function testAlmostCircular()
|
||||
public function testAlmostCircularPrivate()
|
||||
{
|
||||
$public = false;
|
||||
$container = include self::$fixturesPath.'/containers/container_almost_circular.php';
|
||||
$container->compile();
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/php/container_almost_circular.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Almost_Circular')));
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/php/container_almost_circular_private.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Almost_Circular_Private')));
|
||||
|
||||
require self::$fixturesPath.'/php/container_almost_circular.php';
|
||||
require self::$fixturesPath.'/php/container_almost_circular_private.php';
|
||||
|
||||
$container = new \Symfony_DI_PhpDumper_Test_Almost_Circular();
|
||||
$container = new \Symfony_DI_PhpDumper_Test_Almost_Circular_Private();
|
||||
$foo = $container->get('foo');
|
||||
|
||||
$this->assertSame($foo, $foo->bar->foobar->foo);
|
||||
}
|
||||
|
||||
public function testAlmostCircularPublic()
|
||||
{
|
||||
$public = true;
|
||||
$container = include self::$fixturesPath.'/containers/container_almost_circular.php';
|
||||
$container->compile();
|
||||
$dumper = new PhpDumper($container);
|
||||
|
||||
$this->assertStringEqualsFile(self::$fixturesPath.'/php/container_almost_circular_public.php', $dumper->dump(array('class' => 'Symfony_DI_PhpDumper_Test_Almost_Circular_Public')));
|
||||
|
||||
require self::$fixturesPath.'/php/container_almost_circular_public.php';
|
||||
|
||||
$container = new \Symfony_DI_PhpDumper_Test_Almost_Circular_Public();
|
||||
$foo = $container->get('foo');
|
||||
|
||||
$this->assertSame($foo, $foo->bar->foobar->foo);
|
||||
|
@ -10,10 +10,10 @@ $container = new ContainerBuilder();
|
||||
$container->register('foo', FooCircular::class)->setPublic(true)
|
||||
->addArgument(new Reference('bar'));
|
||||
|
||||
$container->register('bar', BarCircular::class)
|
||||
$container->register('bar', BarCircular::class)->setPublic($public)
|
||||
->addMethodCall('addFoobar', array(new Reference('foobar')));
|
||||
|
||||
$container->register('foobar', FoobarCircular::class)
|
||||
$container->register('foobar', FoobarCircular::class)->setPublic($public)
|
||||
->addArgument(new Reference('foo'));
|
||||
|
||||
return $container;
|
||||
|
@ -0,0 +1,75 @@
|
||||
<?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_Almost_Circular_Private extends Container
|
||||
{
|
||||
private $parameters;
|
||||
private $targetDirs = array();
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->services = array();
|
||||
$this->methodMap = array(
|
||||
'foo' => 'getFooService',
|
||||
);
|
||||
|
||||
$this->aliases = array();
|
||||
}
|
||||
|
||||
public function getRemovedIds()
|
||||
{
|
||||
return array(
|
||||
'Psr\\Container\\ContainerInterface' => true,
|
||||
'Symfony\\Component\\DependencyInjection\\ContainerInterface' => true,
|
||||
'bar' => true,
|
||||
'foobar' => true,
|
||||
);
|
||||
}
|
||||
|
||||
public function compile()
|
||||
{
|
||||
throw new LogicException('You cannot compile a dumped container that was already compiled.');
|
||||
}
|
||||
|
||||
public function isCompiled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isFrozen()
|
||||
{
|
||||
@trigger_error(sprintf('The %s() method is deprecated since version 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'foo' shared service.
|
||||
*
|
||||
* @return \FooCircular
|
||||
*/
|
||||
protected function getFooService()
|
||||
{
|
||||
$a = new \BarCircular();
|
||||
|
||||
$this->services['foo'] = $instance = new \FooCircular($a);
|
||||
|
||||
$a->addFoobar(new \FoobarCircular($instance));
|
||||
|
||||
|
||||
return $instance;
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@ use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
||||
*
|
||||
* @final since Symfony 3.3
|
||||
*/
|
||||
class Symfony_DI_PhpDumper_Test_Almost_Circular extends Container
|
||||
class Symfony_DI_PhpDumper_Test_Almost_Circular_Public extends Container
|
||||
{
|
||||
private $parameters;
|
||||
private $targetDirs = array();
|
||||
@ -27,10 +27,6 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular extends Container
|
||||
'foo' => 'getFooService',
|
||||
'foobar' => 'getFoobarService',
|
||||
);
|
||||
$this->privates = array(
|
||||
'bar' => true,
|
||||
'foobar' => true,
|
||||
);
|
||||
|
||||
$this->aliases = array();
|
||||
}
|
||||
@ -60,6 +56,20 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular extends Container
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'bar' shared service.
|
||||
*
|
||||
* @return \BarCircular
|
||||
*/
|
||||
protected function getBarService()
|
||||
{
|
||||
$this->services['bar'] = $instance = new \BarCircular();
|
||||
|
||||
$instance->addFoobar(${($_ = isset($this->services['foobar']) ? $this->services['foobar'] : $this->getFoobarService()) && false ?: '_'});
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the public 'foo' shared service.
|
||||
*
|
||||
@ -77,21 +87,7 @@ class Symfony_DI_PhpDumper_Test_Almost_Circular extends Container
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the private 'bar' shared service.
|
||||
*
|
||||
* @return \BarCircular
|
||||
*/
|
||||
protected function getBarService()
|
||||
{
|
||||
$this->services['bar'] = $instance = new \BarCircular();
|
||||
|
||||
$instance->addFoobar(${($_ = isset($this->services['foobar']) ? $this->services['foobar'] : $this->getFoobarService()) && false ?: '_'});
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the private 'foobar' shared service.
|
||||
* Gets the public 'foobar' shared service.
|
||||
*
|
||||
* @return \FoobarCircular
|
||||
*/
|
Reference in New Issue
Block a user