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