1 <?php\r
2 /**\r
3 * Smarty Internal Plugin Templateparser Parsetrees\r
4 *\r
5 * These are classes to build parsetrees in the template parser\r
6 *\r
7 * @package Smarty\r
8 * @subpackage Compiler\r
9 * @author Thue Kristensen\r
10 * @author Uwe Tews\r
11 */\r
12 \r
13 /**\r
14 * @package Smarty\r
15 * @subpackage Compiler\r
16 * @ignore\r
17 */\r
18 abstract class _smarty_parsetree {\r
19 \r
20 /**\r
21 * Parser object\r
22 * @var object\r
23 */\r
24 public $parser;\r
25 /**\r
26 * Buffer content\r
27 * @var mixed\r
28 */\r
29 public $data;\r
30 \r
31 /**\r
32 * Return buffer\r
33 *\r
34 * @return string buffer content\r
35 */\r
36 abstract public function to_smarty_php();\r
37 \r
38 }\r
39 \r
40 /**\r
41 * A complete smarty tag.\r
42 *\r
43 * @package Smarty\r
44 * @subpackage Compiler\r
45 * @ignore\r
46 */\r
47 class _smarty_tag extends _smarty_parsetree {\r
48 \r
49 /**\r
50 * Saved block nesting level\r
51 * @var int\r
52 */\r
53 public $saved_block_nesting;\r
54 \r
55 /**\r
56 * Create parse tree buffer for Smarty tag\r
57 *\r
58 * @param object $parser parser object\r
59 * @param string $data content\r
60 */\r
61 public function __construct($parser, $data)\r
62 {\r
63 $this->parser = $parser;\r
64 $this->data = $data;\r
65 $this->saved_block_nesting = $parser->block_nesting_level;\r
66 }\r
67 \r
68 /**\r
69 * Return buffer content\r
70 *\r
71 * @return string content\r
72 */\r
73 public function to_smarty_php()\r
74 {\r
75 return $this->data;\r
76 }\r
77 \r
78 /**\r
79 * Return complied code that loads the evaluated outout of buffer content into a temporary variable\r
80 *\r
81 * @return string template code\r
82 */\r
83 public function assign_to_var()\r
84 {\r
85 $var = sprintf('$_tmp%d', ++$this->parser->prefix_number);\r
86 $this->parser->compiler->prefix_code[] = sprintf('<?php ob_start();?>%s<?php %s=ob_get_clean();?>', $this->data, $var);\r
87 return $var;\r
88 }\r
89 \r
90 }\r
91 \r
92 /**\r
93 * Code fragment inside a tag.\r
94 *\r
95 * @package Smarty\r
96 * @subpackage Compiler\r
97 * @ignore\r
98 */\r
99 class _smarty_code extends _smarty_parsetree {\r
100 \r
101 \r
102 /**\r
103 * Create parse tree buffer for code fragment\r
104 *\r
105 * @param object $parser parser object\r
106 * @param string $data content\r
107 */\r
108 public function __construct($parser, $data)\r
109 {\r
110 $this->parser = $parser;\r
111 $this->data = $data;\r
112 }\r
113 \r
114 /**\r
115 * Return buffer content in parentheses\r
116 *\r
117 * @return string content\r
118 */\r
119 public function to_smarty_php()\r
120 {\r
121 return sprintf("(%s)", $this->data);\r
122 }\r
123 \r
124 }\r
125 \r
126 /**\r
127 * Double quoted string inside a tag.\r
128 *\r
129 * @package Smarty\r
130 * @subpackage Compiler\r
131 * @ignore\r
132 */\r
133 class _smarty_doublequoted extends _smarty_parsetree {\r
134 \r
135 /**\r
136 * Create parse tree buffer for double quoted string subtrees\r
137 *\r
138 * @param object $parser parser object\r
139 * @param _smarty_parsetree $subtree parsetree buffer\r
140 */\r
141 public function __construct($parser, _smarty_parsetree $subtree)\r
142 {\r
143 $this->parser = $parser;\r
144 $this->subtrees[] = $subtree;\r
145 if ($subtree instanceof _smarty_tag) {\r
146 $this->parser->block_nesting_level = count($this->parser->compiler->_tag_stack);\r
147 }\r
148 }\r
149 \r
150 /**\r
151 * Append buffer to subtree\r
152 *\r
153 * @param _smarty_parsetree $subtree parsetree buffer\r
154 */\r
155 public function append_subtree(_smarty_parsetree $subtree)\r
156 {\r
157 $last_subtree = count($this->subtrees) - 1;\r
158 if ($last_subtree >= 0 && $this->subtrees[$last_subtree] instanceof _smarty_tag && $this->subtrees[$last_subtree]->saved_block_nesting < $this->parser->block_nesting_level) {\r
159 if ($subtree instanceof _smarty_code) {\r
160 $this->subtrees[$last_subtree]->data .= '<?php echo ' . $subtree->data . ';?>';\r
161 } elseif ($subtree instanceof _smarty_dq_content) {\r
162 $this->subtrees[$last_subtree]->data .= '<?php echo "' . $subtree->data . '";?>';\r
163 } else {\r
164 $this->subtrees[$last_subtree]->data .= $subtree->data;\r
165 }\r
166 } else {\r
167 $this->subtrees[] = $subtree;\r
168 }\r
169 if ($subtree instanceof _smarty_tag) {\r
170 $this->parser->block_nesting_level = count($this->parser->compiler->_tag_stack);\r
171 }\r
172 }\r
173 \r
174 /**\r
175 * Merge subtree buffer content together\r
176 *\r
177 * @return string compiled template code\r
178 */\r
179 public function to_smarty_php()\r
180 {\r
181 $code = '';\r
182 foreach ($this->subtrees as $subtree) {\r
183 if ($code !== "") {\r
184 $code .= ".";\r
185 }\r
186 if ($subtree instanceof _smarty_tag) {\r
187 $more_php = $subtree->assign_to_var();\r
188 } else {\r
189 $more_php = $subtree->to_smarty_php();\r
190 }\r
191 \r
192 $code .= $more_php;\r
193 \r
194 if (!$subtree instanceof _smarty_dq_content) {\r
195 $this->parser->compiler->has_variable_string = true;\r
196 }\r
197 }\r
198 return $code;\r
199 }\r
200 \r
201 }\r
202 \r
203 /**\r
204 * Raw chars as part of a double quoted string.\r
205 *\r
206 * @package Smarty\r
207 * @subpackage Compiler\r
208 * @ignore\r
209 */\r
210 class _smarty_dq_content extends _smarty_parsetree {\r
211 \r
212 \r
213 /**\r
214 * Create parse tree buffer with string content\r
215 *\r
216 * @param object $parser parser object\r
217 * @param string $data string section\r
218 */\r
219 public function __construct($parser, $data)\r
220 {\r
221 $this->parser = $parser;\r
222 $this->data = $data;\r
223 }\r
224 \r
225 /**\r
226 * Return content as double quoted string\r
227 *\r
228 * @return string doubled quoted string\r
229 */\r
230 public function to_smarty_php()\r
231 {\r
232 return '"' . $this->data . '"';\r
233 }\r
234 \r
235 }\r
236 \r
237 /**\r
238 * Template element\r
239 *\r
240 * @package Smarty\r
241 * @subpackage Compiler\r
242 * @ignore\r
243 */\r
244 class _smarty_template_buffer extends _smarty_parsetree {\r
245 \r
246 /**\r
247 * Array of template elements\r
248 *\r
249 * @var array\r
250 */\r
251 public $subtrees = Array();\r
252 \r
253 /**\r
254 * Create root of parse tree for template elements\r
255 *\r
256 * @param object $parser parse object\r
257 */\r
258 public function __construct($parser)\r
259 {\r
260 $this->parser = $parser;\r
261 }\r
262 \r
263 /**\r
264 * Append buffer to subtree\r
265 *\r
266 * @param _smarty_parsetree $subtree\r
267 */\r
268 public function append_subtree(_smarty_parsetree $subtree)\r
269 {\r
270 $this->subtrees[] = $subtree;\r
271 }\r
272 \r
273 /**\r
274 * Sanitize and merge subtree buffers together\r
275 *\r
276 * @return string template code content\r
277 */\r
278 public function to_smarty_php()\r
279 {\r
280 $code = '';\r
281 for ($key = 0, $cnt = count($this->subtrees); $key < $cnt; $key++) {\r
282 if ($key + 2 < $cnt) {\r
283 if ($this->subtrees[$key] instanceof _smarty_linebreak && $this->subtrees[$key + 1] instanceof _smarty_tag && $this->subtrees[$key + 1]->data == '' && $this->subtrees[$key + 2] instanceof _smarty_linebreak) {\r
284 $key = $key + 1;\r
285 continue;\r
286 }\r
287 if (substr($this->subtrees[$key]->data, -1) == '<' && $this->subtrees[$key + 1]->data == '' && substr($this->subtrees[$key + 2]->data, -1) == '?') {\r
288 $key = $key + 2;\r
289 continue;\r
290 }\r
291 }\r
292 if (substr($code, -1) == '<') {\r
293 $subtree = $this->subtrees[$key]->to_smarty_php();\r
294 if (substr($subtree, 0, 1) == '?') {\r
295 $code = substr($code, 0, strlen($code) - 1) . '<<?php ?>?' . substr($subtree, 1);\r
296 } elseif ($this->parser->asp_tags && substr($subtree, 0, 1) == '%') {\r
297 $code = substr($code, 0, strlen($code) - 1) . '<<?php ?>%' . substr($subtree, 1);\r
298 } else {\r
299 $code .= $subtree;\r
300 }\r
301 continue;\r
302 }\r
303 if ($this->parser->asp_tags && substr($code, -1) == '%') {\r
304 $subtree = $this->subtrees[$key]->to_smarty_php();\r
305 if (substr($subtree, 0, 1) == '>') {\r
306 $code = substr($code, 0, strlen($code) - 1) . '%<?php ?>>' . substr($subtree, 1);\r
307 } else {\r
308 $code .= $subtree;\r
309 }\r
310 continue;\r
311 }\r
312 if (substr($code, -1) == '?') {\r
313 $subtree = $this->subtrees[$key]->to_smarty_php();\r
314 if (substr($subtree, 0, 1) == '>') {\r
315 $code = substr($code, 0, strlen($code) - 1) . '?<?php ?>>' . substr($subtree, 1);\r
316 } else {\r
317 $code .= $subtree;\r
318 }\r
319 continue;\r
320 }\r
321 $code .= $this->subtrees[$key]->to_smarty_php();\r
322 }\r
323 return $code;\r
324 }\r
325 \r
326 }\r
327 \r
328 /**\r
329 * template text\r
330 *\r
331 * @package Smarty\r
332 * @subpackage Compiler\r
333 * @ignore\r
334 */\r
335 class _smarty_text extends _smarty_parsetree {\r
336 \r
337 \r
338 /**\r
339 * Create template text buffer\r
340 *\r
341 * @param object $parser parser object\r
342 * @param string $data text\r
343 */\r
344 public function __construct($parser, $data)\r
345 {\r
346 $this->parser = $parser;\r
347 $this->data = $data;\r
348 }\r
349 \r
350 /**\r
351 * Return buffer content\r
352 *\r
353 * @return strint text\r
354 */\r
355 public function to_smarty_php()\r
356 {\r
357 return $this->data;\r
358 }\r
359 \r
360 }\r
361 \r
362 /**\r
363 * template linebreaks\r
364 *\r
365 * @package Smarty\r
366 * @subpackage Compiler\r
367 * @ignore\r
368 */\r
369 class _smarty_linebreak extends _smarty_parsetree {\r
370 \r
371 /**\r
372 * Create buffer with linebreak content\r
373 *\r
374 * @param object $parser parser object\r
375 * @param string $data linebreak string\r
376 */\r
377 public function __construct($parser, $data)\r
378 {\r
379 $this->parser = $parser;\r
380 $this->data = $data;\r
381 }\r
382 \r
383 /**\r
384 * Return linebrak\r
385 *\r
386 * @return string linebreak\r
387 */\r
388 public function to_smarty_php()\r
389 {\r
390 return $this->data;\r
391 }\r
392 \r
393 }\r
394 \r
395 ?>