| 
      1
     | 
    
      <?php
 
     | 
  
  
    | 
      2
     | 
    
      
 
     | 
  
  
    | 
      3
     | 
    
      /*
 
     | 
  
  
    | 
      4
     | 
    
       * This file is part of Twig.
 
     | 
  
  
    | 
      5
     | 
    
       *
 
     | 
  
  
    | 
      6
     | 
    
       * (c) 2009 Fabien Potencier
 
     | 
  
  
    | 
      7
     | 
    
       * (c) 2009 Armin Ronacher
 
     | 
  
  
    | 
      8
     | 
    
       *
 
     | 
  
  
    | 
      9
     | 
    
       * For the full copyright and license information, please view the LICENSE
 
     | 
  
  
    | 
      10
     | 
    
       * file that was distributed with this source code.
 
     | 
  
  
    | 
      11
     | 
    
       */
 
     | 
  
  
    | 
      12
     | 
    
      
 
     | 
  
  
    | 
      13
     | 
    
      /**
 
     | 
  
  
    | 
      14
     | 
    
       * Represents a node in the AST.
 
     | 
  
  
    | 
      15
     | 
    
       *
 
     | 
  
  
    | 
      16
     | 
    
       * @package    twig
 
     | 
  
  
    | 
      17
     | 
    
       * @author     Fabien Potencier <fabien@symfony.com>
 
     | 
  
  
    | 
      18
     | 
    
       */
 
     | 
  
  
    | 
      19
     | 
    
      class Twig_Node implements Twig_NodeInterface
 
     | 
  
  
    | 
      20
     | 
    
      {
     | 
  
  
    | 
      21
     | 
    
          protected $nodes;
 
     | 
  
  
    | 
      22
     | 
    
          protected $attributes;
 
     | 
  
  
    | 
      23
     | 
    
          protected $lineno;
 
     | 
  
  
    | 
      24
     | 
    
          protected $tag;
 
     | 
  
  
    | 
      25
     | 
    
      
 
     | 
  
  
    | 
      26
     | 
    
          /**
 
     | 
  
  
    | 
      27
     | 
    
           * Constructor.
 
     | 
  
  
    | 
      28
     | 
    
           *
 
     | 
  
  
    | 
      29
     | 
    
           * The nodes are automatically made available as properties ($this->node).
 
     | 
  
  
    | 
      30
     | 
    
           * The attributes are automatically made available as array items ($this['name']).
 
     | 
  
  
    | 
      31
     | 
    
           *
 
     | 
  
  
    | 
      32
     | 
    
           * @param array   $nodes      An array of named nodes
 
     | 
  
  
    | 
      33
     | 
    
           * @param array   $attributes An array of attributes (should not be nodes)
 
     | 
  
  
    | 
      34
     | 
    
           * @param integer $lineno     The line number
 
     | 
  
  
    | 
      35
     | 
    
           * @param string  $tag        The tag name associated with the Node
 
     | 
  
  
    | 
      36
     | 
    
           */
 
     | 
  
  
    | 
      37
     | 
    
          public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
 
     | 
  
  
    | 
      38
     | 
    
          {
     | 
  
  
    | 
      39
     | 
    
              $this->nodes = $nodes;
 
     | 
  
  
    | 
      40
     | 
    
              $this->attributes = $attributes;
 
     | 
  
  
    | 
      41
     | 
    
              $this->lineno = $lineno;
 
     | 
  
  
    | 
      42
     | 
    
              $this->tag = $tag;
 
     | 
  
  
    | 
      43
     | 
    
          }
 
     | 
  
  
    | 
      44
     | 
    
      
 
     | 
  
  
    | 
      45
     | 
    
          public function __toString()
 
     | 
  
  
    | 
      46
     | 
    
          {
     | 
  
  
    | 
      47
     | 
    
              $attributes = array();
 
     | 
  
  
    | 
      48
     | 
    
              foreach ($this->attributes as $name => $value) {
     | 
  
  
    | 
      49
     | 
    
                  $attributes[] = sprintf('%s: %s', $name, str_replace("\n", '', var_export($value, true)));
     | 
  
  
    | 
      50
     | 
    
              }
 
     | 
  
  
    | 
      51
     | 
    
      
 
     | 
  
  
    | 
      52
     | 
    
              $repr = array(get_class($this).'('.implode(', ', $attributes));
     | 
  
  
    | 
      53
     | 
    
      
 
     | 
  
  
    | 
      54
     | 
    
              if (count($this->nodes)) {
     | 
  
  
    | 
      55
     | 
    
                  foreach ($this->nodes as $name => $node) {
     | 
  
  
    | 
      56
     | 
    
                      $len = strlen($name) + 4;
 
     | 
  
  
    | 
      57
     | 
    
                      $noderepr = array();
 
     | 
  
  
    | 
      58
     | 
    
                      foreach (explode("\n", (string) $node) as $line) {
     | 
  
  
    | 
      59
     | 
    
                          $noderepr[] = str_repeat(' ', $len).$line;
     | 
  
  
    | 
      60
     | 
    
                      }
 
     | 
  
  
    | 
      61
     | 
    
      
 
     | 
  
  
    | 
      62
     | 
    
                      $repr[] = sprintf('  %s: %s', $name, ltrim(implode("\n", $noderepr)));
     | 
  
  
    | 
      63
     | 
    
                  }
 
     | 
  
  
    | 
      64
     | 
    
      
 
     | 
  
  
    | 
      65
     | 
    
                  $repr[] = ')';
 
     | 
  
  
    | 
      66
     | 
    
              } else {
     | 
  
  
    | 
      67
     | 
    
                  $repr[0] .= ')';
 
     | 
  
  
    | 
      68
     | 
    
              }
 
     | 
  
  
    | 
      69
     | 
    
      
 
     | 
  
  
    | 
      70
     | 
    
              return implode("\n", $repr);
     | 
  
  
    | 
      71
     | 
    
          }
 
     | 
  
  
    | 
      72
     | 
    
      
 
     | 
  
  
    | 
      73
     | 
    
          public function toXml($asDom = false)
 
     | 
  
  
    | 
      74
     | 
    
          {
     | 
  
  
    | 
      75
     | 
    
              $dom = new DOMDocument('1.0', 'UTF-8');
     | 
  
  
    | 
      76
     | 
    
              $dom->formatOutput = true;
 
     | 
  
  
    | 
      77
     | 
    
              $dom->appendChild($xml = $dom->createElement('twig'));
     | 
  
  
    | 
      78
     | 
    
      
 
     | 
  
  
    | 
      79
     | 
    
              $xml->appendChild($node = $dom->createElement('node'));
     | 
  
  
    | 
      80
     | 
    
              $node->setAttribute('class', get_class($this));
     | 
  
  
    | 
      81
     | 
    
      
 
     | 
  
  
    | 
      82
     | 
    
              foreach ($this->attributes as $name => $value) {
     | 
  
  
    | 
      83
     | 
    
                  $node->appendChild($attribute = $dom->createElement('attribute'));
     | 
  
  
    | 
      84
     | 
    
                  $attribute->setAttribute('name', $name);
     | 
  
  
    | 
      85
     | 
    
                  $attribute->appendChild($dom->createTextNode($value));
 
     | 
  
  
    | 
      86
     | 
    
              }
 
     | 
  
  
    | 
      87
     | 
    
      
 
     | 
  
  
    | 
      88
     | 
    
              foreach ($this->nodes as $name => $n) {
     | 
  
  
    | 
      89
     | 
    
                  if (null === $n) {
     | 
  
  
    | 
      90
     | 
    
                      continue;
 
     | 
  
  
    | 
      91
     | 
    
                  }
 
     | 
  
  
    | 
      92
     | 
    
      
 
     | 
  
  
    | 
      93
     | 
    
                  $child = $n->toXml(true)->getElementsByTagName('node')->item(0);
     | 
  
  
    | 
      94
     | 
    
                  $child = $dom->importNode($child, true);
 
     | 
  
  
    | 
      95
     | 
    
                  $child->setAttribute('name', $name);
     | 
  
  
    | 
      96
     | 
    
      
 
     | 
  
  
    | 
      97
     | 
    
                  $node->appendChild($child);
 
     | 
  
  
    | 
      98
     | 
    
              }
 
     | 
  
  
    | 
      99
     | 
    
      
 
     | 
  
  
    | 
      100
     | 
    
              return $asDom ? $dom : $dom->saveXml();
 
     | 
  
  
    | 
      101
     | 
    
          }
 
     | 
  
  
    | 
      102
     | 
    
      
 
     | 
  
  
    | 
      103
     | 
    
          public function compile(Twig_Compiler $compiler)
 
     | 
  
  
    | 
      104
     | 
    
          {
     | 
  
  
    | 
      105
     | 
    
              foreach ($this->nodes as $node) {
     | 
  
  
    | 
      106
     | 
    
                  $node->compile($compiler);
 
     | 
  
  
    | 
      107
     | 
    
              }
 
     | 
  
  
    | 
      108
     | 
    
          }
 
     | 
  
  
    | 
      109
     | 
    
      
 
     | 
  
  
    | 
      110
     | 
    
          public function getLine()
 
     | 
  
  
    | 
      111
     | 
    
          {
     | 
  
  
    | 
      112
     | 
    
              return $this->lineno;
 
     | 
  
  
    | 
      113
     | 
    
          }
 
     | 
  
  
    | 
      114
     | 
    
      
 
     | 
  
  
    | 
      115
     | 
    
          public function getNodeTag()
 
     | 
  
  
    | 
      116
     | 
    
          {
     | 
  
  
    | 
      117
     | 
    
              return $this->tag;
 
     | 
  
  
    | 
      118
     | 
    
          }
 
     | 
  
  
    | 
      119
     | 
    
      
 
     | 
  
  
    | 
      120
     | 
    
          /**
 
     | 
  
  
    | 
      121
     | 
    
           * Returns true if the attribute is defined.
 
     | 
  
  
    | 
      122
     | 
    
           *
 
     | 
  
  
    | 
      123
     | 
    
           * @param  string  The attribute name
 
     | 
  
  
    | 
      124
     | 
    
           *
 
     | 
  
  
    | 
      125
     | 
    
           * @return Boolean true if the attribute is defined, false otherwise
 
     | 
  
  
    | 
      126
     | 
    
           */
 
     | 
  
  
    | 
      127
     | 
    
          public function hasAttribute($name)
 
     | 
  
  
    | 
      128
     | 
    
          {
     | 
  
  
    | 
      129
     | 
    
              return array_key_exists($name, $this->attributes);
 
     | 
  
  
    | 
      130
     | 
    
          }
 
     | 
  
  
    | 
      131
     | 
    
      
 
     | 
  
  
    | 
      132
     | 
    
          /**
 
     | 
  
  
    | 
      133
     | 
    
           * Gets an attribute.
 
     | 
  
  
    | 
      134
     | 
    
           *
 
     | 
  
  
    | 
      135
     | 
    
           * @param  string The attribute name
 
     | 
  
  
    | 
      136
     | 
    
           *
 
     | 
  
  
    | 
      137
     | 
    
           * @return mixed  The attribute value
 
     | 
  
  
    | 
      138
     | 
    
           */
 
     | 
  
  
    | 
      139
     | 
    
          public function getAttribute($name)
 
     | 
  
  
    | 
      140
     | 
    
          {
     | 
  
  
    | 
      141
     | 
    
              if (!array_key_exists($name, $this->attributes)) {
     | 
  
  
    | 
      142
     | 
    
                  throw new Twig_Error_Runtime(sprintf('Attribute "%s" does not exist for Node "%s".', $name, get_class($this)));
     | 
  
  
    | 
      143
     | 
    
              }
 
     | 
  
  
    | 
      144
     | 
    
      
 
     | 
  
  
    | 
      145
     | 
    
              return $this->attributes[$name];
 
     | 
  
  
    | 
      146
     | 
    
          }
 
     | 
  
  
    | 
      147
     | 
    
      
 
     | 
  
  
    | 
      148
     | 
    
          /**
 
     | 
  
  
    | 
      149
     | 
    
           * Sets an attribute.
 
     | 
  
  
    | 
      150
     | 
    
           *
 
     | 
  
  
    | 
      151
     | 
    
           * @param string The attribute name
 
     | 
  
  
    | 
      152
     | 
    
           * @param mixed  The attribute value
 
     | 
  
  
    | 
      153
     | 
    
           */
 
     | 
  
  
    | 
      154
     | 
    
          public function setAttribute($name, $value)
 
     | 
  
  
    | 
      155
     | 
    
          {
     | 
  
  
    | 
      156
     | 
    
              $this->attributes[$name] = $value;
 
     | 
  
  
    | 
      157
     | 
    
          }
 
     | 
  
  
    | 
      158
     | 
    
      
 
     | 
  
  
    | 
      159
     | 
    
          /**
 
     | 
  
  
    | 
      160
     | 
    
           * Removes an attribute.
 
     | 
  
  
    | 
      161
     | 
    
           *
 
     | 
  
  
    | 
      162
     | 
    
           * @param string The attribute name
 
     | 
  
  
    | 
      163
     | 
    
           */
 
     | 
  
  
    | 
      164
     | 
    
          public function removeAttribute($name)
 
     | 
  
  
    | 
      165
     | 
    
          {
     | 
  
  
    | 
      166
     | 
    
              unset($this->attributes[$name]);
 
     | 
  
  
    | 
      167
     | 
    
          }
 
     | 
  
  
    | 
      168
     | 
    
      
 
     | 
  
  
    | 
      169
     | 
    
          /**
 
     | 
  
  
    | 
      170
     | 
    
           * Returns true if the node with the given identifier exists.
 
     | 
  
  
    | 
      171
     | 
    
           *
 
     | 
  
  
    | 
      172
     | 
    
           * @param  string  The node name
 
     | 
  
  
    | 
      173
     | 
    
           *
 
     | 
  
  
    | 
      174
     | 
    
           * @return Boolean true if the node with the given name exists, false otherwise
 
     | 
  
  
    | 
      175
     | 
    
           */
 
     | 
  
  
    | 
      176
     | 
    
          public function hasNode($name)
 
     | 
  
  
    | 
      177
     | 
    
          {
     | 
  
  
    | 
      178
     | 
    
              return array_key_exists($name, $this->nodes);
 
     | 
  
  
    | 
      179
     | 
    
          }
 
     | 
  
  
    | 
      180
     | 
    
      
 
     | 
  
  
    | 
      181
     | 
    
          /**
 
     | 
  
  
    | 
      182
     | 
    
           * Gets a node by name.
 
     | 
  
  
    | 
      183
     | 
    
           *
 
     | 
  
  
    | 
      184
     | 
    
           * @param  string The node name
 
     | 
  
  
    | 
      185
     | 
    
           *
 
     | 
  
  
    | 
      186
     | 
    
           * @return Twig_Node A Twig_Node instance
 
     | 
  
  
    | 
      187
     | 
    
           */
 
     | 
  
  
    | 
      188
     | 
    
          public function getNode($name)
 
     | 
  
  
    | 
      189
     | 
    
          {
     | 
  
  
    | 
      190
     | 
    
              if (!array_key_exists($name, $this->nodes)) {
     | 
  
  
    | 
      191
     | 
    
                  throw new Twig_Error_Runtime(sprintf('Node "%s" does not exist for Node "%s".', $name, get_class($this)));
     | 
  
  
    | 
      192
     | 
    
              }
 
     | 
  
  
    | 
      193
     | 
    
      
 
     | 
  
  
    | 
      194
     | 
    
              return $this->nodes[$name];
 
     | 
  
  
    | 
      195
     | 
    
          }
 
     | 
  
  
    | 
      196
     | 
    
      
 
     | 
  
  
    | 
      197
     | 
    
          /**
 
     | 
  
  
    | 
      198
     | 
    
           * Sets a node.
 
     | 
  
  
    | 
      199
     | 
    
           *
 
     | 
  
  
    | 
      200
     | 
    
           * @param string    The node name
 
     | 
  
  
    | 
      201
     | 
    
           * @param Twig_Node A Twig_Node instance
 
     | 
  
  
    | 
      202
     | 
    
           */
 
     | 
  
  
    | 
      203
     | 
    
          public function setNode($name, $node = null)
 
     | 
  
  
    | 
      204
     | 
    
          {
     | 
  
  
    | 
      205
     | 
    
              $this->nodes[$name] = $node;
 
     | 
  
  
    | 
      206
     | 
    
          }
 
     | 
  
  
    | 
      207
     | 
    
      
 
     | 
  
  
    | 
      208
     | 
    
          /**
 
     | 
  
  
    | 
      209
     | 
    
           * Removes a node by name.
 
     | 
  
  
    | 
      210
     | 
    
           *
 
     | 
  
  
    | 
      211
     | 
    
           * @param string The node name
 
     | 
  
  
    | 
      212
     | 
    
           */
 
     | 
  
  
    | 
      213
     | 
    
          public function removeNode($name)
 
     | 
  
  
    | 
      214
     | 
    
          {
     | 
  
  
    | 
      215
     | 
    
              unset($this->nodes[$name]);
 
     | 
  
  
    | 
      216
     | 
    
          }
 
     | 
  
  
    | 
      217
     | 
    
      
 
     | 
  
  
    | 
      218
     | 
    
          public function count()
 
     | 
  
  
    | 
      219
     | 
    
          {
     | 
  
  
    | 
      220
     | 
    
              return count($this->nodes);
 
     | 
  
  
    | 
      221
     | 
    
          }
 
     | 
  
  
    | 
      222
     | 
    
      
 
     | 
  
  
    | 
      223
     | 
    
          public function getIterator()
 
     | 
  
  
    | 
      224
     | 
    
          {
     | 
  
  
    | 
      225
     | 
    
              return new ArrayIterator($this->nodes);
 
     | 
  
  
    | 
      226
     | 
    
          }
 
     | 
  
  
    | 
      227
     | 
    
      }
 
     |