Node.php 5.7KB

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