removed mods directory from the ATutor codebase
[atutor.git] / mods / phpdoc2 / PhpDocumentor / phpDocumentor / Smarty-2.6.0 / libs / Smarty_Compiler.class.php
diff --git a/mods/phpdoc2/PhpDocumentor/phpDocumentor/Smarty-2.6.0/libs/Smarty_Compiler.class.php b/mods/phpdoc2/PhpDocumentor/phpDocumentor/Smarty-2.6.0/libs/Smarty_Compiler.class.php
deleted file mode 100644 (file)
index 263591f..0000000
+++ /dev/null
@@ -1,2123 +0,0 @@
-<?php\r
-\r
-/**\r
- * Project:     Smarty: the PHP compiling template engine\r
- * File:        Smarty_Compiler.class.php\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- *\r
- * You may contact the authors of Smarty by e-mail at:\r
- * monte@ispi.net\r
- * andrei@php.net\r
- *\r
- * Or, write to:\r
- * Monte Ohrt\r
- * Director of Technology, ispi\r
- * 237 S. 70th suite 220\r
- * Lincoln, NE 68510\r
- *\r
- * The latest version of Smarty can be obtained from:\r
- * http://smarty.php.net/\r
- *\r
- * @link http://smarty.php.net/\r
- * @author Monte Ohrt <monte@ispi.net>\r
- * @author Andrei Zmievski <andrei@php.net>\r
- * @version 2.6.0\r
- * @copyright 2001-2003 ispi of Lincoln, Inc.\r
- * @package Smarty\r
- */\r
-\r
-/* $Id: Smarty_Compiler.class.php,v 1.1 2005/10/17 18:37:39 jeichorn Exp $ */\r
-\r
-/**\r
- * Template compiling class\r
- * @package Smarty\r
- */\r
-class Smarty_Compiler extends Smarty {\r
-\r
-    // internal vars\r
-    /**#@+\r
-     * @access private\r
-     */\r
-    var $_sectionelse_stack     =   array();    // keeps track of whether section had 'else' part\r
-    var $_foreachelse_stack     =   array();    // keeps track of whether foreach had 'else' part\r
-    var $_literal_blocks        =   array();    // keeps literal template blocks\r
-    var $_php_blocks            =   array();    // keeps php code blocks\r
-    var $_current_file          =   null;       // the current template being compiled\r
-    var $_current_line_no       =   1;          // line number for error messages\r
-    var $_capture_stack         =   array();    // keeps track of nested capture buffers\r
-    var $_plugin_info           =   array();    // keeps track of plugins to load\r
-    var $_init_smarty_vars      =   false;\r
-    var $_permitted_tokens      =   array('true','false','yes','no','on','off','null');\r
-    var $_db_qstr_regexp        =   null;        // regexps are setup in the constructor\r
-    var $_si_qstr_regexp        =   null;\r
-    var $_qstr_regexp           =   null;\r
-    var $_func_regexp           =   null;\r
-    var $_var_bracket_regexp    =   null;\r
-    var $_dvar_guts_regexp      =   null;\r
-    var $_dvar_regexp           =   null;\r
-    var $_cvar_regexp           =   null;\r
-    var $_svar_regexp           =   null;\r
-    var $_avar_regexp           =   null;\r
-    var $_mod_regexp            =   null;\r
-    var $_var_regexp            =   null;\r
-    var $_parenth_param_regexp  =   null;\r
-    var $_func_call_regexp      =   null;\r
-    var $_obj_ext_regexp        =   null;\r
-    var $_obj_start_regexp      =   null;\r
-    var $_obj_params_regexp     =   null;\r
-    var $_obj_call_regexp       =   null;\r
-    var $_cacheable_state       =   0;\r
-    var $_cache_attrs_count     =   0;\r
-    var $_nocache_count         =   0;\r
-    var $_cache_serial          =   null;\r
-    var $_cache_include         =   null;\r
-\r
-    var $_strip_depth           =   0;\r
-    var $_additional_newline    =   "\n";\r
-\r
-    /**#@-*/\r
-    /**\r
-     * The class constructor.\r
-     */\r
-    function Smarty_Compiler()\r
-    {\r
-        // matches double quoted strings:\r
-        // "foobar"\r
-        // "foo\"bar"\r
-        $this->_db_qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"';\r
-\r
-        // matches single quoted strings:\r
-        // 'foobar'\r
-        // 'foo\'bar'\r
-        $this->_si_qstr_regexp = '\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'';\r
-\r
-        // matches single or double quoted strings\r
-        $this->_qstr_regexp = '(?:' . $this->_db_qstr_regexp . '|' . $this->_si_qstr_regexp . ')';\r
-\r
-        // matches bracket portion of vars\r
-        // [0]\r
-        // [foo]\r
-        // [$bar]\r
-        $this->_var_bracket_regexp = '\[\$?[\w\.]+\]';\r
-\r
-        // matches $ vars (not objects):\r
-        // $foo\r
-        // $foo.bar\r
-        // $foo.bar.foobar\r
-        // $foo[0]\r
-        // $foo[$bar]\r
-        // $foo[5][blah]\r
-        // $foo[5].bar[$foobar][4]\r
-        $this->_dvar_math_regexp = '[\+\-\*\/\%]';\r
-        $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]';\r
-        $this->_dvar_num_var_regexp = '\-?\d+(?:\.\d+)?' . $this->_dvar_math_var_regexp;\r
-        $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp\r
-                . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:\-?\d+(?:\.\d+)?|' . $this->_dvar_math_var_regexp . ')*)?';\r
-        $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp;\r
-\r
-        // matches config vars:\r
-        // #foo#\r
-        // #foobar123_foo#\r
-        $this->_cvar_regexp = '\#\w+\#';\r
-\r
-        // matches section vars:\r
-        // %foo.bar%\r
-        $this->_svar_regexp = '\%\w+\.\w+\%';\r
-\r
-        // matches all valid variables (no quotes, no modifiers)\r
-        $this->_avar_regexp = '(?:' . $this->_dvar_regexp . '|'\r
-           . $this->_cvar_regexp . '|' . $this->_svar_regexp . ')';\r
-\r
-        // matches valid variable syntax:\r
-        // $foo\r
-        // $foo\r
-        // #foo#\r
-        // #foo#\r
-        // "text"\r
-        // "text"\r
-        $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')';\r
-\r
-        // matches valid object call (no objects allowed in parameters):\r
-        // $foo->bar\r
-        // $foo->bar()\r
-        // $foo->bar("text")\r
-        // $foo->bar($foo, $bar, "text")\r
-        // $foo->bar($foo, "foo")\r
-        // $foo->bar->foo()\r
-        // $foo->bar->foo->bar()\r
-        $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')';\r
-        $this->_obj_params_regexp = '\((?:\w+|'\r
-                . $this->_var_regexp . '(?:\s*,\s*(?:(?:\w+|'\r
-                . $this->_var_regexp . ')))*)?\)';\r
-        $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)';\r
-        $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?)';\r
-\r
-        // matches valid modifier syntax:\r
-        // |foo\r
-        // |@foo\r
-        // |foo:"bar"\r
-        // |foo:$bar\r
-        // |foo:"bar":$foobar\r
-        // |foo|bar\r
-        // |foo:$foo->bar\r
-        $this->_mod_regexp = '(?:\|@?\w+(?::(?>-?\w+|'\r
-           . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)';\r
-\r
-        // matches valid function name:\r
-        // foo123\r
-        // _foo_bar\r
-        $this->_func_regexp = '[a-zA-Z_]\w*';\r
-\r
-        // matches valid registered object:\r
-        // foo->bar\r
-        $this->_reg_obj_regexp = '[a-zA-Z_]\w*->[a-zA-Z_]\w*';\r
-\r
-        // matches valid parameter values:\r
-        // true\r
-        // $foo\r
-        // $foo|bar\r
-        // #foo#\r
-        // #foo#|bar\r
-        // "text"\r
-        // "text"|bar\r
-        // $foo->bar\r
-        $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|'\r
-           . $this->_var_regexp  . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)';\r
-\r
-        // matches valid parenthesised function parameters:\r
-        //\r
-        // "text"\r
-        //    $foo, $bar, "text"\r
-        // $foo|bar, "foo"|bar, $foo->bar($foo)|bar\r
-        $this->_parenth_param_regexp = '(?:\((?:\w+|'\r
-                . $this->_param_regexp . '(?:\s*,\s*(?:(?:\w+|'\r
-                . $this->_param_regexp . ')))*)?\))';\r
-\r
-        // matches valid function call:\r
-        // foo()\r
-        // foo_bar($foo)\r
-        // _foo_bar($foo,"bar")\r
-        // foo123($foo,$foo->bar(),"foo")\r
-        $this->_func_call_regexp = '(?:' . $this->_func_regexp . '\s*(?:'\r
-           . $this->_parenth_param_regexp . '))';\r
-    }\r
-\r
-    /**\r
-     * compile a resource\r
-     *\r
-     * sets $compiled_content to the compiled source\r
-     * @param string $resource_name\r
-     * @param string $source_content\r
-     * @param string $compiled_content\r
-     * @return true\r
-     */\r
-    function _compile_file($resource_name, $source_content, &$compiled_content)\r
-    {\r
-\r
-        if ($this->security) {\r
-            // do not allow php syntax to be executed unless specified\r
-            if ($this->php_handling == SMARTY_PHP_ALLOW &&\r
-                !$this->security_settings['PHP_HANDLING']) {\r
-                $this->php_handling = SMARTY_PHP_PASSTHRU;\r
-            }\r
-        }\r
-\r
-        $this->_load_filters();\r
-\r
-        $this->_current_file = $resource_name;\r
-        $this->_current_line_no = 1;\r
-        $ldq = preg_quote($this->left_delimiter, '!');\r
-        $rdq = preg_quote($this->right_delimiter, '!');\r
-\r
-        // run template source through prefilter functions\r
-        if (count($this->_plugins['prefilter']) > 0) {\r
-            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {\r
-                if ($prefilter === false) continue;\r
-                if ($prefilter[3] || is_callable($prefilter[0])) {\r
-                    $source_content = call_user_func_array($prefilter[0],\r
-                                                            array($source_content, &$this));\r
-                    $this->_plugins['prefilter'][$filter_name][3] = true;\r
-                } else {\r
-                    $this->_trigger_fatal_error("[plugin] prefilter '$filter_name' is not implemented");\r
-                }\r
-            }\r
-        }\r
-\r
-        /* Annihilate the comments. */\r
-        $source_content = preg_replace("!({$ldq})\*(.*?)\*({$rdq})!se",\r
-                                        "'\\1*'.str_repeat(\"\n\", substr_count('\\2', \"\n\")) .'*\\3'",\r
-                                        $source_content);\r
-\r
-        /* Pull out the literal blocks. */\r
-        preg_match_all("!{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}!s", $source_content, $_match);\r
-        $this->_literal_blocks = $_match[1];\r
-        $source_content = preg_replace("!{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}!s",\r
-                                        $this->_quote_replace($this->left_delimiter.'literal'.$this->right_delimiter), $source_content);\r
-\r
-        /* Pull out the php code blocks. */\r
-        preg_match_all("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $source_content, $_match);\r
-        $this->_php_blocks = $_match[1];\r
-        $source_content = preg_replace("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s",\r
-                                        $this->_quote_replace($this->left_delimiter.'php'.$this->right_delimiter), $source_content);\r
-\r
-        /* Gather all template tags. */\r
-        preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $source_content, $_match);\r
-        $template_tags = $_match[1];\r
-        /* Split content by template tags to obtain non-template content. */\r
-        $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $source_content);\r
-\r
-        /* loop through text blocks */\r
-        for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {\r
-            /* match anything resembling php tags */\r
-            if (preg_match_all('!(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?php[\"\']?)!is', $text_blocks[$curr_tb], $sp_match)) {\r
-                /* replace tags with placeholders to prevent recursive replacements */\r
-                $sp_match[1] = array_unique($sp_match[1]);\r
-                usort($sp_match[1], '_smarty_sort_length');\r
-                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {\r
-                    $text_blocks[$curr_tb] = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$text_blocks[$curr_tb]);\r
-                }\r
-                /* process each one */\r
-                for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++) {\r
-                    if ($this->php_handling == SMARTY_PHP_PASSTHRU) {\r
-                        /* echo php contents */\r
-                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo \''.str_replace("'", "\'", $sp_match[1][$curr_sp]).'\'; ?>'."\n", $text_blocks[$curr_tb]);\r
-                    } else if ($this->php_handling == SMARTY_PHP_QUOTE) {\r
-                        /* quote php tags */\r
-                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', htmlspecialchars($sp_match[1][$curr_sp]), $text_blocks[$curr_tb]);\r
-                    } else if ($this->php_handling == SMARTY_PHP_REMOVE) {\r
-                        /* remove php tags */\r
-                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]);\r
-                    } else {\r
-                        /* SMARTY_PHP_ALLOW, but echo non php starting tags */\r
-                        $sp_match[1][$curr_sp] = preg_replace('%(<\?(?!php|=|$))%i', '<?php echo \'\\1\'?>'."\n", $sp_match[1][$curr_sp]);\r
-                        $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        /* Compile the template tags into PHP code. */\r
-        $compiled_tags = array();\r
-        for ($i = 0, $for_max = count($template_tags); $i < $for_max; $i++) {\r
-            $this->_current_line_no += substr_count($text_blocks[$i], "\n");\r
-            $compiled_tags[] = $this->_compile_tag($template_tags[$i]);\r
-            $this->_current_line_no += substr_count($template_tags[$i], "\n");\r
-        }\r
-\r
-        $compiled_content = '';\r
-\r
-        /* Interleave the compiled contents and text blocks to get the final result. */\r
-        for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {\r
-            if ($compiled_tags[$i] == '') {\r
-                // tag result empty, remove first newline from following text block\r
-                $text_blocks[$i+1] = preg_replace('!^(\r\n|\r|\n)!', '', $text_blocks[$i+1]);\r
-            }\r
-            $compiled_content .= $text_blocks[$i].$compiled_tags[$i];\r
-        }\r
-        $compiled_content .= $text_blocks[$i];\r
-\r
-        /* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */\r
-        if (preg_match_all("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $compiled_content, $_match)) {\r
-            $strip_tags = $_match[0];\r
-            $strip_tags_modified = preg_replace("!{$ldq}/?strip{$rdq}|[\t ]+$|^[\t ]+!m", '', $strip_tags);\r
-            $strip_tags_modified = preg_replace('![\r\n]+!m', '', $strip_tags_modified);\r
-            for ($i = 0, $for_max = count($strip_tags); $i < $for_max; $i++)\r
-                $compiled_content = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s",\r
-                                                  $this->_quote_replace($strip_tags_modified[$i]),\r
-                                                  $compiled_content, 1);\r
-        }\r
-\r
-        // remove \n from the end of the file, if any\r
-        if (($_len=strlen($compiled_content)) && ($compiled_content{$_len - 1} == "\n" )) {\r
-            $compiled_content = substr($compiled_content, 0, -1);\r
-        }\r
-\r
-        if (!empty($this->_cache_serial)) {\r
-            $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;\r
-        }\r
-\r
-        // remove unnecessary close/open tags\r
-        $compiled_content = preg_replace('!\?>\n?<\?php!', '', $compiled_content);\r
-\r
-        // run compiled template through postfilter functions\r
-        if (count($this->_plugins['postfilter']) > 0) {\r
-            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {\r
-                if ($postfilter === false) continue;\r
-                if ($postfilter[3] || is_callable($postfilter[0])) {\r
-                    $compiled_content = call_user_func_array($postfilter[0],\r
-                                                              array($compiled_content, &$this));\r
-                    $this->_plugins['postfilter'][$filter_name][3] = true;\r
-                } else {\r
-                    $this->_trigger_fatal_error("Smarty plugin error: postfilter '$filter_name' is not implemented");\r
-                }\r
-            }\r
-        }\r
-\r
-        // put header at the top of the compiled template\r
-        $template_header = "<?php /* Smarty version ".$this->_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n";\r
-        $template_header .= "         compiled from ".strtr(urlencode($resource_name), array('%2F'=>'/', '%3A'=>':'))." */ ?>\n";\r
-\r
-        /* Emit code to load needed plugins. */\r
-        $this->_plugins_code = '';\r
-        if (count($this->_plugin_info)) {\r
-            $_plugins_params = "array('plugins' => array(";\r
-            foreach ($this->_plugin_info as $plugin_type => $plugins) {\r
-                foreach ($plugins as $plugin_name => $plugin_info) {\r
-                    $_plugins_params .= "array('$plugin_type', '$plugin_name', '$plugin_info[0]', $plugin_info[1], ";\r
-                    $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),';\r
-                }\r
-            }\r
-            $_plugins_params .= '))';\r
-            $plugins_code = "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";\r
-            $template_header .= $plugins_code;\r
-            $this->_plugin_info = array();\r
-            $this->_plugins_code = $plugins_code;\r
-        }\r
-\r
-        if ($this->_init_smarty_vars) {\r
-            $template_header .= "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.assign_smarty_interface.php');\nsmarty_core_assign_smarty_interface(null, \$this); ?>\n";\r
-            $this->_init_smarty_vars = false;\r
-        }\r
-\r
-        $compiled_content = $template_header . $compiled_content;\r
-\r
-        return true;\r
-    }\r
-\r
-    /**\r
-     * Compile a template tag\r
-     *\r
-     * @param string $template_tag\r
-     * @return string\r
-     */\r
-    function _compile_tag($template_tag)\r
-    {\r
-        /* Matched comment. */\r
-        if ($template_tag{0} == '*' && $template_tag{strlen($template_tag) - 1} == '*')\r
-            return '';\r
-\r
-        /* Split tag into two three parts: command, command modifiers and the arguments. */\r
-        if(! preg_match('/^(?:(' . $this->_obj_call_regexp . '|' . $this->_var_regexp\r
-                . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*))\r
-                      (?:\s+(.*))?$\r
-                    /xs', $template_tag, $match)) {\r
-            $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__);\r
-        }\r
-\r
-        $tag_command = $match[1];\r
-        $tag_modifier = isset($match[2]) ? $match[2] : null;\r
-        $tag_args = isset($match[3]) ? $match[3] : null;\r
-\r
-        if (preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$!', $tag_command)) {\r
-            /* tag name is a variable or object */\r
-            $_return = $this->_parse_var_props($tag_command . $tag_modifier, $this->_parse_attrs($tag_args));\r
-            if(isset($_tag_attrs['assign'])) {\r
-                return "<?php \$this->assign('" . $this->_dequote($_tag_attrs['assign']) . "', $_return ); ?>\n";\r
-            } else {\r
-                return "<?php echo $_return; ?>" . $this->_additional_newline;\r
-            }\r
-        }\r
-\r
-        /* If the tag name is a registered object, we process it. */\r
-        if (preg_match('!^\/?' . $this->_reg_obj_regexp . '$!', $tag_command)) {\r
-            return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier);\r
-        }\r
-\r
-        switch ($tag_command) {\r
-            case 'include':\r
-                return $this->_compile_include_tag($tag_args);\r
-\r
-            case 'include_php':\r
-                return $this->_compile_include_php_tag($tag_args);\r
-\r
-            case 'if':\r
-                return $this->_compile_if_tag($tag_args);\r
-\r
-            case 'else':\r
-                return '<?php else: ?>';\r
-\r
-            case 'elseif':\r
-                return $this->_compile_if_tag($tag_args, true);\r
-\r
-            case '/if':\r
-                return '<?php endif; ?>';\r
-\r
-            case 'capture':\r
-                return $this->_compile_capture_tag(true, $tag_args);\r
-\r
-            case '/capture':\r
-                return $this->_compile_capture_tag(false);\r
-\r
-            case 'ldelim':\r
-                return $this->left_delimiter;\r
-\r
-            case 'rdelim':\r
-                return $this->right_delimiter;\r
-\r
-            case 'section':\r
-                array_push($this->_sectionelse_stack, false);\r
-                return $this->_compile_section_start($tag_args);\r
-\r
-            case 'sectionelse':\r
-                $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true;\r
-                return "<?php endfor; else: ?>";\r
-\r
-            case '/section':\r
-                if (array_pop($this->_sectionelse_stack))\r
-                    return "<?php endif; ?>";\r
-                else\r
-                    return "<?php endfor; endif; ?>";\r
-\r
-            case 'foreach':\r
-                array_push($this->_foreachelse_stack, false);\r
-                return $this->_compile_foreach_start($tag_args);\r
-                break;\r
-\r
-            case 'foreachelse':\r
-                $this->_foreachelse_stack[count($this->_foreachelse_stack)-1] = true;\r
-                return "<?php endforeach; unset(\$_from); else: ?>";\r
-\r
-            case '/foreach':\r
-                if (array_pop($this->_foreachelse_stack))\r
-                    return "<?php endif; ?>";\r
-                else\r
-                    return "<?php endforeach; unset(\$_from); endif; ?>";\r
-\r
-            case 'strip':\r
-            case '/strip':\r
-                if ($tag_command{0}=='/') {\r
-                    if (--$this->_strip_depth==0) { /* outermost closing {/strip} */\r
-                        $this->_additional_newline = "\n";\r
-                        return $this->left_delimiter.$tag_command.$this->right_delimiter;\r
-                    }\r
-                } else {\r
-                    if ($this->_strip_depth++==0) { /* outermost opening {strip} */\r
-                        $this->_additional_newline = "";\r
-                        return $this->left_delimiter.$tag_command.$this->right_delimiter;\r
-                    }\r
-                }\r
-                return '';\r
-\r
-            case 'literal':\r
-                list (,$literal_block) = each($this->_literal_blocks);\r
-                $this->_current_line_no += substr_count($literal_block, "\n");\r
-                return "<?php echo '".str_replace("'", "\'", str_replace("\\", "\\\\", $literal_block))."'; ?>" . $this->_additional_newline;\r
-\r
-            case 'php':\r
-                if ($this->security && !$this->security_settings['PHP_TAGS']) {\r
-                    $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__);\r
-                    return;\r
-                }\r
-                list (,$php_block) = each($this->_php_blocks);\r
-                $this->_current_line_no += substr_count($php_block, "\n");\r
-                return '<?php '.$php_block.' ?>';\r
-\r
-            case 'insert':\r
-                return $this->_compile_insert_tag($tag_args);\r
-\r
-            default:\r
-                if ($this->_compile_compiler_tag($tag_command, $tag_args, $output)) {\r
-                    return $output;\r
-                } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) {\r
-                    return $output;\r
-                } else {\r
-                    return $this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier);\r
-                }\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * compile the custom compiler tag\r
-     *\r
-     * sets $output to the compiled custom compiler tag\r
-     * @param string $tag_command\r
-     * @param string $tag_args\r
-     * @param string $output\r
-     * @return boolean\r
-     */\r
-    function _compile_compiler_tag($tag_command, $tag_args, &$output)\r
-    {\r
-        $found = false;\r
-        $have_function = true;\r
-\r
-        /*\r
-         * First we check if the compiler function has already been registered\r
-         * or loaded from a plugin file.\r
-         */\r
-        if (isset($this->_plugins['compiler'][$tag_command])) {\r
-            $found = true;\r
-            $plugin_func = $this->_plugins['compiler'][$tag_command][0];\r
-            if (!is_callable($plugin_func)) {\r
-                $message = "compiler function '$tag_command' is not implemented";\r
-                $have_function = false;\r
-            }\r
-        }\r
-        /*\r
-         * Otherwise we need to load plugin file and look for the function\r
-         * inside it.\r
-         */\r
-        else if ($plugin_file = $this->_get_plugin_filepath('compiler', $tag_command)) {\r
-            $found = true;\r
-\r
-            include_once $plugin_file;\r
-\r
-            $plugin_func = 'smarty_compiler_' . $tag_command;\r
-            if (!is_callable($plugin_func)) {\r
-                $message = "plugin function $plugin_func() not found in $plugin_file\n";\r
-                $have_function = false;\r
-            } else {\r
-                $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);\r
-            }\r
-        }\r
-\r
-        /*\r
-         * True return value means that we either found a plugin or a\r
-         * dynamically registered function. False means that we didn't and the\r
-         * compiler should now emit code to load custom function plugin for this\r
-         * tag.\r
-         */\r
-        if ($found) {\r
-            if ($have_function) {\r
-                $output = call_user_func_array($plugin_func, array($tag_args, &$this));\r
-                if($output != '') {\r
-                $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)\r
-                                   . $output\r
-                                   . $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';\r
-                }\r
-            } else {\r
-                $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);\r
-            }\r
-            return true;\r
-        } else {\r
-            return false;\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * compile block function tag\r
-     *\r
-     * sets $output to compiled block function tag\r
-     * @param string $tag_command\r
-     * @param string $tag_args\r
-     * @param string $tag_modifier\r
-     * @param string $output\r
-     * @return boolean\r
-     */\r
-    function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)\r
-    {\r
-        if ($tag_command{0} == '/') {\r
-            $start_tag = false;\r
-            $tag_command = substr($tag_command, 1);\r
-        } else\r
-            $start_tag = true;\r
-\r
-        $found = false;\r
-        $have_function = true;\r
-\r
-        /*\r
-         * First we check if the block function has already been registered\r
-         * or loaded from a plugin file.\r
-         */\r
-        if (isset($this->_plugins['block'][$tag_command])) {\r
-            $found = true;\r
-            $plugin_func = $this->_plugins['block'][$tag_command][0];\r
-            if (!is_callable($plugin_func)) {\r
-                $message = "block function '$tag_command' is not implemented";\r
-                $have_function = false;\r
-            }\r
-        }\r
-        /*\r
-         * Otherwise we need to load plugin file and look for the function\r
-         * inside it.\r
-         */\r
-        else if ($plugin_file = $this->_get_plugin_filepath('block', $tag_command)) {\r
-            $found = true;\r
-\r
-            include_once $plugin_file;\r
-\r
-            $plugin_func = 'smarty_block_' . $tag_command;\r
-            if (!function_exists($plugin_func)) {\r
-                $message = "plugin function $plugin_func() not found in $plugin_file\n";\r
-                $have_function = false;\r
-            } else {\r
-                $this->_plugins['block'][$tag_command] = array($plugin_func, null, null, null, true);\r
-\r
-            }\r
-        }\r
-\r
-        if (!$found) {\r
-            return false;\r
-        } else if (!$have_function) {\r
-            $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);\r
-            return true;\r
-        }\r
-\r
-        /*\r
-         * Even though we've located the plugin function, compilation\r
-         * happens only once, so the plugin will still need to be loaded\r
-         * at runtime for future requests.\r
-         */\r
-        $this->_add_plugin('block', $tag_command);\r
-\r
-        if ($start_tag) {\r
-            $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);\r
-            $attrs = $this->_parse_attrs($tag_args);\r
-            $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs='');\r
-            $output .= "$_cache_attrs\$_params = \$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';\r
-            $output .= $this->_compile_plugin_call('block', $tag_command).'($_params[1], null, $this, $_block_repeat=true); unset($_params);';\r
-            $output .= 'while ($_block_repeat) { ob_start(); ?>';\r
-        } else {\r
-            $output = '<?php $this->_block_content = ob_get_contents(); ob_end_clean(); ';\r
-            $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $this->_block_content, $this, $_block_repeat=false)';\r
-            if ($tag_modifier != '') {\r
-                $this->_parse_modifiers($_out_tag_text, $tag_modifier);\r
-            }\r
-            $output .= 'echo '.$_out_tag_text.'; } ';\r
-            $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';\r
-        }\r
-\r
-        return true;\r
-    }\r
-\r
-\r
-    /**\r
-     * compile custom function tag\r
-     *\r
-     * @param string $tag_command\r
-     * @param string $tag_args\r
-     * @param string $tag_modifier\r
-     * @return string\r
-     */\r
-    function _compile_custom_tag($tag_command, $tag_args, $tag_modifier)\r
-    {\r
-        $this->_add_plugin('function', $tag_command);\r
-\r
-        $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);\r
-        $attrs = $this->_parse_attrs($tag_args);\r
-        $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs='');\r
-\r
-        $_return = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)";\r
-        if($tag_modifier != '') {\r
-            $this->_parse_modifiers($_return, $tag_modifier);\r
-        }\r
-\r
-        if($_return != '') {\r
-            $_return =  '<?php ' . $_cacheable_state . $_cache_attrs . 'echo ' . $_return . ';'\r
-                . $this->_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline;\r
-        }\r
-\r
-        return $_return;\r
-    }\r
-\r
-    /**\r
-     * compile a registered object tag\r
-     *\r
-     * @param string $tag_command\r
-     * @param array $attrs\r
-     * @param string $tag_modifier\r
-     * @return string\r
-     */\r
-    function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)\r
-    {\r
-        if ($tag_command{0} == '/') {\r
-            $start_tag = false;\r
-            $tag_command = substr($tag_command, 1);\r
-        } else {\r
-            $start_tag = true;\r
-        }\r
-\r
-        list($object, $obj_comp) = explode('->', $tag_command);\r
-\r
-        $arg_list = array();\r
-        if(count($attrs)) {\r
-            $_assign_var = false;\r
-            foreach ($attrs as $arg_name => $arg_value) {\r
-                if($arg_name == 'assign') {\r
-                    $_assign_var = $arg_value;\r
-                    unset($attrs['assign']);\r
-                    continue;\r
-                }\r
-                if (is_bool($arg_value))\r
-                    $arg_value = $arg_value ? 'true' : 'false';\r
-                $arg_list[] = "'$arg_name' => $arg_value";\r
-            }\r
-        }\r
-\r
-        if($this->_reg_objects[$object][2]) {\r
-            // smarty object argument format\r
-            $args = "array(".implode(',', (array)$arg_list)."), \$this";\r
-        } else {\r
-            // traditional argument format\r
-            $args = implode(',', array_values($attrs));\r
-            if (empty($args)) {\r
-                $args = 'null';\r
-            }\r
-        }\r
-\r
-        $prefix = '';\r
-        $postfix = '';\r
-        $newline = '';\r
-        if(!is_object($this->_reg_objects[$object][0])) {\r
-            $this->_trigger_fatal_error("registered '$object' is not an object");\r
-        } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) {\r
-            $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'");\r
-        } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) {\r
-            // method\r
-            if(in_array($obj_comp, $this->_reg_objects[$object][3])) {\r
-                // block method\r
-                if ($start_tag) {\r
-                    $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); ";\r
-                    $prefix .= "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat=true); ";\r
-                    $prefix .= "while (\$_block_repeat) { ob_start();";\r
-                    $return = null;\r
-                    $postfix = '';\r
-            } else {\r
-                    $prefix = "\$this->_obj_block_content = ob_get_contents(); ob_end_clean(); ";\r
-                    $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$this->_obj_block_content, \$this, \$_block_repeat=false)";\r
-                    $postfix = "} array_pop(\$this->_tag_stack);";\r
-                }\r
-            } else {\r
-                // non-block method\r
-                $return = "\$this->_reg_objects['$object'][0]->$obj_comp($args)";\r
-            }\r
-        } else {\r
-            // property\r
-            $return = "\$this->_reg_objects['$object'][0]->$obj_comp";\r
-        }\r
-\r
-        if($return != null) {\r
-            if($tag_modifier != '') {\r
-                $this->_parse_modifiers($return, $tag_modifier);\r
-            }\r
-\r
-            if(!empty($_assign_var)) {\r
-                $output = "\$this->assign('" . $this->_dequote($_assign_var) ."',  $return);";\r
-            } else {\r
-                $output = 'echo ' . $return . ';';\r
-                $newline = $this->_additional_newline;\r
-            }\r
-        } else {\r
-            $output = '';\r
-        }\r
-\r
-        return '<?php ' . $prefix . $output . $postfix . "?>" . $newline;\r
-    }\r
-\r
-    /**\r
-     * Compile {insert ...} tag\r
-     *\r
-     * @param string $tag_args\r
-     * @return string\r
-     */\r
-    function _compile_insert_tag($tag_args)\r
-    {\r
-        $attrs = $this->_parse_attrs($tag_args);\r
-        $name = $this->_dequote($attrs['name']);\r
-\r
-        if (empty($name)) {\r
-            $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);\r
-        }\r
-\r
-        if (!empty($attrs['script'])) {\r
-            $delayed_loading = true;\r
-        } else {\r
-            $delayed_loading = false;\r
-        }\r
-\r
-        foreach ($attrs as $arg_name => $arg_value) {\r
-            if (is_bool($arg_value))\r
-                $arg_value = $arg_value ? 'true' : 'false';\r
-            $arg_list[] = "'$arg_name' => $arg_value";\r
-        }\r
-\r
-        $this->_add_plugin('insert', $name, $delayed_loading);\r
-\r
-        $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))";\r
-\r
-        return "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.run_insert_handler.php');\necho smarty_core_run_insert_handler($_params, \$this); ?>" . $this->_additional_newline;\r
-    }\r
-\r
-    /**\r
-     * Compile {include ...} tag\r
-     *\r
-     * @param string $tag_args\r
-     * @return string\r
-     */\r
-    function _compile_include_tag($tag_args)\r
-    {\r
-        $attrs = $this->_parse_attrs($tag_args);\r
-        $arg_list = array();\r
-\r
-        if (empty($attrs['file'])) {\r
-            $this->_syntax_error("missing 'file' attribute in include tag", E_USER_ERROR, __FILE__, __LINE__);\r
-        }\r
-\r
-        foreach ($attrs as $arg_name => $arg_value) {\r
-            if ($arg_name == 'file') {\r
-                $include_file = $arg_value;\r
-                continue;\r
-            } else if ($arg_name == 'assign') {\r
-                $assign_var = $arg_value;\r
-                continue;\r
-            }\r
-            if (is_bool($arg_value))\r
-                $arg_value = $arg_value ? 'true' : 'false';\r
-            $arg_list[] = "'$arg_name' => $arg_value";\r
-        }\r
-\r
-        $output = '<?php ';\r
-\r
-        if (isset($assign_var)) {\r
-            $output .= "ob_start();\n";\r
-        }\r
-\r
-        $output .=\r
-            "\$_smarty_tpl_vars = \$this->_tpl_vars;\n";\r
-\r
-\r
-        $_params = "array('smarty_include_tpl_file' => " . $include_file . ", 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";\r
-        $output .= "\$this->_smarty_include($_params);\n" .\r
-        "\$this->_tpl_vars = \$_smarty_tpl_vars;\n" .\r
-        "unset(\$_smarty_tpl_vars);\n";\r
-\r
-        if (isset($assign_var)) {\r
-            $output .= "\$this->assign(" . $assign_var . ", ob_get_contents()); ob_end_clean();\n";\r
-        }\r
-\r
-        $output .= ' ?>';\r
-\r
-        return $output;\r
-\r
-    }\r
-\r
-    /**\r
-     * Compile {include ...} tag\r
-     *\r
-     * @param string $tag_args\r
-     * @return string\r
-     */\r
-    function _compile_include_php_tag($tag_args)\r
-    {\r
-        $attrs = $this->_parse_attrs($tag_args);\r
-\r
-        if (empty($attrs['file'])) {\r
-            $this->_syntax_error("missing 'file' attribute in include_php tag", E_USER_ERROR, __FILE__, __LINE__);\r
-        }\r
-\r
-        $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']);\r
-        $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true';\r
-\r
-        foreach($attrs as $arg_name => $arg_value) {\r
-            if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') {\r
-                if(is_bool($arg_value))\r
-                    $arg_value = $arg_value ? 'true' : 'false';\r
-                $arg_list[] = "'$arg_name' => $arg_value";\r
-            }\r
-        }\r
-\r
-        $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))";\r
-\r
-        return "<?php require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.smarty_include_php.php');\nsmarty_core_smarty_include_php($_params, \$this); ?>" . $this->_additional_newline;\r
-    }\r
-\r
-\r
-    /**\r
-     * Compile {section ...} tag\r
-     *\r
-     * @param string $tag_args\r
-     * @return string\r
-     */\r
-    function _compile_section_start($tag_args)\r
-    {\r
-        $attrs = $this->_parse_attrs($tag_args);\r
-        $arg_list = array();\r
-\r
-        $output = '<?php ';\r
-        $section_name = $attrs['name'];\r
-        if (empty($section_name)) {\r
-            $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__);\r
-        }\r
-\r
-        $output .= "if (isset(\$this->_sections[$section_name])) unset(\$this->_sections[$section_name]);\n";\r
-        $section_props = "\$this->_sections[$section_name]";\r
-\r
-        foreach ($attrs as $attr_name => $attr_value) {\r
-            switch ($attr_name) {\r
-                case 'loop':\r
-                    $output .= "{$section_props}['loop'] = is_array(\$_loop=$attr_value) ? count(\$_loop) : max(0, (int)\$_loop); unset(\$_loop);\n";\r
-                    break;\r
-\r
-                case 'show':\r
-                    if (is_bool($attr_value))\r
-                        $show_attr_value = $attr_value ? 'true' : 'false';\r
-                    else\r
-                        $show_attr_value = "(bool)$attr_value";\r
-                    $output .= "{$section_props}['show'] = $show_attr_value;\n";\r
-                    break;\r
-\r
-                case 'name':\r
-                    $output .= "{$section_props}['$attr_name'] = $attr_value;\n";\r
-                    break;\r
-\r
-                case 'max':\r
-                case 'start':\r
-                    $output .= "{$section_props}['$attr_name'] = (int)$attr_value;\n";\r
-                    break;\r
-\r
-                case 'step':\r
-                    $output .= "{$section_props}['$attr_name'] = ((int)$attr_value) == 0 ? 1 : (int)$attr_value;\n";\r
-                    break;\r
-\r
-                default:\r
-                    $this->_syntax_error("unknown section attribute - '$attr_name'", E_USER_ERROR, __FILE__, __LINE__);\r
-                    break;\r
-            }\r
-        }\r
-\r
-        if (!isset($attrs['show']))\r
-            $output .= "{$section_props}['show'] = true;\n";\r
-\r
-        if (!isset($attrs['loop']))\r
-            $output .= "{$section_props}['loop'] = 1;\n";\r
-\r
-        if (!isset($attrs['max']))\r
-            $output .= "{$section_props}['max'] = {$section_props}['loop'];\n";\r
-        else\r
-            $output .= "if ({$section_props}['max'] < 0)\n" .\r
-                       "    {$section_props}['max'] = {$section_props}['loop'];\n";\r
-\r
-        if (!isset($attrs['step']))\r
-            $output .= "{$section_props}['step'] = 1;\n";\r
-\r
-        if (!isset($attrs['start']))\r
-            $output .= "{$section_props}['start'] = {$section_props}['step'] > 0 ? 0 : {$section_props}['loop']-1;\n";\r
-        else {\r
-            $output .= "if ({$section_props}['start'] < 0)\n" .\r
-                       "    {$section_props}['start'] = max({$section_props}['step'] > 0 ? 0 : -1, {$section_props}['loop'] + {$section_props}['start']);\n" .\r
-                       "else\n" .\r
-                       "    {$section_props}['start'] = min({$section_props}['start'], {$section_props}['step'] > 0 ? {$section_props}['loop'] : {$section_props}['loop']-1);\n";\r
-        }\r
-\r
-        $output .= "if ({$section_props}['show']) {\n";\r
-        if (!isset($attrs['start']) && !isset($attrs['step']) && !isset($attrs['max'])) {\r
-            $output .= "    {$section_props}['total'] = {$section_props}['loop'];\n";\r
-        } else {\r
-            $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";\r
-        }\r
-        $output .= "    if ({$section_props}['total'] == 0)\n" .\r
-                   "        {$section_props}['show'] = false;\n" .\r
-                   "} else\n" .\r
-                   "    {$section_props}['total'] = 0;\n";\r
-\r
-        $output .= "if ({$section_props}['show']):\n";\r
-        $output .= "\r
-            for ({$section_props}['index'] = {$section_props}['start'], {$section_props}['iteration'] = 1;\r
-                 {$section_props}['iteration'] <= {$section_props}['total'];\r
-                 {$section_props}['index'] += {$section_props}['step'], {$section_props}['iteration']++):\n";\r
-        $output .= "{$section_props}['rownum'] = {$section_props}['iteration'];\n";\r
-        $output .= "{$section_props}['index_prev'] = {$section_props}['index'] - {$section_props}['step'];\n";\r
-        $output .= "{$section_props}['index_next'] = {$section_props}['index'] + {$section_props}['step'];\n";\r
-        $output .= "{$section_props}['first']      = ({$section_props}['iteration'] == 1);\n";\r
-        $output .= "{$section_props}['last']       = ({$section_props}['iteration'] == {$section_props}['total']);\n";\r
-\r
-        $output .= "?>";\r
-\r
-        return $output;\r
-    }\r
-\r
-\r
-    /**\r
-     * Compile {foreach ...} tag.\r
-     *\r
-     * @param string $tag_args\r
-     * @return string\r
-     */\r
-    function _compile_foreach_start($tag_args)\r
-    {\r
-        $attrs = $this->_parse_attrs($tag_args);\r
-        $arg_list = array();\r
-\r
-        if (empty($attrs['from'])) {\r
-            $this->_syntax_error("missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__);\r
-        }\r
-\r
-        if (empty($attrs['item'])) {\r
-            $this->_syntax_error("missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__);\r
-        }\r
-\r
-        $from = $attrs['from'];\r
-        $item = $this->_dequote($attrs['item']);\r
-        if (isset($attrs['name']))\r
-            $name = $attrs['name'];\r
-\r
-        $output = '<?php ';\r
-        if (isset($name)) {\r
-            $output .= "if (isset(\$this->_foreach[$name])) unset(\$this->_foreach[$name]);\n";\r
-            $foreach_props = "\$this->_foreach[$name]";\r
-        }\r
-\r
-        $key_part = '';\r
-\r
-        foreach ($attrs as $attr_name => $attr_value) {\r
-            switch ($attr_name) {\r
-                case 'key':\r
-                    $key  = $this->_dequote($attrs['key']);\r
-                    $key_part = "\$this->_tpl_vars['$key'] => ";\r
-                    break;\r
-\r
-                case 'name':\r
-                    $output .= "{$foreach_props}['$attr_name'] = $attr_value;\n";\r
-                    break;\r
-            }\r
-        }\r
-\r
-        if (isset($name)) {\r
-            $output .= "{$foreach_props}['total'] = count(\$_from = (array)$from);\n";\r
-            $output .= "{$foreach_props}['show'] = {$foreach_props}['total'] > 0;\n";\r
-            $output .= "if ({$foreach_props}['show']):\n";\r
-            $output .= "{$foreach_props}['iteration'] = 0;\n";\r
-            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";\r
-            $output .= "        {$foreach_props}['iteration']++;\n";\r
-            $output .= "        {$foreach_props}['first'] = ({$foreach_props}['iteration'] == 1);\n";\r
-            $output .= "        {$foreach_props}['last']  = ({$foreach_props}['iteration'] == {$foreach_props}['total']);\n";\r
-        } else {\r
-            $output .= "if (count(\$_from = (array)$from)):\n";\r
-            $output .= "    foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n";\r
-        }\r
-        $output .= '?>';\r
-\r
-        return $output;\r
-    }\r
-\r
-\r
-    /**\r
-     * Compile {capture} .. {/capture} tags\r
-     *\r
-     * @param boolean $start true if this is the {capture} tag\r
-     * @param string $tag_args\r
-     * @return string\r
-     */\r
-\r
-    function _compile_capture_tag($start, $tag_args = '')\r
-    {\r
-        $attrs = $this->_parse_attrs($tag_args);\r
-\r
-        if ($start) {\r
-            if (isset($attrs['name']))\r
-                $buffer = $attrs['name'];\r
-            else\r
-                $buffer = "'default'";\r
-\r
-            if (isset($attrs['assign']))\r
-                $assign = $attrs['assign'];\r
-            else\r
-                $assign = null;\r
-            $output = "<?php ob_start(); ?>";\r
-            $this->_capture_stack[] = array($buffer, $assign);\r
-        } else {\r
-            list($buffer, $assign) = array_pop($this->_capture_stack);\r
-            $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";\r
-            if (isset($assign)) {\r
-                $output .= " \$this->assign($assign, ob_get_contents());";\r
-            }\r
-            $output .= "ob_end_clean(); ?>";\r
-        }\r
-\r
-        return $output;\r
-    }\r
-\r
-    /**\r
-     * Compile {if ...} tag\r
-     *\r
-     * @param string $tag_args\r
-     * @param boolean $elseif if true, uses elseif instead of if\r
-     * @return string\r
-     */\r
-    function _compile_if_tag($tag_args, $elseif = false)\r
-    {\r
-\r
-        /* Tokenize args for 'if' tag. */\r
-        preg_match_all('/(?>\r
-                ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call\r
-                ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)?    | # var or quoted string\r
-                \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@    | # valid non-word token\r
-                \b\w+\b                                                        | # valid word token\r
-                \S+                                                           # anything else\r
-                )/x', $tag_args, $match);\r
-\r
-        $tokens = $match[0];\r
-\r
-        // make sure we have balanced parenthesis\r
-        $token_count = array_count_values($tokens);\r
-        if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {\r
-            $this->_syntax_error("unbalanced parenthesis in if statement", E_USER_ERROR, __FILE__, __LINE__);\r
-        }\r
-\r
-        $is_arg_stack = array();\r
-\r
-        for ($i = 0; $i < count($tokens); $i++) {\r
-\r
-            $token = &$tokens[$i];\r
-\r
-            switch (strtolower($token)) {\r
-                case '!':\r
-                case '%':\r
-                case '!==':\r
-                case '==':\r
-                case '===':\r
-                case '>':\r
-                case '<':\r
-                case '!=':\r
-                case '<>':\r
-                case '<<':\r
-                case '>>':\r
-                case '<=':\r
-                case '>=':\r
-                case '&&':\r
-                case '||':\r
-                case '|':\r
-                case '^':\r
-                case '&':\r
-                case '~':\r
-                case ')':\r
-                case ',':\r
-                case '+':\r
-                case '-':\r
-                case '*':\r
-                case '/':\r
-                case '@':\r
-                    break;\r
-\r
-                case 'eq':\r
-                    $token = '==';\r
-                    break;\r
-\r
-                case 'ne':\r
-                case 'neq':\r
-                    $token = '!=';\r
-                    break;\r
-\r
-                case 'lt':\r
-                    $token = '<';\r
-                    break;\r
-\r
-                case 'le':\r
-                case 'lte':\r
-                    $token = '<=';\r
-                    break;\r
-\r
-                case 'gt':\r
-                    $token = '>';\r
-                    break;\r
-\r
-                case 'ge':\r
-                case 'gte':\r
-                    $token = '>=';\r
-                    break;\r
-\r
-                case 'and':\r
-                    $token = '&&';\r
-                    break;\r
-\r
-                case 'or':\r
-                    $token = '||';\r
-                    break;\r
-\r
-                case 'not':\r
-                    $token = '!';\r
-                    break;\r
-\r
-                case 'mod':\r
-                    $token = '%';\r
-                    break;\r
-\r
-                case '(':\r
-                    array_push($is_arg_stack, $i);\r
-                    break;\r
-\r
-                case 'is':\r
-                    /* If last token was a ')', we operate on the parenthesized\r
-                       expression. The start of the expression is on the stack.\r
-                       Otherwise, we operate on the last encountered token. */\r
-                    if ($tokens[$i-1] == ')')\r
-                        $is_arg_start = array_pop($is_arg_stack);\r
-                    else\r
-                        $is_arg_start = $i-1;\r
-                    /* Construct the argument for 'is' expression, so it knows\r
-                       what to operate on. */\r
-                    $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start));\r
-\r
-                    /* Pass all tokens from next one until the end to the\r
-                       'is' expression parsing function. The function will\r
-                       return modified tokens, where the first one is the result\r
-                       of the 'is' expression and the rest are the tokens it\r
-                       didn't touch. */\r
-                    $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1));\r
-\r
-                    /* Replace the old tokens with the new ones. */\r
-                    array_splice($tokens, $is_arg_start, count($tokens), $new_tokens);\r
-\r
-                    /* Adjust argument start so that it won't change from the\r
-                       current position for the next iteration. */\r
-                    $i = $is_arg_start;\r
-                    break;\r
-\r
-                default:\r
-                    if(preg_match('!^' . $this->_func_regexp . '$!', $token) ) {\r
-                            // function call\r
-                            if($this->security &&\r
-                               !in_array($token, $this->security_settings['IF_FUNCS'])) {\r
-                                $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);\r
-                            }\r
-                    } elseif(preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$!', $token)) {\r
-                        // object or variable\r
-                        $token = $this->_parse_var_props($token);\r
-                    } elseif(is_numeric($token)) {\r
-                        // number, skip it\r
-                    } else {\r
-                        $this->_syntax_error("unidentified token '$token'", E_USER_ERROR, __FILE__, __LINE__);\r
-                    }\r
-                    break;\r
-            }\r
-        }\r
-\r
-        if ($elseif)\r
-            return '<?php elseif ('.implode(' ', $tokens).'): ?>';\r
-        else\r
-            return '<?php if ('.implode(' ', $tokens).'): ?>';\r
-    }\r
-\r
-\r
-    function _compile_arg_list($type, $name, $attrs, &$cache_code) {\r
-        $arg_list = array();\r
-\r
-        if (isset($type) && isset($name)\r
-            && isset($this->_plugins[$type])\r
-            && isset($this->_plugins[$type][$name])\r
-            && empty($this->_plugins[$type][$name][4])\r
-            && is_array($this->_plugins[$type][$name][5])\r
-            ) {\r
-            /* we have a list of parameters that should be cached */\r
-            $_cache_attrs = $this->_plugins[$type][$name][5];\r
-            $_count = $this->_cache_attrs_count++;\r
-            $cache_code = "\$_cache_attrs =& \$this->_smarty_cache_attrs('$this->_cache_serial','$_count');";\r
-\r
-        } else {\r
-            /* no parameters are cached */\r
-            $_cache_attrs = null;\r
-        }\r
-\r
-        foreach ($attrs as $arg_name => $arg_value) {\r
-            if (is_bool($arg_value))\r
-                $arg_value = $arg_value ? 'true' : 'false';\r
-            if (is_null($arg_value))\r
-                $arg_value = 'null';\r
-            if ($_cache_attrs && in_array($arg_name, $_cache_attrs)) {\r
-                $arg_list[] = "'$arg_name' => (\$this->_cache_including) ? \$_cache_attrs['$arg_name'] : (\$_cache_attrs['$arg_name']=$arg_value)";\r
-            } else {\r
-                $arg_list[] = "'$arg_name' => $arg_value";\r
-            }\r
-        }\r
-        return $arg_list;\r
-    }\r
-\r
-    /**\r
-     * Parse is expression\r
-     *\r
-     * @param string $is_arg\r
-     * @param array $tokens\r
-     * @return array\r
-     */\r
-    function _parse_is_expr($is_arg, $tokens)\r
-    {\r
-        $expr_end = 0;\r
-        $negate_expr = false;\r
-\r
-        if (($first_token = array_shift($tokens)) == 'not') {\r
-            $negate_expr = true;\r
-            $expr_type = array_shift($tokens);\r
-        } else\r
-            $expr_type = $first_token;\r
-\r
-        switch ($expr_type) {\r
-            case 'even':\r
-                if (@$tokens[$expr_end] == 'by') {\r
-                    $expr_end++;\r
-                    $expr_arg = $tokens[$expr_end++];\r
-                    $expr = "!(($is_arg / $expr_arg) % " . $this->_parse_var_props($expr_arg) . ")";\r
-                } else\r
-                    $expr = "!($is_arg % 2)";\r
-                break;\r
-\r
-            case 'odd':\r
-                if (@$tokens[$expr_end] == 'by') {\r
-                    $expr_end++;\r
-                    $expr_arg = $tokens[$expr_end++];\r
-                    $expr = "(($is_arg / $expr_arg) % ". $this->_parse_var_props($expr_arg) . ")";\r
-                } else\r
-                    $expr = "($is_arg % 2)";\r
-                break;\r
-\r
-            case 'div':\r
-                if (@$tokens[$expr_end] == 'by') {\r
-                    $expr_end++;\r
-                    $expr_arg = $tokens[$expr_end++];\r
-                    $expr = "!($is_arg % " . $this->_parse_var_props($expr_arg) . ")";\r
-                } else {\r
-                    $this->_syntax_error("expecting 'by' after 'div'", E_USER_ERROR, __FILE__, __LINE__);\r
-                }\r
-                break;\r
-\r
-            default:\r
-                $this->_syntax_error("unknown 'is' expression - '$expr_type'", E_USER_ERROR, __FILE__, __LINE__);\r
-                break;\r
-        }\r
-\r
-        if ($negate_expr) {\r
-            $expr = "!($expr)";\r
-        }\r
-\r
-        array_splice($tokens, 0, $expr_end, $expr);\r
-\r
-        return $tokens;\r
-    }\r
-\r
-\r
-    /**\r
-     * Parse attribute string\r
-     *\r
-     * @param string $tag_args\r
-     * @return array\r
-     */\r
-    function _parse_attrs($tag_args)\r
-    {\r
-\r
-        /* Tokenize tag attributes. */\r
-        preg_match_all('/(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+)\r
-                         )+ |\r
-                         [=]\r
-                        /x', $tag_args, $match);\r
-        $tokens       = $match[0];\r
-\r
-        $attrs = array();\r
-        /* Parse state:\r
-            0 - expecting attribute name\r
-            1 - expecting '='\r
-            2 - expecting attribute value (not '=') */\r
-        $state = 0;\r
-\r
-        foreach ($tokens as $token) {\r
-            switch ($state) {\r
-                case 0:\r
-                    /* If the token is a valid identifier, we set attribute name\r
-                       and go to state 1. */\r
-                    if (preg_match('!^\w+$!', $token)) {\r
-                        $attr_name = $token;\r
-                        $state = 1;\r
-                    } else\r
-                        $this->_syntax_error("invalid attribute name: '$token'", E_USER_ERROR, __FILE__, __LINE__);\r
-                    break;\r
-\r
-                case 1:\r
-                    /* If the token is '=', then we go to state 2. */\r
-                    if ($token == '=') {\r
-                        $state = 2;\r
-                    } else\r
-                        $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);\r
-                    break;\r
-\r
-                case 2:\r
-                    /* If token is not '=', we set the attribute value and go to\r
-                       state 0. */\r
-                    if ($token != '=') {\r
-                        /* We booleanize the token if it's a non-quoted possible\r
-                           boolean value. */\r
-                        if (preg_match('!^(on|yes|true)$!', $token)) {\r
-                            $token = 'true';\r
-                        } else if (preg_match('!^(off|no|false)$!', $token)) {\r
-                            $token = 'false';\r
-                        } else if ($token == 'null') {\r
-                            $token = 'null';\r
-                        } else if (preg_match('!^-?([0-9]+|0[xX][0-9a-fA-F]+)$!', $token)) {\r
-                            /* treat integer literally */\r
-                        } else if (!preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$!', $token)) {\r
-                            /* treat as a string, double-quote it escaping quotes */\r
-                            $token = '"'.addslashes($token).'"';\r
-                        }\r
-\r
-                        $attrs[$attr_name] = $token;\r
-                        $state = 0;\r
-                    } else\r
-                        $this->_syntax_error("'=' cannot be an attribute value", E_USER_ERROR, __FILE__, __LINE__);\r
-                    break;\r
-            }\r
-            $last_token = $token;\r
-        }\r
-\r
-        if($state != 0) {\r
-            if($state == 1) {\r
-                $this->_syntax_error("expecting '=' after attribute name '$last_token'", E_USER_ERROR, __FILE__, __LINE__);\r
-            } else {\r
-                $this->_syntax_error("missing attribute value", E_USER_ERROR, __FILE__, __LINE__);\r
-            }\r
-        }\r
-\r
-        $this->_parse_vars_props($attrs);\r
-\r
-        return $attrs;\r
-    }\r
-\r
-    /**\r
-     * compile multiple variables and section properties tokens into\r
-     * PHP code\r
-     *\r
-     * @param array $tokens\r
-     */\r
-    function _parse_vars_props(&$tokens)\r
-    {\r
-        foreach($tokens as $key => $val) {\r
-            $tokens[$key] = $this->_parse_var_props($val);\r
-        }\r
-    }\r
-\r
-    /**\r
-     * compile single variable and section properties token into\r
-     * PHP code\r
-     *\r
-     * @param string $val\r
-     * @param string $tag_attrs\r
-     * @return string\r
-     */\r
-    function _parse_var_props($val)\r
-    {\r
-        $val = trim($val);\r
-\r
-        if(preg_match('!^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$!', $val, $match)) {\r
-                // $ variable or object\r
-                $return = $this->_parse_var($match[1]);\r
-                if($match[2] != '') {\r
-                    $this->_parse_modifiers($return, $match[2]);\r
-                }\r
-                return $return;\r
-            }\r
-        elseif(preg_match('!^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {\r
-                // double quoted text\r
-                preg_match('!^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$!', $val, $match);\r
-                $return = $this->_expand_quoted_text($match[1]);\r
-                if($match[2] != '') {\r
-                    $this->_parse_modifiers($return, $match[2]);\r
-                }\r
-                return $return;\r
-            }\r
-        elseif(preg_match('!^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {\r
-                // single quoted text\r
-                preg_match('!^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$!', $val, $match);\r
-                if($match[2] != '') {\r
-                    $this->_parse_modifiers($match[1], $match[2]);\r
-                    return $match[1];\r
-                }\r
-            }\r
-        elseif(preg_match('!^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {\r
-                // config var\r
-                return $this->_parse_conf_var($val);\r
-            }\r
-        elseif(preg_match('!^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) {\r
-                // section var\r
-                return $this->_parse_section_prop($val);\r
-            }\r
-        elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {\r
-            // literal string\r
-            return $this->_expand_quoted_text('"' . $val .'"');\r
-        }\r
-        return $val;\r
-    }\r
-\r
-    /**\r
-     * expand quoted text with embedded variables\r
-     *\r
-     * @param string $var_expr\r
-     * @return string\r
-     */\r
-    function _expand_quoted_text($var_expr)\r
-    {\r
-        // if contains unescaped $, expand it\r
-        if(preg_match_all('%(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)%', $var_expr, $_match)) {\r
-            $_match = $_match[0];\r
-            rsort($_match);\r
-            reset($_match);\r
-            foreach($_match as $_var) {\r
-                $var_expr = str_replace ($_var, '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."', $var_expr);\r
-            }\r
-            $_return = preg_replace('%\.""|(?<!\\\\)""\.%', '', $var_expr);\r
-        } else {\r
-            $_return = $var_expr;\r
-        }\r
-        // replace double quoted literal string with single quotes\r
-        $_return = preg_replace('!^"([\s\w]+)"$!',"'\\1'",$_return);\r
-        return $_return;\r
-    }\r
-\r
-    /**\r
-     * parse variable expression into PHP code\r
-     *\r
-     * @param string $var_expr\r
-     * @param string $output\r
-     * @return string\r
-     */\r
-    function _parse_var($var_expr)\r
-    {\r
-        $_has_math = false;\r
-        $_math_vars = preg_split('!('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')!', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE);\r
-\r
-        if(count($_math_vars) > 1) {\r
-            $_first_var = "";\r
-            $_complete_var = "";\r
-            // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter)\r
-            foreach($_math_vars as $_k => $_math_var) {\r
-                $_math_var = $_math_vars[$_k];\r
-\r
-                if(!empty($_math_var) || is_numeric($_math_var)) {\r
-                    // hit a math operator, so process the stuff which came before it\r
-                    if(preg_match('!^' . $this->_dvar_math_regexp . '$!', $_math_var)) {\r
-                        $_has_math = true;\r
-                        if(!empty($_complete_var) || is_numeric($_complete_var)) {\r
-                            $_output .= $this->_parse_var($_complete_var);\r
-                        }\r
-\r
-                        // just output the math operator to php\r
-                        $_output .= $_math_var;\r
-\r
-                        if(empty($_first_var))\r
-                            $_first_var = $_complete_var;\r
-\r
-                        $_complete_var = "";\r
-                    } else {\r
-                        // fetch multiple -> (like $foo->bar->baz ) which wouldn't get fetched else, because it would only get $foo->bar and treat the ->baz as "-" ">baz" then\r
-                        for($_i = $_k + 1; $_i <= count($_math_vars); $_i += 2) {\r
-                            // fetch -> because it gets splitted at - and move it back together\r
-                            if( /* prevent notice */ (isset($_math_vars[$_i]) && isset($_math_vars[$_i+1])) && ($_math_vars[$_i] === '-' && $_math_vars[$_i+1]{0} === '>')) {\r
-                                $_math_var .= $_math_vars[$_i].$_math_vars[$_i+1];\r
-                                $_math_vars[$_i] = $_math_vars[$_i+1] = '';\r
-                            } else {\r
-                                break;\r
-                            }\r
-                        }\r
-                        $_complete_var .= $_math_var;\r
-                    }\r
-                }\r
-            }\r
-            if($_has_math) {\r
-                if(!empty($_complete_var) || is_numeric($_complete_var))\r
-                    $_output .= $this->_parse_var($_complete_var, true);\r
-\r
-                // get the modifiers working (only the last var from math + modifier is left)\r
-                $var_expr = $_complete_var;\r
-            }\r
-        }\r
-\r
-        // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit)\r
-        if(is_numeric($var_expr{0}))\r
-            $_var_ref = $var_expr;\r
-        else\r
-            $_var_ref = substr($var_expr, 1);\r
-\r
-        if(!$_has_math) {\r
-            // get [foo] and .foo and ->foo and (...) pieces\r
-            preg_match_all('!(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+!', $_var_ref, $match);\r
-\r
-            $_indexes = $match[0];\r
-            $_var_name = array_shift($_indexes);\r
-\r
-            /* Handle $smarty.* variable references as a special case. */\r
-            if ($_var_name == 'smarty') {\r
-                /*\r
-                 * If the reference could be compiled, use the compiled output;\r
-                 * otherwise, fall back on the $smarty variable generated at\r
-                 * run-time.\r
-                 */\r
-                if (($smarty_ref = $this->_compile_smarty_ref($_indexes)) !== null) {\r
-                    $_output = $smarty_ref;\r
-                } else {\r
-                    $_var_name = substr(array_shift($_indexes), 1);\r
-                    $_output = "\$this->_smarty_vars['$_var_name']";\r
-                }\r
-            } elseif(is_numeric($_var_name) && is_numeric($var_expr{0})) {\r
-                // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers\r
-                if(count($_indexes) > 0)\r
-                {\r
-                    $_var_name .= implode("", $_indexes);\r
-                    $_indexes = array();\r
-                }\r
-                $_output = $_var_name;\r
-            } else {\r
-                $_output = "\$this->_tpl_vars['$_var_name']";\r
-            }\r
-\r
-            foreach ($_indexes as $_index) {\r
-                if ($_index{0} == '[') {\r
-                    $_index = substr($_index, 1, -1);\r
-                    if (is_numeric($_index)) {\r
-                        $_output .= "[$_index]";\r
-                    } elseif ($_index{0} == '$') {\r
-                        if (strpos($_index, '.') !== false) {\r
-                            $_output .= '[' . $this->_parse_var($_index) . ']';\r
-                        } else {\r
-                            $_output .= "[\$this->_tpl_vars['" . substr($_index, 1) . "']]";\r
-                        }\r
-                    } else {\r
-                        $_var_parts = explode('.', $_index);\r
-                        $_var_section = $_var_parts[0];\r
-                        $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';\r
-                        $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";\r
-                    }\r
-                } else if ($_index{0} == '.') {\r
-                    if ($_index{1} == '$')\r
-                        $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";\r
-                    else\r
-                        $_output .= "['" . substr($_index, 1) . "']";\r
-                } else if (substr($_index,0,2) == '->') {\r
-                    if(substr($_index,2,2) == '__') {\r
-                        $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);\r
-                    } elseif($this->security && substr($_index, 2, 1) == '_') {\r
-                        $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);\r
-                    } elseif ($_index{2} == '$') {\r
-                        if ($this->security) {\r
-                            $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);\r
-                        } else {\r
-                            $_output .= '->{(($_var=$this->_tpl_vars[\''.substr($_index,3).'\']) && substr($_var,0,2)!=\'__\') ? $_var : $this->trigger_error("cannot access property \\"$_var\\"")}';\r
-                        }\r
-                    } else {\r
-                        $_output .= $_index;\r
-                    }\r
-                } elseif ($_index{0} == '(') {\r
-                    $_index = $this->_parse_parenth_args($_index);\r
-                    $_output .= $_index;\r
-                } else {\r
-                    $_output .= $_index;\r
-                }\r
-            }\r
-        }\r
-\r
-        return $_output;\r
-    }\r
-\r
-    /**\r
-     * parse arguments in function call parenthesis\r
-     *\r
-     * @param string $parenth_args\r
-     * @return string\r
-     */\r
-    function _parse_parenth_args($parenth_args)\r
-    {\r
-        preg_match_all('!' . $this->_param_regexp . '!',$parenth_args, $match);\r
-        $match = $match[0];\r
-        rsort($match);\r
-        reset($match);\r
-        $orig_vals = $match;\r
-        $this->_parse_vars_props($match);\r
-        return str_replace($orig_vals, $match, $parenth_args);\r
-    }\r
-\r
-    /**\r
-     * parse configuration variable expression into PHP code\r
-     *\r
-     * @param string $conf_var_expr\r
-     */\r
-    function _parse_conf_var($conf_var_expr)\r
-    {\r
-        $parts = explode('|', $conf_var_expr, 2);\r
-        $var_ref = $parts[0];\r
-        $modifiers = isset($parts[1]) ? $parts[1] : '';\r
-\r
-        $var_name = substr($var_ref, 1, -1);\r
-\r
-        $output = "\$this->_config[0]['vars']['$var_name']";\r
-\r
-        $this->_parse_modifiers($output, $modifiers);\r
-\r
-        return $output;\r
-    }\r
-\r
-    /**\r
-     * parse section property expression into PHP code\r
-     *\r
-     * @param string $section_prop_expr\r
-     * @return string\r
-     */\r
-    function _parse_section_prop($section_prop_expr)\r
-    {\r
-        $parts = explode('|', $section_prop_expr, 2);\r
-        $var_ref = $parts[0];\r
-        $modifiers = isset($parts[1]) ? $parts[1] : '';\r
-\r
-        preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match);\r
-        $section_name = $match[1];\r
-        $prop_name = $match[2];\r
-\r
-        $output = "\$this->_sections['$section_name']['$prop_name']";\r
-\r
-        $this->_parse_modifiers($output, $modifiers);\r
-\r
-        return $output;\r
-    }\r
-\r
-\r
-    /**\r
-     * parse modifier chain into PHP code\r
-     *\r
-     * sets $output to parsed modified chain\r
-     * @param string $output\r
-     * @param string $modifier_string\r
-     */\r
-    function _parse_modifiers(&$output, $modifier_string)\r
-    {\r
-        preg_match_all('!\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $_match);\r
-        list(, $_modifiers, $modifier_arg_strings) = $_match;\r
-\r
-        for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) {\r
-            $_modifier_name = $_modifiers[$_i];\r
-\r
-            if($_modifier_name == 'smarty') {\r
-                // skip smarty modifier\r
-                continue;\r
-            }\r
-\r
-            preg_match_all('!:(' . $this->_qstr_regexp . '|[^:]+)!', $modifier_arg_strings[$_i], $_match);\r
-            $_modifier_args = $_match[1];\r
-\r
-            if ($_modifier_name{0} == '@') {\r
-                $_map_array = false;\r
-                $_modifier_name = substr($_modifier_name, 1);\r
-            } else {\r
-                $_map_array = true;\r
-            }\r
-\r
-            $this->_add_plugin('modifier', $_modifier_name);\r
-            if (empty($this->_plugins['modifier'][$_modifier_name])\r
-                && !$this->_get_plugin_filepath('modifier', $_modifier_name)\r
-                && function_exists($_modifier_name)) {\r
-                if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) {\r
-                    $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $_tpl_file, $_tpl_line, __FILE__, __LINE__);\r
-                } else {\r
-                    $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name,  null, null, false);\r
-                }\r
-            }\r
-\r
-            $this->_parse_vars_props($_modifier_args);\r
-\r
-            if($_modifier_name == 'default') {\r
-                // supress notifications of default modifier vars and args\r
-                if($output{0} == '$') {\r
-                    $output = '@' . $output;\r
-                }\r
-                if(isset($_modifier_args[0]) && $_modifier_args[0]{0} == '$') {\r
-                    $_modifier_args[0] = '@' . $_modifier_args[0];\r
-                }\r
-            }\r
-            if (count($_modifier_args) > 0)\r
-                $_modifier_args = ', '.implode(', ', $_modifier_args);\r
-            else\r
-                $_modifier_args = '';\r
-\r
-            if ($_map_array) {\r
-                $output = "((is_array(\$_tmp=$output)) ? \$this->_run_mod_handler('$_modifier_name', true, \$_tmp$_modifier_args) : " . $this->_compile_plugin_call('modifier', $_modifier_name) . "(\$_tmp$_modifier_args))";\r
-\r
-            } else {\r
-\r
-                $output = $this->_compile_plugin_call('modifier', $_modifier_name)."($output$_modifier_args)";\r
-\r
-            }\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * add plugin\r
-     *\r
-     * @param string $type\r
-     * @param string $name\r
-     * @param boolean? $delayed_loading\r
-     */\r
-    function _add_plugin($type, $name, $delayed_loading = null)\r
-    {\r
-        if (!isset($this->_plugin_info[$type])) {\r
-            $this->_plugin_info[$type] = array();\r
-        }\r
-        if (!isset($this->_plugin_info[$type][$name])) {\r
-            $this->_plugin_info[$type][$name] = array($this->_current_file,\r
-                                                      $this->_current_line_no,\r
-                                                      $delayed_loading);\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Compiles references of type $smarty.foo\r
-     *\r
-     * @param string $indexes\r
-     * @return string\r
-     */\r
-    function _compile_smarty_ref(&$indexes)\r
-    {\r
-        /* Extract the reference name. */\r
-        $_ref = substr($indexes[0], 1);\r
-        foreach($indexes as $_index_no=>$_index) {\r
-            if ($_index{0} != '.' && $_index_no<2 || !preg_match('!^(\.|\[|->)!', $_index)) {\r
-                $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);\r
-            }\r
-        }\r
-\r
-        switch ($_ref) {\r
-            case 'now':\r
-                $compiled_ref = 'time()';\r
-                $_max_index = 1;\r
-                break;\r
-\r
-            case 'foreach':\r
-            case 'section':\r
-                array_shift($indexes);\r
-                $_var = $this->_parse_var_props(substr($indexes[0], 1));\r
-                if ($_ref == 'foreach')\r
-                    $compiled_ref = "\$this->_foreach[$_var]";\r
-                else\r
-                    $compiled_ref = "\$this->_sections[$_var]";\r
-                break;\r
-\r
-            case 'get':\r
-                $compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']";\r
-                break;\r
-\r
-            case 'post':\r
-                $compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']";\r
-                break;\r
-\r
-            case 'cookies':\r
-                $compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']";\r
-                break;\r
-\r
-            case 'env':\r
-                $compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']";\r
-                break;\r
-\r
-            case 'server':\r
-                $compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']";\r
-                break;\r
-\r
-            case 'session':\r
-                $compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']";\r
-                break;\r
-\r
-            /*\r
-             * These cases are handled either at run-time or elsewhere in the\r
-             * compiler.\r
-             */\r
-            case 'request':\r
-                if ($this->request_use_auto_globals) {\r
-                    $compiled_ref = '$_REQUEST';\r
-                    break;\r
-                } else {\r
-                    $this->_init_smarty_vars = true;\r
-                }\r
-                return null;\r
-\r
-            case 'capture':\r
-                return null;\r
-\r
-            case 'template':\r
-                $compiled_ref = "'$this->_current_file'";\r
-                $_max_index = 1;\r
-                break;\r
-\r
-            case 'version':\r
-                $compiled_ref = "'$this->_version'";\r
-                $_max_index = 1;\r
-                break;\r
-\r
-            case 'const':\r
-                array_shift($indexes);\r
-                $_val = $this->_parse_var_props(substr($indexes[0],1));\r
-                $compiled_ref = '@constant(' . $_val . ')';\r
-                $_max_index = 1;\r
-                break;\r
-\r
-            case 'config':\r
-                $compiled_ref = "\$this->_config[0]['vars']";\r
-                $_max_index = 2;\r
-                break;\r
-\r
-            default:\r
-                $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__);\r
-                break;\r
-        }\r
-\r
-        if (isset($_max_index) && count($indexes) > $_max_index) {\r
-            $this->_syntax_error('$smarty' . implode('', $indexes) .' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);\r
-        }\r
-\r
-        array_shift($indexes);\r
-        return $compiled_ref;\r
-    }\r
-\r
-    /**\r
-     * compiles call to plugin of type $type with name $name\r
-     * returns a string containing the function-name or method call\r
-     * without the paramter-list that would have follow to make the\r
-     * call valid php-syntax\r
-     *\r
-     * @param string $type\r
-     * @param string $name\r
-     * @return string\r
-     */\r
-    function _compile_plugin_call($type, $name) {\r
-        if (isset($this->_plugins[$type][$name])) {\r
-            /* plugin loaded */\r
-            if (is_array($this->_plugins[$type][$name][0])) {\r
-                return ((is_object($this->_plugins[$type][$name][0][0])) ?\r
-                        "\$this->_plugins['$type']['$name'][0][0]->"    /* method callback */\r
-                        : (string)($this->_plugins[$type][$name][0][0]).'::'    /* class callback */\r
-                       ). $this->_plugins[$type][$name][0][1];\r
-\r
-            } else {\r
-                /* function callback */\r
-                return $this->_plugins[$type][$name][0];\r
-\r
-            }\r
-        } else {\r
-            /* plugin not loaded -> auto-loadable-plugin */\r
-            return 'smarty_'.$type.'_'.$name;\r
-\r
-        }\r
-    }\r
-\r
-    /**\r
-     * load pre- and post-filters\r
-     */\r
-    function _load_filters()\r
-    {\r
-        if (count($this->_plugins['prefilter']) > 0) {\r
-            foreach ($this->_plugins['prefilter'] as $filter_name => $prefilter) {\r
-                if ($prefilter === false) {\r
-                    unset($this->_plugins['prefilter'][$filter_name]);\r
-                    $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false)));\r
-                    require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php');\r
-                    smarty_core_load_plugins($_params, $this);\r
-                }\r
-            }\r
-        }\r
-        if (count($this->_plugins['postfilter']) > 0) {\r
-            foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {\r
-                if ($postfilter === false) {\r
-                    unset($this->_plugins['postfilter'][$filter_name]);\r
-                    $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false)));\r
-                    require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php');\r
-                    smarty_core_load_plugins($_params, $this);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-\r
-    /**\r
-     * Quote subpattern references\r
-     *\r
-     * @param string $string\r
-     * @return string\r
-     */\r
-    function _quote_replace($string)\r
-    {\r
-        return preg_replace('![\\$]\d!', '\\\\\\0', $string);\r
-    }\r
-\r
-    /**\r
-     * display Smarty syntax error\r
-     *\r
-     * @param string $error_msg\r
-     * @param integer $error_type\r
-     * @param string $file\r
-     * @param integer $line\r
-     */\r
-    function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null)\r
-    {\r
-        if(isset($file) && isset($line)) {\r
-            $info = ' ('.basename($file).", line $line)";\r
-        } else {\r
-            $info = null;\r
-        }\r
-        trigger_error('Smarty: [in ' . $this->_current_file . ' line ' .\r
-                      $this->_current_line_no . "]: syntax error: $error_msg$info", $error_type);\r
-    }\r
-\r
-\r
-    /**\r
-     * check if the compilation changes from cacheable to\r
-     * non-cacheable state with the beginning of the current\r
-     * plugin. return php-code to reflect the transition.\r
-     * @return string\r
-     */\r
-    function _push_cacheable_state($type, $name) {\r
-        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];\r
-        if ($_cacheable\r
-            || 0<$this->_cacheable_state++) return '';\r
-        if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));\r
-        $_ret = 'if ($this->caching) { echo \'{nocache:'\r
-            . $this->_cache_serial . '#' . $this->_nocache_count\r
-            . '}\';}';\r
-        return $_ret;\r
-    }\r
-\r
-\r
-    /**\r
-     * check if the compilation changes from non-cacheable to\r
-     * cacheable state with the end of the current plugin return\r
-     * php-code to reflect the transition.\r
-     * @return string\r
-     */\r
-    function _pop_cacheable_state($type, $name) {\r
-        $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];\r
-        if ($_cacheable\r
-            || --$this->_cacheable_state>0) return '';\r
-        return 'if ($this->caching) { echo \'{/nocache:'\r
-            . $this->_cache_serial . '#' . ($this->_nocache_count++)\r
-            . '}\';}';\r
-    }\r
-\r
-}\r
-\r
-/**\r
- * compare to values by their string length\r
- *\r
- * @access private\r
- * @param string $a\r
- * @param string $b\r
- * @return 0|-1|1\r
- */\r
-function _smarty_sort_length($a, $b)\r
-{\r
-    if($a == $b)\r
-        return 0;\r
-\r
-    if(strlen($a) == strlen($b))\r
-        return ($a > $b) ? -1 : 1;\r
-\r
-    return (strlen($a) > strlen($b)) ? -1 : 1;\r
-}\r
-\r
-\r
-/* vim: set et: */\r
-\r
-?>\r