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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 cvsjoko 1.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