f39a89af2be710018cf6d31c5633424934fd6fca
[yaffs-website] / vendor / symfony / dependency-injection / Compiler / CheckCircularReferencesPass.php
1 <?php
2
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11
12 namespace Symfony\Component\DependencyInjection\Compiler;
13
14 use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
15 use Symfony\Component\DependencyInjection\ContainerBuilder;
16
17 /**
18  * Checks your services for circular references.
19  *
20  * References from method calls are ignored since we might be able to resolve
21  * these references depending on the order in which services are called.
22  *
23  * Circular reference from method calls will only be detected at run-time.
24  *
25  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
26  */
27 class CheckCircularReferencesPass implements CompilerPassInterface
28 {
29     private $currentPath;
30     private $checkedNodes;
31
32     /**
33      * Checks the ContainerBuilder object for circular references.
34      *
35      * @param ContainerBuilder $container The ContainerBuilder instances
36      */
37     public function process(ContainerBuilder $container)
38     {
39         $graph = $container->getCompiler()->getServiceReferenceGraph();
40
41         $this->checkedNodes = array();
42         foreach ($graph->getNodes() as $id => $node) {
43             $this->currentPath = array($id);
44
45             $this->checkOutEdges($node->getOutEdges());
46         }
47     }
48
49     /**
50      * Checks for circular references.
51      *
52      * @param ServiceReferenceGraphEdge[] $edges An array of Edges
53      *
54      * @throws ServiceCircularReferenceException When a circular reference is found.
55      */
56     private function checkOutEdges(array $edges)
57     {
58         foreach ($edges as $edge) {
59             $node = $edge->getDestNode();
60             $id = $node->getId();
61
62             if (empty($this->checkedNodes[$id])) {
63                 // don't check circular dependencies for lazy services
64                 if (!$node->getValue() || !$node->getValue()->isLazy()) {
65                     $searchKey = array_search($id, $this->currentPath);
66                     $this->currentPath[] = $id;
67
68                     if (false !== $searchKey) {
69                         throw new ServiceCircularReferenceException($id, array_slice($this->currentPath, $searchKey));
70                     }
71
72                     $this->checkOutEdges($node->getOutEdges());
73                 }
74
75                 $this->checkedNodes[$id] = true;
76                 array_pop($this->currentPath);
77             }
78         }
79     }
80 }