[345] | 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.potencier@symfony-project.com> |
---|
| 18 | */ |
---|
| 19 | class Twig_Node implements Twig_NodeInterface, Countable, IteratorAggregate |
---|
| 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 | } |
---|