Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a31b5d0

Browse files
Merge branch '3.4' into 4.1
* 3.4: [DI] fix analyzing lazy refs involved in circular loops
2 parents 2130c60 + 98d7a95 commit a31b5d0

File tree

3 files changed

+16
-23
lines changed

3 files changed

+16
-23
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,17 @@ class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements Repe
3434
private $graph;
3535
private $currentDefinition;
3636
private $onlyConstructorArguments;
37+
private $hasProxyDumper;
3738
private $lazy;
3839
private $expressionLanguage;
3940

4041
/**
4142
* @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
4243
*/
43-
public function __construct(bool $onlyConstructorArguments = false)
44+
public function __construct(bool $onlyConstructorArguments = false, bool $hasProxyDumper = true)
4445
{
4546
$this->onlyConstructorArguments = $onlyConstructorArguments;
47+
$this->hasProxyDumper = $hasProxyDumper;
4648
}
4749

4850
/**
@@ -97,7 +99,7 @@ protected function processValue($value, $isRoot = false)
9799
$targetId,
98100
$targetDefinition,
99101
$value,
100-
$this->lazy || ($targetDefinition && $targetDefinition->isLazy()),
102+
$this->lazy || ($this->hasProxyDumper && $targetDefinition && $targetDefinition->isLazy()),
101103
ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior()
102104
);
103105

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

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
1616
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
1717
use Symfony\Component\DependencyInjection\Compiler\AnalyzeServiceReferencesPass;
18+
use Symfony\Component\DependencyInjection\Compiler\CheckCircularReferencesPass;
1819
use Symfony\Component\DependencyInjection\Container;
1920
use Symfony\Component\DependencyInjection\ContainerBuilder;
2021
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -140,29 +141,19 @@ public function dump(array $options = array())
140141
$this->initializeMethodNamesMap('Container' === $baseClass ? Container::class : $baseClass);
141142

142143
if ($this->getProxyDumper() instanceof NullDumper) {
143-
(new AnalyzeServiceReferencesPass(true))->process($this->container);
144-
$this->circularReferences = array();
145-
$checkedNodes = array();
146-
foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
147-
$currentPath = array($id => $id);
148-
$this->analyzeCircularReferences($node->getOutEdges(), $checkedNodes, $currentPath);
149-
}
150-
foreach ($this->circularReferences as $parent => $ids) {
151-
$path = array($parent);
152-
while (!isset($ids[$parent])) {
153-
foreach ($ids as $id) {
154-
$path[] = $id;
155-
$ids = $this->circularReferences[$id];
156-
break;
157-
}
158-
}
159-
$path[] = $parent.'". Try running "composer require symfony/proxy-manager-bridge';
144+
(new AnalyzeServiceReferencesPass(true, false))->process($this->container);
145+
try {
146+
(new CheckCircularReferencesPass())->process($this->container);
147+
} catch (ServiceCircularReferenceException $e) {
148+
$path = $e->getPath();
149+
end($path);
150+
$path[key($path)] .= '". Try running "composer require symfony/proxy-manager-bridge';
160151

161-
throw new ServiceCircularReferenceException($parent, $path);
152+
throw new ServiceCircularReferenceException($e->getServiceId(), $path);
162153
}
163154
}
164155

165-
(new AnalyzeServiceReferencesPass())->process($this->container);
156+
(new AnalyzeServiceReferencesPass(false, !$this->getProxyDumper() instanceof NullDumper))->process($this->container);
166157
$this->circularReferences = array();
167158
$checkedNodes = array();
168159
foreach ($this->container->getCompiler()->getServiceReferenceGraph()->getNodes() as $id => $node) {
@@ -369,7 +360,7 @@ private function analyzeCircularReferences(array $edges, &$checkedNodes, &$curre
369360
$node = $edge->getDestNode();
370361
$id = $node->getId();
371362

372-
if ($node->getValue() && (($edge->isLazy() && !$this->getProxyDumper() instanceof NullDumper) || $edge->isWeak())) {
363+
if ($node->getValue() && ($edge->isLazy() || $edge->isWeak())) {
373364
// no-op
374365
} elseif (isset($currentPath[$id])) {
375366
foreach (array_reverse($currentPath) as $parentId) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ public function testCircularReferenceAllowanceForLazyServices()
578578

579579
$dumper = new PhpDumper($container);
580580

581-
$message = 'Circular reference detected for service "bar", path: "bar -> foo -> bar". Try running "composer require symfony/proxy-manager-bridge".';
581+
$message = 'Circular reference detected for service "foo", path: "foo -> bar -> foo". Try running "composer require symfony/proxy-manager-bridge".';
582582
if (method_exists($this, 'expectException')) {
583583
$this->expectException(ServiceCircularReferenceException::class);
584584
$this->expectExceptionMessage($message);

0 commit comments

Comments
 (0)