|
1 <?php |
|
2 |
|
3 /* |
|
4 * This file is part of Twig. |
|
5 * |
|
6 * (c) 2009 Fabien Potencier |
|
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 /** |
|
13 * Twig_NodeTraverser is a node traverser. |
|
14 * |
|
15 * It visits all nodes and their children and call the given visitor for each. |
|
16 * |
|
17 * @package twig |
|
18 * @author Fabien Potencier <fabien@symfony.com> |
|
19 */ |
|
20 class Twig_NodeTraverser |
|
21 { |
|
22 protected $env; |
|
23 protected $visitors; |
|
24 |
|
25 /** |
|
26 * Constructor. |
|
27 * |
|
28 * @param Twig_Environment $env A Twig_Environment instance |
|
29 * @param array $visitors An array of Twig_NodeVisitorInterface instances |
|
30 */ |
|
31 public function __construct(Twig_Environment $env, array $visitors = array()) |
|
32 { |
|
33 $this->env = $env; |
|
34 $this->visitors = array(); |
|
35 foreach ($visitors as $visitor) { |
|
36 $this->addVisitor($visitor); |
|
37 } |
|
38 } |
|
39 |
|
40 /** |
|
41 * Adds a visitor. |
|
42 * |
|
43 * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance |
|
44 */ |
|
45 public function addVisitor(Twig_NodeVisitorInterface $visitor) |
|
46 { |
|
47 if (!isset($this->visitors[$visitor->getPriority()])) { |
|
48 $this->visitors[$visitor->getPriority()] = array(); |
|
49 } |
|
50 |
|
51 $this->visitors[$visitor->getPriority()][] = $visitor; |
|
52 } |
|
53 |
|
54 /** |
|
55 * Traverses a node and calls the registered visitors. |
|
56 * |
|
57 * @param Twig_NodeInterface $node A Twig_NodeInterface instance |
|
58 */ |
|
59 public function traverse(Twig_NodeInterface $node) |
|
60 { |
|
61 ksort($this->visitors); |
|
62 foreach ($this->visitors as $visitors) { |
|
63 foreach ($visitors as $visitor) { |
|
64 $node = $this->traverseForVisitor($visitor, $node); |
|
65 } |
|
66 } |
|
67 |
|
68 return $node; |
|
69 } |
|
70 |
|
71 protected function traverseForVisitor(Twig_NodeVisitorInterface $visitor, Twig_NodeInterface $node = null) |
|
72 { |
|
73 if (null === $node) { |
|
74 return null; |
|
75 } |
|
76 |
|
77 $node = $visitor->enterNode($node, $this->env); |
|
78 |
|
79 foreach ($node as $k => $n) { |
|
80 if (false !== $n = $this->traverseForVisitor($visitor, $n)) { |
|
81 $node->setNode($k, $n); |
|
82 } else { |
|
83 $node->removeNode($k); |
|
84 } |
|
85 } |
|
86 |
|
87 return $visitor->leaveNode($node, $this->env); |
|
88 } |
|
89 } |