NodeTraverser.php (2454B)
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 calls the given visitor for each. 16 * 17 * @author Fabien Potencier <fabien@symfony.com> 18 */ 19 class Twig_NodeTraverser 20 { 21 protected $env; 22 protected $visitors = array(); 23 24 /** 25 * Constructor. 26 * 27 * @param Twig_Environment $env A Twig_Environment instance 28 * @param Twig_NodeVisitorInterface[] $visitors An array of Twig_NodeVisitorInterface instances 29 */ 30 public function __construct(Twig_Environment $env, array $visitors = array()) 31 { 32 $this->env = $env; 33 foreach ($visitors as $visitor) { 34 $this->addVisitor($visitor); 35 } 36 } 37 38 /** 39 * Adds a visitor. 40 * 41 * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance 42 */ 43 public function addVisitor(Twig_NodeVisitorInterface $visitor) 44 { 45 if (!isset($this->visitors[$visitor->getPriority()])) { 46 $this->visitors[$visitor->getPriority()] = array(); 47 } 48 49 $this->visitors[$visitor->getPriority()][] = $visitor; 50 } 51 52 /** 53 * Traverses a node and calls the registered visitors. 54 * 55 * @param Twig_NodeInterface $node A Twig_NodeInterface instance 56 * 57 * @return Twig_NodeInterface 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; 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 }