8000 [DependencyInjection] PhpDumper.php: hasReference() should not search… · symfony/symfony@595a978 · GitHub
[go: up one dir, main page]

Skip to content

Commit 595a978

Browse files
[DependencyInjection] PhpDumper.php: hasReference() should not search references in lazy service arguments.
1 parent 777cdfc commit 595a978

File tree

4 files changed

+99
-6
lines changed

4 files changed

+99
-6
lines changed

src/Symfony/Component/DependencyInjection/Compiler/CheckCircularReferencesPass.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,19 @@ private function checkOutEdges(array $edges)
6060
$id = $node->getId();
6161

6262
if (empty($this->checkedNodes[$id])) {
63-
$searchKey = array_search($id, $this->currentPath);
64-
$this->currentPath[] = $id;
6563

66-
if (false !== $searchKey) {
67-
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
68-
}
64+
// * don't check circular dependencies in lazy services.
65+
$isLazy = $node->getValue() && $node->getValue()->isLazy();
66+
if (!$isLazy) {
67+
$searchKey = array_search($id, $this->currentPath);
68+
$this->currentPath[] = $id;
69+
70+
if (false !== $searchKey) {
71+
throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
72+
}
6973

70-
$this->checkOutEdges($node->getOutEdges());
74+
$this->checkOutEdges($node->getOutEdges());
75+
}
7176

7277
$this->checkedNodes[$id] = true;
7378
array_pop($this->currentPath);

src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,6 +1293,13 @@ private function hasReference($id, array $arguments, $deep = false, array &$visi
12931293
$visited[$argumentId] = true;
12941294

12951295
$service = $this->container->getDefinition($argumentId);
1296+
1297+
// if exists proxy dumper (proxy-manager) don't search references in lazy services.
1298+
// As these services will be instantiated lazily and don't have direct related references.
1299+
if ($service->isLazy() && !($this->getProxyDumper() instanceof NullDumper)) {
1300+
continue;
1301+
}
1302+
12961303
$arguments = array_merge($service->getMethodCalls(), $service->getArguments(), $service->getProperties());
12971304

12981305
if ($this->hasReference($id, $arguments, $deep, $visited)) {

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection\Tests\Dumper;
1313

14+
8000 use DummyProxyDumper;
1415
use Symfony\Component\DependencyInjection\ContainerBuilder;
1516
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
1617
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
@@ -19,6 +20,8 @@
1920
use Symfony\Component\DependencyInjection\Variable;
2021
use Symfony\Component\ExpressionLanguage\Expression;
2122

23+
require_once __DIR__.'/../Fixtures/includes/classes.php';
24+
2225
class PhpDumperTest extends \PHPUnit_Framework_TestCase
2326
{
2427
protected static $fixturesPath;
@@ -286,4 +289,52 @@ public function testInitializePropertiesBeforeMethodCalls()
286289
$container = new \Symfony_DI_PhpDumper_Test_Properties_Before_Method_Calls();
287290
$this->assertTrue($container->get('bar')->callPassed(), '->dump() initializes properties before method calls');
288291
}
292+
293+
public function testCircularReferenceAllowanceForLazyServices()
294+
{
295+
$container = new ContainerBuilder();
296+
$container->register('foo', 'stdClass')->addArgument(new Reference('bar'));
297+
$container->register('bar', 'stdClass')->setLazy(true)->addArgument(new Reference('foo'));
298+
$container->compile();
299+
300+
$dumper = new PhpDumper($container);
301+
$dumper->dump();
302+
}
303+
304+
public function testCircularReferenceAllowanceForInlinedDefinitionsForLazyServices()
305+
{
306+
/*
307+
* test graph:
308+
* [connection] -> [event_manager] --> [entity_manager](lazy)
309+
* |
310+
* --(call)- addEventListener ("@lazy_service")
311+
*
312+
* [lazy_service](lazy) -> [entity_manager](lazy)
313+
*
314+
*/
315+
316+
$container = new ContainerBuilder();
317+
318+
$eventManagerDefinition = new Definition('stdClass');
319+
320+
$connectionDefinition = $container->register('connection', 'stdClass');
321+
$connectionDefinition->addArgument($eventManagerDefinition);
322+
323+
$container->register('entity_manager', 'stdClass')
324+
->setLazy(true)
325+
->addArgument(new Reference('connection'));
326+
327+
$lazyServiceDefinition = $container->register('lazy_service', 'stdClass');
328+
$lazyServiceDefinition->setLazy(true);
329+
$lazyServiceDefinition->addArgument(new Reference('entity_manager'));
330+
331+
$eventManagerDefinition->addMethodCall('addEventListener', array(new Reference('lazy_service')));
332+
333+
$container->compile();
334+
335+
$dumper = new PhpDumper($container);
336+
337+
$dumper->setProxyDumper(new DummyProxyDumper());
338+
$dumper->dump();
339+
}
289340
}

src/Symfony/Component/DependencyInjection/Tests/Fixtures/includes/classes.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<?php
22

3+
use Symfony\Component\DependencyInjection\Definition;
4+
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface as ProxyDumper;
5+
36
function sc_configure($instance)
47
{
58
$instance->configure();
@@ -76,3 +79,30 @@ public function callPassed()
7679
return $this->callPassed;
7780
}
7881
}
82+
83+
class DummyProxyDumper implements ProxyDumper
84+
{
85+
/**
86+
* {@inheritdoc}
87+
*/
88+
public function isProxyCandidate(Definition $definition)
89+
{
90+
return false;
91+
}
92+
93+
/**
94+
* {@inheritdoc}
95+
*/
96+
public function getProxyFactoryCode(Definition $definition, $id)
97+
{
98+
return '';
99+
}
100+
101+
/**
102+
* {@inheritdoc}
103+
*/
104+
public function getProxyCode(Definition $definition)
105+
{
106+
return '';
107+
}
108+
}

0 commit comments

Comments
 (0)
0