Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. PhpDumper.php

function PhpDumper::collectCircularReferences

1 call to PhpDumper::collectCircularReferences()
PhpDumper::analyzeReferences in vendor/symfony/dependency-injection/Dumper/PhpDumper.php

File

vendor/symfony/dependency-injection/Dumper/PhpDumper.php, line 439

Class

PhpDumper
PhpDumper dumps a service container as a PHP class.

Namespace

Symfony\Component\DependencyInjection\Dumper

Code

private function collectCircularReferences(string $sourceId, array $edges, array &$checkedNodes, array &$loops = [], array $path = [], bool $byConstructor = true) : void {
    $path[$sourceId] = $byConstructor;
    $checkedNodes[$sourceId] = true;
    foreach ($edges as $edge) {
        $node = $edge->getDestNode();
        $id = $node->getId();
        if ($sourceId === $id || !$node->getValue() instanceof Definition || $edge->isWeak()) {
            continue;
        }
        if (isset($path[$id])) {
            $loop = null;
            $loopByConstructor = $edge->isReferencedByConstructor() && !$edge->isLazy();
            $pathInLoop = [
                $id,
                [],
            ];
            foreach ($path as $k => $pathByConstructor) {
                if (null !== $loop) {
                    $loop[] = $k;
                    $pathInLoop[1][$k] = $pathByConstructor;
                    $loops[$k][] =& $pathInLoop;
                    $loopByConstructor = $loopByConstructor && $pathByConstructor;
                }
                elseif ($k === $id) {
                    $loop = [];
                }
            }
            $this->addCircularReferences($id, $loop, $loopByConstructor);
        }
        elseif (!isset($checkedNodes[$id])) {
            $this->collectCircularReferences($id, $node->getOutEdges(), $checkedNodes, $loops, $path, $edge->isReferencedByConstructor() && !$edge->isLazy());
        }
        elseif (isset($loops[$id])) {
            // we already had detected loops for this edge
            // let's check if we have a common ancestor in one of the detected loops
            foreach ($loops[$id] as [
                $first,
                $loopPath,
            ]) {
                if (!isset($path[$first])) {
                    continue;
                }
                // We have a common ancestor, let's fill the current path
                $fillPath = null;
                foreach ($loopPath as $k => $pathByConstructor) {
                    if (null !== $fillPath) {
                        $fillPath[$k] = $pathByConstructor;
                    }
                    elseif ($k === $id) {
                        $fillPath = $path;
                        $fillPath[$k] = $pathByConstructor;
                    }
                }
                // we can now build the loop
                $loop = null;
                $loopByConstructor = $edge->isReferencedByConstructor() && !$edge->isLazy();
                foreach ($fillPath as $k => $pathByConstructor) {
                    if (null !== $loop) {
                        $loop[] = $k;
                        $loopByConstructor = $loopByConstructor && $pathByConstructor;
                    }
                    elseif ($k === $first) {
                        $loop = [];
                    }
                }
                $this->addCircularReferences($first, $loop, $loopByConstructor);
                break;
            }
        }
    }
    unset($path[$sourceId]);
}
RSS feed
Powered by Drupal