/[cvs]/nfo/php/libs/net.php.smarty/Smarty_Compiler.class.php
ViewVC logotype

Contents of /nfo/php/libs/net.php.smarty/Smarty_Compiler.class.php

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations)
Wed Oct 9 00:45:29 2002 UTC (21 years, 9 months ago) by cvsjoko
Branch: MAIN
no message

1 <?php
2
3 /*
4 * Project: Smarty: the PHP compiling template engine
5 * File: Smarty_Compiler.class.php
6 * Author: Monte Ohrt <monte@ispi.net>
7 * Andrei Zmievski <andrei@php.net>
8 *
9 * Version: 2.3.0
10 * Copyright: 2001,2002 ispi of Lincoln, Inc.
11 *
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
16 *
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 * You may contact the authors of Smarty by e-mail at:
27 * monte@ispi.net
28 * andrei@php.net
29 *
30 * Or, write to:
31 * Monte Ohrt
32 * Director of Technology, ispi
33 * 237 S. 70th suite 220
34 * Lincoln, NE 68510
35 *
36 * The latest version of Smarty can be obtained from:
37 * http://www.phpinsider.com/
38 *
39 */
40
41 class Smarty_Compiler extends Smarty {
42
43 // internal vars
44 var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part
45 var $_foreachelse_stack = array(); // keeps track of whether foreach had 'else' part
46 var $_literal_blocks = array(); // keeps literal template blocks
47 var $_php_blocks = array(); // keeps php code blocks
48 var $_current_file = null; // the current template being compiled
49 var $_current_line_no = 1; // line number for error messages
50 var $_capture_stack = array(); // keeps track of nested capture buffers
51 var $_plugin_info = array(); // keeps track of plugins to load
52 var $_init_smarty_vars = false;
53
54
55 /*======================================================================*\
56 Function: _compile_file()
57 Input: compile a template file
58 \*======================================================================*/
59 function _compile_file($tpl_file, $template_source, &$template_compiled)
60 {
61 if ($this->security) {
62 // do not allow php syntax to be executed unless specified
63 if ($this->php_handling == SMARTY_PHP_ALLOW &&
64 !$this->security_settings['PHP_HANDLING']) {
65 $this->php_handling = SMARTY_PHP_PASSTHRU;
66 }
67 }
68
69 $this->_load_filters();
70
71 $this->_current_file = $tpl_file;
72 $this->_current_line_no = 1;
73 $ldq = preg_quote($this->left_delimiter, '!');
74 $rdq = preg_quote($this->right_delimiter, '!');
75
76 // run template source through prefilter functions
77 if (count($this->_plugins['prefilter']) > 0) {
78 foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
79 if ($prefilter === false) continue;
80 if ($prefilter[3] || function_exists($prefilter[0])) {
81 $template_source = $prefilter[0]($template_source, $this);
82 $this->_plugins['prefilter'][$filter_name][3] = true;
83 } else {
84 $this->_trigger_plugin_error("Smarty plugin error: prefilter '$filter_name' is not implemented");
85 }
86 }
87 }
88
89 /* Annihilate the comments. */
90 $template_source = preg_replace("!({$ldq})\*(.*?)\*({$rdq})!se",
91 "'\\1*'.str_repeat(\"\n\", substr_count('\\2', \"\n\")) .'*\\3'",
92 $template_source);
93
94 /* Pull out the literal blocks. */
95 preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_source, $match);
96 $this->_literal_blocks = $match[1];
97 $template_source = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s",
98 $this->quote_replace($this->left_delimiter.'literal'.$this->right_delimiter), $template_source);
99
100 /* Pull out the php code blocks. */
101 preg_match_all("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $template_source, $match);
102 $this->_php_blocks = $match[1];
103 $template_source = preg_replace("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s",
104 $this->quote_replace($this->left_delimiter.'php'.$this->right_delimiter), $template_source);
105
106 /* Gather all template tags. */
107 preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_source, $match);
108 $template_tags = $match[1];
109 /* Split content by template tags to obtain non-template content. */
110 $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $template_source);
111
112 /* loop through text blocks */
113 for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
114 /* match anything within <? ?> */
115 if (preg_match_all('!(<\?[^?]*?\?>|<script\s+language\s*=\s*[\"\']?php[\"\']?\s*>)!is', $text_blocks[$curr_tb], $sp_match)) {
116 /* found at least one match, loop through each one */
117 for ($curr_sp = 0, $for_max2 = count($sp_match[0]); $curr_sp < $for_max2; $curr_sp++) {
118 if (preg_match('!^(<\?(php\s|\s|=\s)|<script\s*language\s*=\s*[\"\']?php[\"\']?\s*>)!is', $sp_match[0][$curr_sp])) {
119 /* php tag */
120 if ($this->php_handling == SMARTY_PHP_PASSTHRU) {
121 /* echo php contents */
122 $text_blocks[$curr_tb] = str_replace($sp_match[0][$curr_sp], '<?php echo \''.str_replace("'", "\'", $sp_match[0][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
123 } else if ($this->php_handling == SMARTY_PHP_QUOTE) {
124 /* quote php tags */
125 $text_blocks[$curr_tb] = str_replace($sp_match[0][$curr_sp], htmlspecialchars($sp_match[0][$curr_sp]), $text_blocks[$curr_tb]);
126 } else if ($this->php_handling == SMARTY_PHP_REMOVE) {
127 /* remove php tags */
128 if (substr($sp_match[0][$curr_sp], 0, 2) == '<?')
129 $text_blocks[$curr_tb] = str_replace($sp_match[0][$curr_sp], '', $text_blocks[$curr_tb]);
130 else
131 /* attempt to remove everything between <script ...> and </script> */
132 $text_blocks[$curr_tb] = preg_replace('!'.preg_quote($sp_match[0][$curr_sp], '!').'.*?</script\s*>!is', '', $text_blocks[$curr_tb]);
133 }
134 } else
135 /* echo the non-php tags */
136 $text_blocks[$curr_tb] = str_replace($sp_match[0][$curr_sp], '<?php echo \''.str_replace("'", "\'", $sp_match[0][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);
137 }
138 }
139 }
140
141 /* Compile the template tags into PHP code. */
142 $compiled_tags = array();
143 for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {
144 $this->_current_line_no += substr_count($text_blocks[$i], "\n");
145 $compiled_tags[] = $this->_compile_tag($template_tags[$i]);
146 $this->_current_line_no += substr_count($template_tags[$i], "\n");
147 }
148
149 $template_compiled = '';
150
151 /* Interleave the compiled contents and text blocks to get the final result. */
152 for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
153 $template_compiled .= $text_blocks[$i].$compiled_tags[$i];
154 }
155 $template_compiled .= $text_blocks[$i];
156
157 /* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */
158 if (preg_match_all("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $template_compiled, $match)) {
159 $strip_tags = $match[0];
160 $strip_tags_modified = preg_replace("!{$ldq}/?strip{$rdq}|[\t ]+$|^[\t ]+!m", '', $strip_tags);
161 $strip_tags_modified = preg_replace('![\r\n]+!m', '', $strip_tags_modified);
162 for ($i = 0, $for_max = count($strip_tags); $i < $for_max; $i++)
163 $template_compiled = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s",
164 $this->quote_replace($strip_tags_modified[$i]),
165 $template_compiled, 1);
166 }
167
168 // remove \n from the end of the file, if any
169 if ($template_compiled{strlen($template_compiled) - 1} == "\n" ) {
170 $template_compiled = substr($template_compiled, 0, -1);
171 }
172
173 // run compiled template through postfilter functions
174 if (count($this->_plugins['postfilter']) > 0) {
175 foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
176 if ($postfilter === false) continue;
177 if ($postfilter[3] || function_exists($postfilter[0])) {
178 $template_compiled = $postfilter[0]($template_compiled, $this);
179 $this->_plugins['postfilter'][$filter_name][3] = true;
180 } else {
181 $this->_trigger_plugin_error("Smarty plugin error: postfilter '$filter_name' is not implemented");
182 }
183 }
184 }
185
186 // put header at the top of the compiled template
187 $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";
188 $template_header .= " compiled from ".$tpl_file." */ ?>\n";
189
190 /* Emit code to load needed plugins. */
191 if (count($this->_plugin_info)) {
192 $plugins_code = '<?php $this->_load_plugins(array(';
193 foreach ($this->_plugin_info as $plugin_type => $plugins) {
194 foreach ($plugins as $plugin_name => $plugin_info) {
195 $plugins_code .= "\narray('$plugin_type', '$plugin_name', '$plugin_info[0]', $plugin_info[1], ";
196 $plugins_code .= $plugin_info[2] ? 'true),' : 'false),';
197 }
198 }
199 $plugins_code .= ")); ?>";
200 $template_header .= $plugins_code;
201 $this->_plugin_info = array();
202 }
203
204 if ($this->_init_smarty_vars) {
205 $template_header .= "<?php \$this->_assign_smarty_interface(); ?>\n";
206 $this->_init_smarty_vars = false;
207 }
208
209 $template_compiled = $template_header . $template_compiled;
210
211 return true;
212 }
213
214
215 /*======================================================================*\
216 Function: _compile_tag
217 Purpose: Compile a template tag
218 \*======================================================================*/
219 function _compile_tag($template_tag)
220 {
221 /* Matched comment. */
222 if ($template_tag{0} == '*' && $template_tag{strlen($template_tag) - 1} == '*')
223 return '';
224
225 $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
226
227 /* Split tag into two parts: command and the arguments. */
228 preg_match('/^(
229 (?: ' . $qstr_regexp . ' | (?>[^"\'\s]+))+
230 )
231 (?:\s+(.*))?
232 /xs', $template_tag, $match);
233 $tag_command = $match[1];
234 $tag_args = isset($match[2]) ? $match[2] : '';
235
236 /* If the tag name matches a variable or section property definition,
237 we simply process it. */
238 if (preg_match('!^\$\w+(?>(\[(\d+|\$\w+|\w+(\.\w+)?)\])|((\.|->)\$?\w+))*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tag_command) || // if a variable
239 preg_match('!^#(\w+)#(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tag_command) || // or a configuration variable
240 preg_match('!^%\w+\.\w+%(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tag_command)) { // or a section property
241 settype($tag_command, 'array');
242 $this->_parse_vars_props($tag_command);
243 return "<?php echo $tag_command[0]; ?>\n";
244 }
245
246 switch ($tag_command) {
247 case 'include':
248 return $this->_compile_include_tag($tag_args);
249
250 case 'include_php':
251 return $this->_compile_include_php_tag($tag_args);
252
253 case 'if':
254 return $this->_compile_if_tag($tag_args);
255
256 case 'else':
257 return '<?php else: ?>';
258
259 case 'elseif':
260 return $this->_compile_if_tag($tag_args, true);
261
262 case '/if':
263 return '<?php endif; ?>';
264
265 case 'capture':
266 return $this->_compile_capture_tag(true, $tag_args);
267
268 case '/capture':
269 return $this->_compile_capture_tag(false);
270
271 case 'ldelim':
272 return $this->left_delimiter;
273
274 case 'rdelim':
275 return $this->right_delimiter;
276
277 case 'section':
278 array_push($this->_sectionelse_stack, false);
279 return $this->_compile_section_start($tag_args);
280
281 case 'sectionelse':
282 $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true;
283 return "<?php endfor; else: ?>";
284
285 case '/section':
286 if (array_pop($this->_sectionelse_stack))
287 return "<?php endif; ?>";
288 else
289 return "<?php endfor; endif; ?>";
290
291 case 'foreach':
292 array_push($this->_foreachelse_stack, false);
293 return $this->_compile_foreach_start($tag_args);
294 break;
295
296 case 'foreachelse':
297 $this->_foreachelse_stack[count($this->_foreachelse_stack)-1] = true;
298 return "<?php endforeach; else: ?>";
299
300 case '/foreach':
301 if (array_pop($this->_foreachelse_stack))
302 return "<?php endif; ?>";
303 else
304 return "<?php endforeach; endif; ?>";
305
306 case 'config_load':
307 return $this->_compile_config_load_tag($tag_args);
308
309 case 'strip':
310 case '/strip':
311 return $this->left_delimiter.$tag_command.$this->right_delimiter;
312
313 case 'literal':
314 list (,$literal_block) = each($this->_literal_blocks);
315 $this->_current_line_no += substr_count($literal_block, "\n");
316 return "<?php echo '".str_replace("'", "\'", str_replace("\\", "\\\\", $literal_block))."'; ?>\n";
317
318 case 'php':
319 if ($this->security && !$this->security_settings['PHP_TAGS']) {
320 $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING);
321 return;
322 }
323 list (,$php_block) = each($this->_php_blocks);
324 $this->_current_line_no += substr_count($php_block, "\n");
325 return '<?php '.$php_block.' ?>';
326
327 case 'insert':
328 return $this->_compile_insert_tag($tag_args);
329
330 default:
331 if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {
332 return $output;
333 } else if ($this->_compile_block_tag($tag_command, $tag_args, $output)) {
334 return $output;
335 } else {
336 return $this->_compile_custom_tag($tag_command, $tag_args);
337 }
338 }
339 }
340
341
342 /*======================================================================*\
343 Function: _compile_compiler_tag
344 Purpose: compile the custom compiler tag
345 \*======================================================================*/
346 function _compile_compiler_tag($tag_command, $tag_args, &$output)
347 {
348 $found = false;
349 $have_function = true;
350
351 /*
352 * First we check if the compiler function has already been registered
353 * or loaded from a plugin file.
354 */
355 if (isset($this->_plugins['compiler'][$tag_command])) {
356 $found = true;
357 $plugin_func = $this->_plugins['compiler'][$tag_command][0];
358 if (!function_exists($plugin_func)) {
359 $message = "compiler function '$tag_command' is not implemented";
360 $have_function = false;
361 }
362 }
363 /*
364 * Otherwise we need to load plugin file and look for the function
365 * inside it.
366 */
367 else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {
368 $found = true;
369
370 include_once $plugin_file;
371
372 $plugin_func = 'smarty_compiler_' . $tag_command;
373 if (!function_exists($plugin_func)) {
374 $message = "plugin function $plugin_func() not found in $plugin_file\n";
375 $have_function = false;
376 } else {
377 $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null);
378 }
379 }
380
381 /*
382 * True return value means that we either found a plugin or a
383 * dynamically registered function. False means that we didn't and the
384 * compiler should now emit code to load custom function plugin for this
385 * tag.
386 */
387 if ($found) {
388 if ($have_function) {
389 $output = '<?php ' . $plugin_func($tag_args, $this) . ' ?>';
390 } else {
391 $this->_syntax_error($message, E_USER_WARNING);
392 }
393 return true;
394 } else {
395 return false;
396 }
397 }
398
399
400 /*======================================================================*\
401 Function: _compile_block_tag
402 Purpose: compile block function tag
403 \*======================================================================*/
404 function _compile_block_tag($tag_command, $tag_args, &$output)
405 {
406 if ($tag_command{0} == '/') {
407 $start_tag = false;
408 $tag_command = substr($tag_command, 1);
409 } else
410 $start_tag = true;
411
412 $found = false;
413 $have_function = true;
414
415 /*
416 * First we check if the block function has already been registered
417 * or loaded from a plugin file.
418 */
419 if (isset($this->_plugins['block'][$tag_command])) {
420 $found = true;
421 $plugin_func = $this->_plugins['block'][$tag_command][0];
422 if (!function_exists($plugin_func)) {
423 $message = "block function '$tag_command' is not implemented";
424 $have_function = false;
425 }
426 }
427 /*
428 * Otherwise we need to load plugin file and look for the function
429 * inside it.
430 */
431 else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {
432 $found = true;
433
434 include_once $plugin_file;
435
436 $plugin_func = 'smarty_block_' . $tag_command;
437 if (!function_exists($plugin_func)) {
438 $message = "plugin function $plugin_func() not found in $plugin_file\n";
439 $have_function = false;
440 } else {
441 $this->_plugins['block'][$tag_command] = array($plugin_func, null, null);
442 }
443 }
444
445 if (!$found) {
446 return false;
447 } else if (!$have_function) {
448 $this->_syntax_error($message, E_USER_WARNING);
449 return true;
450 }
451
452 /*
453 * Even though we've located the plugin function, compilation
454 * happens only once, so the plugin will still need to be loaded
455 * at runtime for future requests.
456 */
457 $this->_add_plugin('block', $tag_command);
458
459 if ($start_tag) {
460 $arg_list = array();
461 $attrs = $this->_parse_attrs($tag_args);
462 foreach ($attrs as $arg_name => $arg_value) {
463 if (is_bool($arg_value))
464 $arg_value = $arg_value ? 'true' : 'false';
465 $arg_list[] = "'$arg_name' => $arg_value";
466 }
467
468 $output = "<?php \$this->_tag_stack[] = array('$tag_command', array(".implode(',', (array)$arg_list).")); \$this->_plugins['block']['$tag_command'][0](array(".implode(',', (array)$arg_list)."), null, \$this); ob_start(); ?>";
469 } else {
470 $output = "<?php \$this->_block_content = ob_get_contents(); ob_end_clean(); \$this->_plugins['block']['$tag_command'][0](\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$this->_block_content, \$this); array_pop(\$this->_tag_stack); ?>";
471 }
472
473 return true;
474 }
475
476
477 /*======================================================================*\
478 Function: _compile_custom_tag
479 Purpose: compile custom function tag
480 \*======================================================================*/
481 function _compile_custom_tag($tag_command, $tag_args)
482 {
483 $this->_add_plugin('function', $tag_command);
484
485 $arg_list = array();
486 $attrs = $this->_parse_attrs($tag_args);
487 foreach ($attrs as $arg_name => $arg_value) {
488 if (is_bool($arg_value))
489 $arg_value = $arg_value ? 'true' : 'false';
490 $arg_list[] = "'$arg_name' => $arg_value";
491 }
492
493 return "<?php \$this->_plugins['function']['$tag_command'][0](array(".implode(',', (array)$arg_list)."), \$this); if(\$this->_extract) { extract(\$this->_tpl_vars); \$this->_extract=false; } ?>";
494 }
495
496
497 /*======================================================================*\
498 Function: _compile_insert_tag
499 Purpose: Compile {insert ...} tag
500 \*======================================================================*/
501 function _compile_insert_tag($tag_args)
502 {
503 $attrs = $this->_parse_attrs($tag_args);
504 $name = $this->_dequote($attrs['name']);
505
506 if (empty($name)) {
507 $this->_syntax_error("missing insert name");
508 }
509
510 if (!empty($attrs['script'])) {
511 $delayed_loading = true;
512 }
513
514 foreach ($attrs as $arg_name => $arg_value) {
515 if (is_bool($arg_value))
516 $arg_value = $arg_value ? 'true' : 'false';
517 $arg_list[] = "'$arg_name' => $arg_value";
518 }
519
520 $this->_add_plugin('insert', $name, $delayed_loading);
521
522 return "<?php echo \$this->_run_insert_handler(array(".implode(', ', (array)$arg_list).")); ?>\n";
523 }
524
525
526 /*======================================================================*\
527 Function: _compile_config_load_tag
528 Purpose: Compile {config_load ...} tag
529 \*======================================================================*/
530 function _compile_config_load_tag($tag_args)
531 {
532 $attrs = $this->_parse_attrs($tag_args);
533
534 if (empty($attrs['file'])) {
535 $this->_syntax_error("missing 'file' attribute in config_load tag");
536 }
537
538 if (empty($attrs['section'])) {
539 $attrs['section'] = 'null';
540 }
541
542 $scope = @$this->_dequote($attrs['scope']);
543 if (!empty($scope)) {
544 if ($scope != 'local' &&
545 $scope != 'parent' &&
546 $scope != 'global') {
547 $this->_syntax_error("invalid 'scope' attribute value");
548 }
549 } else {
550 if (!empty($attrs['global']) && $attrs['global'])
551 $scope = 'parent';
552 else
553 $scope = 'local';
554 }
555
556 $output = '<?php $this->_config_load(' . $attrs['file'] . ', ' . $attrs['section'] . ", '$scope'); ?>";
557
558 return $output;
559 }
560
561
562 /*======================================================================*\
563 Function: _compile_include_tag
564 Purpose: Compile {include ...} tag
565 \*======================================================================*/
566 function _compile_include_tag($tag_args)
567 {
568 $attrs = $this->_parse_attrs($tag_args);
569 $arg_list = array();
570
571 if (empty($attrs['file'])) {
572 $this->_syntax_error("missing 'file' attribute in include tag");
573 }
574
575 foreach ($attrs as $arg_name => $arg_value) {
576 if ($arg_name == 'file') {
577 $include_file = $arg_value;
578 continue;
579 } else if ($arg_name == 'assign') {
580 $assign_var = $arg_value;
581 continue;
582 }
583 if (is_bool($arg_value))
584 $arg_value = $arg_value ? 'true' : 'false';
585 $arg_list[] = "'$arg_name' => $arg_value";
586 }
587
588 $output = '<?php ';
589
590 if (isset($assign_var)) {
591 $output .= "ob_start();\n";
592 }
593
594 $output .=
595 "\$_smarty_tpl_vars = \$this->_tpl_vars;\n" .
596 "\$this->_smarty_include(".$include_file.", array(".implode(',', (array)$arg_list)."));\n" .
597 "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .
598 "unset(\$_smarty_tpl_vars);\n";
599
600 if (isset($assign_var)) {
601 $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";
602 }
603
604 $output .= ' ?>';
605
606 return $output;
607
608 }
609
610 /*======================================================================*\
611 Function: _compile_include_php_tag
612 Purpose: Compile {include ...} tag
613 \*======================================================================*/
614 function _compile_include_php_tag($tag_args)
615 {
616 $attrs = $this->_parse_attrs($tag_args);
617
618 if (empty($attrs['file'])) {
619 $this->_syntax_error("missing 'file' attribute in include_php tag");
620 }
621
622 $assign_var = $this->_dequote($attrs['assign']);
623
624 $once_var = ( $attrs['once'] === false ) ? 'false' : 'true';
625
626 return "<?php \$this->_smarty_include_php($attrs[file], '$assign_var', $once_var); ?>";
627 }
628
629
630 /*======================================================================*\
631 Function: _compile_section_start
632 Purpose: Compile {section ...} tag
633 \*======================================================================*/
634 function _compile_section_start($tag_args)
635 {
636 $attrs = $this->_parse_attrs($tag_args);
637 $arg_list = array();
638
639 $output = "<?php ";
640 $section_name = $attrs['name'];
641 if (empty($section_name)) {
642 $this->_syntax_error("missing section name");
643 }
644
645 $output .= "if (isset(\$this->_sections[$section_name])) unset(\$this->_sections[$section_name]);\n";
646 $section_props = "\$this->_sections[$section_name]";
647
648 foreach ($attrs as $attr_name => $attr_value) {
649 switch ($attr_name) {
650 case 'loop':
651 $output .= "{$section_props}['loop'] = is_array($attr_value) ? count($attr_value) : max(0, (int)$attr_value);\n";
652 break;
653
654 case 'show':
655 if (is_bool($attr_value))
656 $show_attr_value = $attr_value ? 'true' : 'false';
657 else
658 $show_attr_value = "(bool)$attr_value";
659 $output .= "{$section_props}['show'] = $show_attr_value;\n";
660 break;
661
662 case 'name':
663 $output .= "{$section_props}['$attr_name'] = $attr_value;\n";
664 break;
665
666 case 'max':
667 case 'start':
668 $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";
669 break;
670
671 case 'step':
672 $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";
673 break;
674
675 default:
676 $this->_syntax_error("unknown section attribute - '$attr_name'");
677 break;
678 }
679 }
680
681 if (!isset($attrs['show']))
682 $output .= "{$section_props}['show'] = true;\n";
683
684 if (!isset($attrs['loop']))
685 $output .= "{$section_props}['loop'] = 1;\n";
686
687 if (!isset($attrs['max']))
688 $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";
689 else
690 $output .= "if ({$section_props}['max'] < 0)\n" .
691 " {$section_props}['max'] = {$section_props}['loop'];\n";
692
693 if (!isset($attrs['step']))
694 $output .= "{$section_props}['step'] = 1;\n";
695
696 if (!isset($attrs['start']))
697 $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";
698 else {
699 $output .= "if ({$section_props}['start'] < 0)\n" .
700 " {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .
701 "else\n" .
702 " {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";
703 }
704
705 $output .= "if ({$section_props}['show']) {\n";
706 if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {
707 $output .= " {$section_props}['total'] = {$section_props}['loop'];\n";
708 } else {
709 $output .= " {$section_props}['total'] = min(ceil(({$section_props}['step'] > 0 ? {$section_props}['loop'] - {$section_props}['start'] : {$section_props}['start']+1)/abs({$section_props}['step'])), {$section_props}['max']);\n";
710 }
711 $output .= " if ({$section_props}['total'] == 0)\n" .
712 " {$section_props}['show'] = false;\n" .
713 "} else\n" .
714 " {$section_props}['total'] = 0;\n";
715
716 $output .= "if ({$section_props}['show']):\n";
717 $output .= "
718 for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;
719 {$section_props}['iteration'] <= {$section_props}['total'];
720 {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";
721 $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";
722 $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";
723 $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";
724 $output .= "{$section_props}['first'] = ({$section_props}['iteration'] == 1);\n";
725 $output .= "{$section_props}['last'] = ({$section_props}['iteration'] == {$section_props}['total']);\n";
726
727 $output .= "?>";
728
729 return $output;
730 }
731
732
733 /*======================================================================*\
734 Function: _compile_foreach_start
735 Purpose: Compile {foreach ...} tag
736 \*======================================================================*/
737 function _compile_foreach_start($tag_args)
738 {
739 $attrs = $this->_parse_attrs($tag_args);
740 $arg_list = array();
741
742 if (empty($attrs['from'])) {
743 $this->_syntax_error("missing 'from' attribute");
744 }
745
746 if (empty($attrs['item'])) {
747 $this->_syntax_error("missing 'item' attribute");
748 }
749
750 $from = $attrs['from'];
751 $item = $this->_dequote($attrs['item']);
752 if (isset($attrs['name']))
753 $name = $attrs['name'];
754
755 $output = '<?php ';
756 if (isset($name)) {
757 $output .= "if (isset(\$this->_foreach[$name])) unset(\$this->_foreach[$name]);\n";
758 $foreach_props = "\$this->_foreach[$name]";
759 }
760
761 $key_part = '';
762
763 foreach ($attrs as $attr_name => $attr_value) {
764 switch ($attr_name) {
765 case 'key':
766 $key = $this->_dequote($attrs['key']);
767 $key_part = "\$this->_tpl_vars['$key'] => ";
768 break;
769
770 case 'name':
771 $output .= "{$foreach_props}['$attr_name'] = $attr_value;\n";
772 break;
773 }
774 }
775
776 if (isset($name)) {
777 $output .= "{$foreach_props}['total'] = count((array)$from);\n";
778 $output .= "{$foreach_props}['show'] = {$foreach_props}['total'] > 0;\n";
779 $output .= "if ({$foreach_props}['show']):\n";
780 $output .= "{$foreach_props}['iteration'] = 0;\n";
781 $output .= " foreach ((array)$from as $key_part\$this->_tpl_vars['$item']):\n";
782 $output .= " {$foreach_props}['iteration']++;\n";
783 $output .= " {$foreach_props}['first'] = ({$foreach_props}['iteration'] == 1);\n";
784 $output .= " {$foreach_props}['last'] = ({$foreach_props}['iteration'] == {$foreach_props}['total']);\n";
785 } else {
786 $output .= "if (count((array)$from)):\n";
787 $output .= " foreach ((array)$from as $key_part\$this->_tpl_vars['$item']):\n";
788 }
789 $output .= '?>';
790
791 return $output;
792 }
793
794
795 /*======================================================================*\
796 Function: _compile_capture_tag
797 Purpose: Compile {capture} .. {/capture} tags
798 \*======================================================================*/
799 function _compile_capture_tag($start, $tag_args = '')
800 {
801 $attrs = $this->_parse_attrs($tag_args);
802
803 if ($start) {
804 if (isset($attrs['name']))
805 $buffer = $attrs['name'];
806 else
807 $buffer = "'default'";
808
809 $output = "<?php ob_start(); ?>";
810 $this->_capture_stack[] = $buffer;
811 } else {
812 $buffer = array_pop($this->_capture_stack);
813 $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ob_end_clean(); ?>";
814 }
815
816 return $output;
817 }
818
819
820 /*======================================================================*\
821 Function: _compile_if_tag
822 Purpose: Compile {if ...} tag
823 \*======================================================================*/
824 function _compile_if_tag($tag_args, $elseif = false)
825 {
826 /* Tokenize args for 'if' tag. */
827 preg_match_all('/(?:
828 "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | # match all double quoted strings allowing escaped double quotes
829 \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | # match all single quoted strings allowing escaped single quotes
830 [(),] | # match parentheses and commas
831 [^\s(),]+ # match any other token that is not any of the above
832 )/x', $tag_args, $match);
833 $tokens = $match[0];
834
835 $this->_parse_vars_props($tokens);
836
837 $is_arg_stack = array();
838
839 for ($i = 0, $for_max = count($tokens); $i < $for_max; $i++) {
840
841 $token = &$tokens[$i];
842 switch ($token) {
843 case 'eq':
844 $token = '==';
845 break;
846
847 case 'ne':
848 case 'neq':
849 $token = '!=';
850 break;
851
852 case 'lt':
853 $token = '<';
854 break;
855
856 case 'le':
857 case 'lte':
858 $token = '<=';
859 break;
860
861 case 'gt':
862 $token = '>';
863 break;
864
865 case 'ge':
866 case 'gte':
867 $token = '>=';
868 break;
869
870 case 'and':
871 $token = '&&';
872 break;
873
874 case 'or':
875 $token = '||';
876 break;
877
878 case 'not':
879 $token = '!';
880 break;
881
882 case 'mod':
883 $token = '%';
884 break;
885
886 case '(':
887 array_push($is_arg_stack, $i);
888 break;
889
890 case 'is':
891 /* If last token was a ')', we operate on the parenthesized
892 expression. The start of the expression is on the stack.
893 Otherwise, we operate on the last encountered token. */
894 if ($tokens[$i-1] == ')')
895 $is_arg_start = array_pop($is_arg_stack);
896 else
897 $is_arg_start = $i-1;
898 /* Construct the argument for 'is' expression, so it knows
899 what to operate on. */
900 $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));
901
902 /* Pass all tokens from next one until the end to the
903 'is' expression parsing function. The function will
904 return modified tokens, where the first one is the result
905 of the 'is' expression and the rest are the tokens it
906 didn't touch. */
907 $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));
908
909 /* Replace the old tokens with the new ones. */
910 array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);
911
912 /* Adjust argument start so that it won't change from the
913 current position for the next iteration. */
914 $i = $is_arg_start;
915 break;
916
917 default:
918 if($this->security &&
919 $i+1 < count($tokens) &&
920 $tokens[$i+1] == '(' &&
921 preg_match('!^[a-zA-Z_]\w+$!', $tokens[$i]) &&
922 !in_array($tokens[$i], $this->security_settings['IF_FUNCS'])) {
923 $this->_syntax_error("(secure mode) '".$tokens[$i]."' not allowed in if statement");
924 }
925 break;
926 }
927 }
928
929 if ($elseif)
930 return '<?php elseif ('.implode(' ', $tokens).'): ?>';
931 else
932 return '<?php if ('.implode(' ', $tokens).'): ?>';
933 }
934
935
936 /*======================================================================*\
937 Function: _parse_is_expr
938 Purpose: Parse is expression
939 \*======================================================================*/
940 function _parse_is_expr($is_arg, $tokens)
941 {
942 $expr_end = 0;
943 $negate_expr = false;
944
945 if (($first_token = array_shift($tokens)) == 'not') {
946 $negate_expr = true;
947 $expr_type = array_shift($tokens);
948 } else
949 $expr_type = $first_token;
950
951 switch ($expr_type) {
952 case 'even':
953 if (@$tokens[$expr_end] == 'by') {
954 $expr_end++;
955 $expr_arg = $tokens[$expr_end++];
956 $expr = "!(($is_arg / $expr_arg) % $expr_arg)";
957 } else
958 $expr = "!($is_arg % 2)";
959 break;
960
961 case 'odd':
962 if (@$tokens[$expr_end] == 'by') {
963 $expr_end++;
964 $expr_arg = $tokens[$expr_end++];
965 $expr = "(($is_arg / $expr_arg) % $expr_arg)";
966 } else
967 $expr = "($is_arg % 2)";
968 break;
969
970 case 'div':
971 if (@$tokens[$expr_end] == 'by') {
972 $expr_end++;
973 $expr_arg = $tokens[$expr_end++];
974 $expr = "!($is_arg % $expr_arg)";
975 } else {
976 $this->_syntax_error("expecting 'by' after 'div'");
977 }
978 break;
979
980 default:
981 $this->_syntax_error("unknown 'is' expression - '$expr_type'");
982 break;
983 }
984
985 if ($negate_expr) {
986 $expr = "!($expr)";
987 }
988
989 array_splice($tokens, 0, $expr_end, $expr);
990
991 return $tokens;
992 }
993
994
995 /*======================================================================*\
996 Function: _parse_attrs
997 Purpose: Parse attribute string
998 \*======================================================================*/
999 function _parse_attrs($tag_args, $quote = true)
1000 {
1001 /* Tokenize tag attributes. */
1002 preg_match_all('/(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" |
1003 \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | (?>[^"\'=\s]+)
1004 )+ |
1005 [=]
1006 /x', $tag_args, $match);
1007 $tokens = $match[0];
1008 $var_delims = array('$', '#', '%');
1009
1010 $attrs = array();
1011 /* Parse state:
1012 0 - expecting attribute name
1013 1 - expecting '='
1014 2 - expecting attribute value (not '=') */
1015 $state = 0;
1016
1017 foreach ($tokens as $token) {
1018 switch ($state) {
1019 case 0:
1020 /* If the token is a valid identifier, we set attribute name
1021 and go to state 1. */
1022 if (preg_match('!^\w+$!', $token)) {
1023 $attr_name = $token;
1024 $state = 1;
1025 } else
1026 $this->_syntax_error("invalid attribute name - '$token'");
1027 break;
1028
1029 case 1:
1030 /* If the token is '=', then we go to state 2. */
1031 if ($token == '=') {
1032 $state = 2;
1033 } else
1034 $this->_syntax_error("expecting '=' after attribute name");
1035 break;
1036
1037 case 2:
1038 /* If token is not '=', we set the attribute value and go to
1039 state 0. */
1040 if ($token != '=') {
1041 /* We booleanize the token if it's a non-quoted possible
1042 boolean value. */
1043 if (preg_match('!^(on|yes|true)$!', $token))
1044 $token = true;
1045 else if (preg_match('!^(off|no|false)$!', $token))
1046 $token = false;
1047 /* If the token is not variable (doesn't start with
1048 '$', '#', or '%') and not enclosed in single or
1049 double quotes we single-quote it. */
1050 else if ($quote && !in_array($token{0}, $var_delims) &&
1051 !(($token{0} == '"' || $token{0} == "'") &&
1052 $token{strlen($token)-1} == $token{0}))
1053 $token = '"'.$token.'"';
1054
1055 $attrs[$attr_name] = $token;
1056 $state = 0;
1057 } else
1058 $this->_syntax_error("'=' cannot be an attribute value");
1059 break;
1060 }
1061 }
1062
1063 $this->_parse_vars_props($attrs);
1064
1065 return $attrs;
1066 }
1067
1068
1069 /*======================================================================*\
1070 Function: _parse_vars_props
1071 Purpose: compile variables and section properties tokens into
1072 PHP code
1073 \*======================================================================*/
1074 function _parse_vars_props(&$tokens)
1075 {
1076 $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
1077
1078 $var_exprs = preg_grep('!^\$\w+(?>(\[(\d+|\$\w+|\w+(\.\w+)?)\])|((\.|->)\$?\w+))*(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
1079 $conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
1080 $sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(?>' . $qstr_regexp . '|[^|]+))*)*$!', $tokens);
1081
1082 if (count($var_exprs)) {
1083 foreach ($var_exprs as $expr_index => $var_expr) {
1084 $tokens[$expr_index] = $this->_parse_var($var_expr);
1085 }
1086 }
1087
1088 if (count($conf_var_exprs)) {
1089 foreach ($conf_var_exprs as $expr_index => $var_expr) {
1090 $tokens[$expr_index] = $this->_parse_conf_var($var_expr);
1091 }
1092 }
1093
1094 if (count($sect_prop_exprs)) {
1095 foreach ($sect_prop_exprs as $expr_index => $section_prop_expr) {
1096 $tokens[$expr_index] = $this->_parse_section_prop($section_prop_expr);
1097 }
1098 }
1099 }
1100
1101
1102 /*======================================================================*\
1103 Function: _parse_var
1104 Purpose: parse variable expression into PHP code
1105 \*======================================================================*/
1106 function _parse_var($var_expr)
1107 {
1108 $parts = explode('|', substr($var_expr, 1), 2);
1109 $var_ref = $parts[0];
1110 $modifiers = isset($parts[1]) ? $parts[1] : '';
1111
1112 if(!empty($this->default_modifiers) && !preg_match('!(^|\|)smarty:nodefaults($|\|)!',$modifiers)) {
1113 $_default_mod_string = implode('|',(array)$this->default_modifiers);
1114 $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers;
1115 }
1116
1117 preg_match_all('!\[(?:\$\w+|\w+(\.\w+)?)\]|(->|\.)\$?\w+|^\w+!', $var_ref, $match);
1118 $indexes = $match[0];
1119 $var_name = array_shift($indexes);
1120
1121 /* Handle $smarty.* variable references as a special case. */
1122 if ($var_name == 'smarty') {
1123 /*
1124 * If the reference could be compiled, use the compiled output;
1125 * otherwise, fall back on the $smarty variable generated at
1126 * run-time.
1127 */
1128 if (($smarty_ref = $this->_compile_smarty_ref($indexes)) !== null) {
1129 $output = $smarty_ref;
1130 } else {
1131 $var_name = substr(array_shift($indexes), 1);
1132 $output = "\$this->_smarty_vars['$var_name']";
1133 }
1134 } else {
1135 $output = "\$this->_tpl_vars['$var_name']";
1136 }
1137
1138 foreach ($indexes as $index) {
1139 if ($index{0} == '[') {
1140 $index = substr($index, 1, -1);
1141 if (is_numeric($index)) {
1142 $output .= "[$index]";
1143 } elseif ($index{0} == '$') {
1144 $output .= "[\$this->_tpl_vars['" . substr($index, 1) . "']]";
1145 } else {
1146 $parts = explode('.', $index);
1147 $section = $parts[0];
1148 $section_prop = isset($parts[1]) ? $parts[1] : 'index';
1149 $output .= "[\$this->_sections['$section']['$section_prop']]";
1150 }
1151 } else if ($index{0} == '.') {
1152 if ($index{1} == '$')
1153 $output .= "[\$this->_tpl_vars['" . substr($index, 2) . "']]";
1154 else
1155 $output .= "['" . substr($index, 1) . "']";
1156 } else {
1157 $output .= $index;
1158 }
1159 }
1160
1161 $this->_parse_modifiers($output, $modifiers);
1162
1163 return $output;
1164 }
1165
1166
1167 /*======================================================================*\
1168 Function: _parse_conf_var
1169 Purpose: parse configuration variable expression into PHP code
1170 \*======================================================================*/
1171 function _parse_conf_var($conf_var_expr)
1172 {
1173 $parts = explode('|', $conf_var_expr, 2);
1174 $var_ref = $parts[0];
1175 $modifiers = isset($parts[1]) ? $parts[1] : '';
1176
1177 $var_name = substr($var_ref, 1, -1);
1178
1179 $output = "\$this->_config[0]['vars']['$var_name']";
1180
1181 $this->_parse_modifiers($output, $modifiers);
1182
1183 return $output;
1184 }
1185
1186
1187 /*======================================================================*\
1188 Function: _parse_section_prop
1189 Purpose: parse section property expression into PHP code
1190 \*======================================================================*/
1191 function _parse_section_prop($section_prop_expr)
1192 {
1193 $parts = explode('|', $section_prop_expr, 2);
1194 $var_ref = $parts[0];
1195 $modifiers = isset($parts[1]) ? $parts[1] : '';
1196
1197 preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);
1198 $section_name = $match[1];
1199 $prop_name = $match[2];
1200
1201 $output = "\$this->_sections['$section_name']['$prop_name']";
1202
1203 $this->_parse_modifiers($output, $modifiers);
1204
1205 return $output;
1206 }
1207
1208
1209 /*======================================================================*\
1210 Function: _parse_modifiers
1211 Purpose: parse modifier chain into PHP code
1212 \*======================================================================*/
1213 function _parse_modifiers(&$output, $modifier_string)
1214 {
1215 $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';
1216 preg_match_all('!\|(@?\w+)((?>:(?:'. $qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $match);
1217 list(, $modifiers, $modifier_arg_strings) = $match;
1218
1219 for ($i = 0, $for_max = count($modifiers); $i < $for_max; $i++) {
1220 $modifier_name = $modifiers[$i];
1221
1222 if($modifier_name == 'smarty') {
1223 // skip smarty modifier
1224 continue;
1225 }
1226
1227 preg_match_all('!:(' . $qstr_regexp . '|[^:]+)!', $modifier_arg_strings[$i], $match);
1228 $modifier_args = $match[1];
1229
1230 if ($modifier_name{0} == '@') {
1231 $map_array = 'false';
1232 $modifier_name = substr($modifier_name, 1);
1233 } else {
1234 $map_array = 'true';
1235 }
1236
1237 $this->_add_plugin('modifier', $modifier_name);
1238
1239 $this->_parse_vars_props($modifier_args);
1240
1241 if (count($modifier_args) > 0)
1242 $modifier_args = ', '.implode(', ', $modifier_args);
1243 else
1244 $modifier_args = '';
1245
1246 $output = "\$this->_run_mod_handler('$modifier_name', $map_array, $output$modifier_args)";
1247 }
1248 }
1249
1250
1251 /*======================================================================*\
1252 Function: _add_plugin
1253 Purpose:
1254 \*======================================================================*/
1255 function _add_plugin($type, $name, $delayed_loading = null)
1256 {
1257 if (!isset($this->_plugin_info[$type])) {
1258 $this->_plugin_info[$type] = array();
1259 }
1260 if (!isset($this->_plugin_info[$type][$name])) {
1261 $this->_plugin_info[$type][$name] = array($this->_current_file,
1262 $this->_current_line_no,
1263 $delayed_loading);
1264 }
1265 }
1266
1267
1268 /*======================================================================*\
1269 Function: _compile_smarty_ref
1270 Purpose: Compiles references of type $smarty.foo
1271 \*======================================================================*/
1272 function _compile_smarty_ref(&$indexes)
1273 {
1274 /* Extract the reference name. */
1275 $ref = substr($indexes[0], 1);
1276
1277 switch ($ref) {
1278 case 'now':
1279 $compiled_ref = 'time()';
1280 if (count($indexes) > 1) {
1281 $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference');
1282 }
1283 break;
1284
1285 case 'foreach':
1286 case 'section':
1287 if ($indexes[1]{0} != '.') {
1288 $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference');
1289 }
1290 $name = substr($indexes[1], 1);
1291 array_shift($indexes);
1292 if ($ref == 'foreach')
1293 $compiled_ref = "\$this->_foreach['$name']";
1294 else
1295 $compiled_ref = "\$this->_sections['$name']";
1296 break;
1297
1298 case 'get':
1299 array_shift($indexes);
1300 $name = substr($indexes[0], 1);
1301 $compiled_ref = "\$GLOBALS['HTTP_GET_VARS']['$name']";
1302 break;
1303
1304 case 'post':
1305 array_shift($indexes);
1306 $name = substr($indexes[0], 1);
1307 $compiled_ref = "\$GLOBALS['HTTP_POST_VARS']['$name']";
1308 break;
1309
1310 case 'cookies':
1311 array_shift($indexes);
1312 $name = substr($indexes[0], 1);
1313 $compiled_ref = "\$GLOBALS['HTTP_COOKIE_VARS']['$name']";
1314 break;
1315
1316 case 'env':
1317 array_shift($indexes);
1318 $name = substr($indexes[0], 1);
1319 $compiled_ref = "\$GLOBALS['HTTP_ENV_VARS']['$name']";
1320 break;
1321
1322 case 'server':
1323 array_shift($indexes);
1324 $name = substr($indexes[0], 1);
1325 $compiled_ref = "\$GLOBALS['HTTP_SERVER_VARS']['$name']";
1326 break;
1327
1328 case 'session':
1329 array_shift($indexes);
1330 $name = substr($indexes[0], 1);
1331 $compiled_ref = "\$GLOBALS['HTTP_SESSION_VARS']['$name']";
1332 break;
1333
1334 /*
1335 * These cases are handled either at run-time or elsewhere in the
1336 * compiler.
1337 */
1338 case 'request':
1339 $this->_init_smarty_vars = true;
1340 return null;
1341
1342 case 'capture':
1343 return null;
1344
1345 case 'template':
1346 $compiled_ref = "'$this->_current_file'";
1347 if (count($indexes) > 1) {
1348 $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference');
1349 }
1350 break;
1351
1352 case 'version':
1353 $compiled_ref = "'$this->_version'";
1354 break;
1355
1356 default:
1357 $this->_syntax_error('$smarty.' . $ref . ' is an unknown reference');
1358 break;
1359 }
1360
1361 array_shift($indexes);
1362 return $compiled_ref;
1363 }
1364
1365
1366 /*======================================================================*\
1367 Function: _load_filters
1368 Purpose: load pre- and post-filters
1369 \*======================================================================*/
1370 function _load_filters()
1371 {
1372 if (count($this->_plugins['prefilter']) > 0) {
1373 foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {
1374 if ($prefilter === false) {
1375 unset($this->_plugins['prefilter'][$filter_name]);
1376 $this->_load_plugins(array(array('prefilter', $filter_name, null, null, false)));
1377 }
1378 }
1379 }
1380 if (count($this->_plugins['postfilter']) > 0) {
1381 foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
1382 if ($postfilter === false) {
1383 unset($this->_plugins['postfilter'][$filter_name]);
1384 $this->_load_plugins(array(array('postfilter', $filter_name, null, null, false)));
1385 }
1386 }
1387 }
1388 }
1389
1390
1391 /*======================================================================*\
1392 Function: _syntax_error
1393 Purpose: display Smarty syntax error
1394 \*======================================================================*/
1395 function _syntax_error($error_msg, $error_type = E_USER_ERROR)
1396 {
1397 trigger_error("Smarty: [in " . $this->_current_file . " line " .
1398 $this->_current_line_no . "]: syntax error: $error_msg", $error_type);
1399 }
1400 }
1401
1402 /* vim: set et: */
1403
1404 ?>

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed