| 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 | }
 |