diff --git a/Smarty.class.php b/Smarty.class.php index 5b316814..5fa82b96 100644 --- a/Smarty.class.php +++ b/Smarty.class.php @@ -1,13 +1,13 @@ + * Project: Smarty: the PHP compiling template engine + * File: Smarty.class.php + * Author: Monte Ohrt * Andrei Zmievski * * Version: 1.2.3 * Copyright: 2001 ispi of Lincoln, Inc. - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -42,239 +42,239 @@ require("Smarty.addons.php"); class Smarty { - // public vars - var $compile_check = true; // whether to check for compiling step or not: + // public vars + var $compile_check = true; // whether to check for compiling step or not: // This is generally set to false once the // application is entered into production and // initially compiled. Leave set to true // during development. true/false - var $force_compile = false; // force templates to compile every time. + var $force_compile = false; // force templates to compile every time. // overrides compile_check. true/false - + // NOTE: all cache directives override // compiling directives. If a cached version // is available, that will be used regardless // of compile settings. - var $caching = false; // whether to use caching or not. true/false - var $cache_lifetime = 3600; // number of seconds cached content will persist. + var $caching = false; // whether to use caching or not. true/false + var $cache_lifetime = 3600; // number of seconds cached content will persist. // 0 = never expires. default is one hour (3600) - var $template_dir = "./templates"; // name of directory for templates - var $compile_dir = "./templates_c"; // name of directory for compiled templates - var $cache_dir = "./cache"; // name of directory for template cache - - - var $tpl_file_ext = ".tpl"; // template file extentions - - var $allow_php = false; // whether or not to allow embedded php + var $template_dir = "./templates"; // name of directory for templates + var $compile_dir = "./templates_c"; // name of directory for compiled templates + var $cache_dir = "./cache"; // name of directory for template cache + + + var $tpl_file_ext = ".tpl"; // template file extentions + + var $allow_php = false; // whether or not to allow embedded php // in the templates. By default, php tags // are escaped. true/false - var $left_delimiter = "{"; // template tag delimiters. - var $right_delimiter = "}"; + var $left_delimiter = "{"; // template tag delimiters. + var $right_delimiter = "}"; - var $config_dir = "./configs"; // directory where config files are located + var $config_dir = "./configs"; // directory where config files are located - var $custom_funcs = array( 'html_options' => 'smarty_func_html_options', - 'html_select_date' => 'smarty_func_html_select_date' - ); - - var $custom_mods = array( 'lower' => 'strtolower', - 'upper' => 'strtoupper', - 'capitalize' => 'ucwords', - 'escape' => 'smarty_mod_escape', - 'truncate' => 'smarty_mod_truncate', - 'spacify' => 'smarty_mod_spacify', - 'date_format' => 'smarty_mod_date_format', - 'string_format' => 'smarty_mod_string_format', - 'replace' => 'smarty_mod_replace', - 'strip_tags' => 'smarty_mod_strip_tags', - 'default' => 'smarty_mod_default' - ); - var $global_assign = array( 'SCRIPT_NAME' - ); - - // internal vars - var $_error_msg = false; // error messages. true/false - var $_tpl_vars = array(); - var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part - var $_literal_blocks = array(); // keeps literal template blocks - var $_current_file = null; // the current template being compiled - var $_current_line_no = 1; // line number for error messages - var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' + var $custom_funcs = array( 'html_options' => 'smarty_func_html_options', + 'html_select_date' => 'smarty_func_html_select_date' + ); + + var $custom_mods = array( 'lower' => 'strtolower', + 'upper' => 'strtoupper', + 'capitalize' => 'ucwords', + 'escape' => 'smarty_mod_escape', + 'truncate' => 'smarty_mod_truncate', + 'spacify' => 'smarty_mod_spacify', + 'date_format' => 'smarty_mod_date_format', + 'string_format' => 'smarty_mod_string_format', + 'replace' => 'smarty_mod_replace', + 'strip_tags' => 'smarty_mod_strip_tags', + 'default' => 'smarty_mod_default' + ); + var $global_assign = array( 'SCRIPT_NAME' + ); + + // internal vars + var $_error_msg = false; // error messages. true/false + var $_tpl_vars = array(); + var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part + var $_literal_blocks = array(); // keeps literal template blocks + var $_current_file = null; // the current template being compiled + var $_current_line_no = 1; // line number for error messages + var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' - + /*======================================================================*\ - Function: Smarty - Purpose: Constructor + Function: Smarty + Purpose: Constructor \*======================================================================*/ - function Smarty() - { - foreach ($this->global_assign as $var_name) - $this->assign($var_name, $GLOBALS[$var_name]); - } + function Smarty() + { + foreach ($this->global_assign as $var_name) + $this->assign($var_name, $GLOBALS[$var_name]); + } /*======================================================================*\ - Function: assign() - Purpose: assigns values to template variables + Function: assign() + Purpose: assigns values to template variables \*======================================================================*/ - function assign($tpl_var, $value = NULL) - { - if (is_array($tpl_var)){ - foreach ($tpl_var as $key => $val) { - if (!empty($key)) - $this->_tpl_vars[$key] = $val; - } - } else { - if (!empty($tpl_var) && isset($value)) - $this->_tpl_vars[$tpl_var] = $value; - } - } + function assign($tpl_var, $value = NULL) + { + if (is_array($tpl_var)){ + foreach ($tpl_var as $key => $val) { + if (!empty($key)) + $this->_tpl_vars[$key] = $val; + } + } else { + if (!empty($tpl_var) && isset($value)) + $this->_tpl_vars[$tpl_var] = $value; + } + } - + /*======================================================================*\ - Function: append - Purpose: appens values to template variables + Function: append + Purpose: appens values to template variables \*======================================================================*/ - function append($tpl_var, $value = NULL) - { - if (is_array($tpl_var)) { - foreach ($tpl_var as $key => $val) { - if (!empty($key)) { - if (!is_array($this->_tpl_vars[$key])) - settype($this->_tpl_vars[$key], 'array'); - $this->_tpl_vars[$key][] = $val; - } - } - } else { - if (!empty($tpl_var) && isset($value)) { - if (!is_array($this->_tpl_vars[$tpl_var])) - settype($this->_tpl_vars[$tpl_var], 'array'); - $this->_tpl_vars[$tpl_var][] = $value; - } - } - } + function append($tpl_var, $value = NULL) + { + if (is_array($tpl_var)) { + foreach ($tpl_var as $key => $val) { + if (!empty($key)) { + if (!is_array($this->_tpl_vars[$key])) + settype($this->_tpl_vars[$key], 'array'); + $this->_tpl_vars[$key][] = $val; + } + } + } else { + if (!empty($tpl_var) && isset($value)) { + if (!is_array($this->_tpl_vars[$tpl_var])) + settype($this->_tpl_vars[$tpl_var], 'array'); + $this->_tpl_vars[$tpl_var][] = $value; + } + } + } /*======================================================================*\ - Function: clear_assign() - Purpose: clear the given assigned template variable. + Function: clear_assign() + Purpose: clear the given assigned template variable. \*======================================================================*/ - function clear_assign($tpl_var) - { - unset($this->_tpl_vars[$tpl_var]); - } + function clear_assign($tpl_var) + { + unset($this->_tpl_vars[$tpl_var]); + } /*======================================================================*\ - Function: clear_cache() - Purpose: clear all cached template files for given template + Function: clear_cache() + Purpose: clear all cached template files for given template \*======================================================================*/ - function clear_cache($tpl_file) - { - if(is_dir($this->cache_dir)) - $dir_handle = opendir($this->cache_dir); - else - return false; - - // remove leading . or / - $tpl_file = preg_replace("/^(\.{0,2}\/)*/","",$tpl_file); - $tpl_file_url = urlencode($tpl_file); - - while($curr_file = readdir($dir_handle)) { - if ($curr_file == '.' || $curr_file == '..') - continue; - - if(is_file($this->cache_dir."/".$curr_file) && - substr($curr_file,0,strlen($tpl_file_url)) == $tpl_file_url) - unlink($this->cache_dir."/".$curr_file); - } - return true; - } - - + function clear_cache($tpl_file) + { + if(is_dir($this->cache_dir)) + $dir_handle = opendir($this->cache_dir); + else + return false; + + // remove leading . or / + $tpl_file = preg_replace("/^(\.{0,2}\/)*/","",$tpl_file); + $tpl_file_url = urlencode($tpl_file); + + while($curr_file = readdir($dir_handle)) { + if ($curr_file == '.' || $curr_file == '..') + continue; + + if(is_file($this->cache_dir."/".$curr_file) && + substr($curr_file,0,strlen($tpl_file_url)) == $tpl_file_url) + unlink($this->cache_dir."/".$curr_file); + } + return true; + } + + /*======================================================================*\ - Function: clear_all_cache() - Purpose: clear all the cached template files. + Function: clear_all_cache() + Purpose: clear all the cached template files. \*======================================================================*/ - function clear_all_cache() - { - if(is_dir($this->cache_dir)) - $dir_handle = opendir($this->cache_dir); - else - return false; + function clear_all_cache() + { + if(is_dir($this->cache_dir)) + $dir_handle = opendir($this->cache_dir); + else + return false; - while($curr_file = readdir($dir_handle)) { - if ($curr_file == '.' || $curr_file == '..') - continue; - if(is_file($this->cache_dir."/".$curr_file) && substr($curr_file,-6) == '.cache') - unlink($this->cache_dir."/".$curr_file); - } - return true; - } - + while($curr_file = readdir($dir_handle)) { + if ($curr_file == '.' || $curr_file == '..') + continue; + if(is_file($this->cache_dir."/".$curr_file) && substr($curr_file,-6) == '.cache') + unlink($this->cache_dir."/".$curr_file); + } + return true; + } + /*======================================================================*\ - Function: clear_all_assign() - Purpose: clear all the assigned template variables. + Function: clear_all_assign() + Purpose: clear all the assigned template variables. \*======================================================================*/ - function clear_all_assign() - { - $this->_tpl_vars = array(); - } + function clear_all_assign() + { + $this->_tpl_vars = array(); + } /*======================================================================*\ - Function: get_template_vars - Purpose: Returns an array containing template variables + Function: get_template_vars + Purpose: Returns an array containing template variables \*======================================================================*/ - function &get_template_vars() - { - return $this->_tpl_vars; - } + function &get_template_vars() + { + return $this->_tpl_vars; + } /*======================================================================*\ - Function: display() - Purpose: executes & displays the template results + Function: display() + Purpose: executes & displays the template results \*======================================================================*/ - function display($tpl_file) - { - $this->fetch($tpl_file, true); - } - + function display($tpl_file) + { + $this->fetch($tpl_file, true); + } + /*======================================================================*\ - Function: fetch() - Purpose: executes & returns or displays the template results + Function: fetch() + Purpose: executes & returns or displays the template results \*======================================================================*/ - function fetch($tpl_file, $display = false) - { - global $PHP_SELF; + function fetch($tpl_file, $display = false) + { + global $PHP_SELF; - if($this->caching) { - // cache id = template path + the invoked script - $cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".cache"; - if(!$this->cache_force && - (file_exists($cache_file) && - ($this->cache_lifetime == 0 || - (mktime() - filemtime($cache_file) <= $this->cache_lifetime) - ))) { - $results = $this->_read_file($cache_file); - $results = $this->_process_cached_inserts($results); + if($this->caching) { + // cache id = template path + the invoked script + $cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".cache"; + if(!$this->cache_force && + (file_exists($cache_file) && + ($this->cache_lifetime == 0 || + (mktime() - filemtime($cache_file) <= $this->cache_lifetime) + ))) { + $results = $this->_read_file($cache_file); + $results = $this->_process_cached_inserts($results); if ($display) { print $results; return; } else return $results; - } - } + } + } // compile files $this->_compile($this->template_dir); @@ -294,893 +294,895 @@ class Smarty ob_end_clean(); } - if($this->caching) { - $this->_write_file($cache_file, $results); - $results = $this->_process_cached_inserts($results); - } + if($this->caching) { + $this->_write_file($cache_file, $results); + $results = $this->_process_cached_inserts($results); + } if ($display) { print $results; return; } else return $results; - } - + } + /*======================================================================*\ - Function: compile() - Purpose: called to compile the templates + Function: compile() + Purpose: called to compile the templates \*======================================================================*/ - function _compile($tpl_dir) - { - if($this->compile_check || $this->force_compile) - { - if($this->_traverse_files($tpl_dir, 0)) - return true; - else - return false; - } - else - return false; - } - + function _compile($tpl_dir) + { + if($this->compile_check || $this->force_compile) + { + if($this->_traverse_files($tpl_dir, 0)) + return true; + else + return false; + } + else + return false; + } + /*======================================================================*\ - Function: _traverse_files() - Purpose: traverse the template files & process each one + Function: _traverse_files() + Purpose: traverse the template files & process each one \*======================================================================*/ - function _traverse_files($tpl_dir, $depth) - { - if(is_dir($tpl_dir)) { - if($tpl_dir) - $dir_handle = opendir($tpl_dir); + function _traverse_files($tpl_dir, $depth) + { + if(is_dir($tpl_dir)) { + if($tpl_dir) + $dir_handle = opendir($tpl_dir); - while($curr_file = readdir($dir_handle)) { - if ($curr_file == '.' || $curr_file == '..') - continue; + while($curr_file = readdir($dir_handle)) { + if ($curr_file == '.' || $curr_file == '..') + continue; - $filepath = $tpl_dir."/".$curr_file; - if(is_readable($filepath)) { - - if(is_file($filepath) && substr($curr_file, -strlen($this->tpl_file_ext)) == $this->tpl_file_ext) { - if(!$this->_process_file($filepath)) - return false; - } else if (is_dir($filepath)) { - if (!$this->_traverse_files($filepath, $depth + 1)) - return false; - } else { - // invalid file type, skipping - $this->_set_error_msg("Invalid filetype for $filepath, skipping"); - continue; - } - } - } - } else { - $this->_set_error_msg("Directory \"$tpl_dir\" does not exist or is not a directory."); - return false; - } + $filepath = $tpl_dir."/".$curr_file; + if(is_readable($filepath)) { + + if(is_file($filepath) && substr($curr_file, -strlen($this->tpl_file_ext)) == $this->tpl_file_ext) { + if(!$this->_process_file($filepath)) + return false; + } else if (is_dir($filepath)) { + if (!$this->_traverse_files($filepath, $depth + 1)) + return false; + } else { + // invalid file type, skipping + $this->_set_error_msg("Invalid filetype for $filepath, skipping"); + continue; + } + } + } + } else { + $this->_set_error_msg("Directory \"$tpl_dir\" does not exist or is not a directory."); + return false; + } - return true; - } + return true; + } /*======================================================================*\ - Function: _process_file() - Input: test template files for modifications - and execute the compilation for each - one requiring it. + Function: _process_file() + Input: test template files for modifications + and execute the compilation for each + one requiring it. \*======================================================================*/ - function _process_file($filepath) - { - if(preg_match("/^(.+)\/([^\/]+)$/", $filepath, $match)) { - $tpl_file_dir = $match[1]; - $tpl_file_name = $match[2] . ".php"; + function _process_file($filepath) + { + if(preg_match("/^(.+)\/([^\/]+)$/", $filepath, $match)) { + $tpl_file_dir = $match[1]; + $tpl_file_name = $match[2] . ".php"; - $compile_dir = preg_replace('!^' . preg_quote($this->template_dir, '!') . '!', - $this->compile_dir, $match[1]); + $compile_dir = preg_replace('!^' . preg_quote($this->template_dir, '!') . '!', + $this->compile_dir, $match[1]); - //create directory if none exists - if(!file_exists($compile_dir)) { - $compile_dir_parts = preg_split('!/+!', $compile_dir); - $new_dir = ""; - foreach ($compile_dir_parts as $dir_part) { - $new_dir .= $dir_part."/"; - if (!file_exists($new_dir) && !mkdir($new_dir, 0755)) { - $this->_set_error_msg("problem creating directory \"$compile_dir\""); - return false; - } - } - } + //create directory if none exists + if(!file_exists($compile_dir)) { + $compile_dir_parts = preg_split('!/+!', $compile_dir); + $new_dir = ""; + foreach ($compile_dir_parts as $dir_part) { + $new_dir .= $dir_part."/"; + if (!file_exists($new_dir) && !mkdir($new_dir, 0755)) { + $this->_set_error_msg("problem creating directory \"$compile_dir\""); + return false; + } + } + } - // compile the template file if none exists or has been modified or recompile is forced - if ($this->force_compile || !file_exists($compile_dir."/".$tpl_file_name) || - ($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) { - if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name)) - return false; - } else { - // no compilation needed - return true; - } - } else { - $this->_set_error_msg("problem matching \"$filepath.\""); - return false; - } + // compile the template file if none exists or has been modified or recompile is forced + if ($this->force_compile || !file_exists($compile_dir."/".$tpl_file_name) || + ($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) { + if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name)) + return false; + } else { + // no compilation needed + return true; + } + } else { + $this->_set_error_msg("problem matching \"$filepath.\""); + return false; + } - return true; - } + return true; + } /*======================================================================*\ - Function: _modified_file() - Input: return comparison of modification times of files + Function: _modified_file() + Input: return comparison of modification times of files \*======================================================================*/ - function _modified_file($filepath, $compilepath) - { - if(filemtime($filepath) >= filemtime($compilepath)) - return true; - return false; - } + function _modified_file($filepath, $compilepath) + { + if(filemtime($filepath) >= filemtime($compilepath)) + return true; + return false; + } /*======================================================================*\ - Function: _compile_file() - Input: compile a template file + Function: _compile_file() + Input: compile a template file \*======================================================================*/ - function _compile_file($filepath, $compilepath) - { - if (!($template_contents = $this->_read_file($filepath))) - return false; + function _compile_file($filepath, $compilepath) + { + if (!($template_contents = $this->_read_file($filepath))) + return false; - $this->_current_file = str_replace($this->template_dir . "/", "", $filepath); - $this->_current_line_no = 1; - $ldq = preg_quote($this->left_delimiter, '!'); - $rdq = preg_quote($this->right_delimiter, '!'); + $this->_current_file = str_replace($this->template_dir . "/", "", $filepath); + $this->_current_line_no = 1; + $ldq = preg_quote($this->left_delimiter, '!'); + $rdq = preg_quote($this->right_delimiter, '!'); - /* Pull out the literal blocks. */ - preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_contents, $match); - $this->_literal_blocks = $match[1]; - $template_contents = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", - '{literal}', $template_contents); + /* Pull out the literal blocks. */ + preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_contents, $match); + $this->_literal_blocks = $match[1]; + $template_contents = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", + '{literal}', $template_contents); - /* Gather all template tags. */ - preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_contents, $match); - $template_tags = $match[1]; - /* Split content by template tags to obtain non-template content. */ - $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $template_contents); - if(!$this->allow_php) { - /* Escape php tags. */ - $text_blocks = preg_replace('!<\?([^?]*?)\?>!', '<?$1?>', $text_blocks); - } + /* Gather all template tags. */ + preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_contents, $match); + $template_tags = $match[1]; + /* Split content by template tags to obtain non-template content. */ + $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $template_contents); + if(!$this->allow_php) { + /* Escape php tags. */ + $text_blocks = preg_replace('!<\?([^?]*?)\?>!', '<?$1?>', $text_blocks); + } - /* Compile the template tags into PHP code. */ - $compiled_tags = array(); - for ($i = 0; $i < count($template_tags); $i++) { - $this->_current_line_no += substr_count($text_blocks[$i], "\n"); - $compiled_tags[] = $this->_compile_tag($template_tags[$i]); - $this->_current_line_no += substr_count($template_tags[$i], "\n"); - } + /* Compile the template tags into PHP code. */ + $compiled_tags = array(); + for ($i = 0; $i < count($template_tags); $i++) { + $this->_current_line_no += substr_count($text_blocks[$i], "\n"); + $compiled_tags[] = $this->_compile_tag($template_tags[$i]); + $this->_current_line_no += substr_count($template_tags[$i], "\n"); + } - $compiled_contents = ""; - - /* Interleave the compiled contents and text blocks to get the final result. */ - for ($i = 0; $i < count($compiled_tags); $i++) { - $compiled_contents .= $text_blocks[$i].$compiled_tags[$i]; - } - $compiled_contents .= $text_blocks[$i]; - - /* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */ - if (preg_match_all("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $compiled_contents, $match)) { - $strip_tags = $match[0]; - $strip_tags_modified = preg_replace("!{$ldq}/?strip{$rdq}|[\t ]+$|^[\t ]+!m", '', $strip_tags); - $strip_tags_modified = preg_replace('![\r\n]+!m', '', $strip_tags_modified); - for ($i = 0; $i < count($strip_tags); $i++) - $compiled_contents = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", - $strip_tags_modified[$i], $compiled_contents, 1); - } + $compiled_contents = ""; + + /* Interleave the compiled contents and text blocks to get the final result. */ + for ($i = 0; $i < count($compiled_tags); $i++) { + $compiled_contents .= $text_blocks[$i].$compiled_tags[$i]; + } + $compiled_contents .= $text_blocks[$i]; + + /* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */ + if (preg_match_all("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $compiled_contents, $match)) { + $strip_tags = $match[0]; + $strip_tags_modified = preg_replace("!{$ldq}/?strip{$rdq}|[\t ]+$|^[\t ]+!m", '', $strip_tags); + $strip_tags_modified = preg_replace('![\r\n]+!m', '', $strip_tags_modified); + for ($i = 0; $i < count($strip_tags); $i++) + $compiled_contents = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", + $strip_tags_modified[$i], $compiled_contents, 1); + } - if(!$this->_write_file($compilepath, $compiled_contents)) - return false; + if(!$this->_write_file($compilepath, $compiled_contents)) + return false; - return true; - } + return true; + } /*======================================================================*\ - Function: _process_cached_inserts - Purpose: Replace cached inserts with the actual results + Function: _process_cached_inserts + Purpose: Replace cached inserts with the actual results \*======================================================================*/ - function _process_cached_inserts($results) - { - preg_match_all('!'.$this->_smarty_md5.'{insert_cache (.*)}'.$this->_smarty_md5.'!Uis', - $results, $match); - list($cached_inserts, $insert_args) = $match; - - for ($i = 0; $i < count($cached_inserts); $i++) { - $attrs = $this->_parse_attrs($insert_args[$i], false); - $name = $this->_dequote($attrs['name']); - - if (empty($name)) { - $this->_syntax_error("missing insert name"); - } - - $arg_list = array(); - foreach ($attrs as $arg_name => $arg_value) { - if ($arg_name == 'name') continue; - $arg_list[$arg_name] = $arg_value; - } - - $function_name = 'insert_' . $name; - $replace = $function_name($arg_list); - - $results = str_replace($cached_inserts[$i], $replace, $results); - } - - return $results; - } - - function _compile_tag($template_tag) - { - /* Matched comment. */ - if ($template_tag{0} == '*' && $template_tag{strlen($template_tag)-1} == '*') - return ""; - - $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; - - /* Split tag into two parts: command and the arguments. */ - preg_match('/^( - (?: ' . $qstr_regexp . ' | (?>[^"\'\s]+))+ - ) - (?:\s+(.*))? - /xs', $template_tag, $match); - list(, $tag_command, $tag_args) = $match; - - /* If the tag name matches a variable or section property definition, - we simply process it. */ - if (preg_match('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // if a variable - preg_match('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // or a configuration variable - preg_match('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command)) { // or a section property - settype($tag_command, 'array'); - $this->_parse_vars_props($tag_command); - return ""; - } - - switch ($tag_command) { - case 'include': - return $this->_compile_include_tag($tag_args); - - case 'if': - return $this->_compile_if_tag($tag_args); - - case 'else': - return ''; - - case 'elseif': - return $this->_compile_if_tag($tag_args, true); - - case '/if': - return ''; - - case 'ldelim': - return $this->left_delimiter; - - case 'rdelim': - return $this->right_delimiter; - - case 'section': - array_push($this->_sectionelse_stack, false); - return $this->_compile_section_start($tag_args); - - case 'sectionelse': - $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true; - return ""; - - case '/section': - if (array_pop($this->_sectionelse_stack)) - return ""; - else - return ""; - - case 'config_load': - return $this->_compile_config_load_tag($tag_args); - - case 'strip': - case '/strip': - return $this->left_delimiter.$tag_command.$this->right_delimiter; - - case 'literal': - list (,$literal_block) = each($this->_literal_blocks); - $this->_current_line_no += substr_count($literal_block, "\n"); - return $literal_block; - - case 'insert': - return $this->_compile_insert_tag($tag_args); - - default: - if (isset($this->custom_funcs[$tag_command])) { - return $this->_compile_custom_tag($tag_command, $tag_args); - } else { - $this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING); - return ""; - } - } - } - - function _compile_custom_tag($tag_command, $tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $function = $this->custom_funcs[$tag_command]; - foreach ($attrs as $arg_name => $arg_value) { - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - return ""; - } - - function _compile_insert_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $name = substr($attrs['name'], 1, -1); - - if (empty($name)) { - $this->_syntax_error("missing insert name"); - } - - if($this->caching) - return $this->_smarty_md5."{insert_cache $tag_args}".$this->_smarty_md5; - - foreach ($attrs as $arg_name => $arg_value) { - if ($arg_name == 'name') continue; - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - return ""; - } - - function _compile_config_load_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - - if (empty($attrs['file'])) { - $this->_syntax_error("missing 'file' attribute in config_load tag"); - } - - $output = "config_dir."');\n" . - "}\n" . - "\$_config = array_merge((array)\$_config, \$_conf_obj->get(".$attrs['file']."));\n"; - - if (!empty($attrs['section'])) - $output .= '$_config = array_merge((array)$_config, $_conf_obj->get('.$attrs['file'].', '.$attrs['section'].')); '; - - $output .= '?>'; - - return $output; - } - - - function _compile_include_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - - if (empty($attrs['file'])) { - $this->_syntax_error("missing 'file' attribute in include tag"); - } else - $attrs['file'] = $this->_dequote($attrs['file']); - - if (count($attrs) > 1) { - $include_func_name = uniqid("_include_"); - $include_file_name = $this->compile_dir.'/'.$attrs['file']; - - foreach ($attrs as $arg_name => $arg_value) { - if ($arg_name == 'file') continue; - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - return "\n"; - } else - return 'compile_dir.'/'.$attrs['file'].'.php"; ?>'; - } - - function _compile_section_start($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - - $output = "_syntax_error("missing section name"); - } - - $output .= "unset(\$_sections[$section_name]);\n"; - $section_props = "\$_sections[$section_name]['properties']"; - - foreach ($attrs as $attr_name => $attr_value) { - switch ($attr_name) { - case 'loop': - $output .= "{$section_props}['loop'] = is_array($attr_value) ? count($attr_value) : $attr_value;\n"; - break; - - case 'show': - if (is_bool($attr_value)) - $attr_value = $attr_value ? 'true' : 'false'; - $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; - break; - - default: - $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; - break; - } - } - - if (isset($attrs['loop'])) { - $loop_check_code = "{$section_props}['loop'] > 0 && "; - } else { - $output .= "{$section_props}['loop'] = 1;\n"; - } - - if (isset($attrs['show'])) { - $show_check_code = "{$section_props}['show'] && "; - } else { - $output .= "{$section_props}['show'] = {$section_props}['loop'] > 0;\n"; - } - - $output .= "if ($loop_check_code $show_check_code true): "; - - $output .= " - for ({$section_props}['index'] = 0; - {$section_props}['index'] < {$section_props}['loop']; - {$section_props}['index']++):\n"; - $output .= "{$section_props}['rownum'] = {$section_props}['index'] + 1;\n"; - - $output .= "?>\n"; - - return $output; - } - - function _compile_if_tag($tag_args, $elseif = false) - { - /* Tokenize args for 'if' tag. */ - preg_match_all('/(?: - "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | # match all double quoted strings allowed escaped double quotes - \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | # match all single quoted strings allowed escaped single quotes - [()] | # match parentheses - [^"\'\s()]+ # match any other token that is not any of the above - )/x', $tag_args, $match); - $tokens = $match[0]; - - $this->_parse_vars_props($tokens); - - $is_arg_stack = array(); - - for ($i = 0; $i < count($tokens); $i++) { - $token = &$tokens[$i]; - switch ($token) { - case 'eq': - $token = '=='; - break; - - case 'ne': - case 'neq': - $token = '!='; - break; - - case 'lt': - $token = '<'; - break; - - case 'le': - case 'lte': - $token = '<='; - break; - - case 'gt': - $token = '>'; - break; - - case 'ge': - case 'gte': - $token = '>='; - break; - - case 'and': - $token = '&&'; - break; - - case 'or': - $token = '||'; - break; - - case 'not': - $token = '!'; - break; - - case 'mod': - $token = '%'; - break; - - case '(': - array_push($is_arg_stack, $i); - break; - - case 'is': - /* If last token was a ')', we operate on the parenthesized - expression. The start of the expression is on the stack. - Otherwise, we operate on the last encountered token. */ - if ($tokens[$i-1] == ')') - $is_arg_start = array_pop($is_arg_stack); - else - $is_arg_start = $i-1; - /* Construct the argument for 'is' expression, so it knows - what to operate on. */ - $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); - - /* Pass all tokens from next one until the end to the - 'is' expression parsing function. The function will - return modified tokens, where the first one is the result - of the 'is' expression and the rest are the tokens it - didn't touch. */ - $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); - - /* Replace the old tokens with the new ones. */ - array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); - - /* Adjust argument start so that it won't change from the - current position for the next iteration. */ - $i = $is_arg_start; - break; - } - } - - if ($elseif) - return ''; - else - return ''; - } - - function _parse_is_expr($is_arg, $tokens) - { - $expr_end = 0; - - if (($first_token = array_shift($tokens)) == 'not') { - $negate_expr = true; - $expr_type = array_shift($tokens); - } else - $expr_type = $first_token; - - switch ($expr_type) { - case 'even': - if ($tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!(($is_arg / $expr_arg) % $expr_arg)"; - } - else - $expr = "!($is_arg % 2)"; - break; - - case 'odd': - if ($tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "(($is_arg / $expr_arg) % $expr_arg)"; - } - else - $expr = "($is_arg % 2)"; - break; - - case 'div': - if ($tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!($is_arg % $expr_arg)"; - } else { - $this->_syntax_error("expecting 'by' after 'div'"); - } - break; - - default: - $this->_syntax_error("unknown 'is' expression - '$expr_type'"); - break; - } - - if ($negate_expr) { - $expr = "!($expr)"; - } - - array_splice($tokens, 0, $expr_end, $expr); - - return $tokens; - } - - function _parse_attrs($tag_args, $quote = true) - { - /* Tokenize tag attributes. */ - preg_match_all('/(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | - \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | (?>[^"\'=\s]+) - )+ | - [=] - /x', $tag_args, $match); - $tokens = $match[0]; - $var_delims = array('$', '#', '%'); - - $attrs = array(); - /* Parse state: - 0 - expecting attribute name - 1 - expecting '=' - 2 - expecting attribute value (not '=') */ - $state = 0; - - foreach ($tokens as $token) { - switch ($state) { - case 0: - /* If the token is a valid identifier, we set attribute name - and go to state 1. */ - if (preg_match('!^\w+$!', $token)) { - $attr_name = $token; - $state = 1; - } else - $this->_syntax_error("invalid attribute name - '$token'"); - break; - - case 1: - /* If the token is '=', then we go to state 2. */ - if ($token == '=') { - $state = 2; - } else - $this->_syntax_error("expecting '=' after attribute name"); - break; - - case 2: - /* If token is not '=', we set the attribute value and go to - state 0. */ - if ($token != '=') { - /* We booleanize the token if it's a non-quoted possible - boolean value. */ - if (preg_match('!^(on|yes|true)$!', $token)) - $token = true; - else if (preg_match('!^(off|no|false)$!', $token)) - $token = false; - /* If the token is not variable (doesn't start with - '$', '#', or '%') and not enclosed in single or - double quotes we single-quote it. */ - else if ($quote && !in_array($token{0}, $var_delims) && - !(($token{0} == '"' || $token[0] == "'") && - $token{strlen($token)-1} == $token{0})) - $token = "'".$token."'"; - - $attrs[$attr_name] = $token; - $state = 0; - } else - $this->_syntax_error("'=' cannot be an attribute value"); - break; - } - } - - $this->_parse_vars_props($attrs); - - return $attrs; - } - - function _preg_grep($pattern, $array) - { - $result = array(); - - foreach ($array as $key => $entry) { - if (preg_match($pattern, $entry)) - $result[$key] = $entry; - } - - return $result; - } - - function _parse_vars_props(&$tokens) - { - $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; - - /* preg_grep() was fixed to return keys properly in 4.0.4 and later. To - allow people to use older versions of PHP we emulate preg_grep() and - use the version check to see what function to call. */ - if (strnatcmp(PHP_VERSION, '4.0.4') >= 0) { - $var_exprs = preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - $conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - $sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - } else { - $var_exprs = $this->_preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - $conf_var_exprs = $this->_preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - $sect_prop_exprs = $this->_preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - } - - if (count($var_exprs)) { - foreach ($var_exprs as $expr_index => $var_expr) { - $tokens[$expr_index] = $this->_parse_var($var_expr); - } - } - - if (count($conf_var_exprs)) { - foreach ($conf_var_exprs as $expr_index => $var_expr) { - $tokens[$expr_index] = $this->_parse_conf_var($var_expr); - } - } - - if (count($sect_prop_exprs)) { - foreach ($sect_prop_exprs as $expr_index => $section_prop_expr) { - $tokens[$expr_index] = $this->_parse_section_prop($section_prop_expr); - } - } - } - - function _parse_var($var_expr) - { - list($var_ref, $modifiers) = explode('|', substr($var_expr, 1), 2); - - $sections = explode('/', $var_ref); - $props = explode('.', array_pop($sections)); - $var_name = array_shift($props); - - $output = "\$$var_name"; - - foreach ($sections as $section) { - $output .= "[\$_sections['$section']['properties']['index']]"; - } - foreach ($props as $prop) { - $output .= "['$prop']"; - } - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - function _parse_conf_var($conf_var_expr) - { - list($var_ref, $modifiers) = explode('|', $conf_var_expr, 2); - - $var_name = substr($var_ref, 1, -1); - - $output = "\$_config['$var_name']"; - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - function _parse_section_prop($section_prop_expr) - { - list($var_ref, $modifiers) = explode('|', $section_prop_expr, 2); - - preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); - $section_name = $match[1]; - $prop_name = $match[2]; - - $output = "\$_sections['$section_name']['properties']['$prop_name']"; - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - function _parse_modifiers(&$output, $modifier_string) - { - $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; - preg_match_all('!\|@?(\w+)((?::(?:'. $qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $match); - list(, $modifiers, $modifier_arg_strings) = $match; - - for ($i = 0; $i < count($modifiers); $i++) { - $modifier_name = $modifiers[$i]; - preg_match_all('!:(' . $qstr_regexp . '|[^|]+)!', $modifier_arg_strings[$i], $match); - $modifier_args = $match[1]; - - if ($modifier_name{0} == '@') { - $map_array = 'false'; - $modifier_name = substr($modifier_name, 1); - } else - $map_array = 'true'; - - /* - * First we lookup the modifier function name in the registered - * modifiers table. - */ - $mod_func_name = $this->custom_mods[$modifier_name]; - - /* - * If we don't find that modifier there, we assume it's just a PHP - * function name. - */ - if (!isset($mod_func_name)) - $mod_func_name = $modifier_name; - - $this->_parse_vars_props($modifier_args); - - if (count($modifier_args) > 0) - $modifier_args = ', '.implode(', ', $modifier_args); - else - $modifier_args = ''; - - $output = "_smarty_mod_handler('$mod_func_name', $map_array, $output$modifier_args)"; - } - } - + function _process_cached_inserts($results) + { + preg_match_all('!'.$this->_smarty_md5.'{insert_cache (.*)}'.$this->_smarty_md5.'!Uis', + $results, $match); + list($cached_inserts, $insert_args) = $match; + + for ($i = 0; $i < count($cached_inserts); $i++) { + $attrs = $this->_parse_attrs($insert_args[$i], false); + $name = $this->_dequote($attrs['name']); + + if (empty($name)) { + $this->_syntax_error("missing insert name"); + } + + $arg_list = array(); + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'name') continue; + $arg_list[$arg_name] = $arg_value; + } + + $function_name = 'insert_' . $name; + $replace = $function_name($arg_list); + + $results = str_replace($cached_inserts[$i], $replace, $results); + } + + return $results; + } + + function _compile_tag($template_tag) + { + /* Matched comment. */ + if ($template_tag{0} == '*' && $template_tag{strlen($template_tag)-1} == '*') + return ""; + + $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + + /* Split tag into two parts: command and the arguments. */ + preg_match('/^( + (?: ' . $qstr_regexp . ' | (?>[^"\'\s]+))+ + ) + (?:\s+(.*))? + /xs', $template_tag, $match); + list(, $tag_command, $tag_args) = $match; + + /* If the tag name matches a variable or section property definition, + we simply process it. */ + if (preg_match('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // if a variable + preg_match('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // or a configuration variable + preg_match('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command)) { // or a section property + settype($tag_command, 'array'); + $this->_parse_vars_props($tag_command); + return ""; + } + + switch ($tag_command) { + case 'include': + return $this->_compile_include_tag($tag_args); + + case 'if': + return $this->_compile_if_tag($tag_args); + + case 'else': + return ''; + + case 'elseif': + return $this->_compile_if_tag($tag_args, true); + + case '/if': + return ''; + + case 'ldelim': + return $this->left_delimiter; + + case 'rdelim': + return $this->right_delimiter; + + case 'section': + array_push($this->_sectionelse_stack, false); + return $this->_compile_section_start($tag_args); + + case 'sectionelse': + $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true; + return ""; + + case '/section': + if (array_pop($this->_sectionelse_stack)) + return ""; + else + return ""; + + case 'config_load': + return $this->_compile_config_load_tag($tag_args); + + case 'strip': + case '/strip': + return $this->left_delimiter.$tag_command.$this->right_delimiter; + + case 'literal': + list (,$literal_block) = each($this->_literal_blocks); + $this->_current_line_no += substr_count($literal_block, "\n"); + return $literal_block; + + case 'insert': + return $this->_compile_insert_tag($tag_args); + + default: + if (isset($this->custom_funcs[$tag_command])) { + return $this->_compile_custom_tag($tag_command, $tag_args); + } else { + $this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING); + return ""; + } + } + } + + function _compile_custom_tag($tag_command, $tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $function = $this->custom_funcs[$tag_command]; + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + return ""; + } + + function _compile_insert_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $name = substr($attrs['name'], 1, -1); + + if (empty($name)) { + $this->_syntax_error("missing insert name"); + } + + if($this->caching) + return $this->_smarty_md5."{insert_cache $tag_args}".$this->_smarty_md5; + + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'name') continue; + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + return ""; + } + + function _compile_config_load_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in config_load tag"); + } + + $output = "config_dir."');\n" . + "}\n" . + "\$_config = array_merge((array)\$_config, \$_conf_obj->get(".$attrs['file']."));\n"; + + if (!empty($attrs['section'])) + $output .= '$_config = array_merge((array)$_config, $_conf_obj->get('.$attrs['file'].', '.$attrs['section'].')); '; + + $output .= '?>'; + + return $output; + } + + + function _compile_include_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include tag"); + } else + $attrs['file'] = $this->_dequote($attrs['file']); + + if (count($attrs) > 1) { + $include_func_name = uniqid("_include_"); + $include_file_name = $this->compile_dir.'/'.$attrs['file']; + + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'file') continue; + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + return "\n"; + } else + return 'compile_dir.'/'.$attrs['file'].'.php"; ?>'; + } + + function _compile_section_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + $output = "_syntax_error("missing section name"); + } + + $output .= "unset(\$_sections[$section_name]);\n"; + $section_props = "\$_sections[$section_name]['properties']"; + + foreach ($attrs as $attr_name => $attr_value) { + switch ($attr_name) { + case 'loop': + $output .= "{$section_props}['loop'] = is_array($attr_value) ? count($attr_value) : $attr_value;\n"; + break; + + case 'show': + if (is_bool($attr_value)) + $attr_value = $attr_value ? 'true' : 'false'; + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; + break; + + default: + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; + break; + } + } + + if (isset($attrs['loop'])) { + $loop_check_code = "{$section_props}['loop'] > 0 && "; + } else { + $output .= "{$section_props}['loop'] = 1;\n"; + } + + if (isset($attrs['show'])) { + $show_check_code = "{$section_props}['show'] && "; + } else { + $output .= "{$section_props}['show'] = {$section_props}['loop'] > 0;\n"; + } + + $output .= "if ($loop_check_code $show_check_code true): "; + + $output .= " + for ({$section_props}['index'] = 0; + {$section_props}['index'] < {$section_props}['loop']; + {$section_props}['index']++):\n"; + $output .= "{$section_props}['rownum'] = {$section_props}['index'] + 1;\n"; + + $output .= "?>\n"; + + return $output; + } + + function _compile_if_tag($tag_args, $elseif = false) + { + /* Tokenize args for 'if' tag. */ + preg_match_all('/(?: + "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | # match all double quoted strings allowed escaped double quotes + \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | # match all single quoted strings allowed escaped single quotes + [()] | # match parentheses + [^"\'\s()]+ # match any other token that is not any of the above + )/x', $tag_args, $match); + $tokens = $match[0]; + + $this->_parse_vars_props($tokens); + + $is_arg_stack = array(); + + for ($i = 0; $i < count($tokens); $i++) { + $token = &$tokens[$i]; + switch ($token) { + case 'eq': + $token = '=='; + break; + + case 'ne': + case 'neq': + $token = '!='; + break; + + case 'lt': + $token = '<'; + break; + + case 'le': + case 'lte': + $token = '<='; + break; + + case 'gt': + $token = '>'; + break; + + case 'ge': + case 'gte': + $token = '>='; + break; + + case 'and': + $token = '&&'; + break; + + case 'or': + $token = '||'; + break; + + case 'not': + $token = '!'; + break; + + case 'mod': + $token = '%'; + break; + + case '(': + array_push($is_arg_stack, $i); + break; + + case 'is': + /* If last token was a ')', we operate on the parenthesized + expression. The start of the expression is on the stack. + Otherwise, we operate on the last encountered token. */ + if ($tokens[$i-1] == ')') + $is_arg_start = array_pop($is_arg_stack); + else + $is_arg_start = $i-1; + /* Construct the argument for 'is' expression, so it knows + what to operate on. */ + $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); + + /* Pass all tokens from next one until the end to the + 'is' expression parsing function. The function will + return modified tokens, where the first one is the result + of the 'is' expression and the rest are the tokens it + didn't touch. */ + $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); + + /* Replace the old tokens with the new ones. */ + array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); + + /* Adjust argument start so that it won't change from the + current position for the next iteration. */ + $i = $is_arg_start; + break; + } + } + + if ($elseif) + return ''; + else + return ''; + } + + function _parse_is_expr($is_arg, $tokens) + { + $expr_end = 0; + + if (($first_token = array_shift($tokens)) == 'not') { + $negate_expr = true; + $expr_type = array_shift($tokens); + } else + $expr_type = $first_token; + + switch ($expr_type) { + case 'even': + if ($tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!(($is_arg / $expr_arg) % $expr_arg)"; + } + else + $expr = "!($is_arg % 2)"; + break; + + case 'odd': + if ($tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "(($is_arg / $expr_arg) % $expr_arg)"; + } + else + $expr = "($is_arg % 2)"; + break; + + case 'div': + if ($tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!($is_arg % $expr_arg)"; + } else { + $this->_syntax_error("expecting 'by' after 'div'"); + } + break; + + default: + $this->_syntax_error("unknown 'is' expression - '$expr_type'"); + break; + } + + if ($negate_expr) { + $expr = "!($expr)"; + } + + array_splice($tokens, 0, $expr_end, $expr); + + return $tokens; + } + + function _parse_attrs($tag_args, $quote = true) + { + /* Tokenize tag attributes. */ + preg_match_all('/(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | + \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | (?>[^"\'=\s]+) + )+ | + [=] + /x', $tag_args, $match); + $tokens = $match[0]; + $var_delims = array('$', '#', '%'); + + $attrs = array(); + /* Parse state: + 0 - expecting attribute name + 1 - expecting '=' + 2 - expecting attribute value (not '=') */ + $state = 0; + + foreach ($tokens as $token) { + switch ($state) { + case 0: + /* If the token is a valid identifier, we set attribute name + and go to state 1. */ + if (preg_match('!^\w+$!', $token)) { + $attr_name = $token; + $state = 1; + } else + $this->_syntax_error("invalid attribute name - '$token'"); + break; + + case 1: + /* If the token is '=', then we go to state 2. */ + if ($token == '=') { + $state = 2; + } else + $this->_syntax_error("expecting '=' after attribute name"); + break; + + case 2: + /* If token is not '=', we set the attribute value and go to + state 0. */ + if ($token != '=') { + /* We booleanize the token if it's a non-quoted possible + boolean value. */ + if (preg_match('!^(on|yes|true)$!', $token)) + $token = true; + else if (preg_match('!^(off|no|false)$!', $token)) + $token = false; + /* If the token is not variable (doesn't start with + '$', '#', or '%') and not enclosed in single or + double quotes we single-quote it. */ + else if ($quote && !in_array($token{0}, $var_delims) && + !(($token{0} == '"' || $token[0] == "'") && + $token{strlen($token)-1} == $token{0})) + $token = "'".$token."'"; + + $attrs[$attr_name] = $token; + $state = 0; + } else + $this->_syntax_error("'=' cannot be an attribute value"); + break; + } + } + + $this->_parse_vars_props($attrs); + + return $attrs; + } + + function _preg_grep($pattern, $array) + { + $result = array(); + + foreach ($array as $key => $entry) { + if (preg_match($pattern, $entry)) + $result[$key] = $entry; + } + + return $result; + } + + function _parse_vars_props(&$tokens) + { + $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + + /* preg_grep() was fixed to return keys properly in 4.0.4 and later. To + allow people to use older versions of PHP we emulate preg_grep() and + use the version check to see what function to call. */ + if (strnatcmp(PHP_VERSION, '4.0.4') >= 0) { + $var_exprs = preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + $conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + $sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + } else { + $var_exprs = $this->_preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + $conf_var_exprs = $this->_preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + $sect_prop_exprs = $this->_preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + } + + if (count($var_exprs)) { + foreach ($var_exprs as $expr_index => $var_expr) { + $tokens[$expr_index] = $this->_parse_var($var_expr); + } + } + + if (count($conf_var_exprs)) { + foreach ($conf_var_exprs as $expr_index => $var_expr) { + $tokens[$expr_index] = $this->_parse_conf_var($var_expr); + } + } + + if (count($sect_prop_exprs)) { + foreach ($sect_prop_exprs as $expr_index => $section_prop_expr) { + $tokens[$expr_index] = $this->_parse_section_prop($section_prop_expr); + } + } + } + + function _parse_var($var_expr) + { + list($var_ref, $modifiers) = explode('|', substr($var_expr, 1), 2); + + $sections = explode('/', $var_ref); + $props = explode('.', array_pop($sections)); + $var_name = array_shift($props); + + $output = "\$$var_name"; + + foreach ($sections as $section) { + $output .= "[\$_sections['$section']['properties']['index']]"; + } + foreach ($props as $prop) { + $output .= "['$prop']"; + } + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + function _parse_conf_var($conf_var_expr) + { + list($var_ref, $modifiers) = explode('|', $conf_var_expr, 2); + + $var_name = substr($var_ref, 1, -1); + + $output = "\$_config['$var_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + function _parse_section_prop($section_prop_expr) + { + list($var_ref, $modifiers) = explode('|', $section_prop_expr, 2); + + preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); + $section_name = $match[1]; + $prop_name = $match[2]; + + $output = "\$_sections['$section_name']['properties']['$prop_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + function _parse_modifiers(&$output, $modifier_string) + { + $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + preg_match_all('!\|@?(\w+)((?::(?:'. $qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $match); + list(, $modifiers, $modifier_arg_strings) = $match; + + for ($i = 0; $i < count($modifiers); $i++) { + $modifier_name = $modifiers[$i]; + preg_match_all('!:(' . $qstr_regexp . '|[^|]+)!', $modifier_arg_strings[$i], $match); + $modifier_args = $match[1]; + + if ($modifier_name{0} == '@') { + $map_array = 'false'; + $modifier_name = substr($modifier_name, 1); + } else + $map_array = 'true'; + + /* + * First we lookup the modifier function name in the registered + * modifiers table. + */ + $mod_func_name = $this->custom_mods[$modifier_name]; + + /* + * If we don't find that modifier there, we assume it's just a PHP + * function name. + */ + if (!isset($mod_func_name)) + $mod_func_name = $modifier_name; + + $this->_parse_vars_props($modifier_args); + + if (count($modifier_args) > 0) + $modifier_args = ', '.implode(', ', $modifier_args); + else + $modifier_args = ''; + + $output = "_smarty_mod_handler('$mod_func_name', $map_array, $output$modifier_args)"; + } + } + /*======================================================================*\ - Function: _dequote - Purpose: Remove starting and ending quotes from the string + Function: _dequote + Purpose: Remove starting and ending quotes from the string \*======================================================================*/ - function _dequote($string) - { - if (($string{0} == "'" || $string{0} == '"') && - $string{strlen($string)-1} == $string{0}) - return substr($string, 1, -1); - else - return $string; - } + function _dequote($string) + { + if (($string{0} == "'" || $string{0} == '"') && + $string{strlen($string)-1} == $string{0}) + return substr($string, 1, -1); + else + return $string; + } - + /*======================================================================*\ - Function: _read_file() - Purpose: read in a file + Function: _read_file() + Purpose: read in a file \*======================================================================*/ - function _read_file($filename) - { - if(!($fd = fopen($filename, 'r'))) { - $this->_set_error_msg("problem reading '$filename.'"); - return false; - } - $contents = fread($fd, filesize($filename)); - fclose($fd); - return $contents; - } + function _read_file($filename) + { + if(!($fd = fopen($filename, 'r'))) { + $this->_set_error_msg("problem reading '$filename.'"); + return false; + } + $contents = fread($fd, filesize($filename)); + fclose($fd); + return $contents; + } /*======================================================================*\ - Function: _write_file() - Purpose: write out a file + Function: _write_file() + Purpose: write out a file \*======================================================================*/ - function _write_file($filename,$contents) - { - if(!($fd = fopen($filename, 'w'))) { - $this->_set_error_msg("problem writing '$filename.'"); - return false; - } - fwrite($fd, $contents); - fclose($fd); - return true; - } + function _write_file($filename,$contents) + { + if(!($fd = fopen($filename, 'w'))) { + $this->_set_error_msg("problem writing '$filename.'"); + return false; + } + fwrite($fd, $contents); + fclose($fd); + return true; + } /*======================================================================*\ - Function: _set_error_msg() - Purpose: set the error message + Function: _set_error_msg() + Purpose: set the error message \*======================================================================*/ - function _set_error_msg($error_msg) - { - $this->_error_msg="smarty error: $error_msg"; - return true; - } + function _set_error_msg($error_msg) + { + $this->_error_msg="smarty error: $error_msg"; + return true; + } /*======================================================================*\ - Function: _syntax_error - Purpose: display Smarty syntax error + Function: _syntax_error + Purpose: display Smarty syntax error \*======================================================================*/ - function _syntax_error($error_msg, $error_type = E_USER_ERROR) - { - trigger_error("Smarty: [in " . $this->_current_file . " line " . - $this->_current_line_no . "]: syntax error: $error_msg", $error_type); - } + function _syntax_error($error_msg, $error_type = E_USER_ERROR) + { + trigger_error("Smarty: [in " . $this->_current_file . " line " . + $this->_current_line_no . "]: syntax error: $error_msg", $error_type); + } } +/* vim: set expandtab: */ + ?> diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 5b316814..5fa82b96 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -1,13 +1,13 @@ + * Project: Smarty: the PHP compiling template engine + * File: Smarty.class.php + * Author: Monte Ohrt * Andrei Zmievski * * Version: 1.2.3 * Copyright: 2001 ispi of Lincoln, Inc. - * + * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 @@ -42,239 +42,239 @@ require("Smarty.addons.php"); class Smarty { - // public vars - var $compile_check = true; // whether to check for compiling step or not: + // public vars + var $compile_check = true; // whether to check for compiling step or not: // This is generally set to false once the // application is entered into production and // initially compiled. Leave set to true // during development. true/false - var $force_compile = false; // force templates to compile every time. + var $force_compile = false; // force templates to compile every time. // overrides compile_check. true/false - + // NOTE: all cache directives override // compiling directives. If a cached version // is available, that will be used regardless // of compile settings. - var $caching = false; // whether to use caching or not. true/false - var $cache_lifetime = 3600; // number of seconds cached content will persist. + var $caching = false; // whether to use caching or not. true/false + var $cache_lifetime = 3600; // number of seconds cached content will persist. // 0 = never expires. default is one hour (3600) - var $template_dir = "./templates"; // name of directory for templates - var $compile_dir = "./templates_c"; // name of directory for compiled templates - var $cache_dir = "./cache"; // name of directory for template cache - - - var $tpl_file_ext = ".tpl"; // template file extentions - - var $allow_php = false; // whether or not to allow embedded php + var $template_dir = "./templates"; // name of directory for templates + var $compile_dir = "./templates_c"; // name of directory for compiled templates + var $cache_dir = "./cache"; // name of directory for template cache + + + var $tpl_file_ext = ".tpl"; // template file extentions + + var $allow_php = false; // whether or not to allow embedded php // in the templates. By default, php tags // are escaped. true/false - var $left_delimiter = "{"; // template tag delimiters. - var $right_delimiter = "}"; + var $left_delimiter = "{"; // template tag delimiters. + var $right_delimiter = "}"; - var $config_dir = "./configs"; // directory where config files are located + var $config_dir = "./configs"; // directory where config files are located - var $custom_funcs = array( 'html_options' => 'smarty_func_html_options', - 'html_select_date' => 'smarty_func_html_select_date' - ); - - var $custom_mods = array( 'lower' => 'strtolower', - 'upper' => 'strtoupper', - 'capitalize' => 'ucwords', - 'escape' => 'smarty_mod_escape', - 'truncate' => 'smarty_mod_truncate', - 'spacify' => 'smarty_mod_spacify', - 'date_format' => 'smarty_mod_date_format', - 'string_format' => 'smarty_mod_string_format', - 'replace' => 'smarty_mod_replace', - 'strip_tags' => 'smarty_mod_strip_tags', - 'default' => 'smarty_mod_default' - ); - var $global_assign = array( 'SCRIPT_NAME' - ); - - // internal vars - var $_error_msg = false; // error messages. true/false - var $_tpl_vars = array(); - var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part - var $_literal_blocks = array(); // keeps literal template blocks - var $_current_file = null; // the current template being compiled - var $_current_line_no = 1; // line number for error messages - var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' + var $custom_funcs = array( 'html_options' => 'smarty_func_html_options', + 'html_select_date' => 'smarty_func_html_select_date' + ); + + var $custom_mods = array( 'lower' => 'strtolower', + 'upper' => 'strtoupper', + 'capitalize' => 'ucwords', + 'escape' => 'smarty_mod_escape', + 'truncate' => 'smarty_mod_truncate', + 'spacify' => 'smarty_mod_spacify', + 'date_format' => 'smarty_mod_date_format', + 'string_format' => 'smarty_mod_string_format', + 'replace' => 'smarty_mod_replace', + 'strip_tags' => 'smarty_mod_strip_tags', + 'default' => 'smarty_mod_default' + ); + var $global_assign = array( 'SCRIPT_NAME' + ); + + // internal vars + var $_error_msg = false; // error messages. true/false + var $_tpl_vars = array(); + var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part + var $_literal_blocks = array(); // keeps literal template blocks + var $_current_file = null; // the current template being compiled + var $_current_line_no = 1; // line number for error messages + var $_smarty_md5 = 'f8d698aea36fcbead2b9d5359ffca76f'; // md5 checksum of the string 'Smarty' - + /*======================================================================*\ - Function: Smarty - Purpose: Constructor + Function: Smarty + Purpose: Constructor \*======================================================================*/ - function Smarty() - { - foreach ($this->global_assign as $var_name) - $this->assign($var_name, $GLOBALS[$var_name]); - } + function Smarty() + { + foreach ($this->global_assign as $var_name) + $this->assign($var_name, $GLOBALS[$var_name]); + } /*======================================================================*\ - Function: assign() - Purpose: assigns values to template variables + Function: assign() + Purpose: assigns values to template variables \*======================================================================*/ - function assign($tpl_var, $value = NULL) - { - if (is_array($tpl_var)){ - foreach ($tpl_var as $key => $val) { - if (!empty($key)) - $this->_tpl_vars[$key] = $val; - } - } else { - if (!empty($tpl_var) && isset($value)) - $this->_tpl_vars[$tpl_var] = $value; - } - } + function assign($tpl_var, $value = NULL) + { + if (is_array($tpl_var)){ + foreach ($tpl_var as $key => $val) { + if (!empty($key)) + $this->_tpl_vars[$key] = $val; + } + } else { + if (!empty($tpl_var) && isset($value)) + $this->_tpl_vars[$tpl_var] = $value; + } + } - + /*======================================================================*\ - Function: append - Purpose: appens values to template variables + Function: append + Purpose: appens values to template variables \*======================================================================*/ - function append($tpl_var, $value = NULL) - { - if (is_array($tpl_var)) { - foreach ($tpl_var as $key => $val) { - if (!empty($key)) { - if (!is_array($this->_tpl_vars[$key])) - settype($this->_tpl_vars[$key], 'array'); - $this->_tpl_vars[$key][] = $val; - } - } - } else { - if (!empty($tpl_var) && isset($value)) { - if (!is_array($this->_tpl_vars[$tpl_var])) - settype($this->_tpl_vars[$tpl_var], 'array'); - $this->_tpl_vars[$tpl_var][] = $value; - } - } - } + function append($tpl_var, $value = NULL) + { + if (is_array($tpl_var)) { + foreach ($tpl_var as $key => $val) { + if (!empty($key)) { + if (!is_array($this->_tpl_vars[$key])) + settype($this->_tpl_vars[$key], 'array'); + $this->_tpl_vars[$key][] = $val; + } + } + } else { + if (!empty($tpl_var) && isset($value)) { + if (!is_array($this->_tpl_vars[$tpl_var])) + settype($this->_tpl_vars[$tpl_var], 'array'); + $this->_tpl_vars[$tpl_var][] = $value; + } + } + } /*======================================================================*\ - Function: clear_assign() - Purpose: clear the given assigned template variable. + Function: clear_assign() + Purpose: clear the given assigned template variable. \*======================================================================*/ - function clear_assign($tpl_var) - { - unset($this->_tpl_vars[$tpl_var]); - } + function clear_assign($tpl_var) + { + unset($this->_tpl_vars[$tpl_var]); + } /*======================================================================*\ - Function: clear_cache() - Purpose: clear all cached template files for given template + Function: clear_cache() + Purpose: clear all cached template files for given template \*======================================================================*/ - function clear_cache($tpl_file) - { - if(is_dir($this->cache_dir)) - $dir_handle = opendir($this->cache_dir); - else - return false; - - // remove leading . or / - $tpl_file = preg_replace("/^(\.{0,2}\/)*/","",$tpl_file); - $tpl_file_url = urlencode($tpl_file); - - while($curr_file = readdir($dir_handle)) { - if ($curr_file == '.' || $curr_file == '..') - continue; - - if(is_file($this->cache_dir."/".$curr_file) && - substr($curr_file,0,strlen($tpl_file_url)) == $tpl_file_url) - unlink($this->cache_dir."/".$curr_file); - } - return true; - } - - + function clear_cache($tpl_file) + { + if(is_dir($this->cache_dir)) + $dir_handle = opendir($this->cache_dir); + else + return false; + + // remove leading . or / + $tpl_file = preg_replace("/^(\.{0,2}\/)*/","",$tpl_file); + $tpl_file_url = urlencode($tpl_file); + + while($curr_file = readdir($dir_handle)) { + if ($curr_file == '.' || $curr_file == '..') + continue; + + if(is_file($this->cache_dir."/".$curr_file) && + substr($curr_file,0,strlen($tpl_file_url)) == $tpl_file_url) + unlink($this->cache_dir."/".$curr_file); + } + return true; + } + + /*======================================================================*\ - Function: clear_all_cache() - Purpose: clear all the cached template files. + Function: clear_all_cache() + Purpose: clear all the cached template files. \*======================================================================*/ - function clear_all_cache() - { - if(is_dir($this->cache_dir)) - $dir_handle = opendir($this->cache_dir); - else - return false; + function clear_all_cache() + { + if(is_dir($this->cache_dir)) + $dir_handle = opendir($this->cache_dir); + else + return false; - while($curr_file = readdir($dir_handle)) { - if ($curr_file == '.' || $curr_file == '..') - continue; - if(is_file($this->cache_dir."/".$curr_file) && substr($curr_file,-6) == '.cache') - unlink($this->cache_dir."/".$curr_file); - } - return true; - } - + while($curr_file = readdir($dir_handle)) { + if ($curr_file == '.' || $curr_file == '..') + continue; + if(is_file($this->cache_dir."/".$curr_file) && substr($curr_file,-6) == '.cache') + unlink($this->cache_dir."/".$curr_file); + } + return true; + } + /*======================================================================*\ - Function: clear_all_assign() - Purpose: clear all the assigned template variables. + Function: clear_all_assign() + Purpose: clear all the assigned template variables. \*======================================================================*/ - function clear_all_assign() - { - $this->_tpl_vars = array(); - } + function clear_all_assign() + { + $this->_tpl_vars = array(); + } /*======================================================================*\ - Function: get_template_vars - Purpose: Returns an array containing template variables + Function: get_template_vars + Purpose: Returns an array containing template variables \*======================================================================*/ - function &get_template_vars() - { - return $this->_tpl_vars; - } + function &get_template_vars() + { + return $this->_tpl_vars; + } /*======================================================================*\ - Function: display() - Purpose: executes & displays the template results + Function: display() + Purpose: executes & displays the template results \*======================================================================*/ - function display($tpl_file) - { - $this->fetch($tpl_file, true); - } - + function display($tpl_file) + { + $this->fetch($tpl_file, true); + } + /*======================================================================*\ - Function: fetch() - Purpose: executes & returns or displays the template results + Function: fetch() + Purpose: executes & returns or displays the template results \*======================================================================*/ - function fetch($tpl_file, $display = false) - { - global $PHP_SELF; + function fetch($tpl_file, $display = false) + { + global $PHP_SELF; - if($this->caching) { - // cache id = template path + the invoked script - $cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".cache"; - if(!$this->cache_force && - (file_exists($cache_file) && - ($this->cache_lifetime == 0 || - (mktime() - filemtime($cache_file) <= $this->cache_lifetime) - ))) { - $results = $this->_read_file($cache_file); - $results = $this->_process_cached_inserts($results); + if($this->caching) { + // cache id = template path + the invoked script + $cache_file = $this->cache_dir."/".urlencode($tpl_file."@".$PHP_SELF).".cache"; + if(!$this->cache_force && + (file_exists($cache_file) && + ($this->cache_lifetime == 0 || + (mktime() - filemtime($cache_file) <= $this->cache_lifetime) + ))) { + $results = $this->_read_file($cache_file); + $results = $this->_process_cached_inserts($results); if ($display) { print $results; return; } else return $results; - } - } + } + } // compile files $this->_compile($this->template_dir); @@ -294,893 +294,895 @@ class Smarty ob_end_clean(); } - if($this->caching) { - $this->_write_file($cache_file, $results); - $results = $this->_process_cached_inserts($results); - } + if($this->caching) { + $this->_write_file($cache_file, $results); + $results = $this->_process_cached_inserts($results); + } if ($display) { print $results; return; } else return $results; - } - + } + /*======================================================================*\ - Function: compile() - Purpose: called to compile the templates + Function: compile() + Purpose: called to compile the templates \*======================================================================*/ - function _compile($tpl_dir) - { - if($this->compile_check || $this->force_compile) - { - if($this->_traverse_files($tpl_dir, 0)) - return true; - else - return false; - } - else - return false; - } - + function _compile($tpl_dir) + { + if($this->compile_check || $this->force_compile) + { + if($this->_traverse_files($tpl_dir, 0)) + return true; + else + return false; + } + else + return false; + } + /*======================================================================*\ - Function: _traverse_files() - Purpose: traverse the template files & process each one + Function: _traverse_files() + Purpose: traverse the template files & process each one \*======================================================================*/ - function _traverse_files($tpl_dir, $depth) - { - if(is_dir($tpl_dir)) { - if($tpl_dir) - $dir_handle = opendir($tpl_dir); + function _traverse_files($tpl_dir, $depth) + { + if(is_dir($tpl_dir)) { + if($tpl_dir) + $dir_handle = opendir($tpl_dir); - while($curr_file = readdir($dir_handle)) { - if ($curr_file == '.' || $curr_file == '..') - continue; + while($curr_file = readdir($dir_handle)) { + if ($curr_file == '.' || $curr_file == '..') + continue; - $filepath = $tpl_dir."/".$curr_file; - if(is_readable($filepath)) { - - if(is_file($filepath) && substr($curr_file, -strlen($this->tpl_file_ext)) == $this->tpl_file_ext) { - if(!$this->_process_file($filepath)) - return false; - } else if (is_dir($filepath)) { - if (!$this->_traverse_files($filepath, $depth + 1)) - return false; - } else { - // invalid file type, skipping - $this->_set_error_msg("Invalid filetype for $filepath, skipping"); - continue; - } - } - } - } else { - $this->_set_error_msg("Directory \"$tpl_dir\" does not exist or is not a directory."); - return false; - } + $filepath = $tpl_dir."/".$curr_file; + if(is_readable($filepath)) { + + if(is_file($filepath) && substr($curr_file, -strlen($this->tpl_file_ext)) == $this->tpl_file_ext) { + if(!$this->_process_file($filepath)) + return false; + } else if (is_dir($filepath)) { + if (!$this->_traverse_files($filepath, $depth + 1)) + return false; + } else { + // invalid file type, skipping + $this->_set_error_msg("Invalid filetype for $filepath, skipping"); + continue; + } + } + } + } else { + $this->_set_error_msg("Directory \"$tpl_dir\" does not exist or is not a directory."); + return false; + } - return true; - } + return true; + } /*======================================================================*\ - Function: _process_file() - Input: test template files for modifications - and execute the compilation for each - one requiring it. + Function: _process_file() + Input: test template files for modifications + and execute the compilation for each + one requiring it. \*======================================================================*/ - function _process_file($filepath) - { - if(preg_match("/^(.+)\/([^\/]+)$/", $filepath, $match)) { - $tpl_file_dir = $match[1]; - $tpl_file_name = $match[2] . ".php"; + function _process_file($filepath) + { + if(preg_match("/^(.+)\/([^\/]+)$/", $filepath, $match)) { + $tpl_file_dir = $match[1]; + $tpl_file_name = $match[2] . ".php"; - $compile_dir = preg_replace('!^' . preg_quote($this->template_dir, '!') . '!', - $this->compile_dir, $match[1]); + $compile_dir = preg_replace('!^' . preg_quote($this->template_dir, '!') . '!', + $this->compile_dir, $match[1]); - //create directory if none exists - if(!file_exists($compile_dir)) { - $compile_dir_parts = preg_split('!/+!', $compile_dir); - $new_dir = ""; - foreach ($compile_dir_parts as $dir_part) { - $new_dir .= $dir_part."/"; - if (!file_exists($new_dir) && !mkdir($new_dir, 0755)) { - $this->_set_error_msg("problem creating directory \"$compile_dir\""); - return false; - } - } - } + //create directory if none exists + if(!file_exists($compile_dir)) { + $compile_dir_parts = preg_split('!/+!', $compile_dir); + $new_dir = ""; + foreach ($compile_dir_parts as $dir_part) { + $new_dir .= $dir_part."/"; + if (!file_exists($new_dir) && !mkdir($new_dir, 0755)) { + $this->_set_error_msg("problem creating directory \"$compile_dir\""); + return false; + } + } + } - // compile the template file if none exists or has been modified or recompile is forced - if ($this->force_compile || !file_exists($compile_dir."/".$tpl_file_name) || - ($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) { - if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name)) - return false; - } else { - // no compilation needed - return true; - } - } else { - $this->_set_error_msg("problem matching \"$filepath.\""); - return false; - } + // compile the template file if none exists or has been modified or recompile is forced + if ($this->force_compile || !file_exists($compile_dir."/".$tpl_file_name) || + ($this->_modified_file($filepath, $compile_dir."/".$tpl_file_name))) { + if (!$this->_compile_file($filepath, $compile_dir."/".$tpl_file_name)) + return false; + } else { + // no compilation needed + return true; + } + } else { + $this->_set_error_msg("problem matching \"$filepath.\""); + return false; + } - return true; - } + return true; + } /*======================================================================*\ - Function: _modified_file() - Input: return comparison of modification times of files + Function: _modified_file() + Input: return comparison of modification times of files \*======================================================================*/ - function _modified_file($filepath, $compilepath) - { - if(filemtime($filepath) >= filemtime($compilepath)) - return true; - return false; - } + function _modified_file($filepath, $compilepath) + { + if(filemtime($filepath) >= filemtime($compilepath)) + return true; + return false; + } /*======================================================================*\ - Function: _compile_file() - Input: compile a template file + Function: _compile_file() + Input: compile a template file \*======================================================================*/ - function _compile_file($filepath, $compilepath) - { - if (!($template_contents = $this->_read_file($filepath))) - return false; + function _compile_file($filepath, $compilepath) + { + if (!($template_contents = $this->_read_file($filepath))) + return false; - $this->_current_file = str_replace($this->template_dir . "/", "", $filepath); - $this->_current_line_no = 1; - $ldq = preg_quote($this->left_delimiter, '!'); - $rdq = preg_quote($this->right_delimiter, '!'); + $this->_current_file = str_replace($this->template_dir . "/", "", $filepath); + $this->_current_line_no = 1; + $ldq = preg_quote($this->left_delimiter, '!'); + $rdq = preg_quote($this->right_delimiter, '!'); - /* Pull out the literal blocks. */ - preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_contents, $match); - $this->_literal_blocks = $match[1]; - $template_contents = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", - '{literal}', $template_contents); + /* Pull out the literal blocks. */ + preg_match_all("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", $template_contents, $match); + $this->_literal_blocks = $match[1]; + $template_contents = preg_replace("!{$ldq}literal{$rdq}(.*?){$ldq}/literal{$rdq}!s", + '{literal}', $template_contents); - /* Gather all template tags. */ - preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_contents, $match); - $template_tags = $match[1]; - /* Split content by template tags to obtain non-template content. */ - $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $template_contents); - if(!$this->allow_php) { - /* Escape php tags. */ - $text_blocks = preg_replace('!<\?([^?]*?)\?>!', '<?$1?>', $text_blocks); - } + /* Gather all template tags. */ + preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $template_contents, $match); + $template_tags = $match[1]; + /* Split content by template tags to obtain non-template content. */ + $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $template_contents); + if(!$this->allow_php) { + /* Escape php tags. */ + $text_blocks = preg_replace('!<\?([^?]*?)\?>!', '<?$1?>', $text_blocks); + } - /* Compile the template tags into PHP code. */ - $compiled_tags = array(); - for ($i = 0; $i < count($template_tags); $i++) { - $this->_current_line_no += substr_count($text_blocks[$i], "\n"); - $compiled_tags[] = $this->_compile_tag($template_tags[$i]); - $this->_current_line_no += substr_count($template_tags[$i], "\n"); - } + /* Compile the template tags into PHP code. */ + $compiled_tags = array(); + for ($i = 0; $i < count($template_tags); $i++) { + $this->_current_line_no += substr_count($text_blocks[$i], "\n"); + $compiled_tags[] = $this->_compile_tag($template_tags[$i]); + $this->_current_line_no += substr_count($template_tags[$i], "\n"); + } - $compiled_contents = ""; - - /* Interleave the compiled contents and text blocks to get the final result. */ - for ($i = 0; $i < count($compiled_tags); $i++) { - $compiled_contents .= $text_blocks[$i].$compiled_tags[$i]; - } - $compiled_contents .= $text_blocks[$i]; - - /* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */ - if (preg_match_all("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $compiled_contents, $match)) { - $strip_tags = $match[0]; - $strip_tags_modified = preg_replace("!{$ldq}/?strip{$rdq}|[\t ]+$|^[\t ]+!m", '', $strip_tags); - $strip_tags_modified = preg_replace('![\r\n]+!m', '', $strip_tags_modified); - for ($i = 0; $i < count($strip_tags); $i++) - $compiled_contents = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", - $strip_tags_modified[$i], $compiled_contents, 1); - } + $compiled_contents = ""; + + /* Interleave the compiled contents and text blocks to get the final result. */ + for ($i = 0; $i < count($compiled_tags); $i++) { + $compiled_contents .= $text_blocks[$i].$compiled_tags[$i]; + } + $compiled_contents .= $text_blocks[$i]; + + /* Reformat data between 'strip' and '/strip' tags, removing spaces, tabs and newlines. */ + if (preg_match_all("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", $compiled_contents, $match)) { + $strip_tags = $match[0]; + $strip_tags_modified = preg_replace("!{$ldq}/?strip{$rdq}|[\t ]+$|^[\t ]+!m", '', $strip_tags); + $strip_tags_modified = preg_replace('![\r\n]+!m', '', $strip_tags_modified); + for ($i = 0; $i < count($strip_tags); $i++) + $compiled_contents = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", + $strip_tags_modified[$i], $compiled_contents, 1); + } - if(!$this->_write_file($compilepath, $compiled_contents)) - return false; + if(!$this->_write_file($compilepath, $compiled_contents)) + return false; - return true; - } + return true; + } /*======================================================================*\ - Function: _process_cached_inserts - Purpose: Replace cached inserts with the actual results + Function: _process_cached_inserts + Purpose: Replace cached inserts with the actual results \*======================================================================*/ - function _process_cached_inserts($results) - { - preg_match_all('!'.$this->_smarty_md5.'{insert_cache (.*)}'.$this->_smarty_md5.'!Uis', - $results, $match); - list($cached_inserts, $insert_args) = $match; - - for ($i = 0; $i < count($cached_inserts); $i++) { - $attrs = $this->_parse_attrs($insert_args[$i], false); - $name = $this->_dequote($attrs['name']); - - if (empty($name)) { - $this->_syntax_error("missing insert name"); - } - - $arg_list = array(); - foreach ($attrs as $arg_name => $arg_value) { - if ($arg_name == 'name') continue; - $arg_list[$arg_name] = $arg_value; - } - - $function_name = 'insert_' . $name; - $replace = $function_name($arg_list); - - $results = str_replace($cached_inserts[$i], $replace, $results); - } - - return $results; - } - - function _compile_tag($template_tag) - { - /* Matched comment. */ - if ($template_tag{0} == '*' && $template_tag{strlen($template_tag)-1} == '*') - return ""; - - $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; - - /* Split tag into two parts: command and the arguments. */ - preg_match('/^( - (?: ' . $qstr_regexp . ' | (?>[^"\'\s]+))+ - ) - (?:\s+(.*))? - /xs', $template_tag, $match); - list(, $tag_command, $tag_args) = $match; - - /* If the tag name matches a variable or section property definition, - we simply process it. */ - if (preg_match('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // if a variable - preg_match('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // or a configuration variable - preg_match('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command)) { // or a section property - settype($tag_command, 'array'); - $this->_parse_vars_props($tag_command); - return ""; - } - - switch ($tag_command) { - case 'include': - return $this->_compile_include_tag($tag_args); - - case 'if': - return $this->_compile_if_tag($tag_args); - - case 'else': - return ''; - - case 'elseif': - return $this->_compile_if_tag($tag_args, true); - - case '/if': - return ''; - - case 'ldelim': - return $this->left_delimiter; - - case 'rdelim': - return $this->right_delimiter; - - case 'section': - array_push($this->_sectionelse_stack, false); - return $this->_compile_section_start($tag_args); - - case 'sectionelse': - $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true; - return ""; - - case '/section': - if (array_pop($this->_sectionelse_stack)) - return ""; - else - return ""; - - case 'config_load': - return $this->_compile_config_load_tag($tag_args); - - case 'strip': - case '/strip': - return $this->left_delimiter.$tag_command.$this->right_delimiter; - - case 'literal': - list (,$literal_block) = each($this->_literal_blocks); - $this->_current_line_no += substr_count($literal_block, "\n"); - return $literal_block; - - case 'insert': - return $this->_compile_insert_tag($tag_args); - - default: - if (isset($this->custom_funcs[$tag_command])) { - return $this->_compile_custom_tag($tag_command, $tag_args); - } else { - $this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING); - return ""; - } - } - } - - function _compile_custom_tag($tag_command, $tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $function = $this->custom_funcs[$tag_command]; - foreach ($attrs as $arg_name => $arg_value) { - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - return ""; - } - - function _compile_insert_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - $name = substr($attrs['name'], 1, -1); - - if (empty($name)) { - $this->_syntax_error("missing insert name"); - } - - if($this->caching) - return $this->_smarty_md5."{insert_cache $tag_args}".$this->_smarty_md5; - - foreach ($attrs as $arg_name => $arg_value) { - if ($arg_name == 'name') continue; - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - return ""; - } - - function _compile_config_load_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - - if (empty($attrs['file'])) { - $this->_syntax_error("missing 'file' attribute in config_load tag"); - } - - $output = "config_dir."');\n" . - "}\n" . - "\$_config = array_merge((array)\$_config, \$_conf_obj->get(".$attrs['file']."));\n"; - - if (!empty($attrs['section'])) - $output .= '$_config = array_merge((array)$_config, $_conf_obj->get('.$attrs['file'].', '.$attrs['section'].')); '; - - $output .= '?>'; - - return $output; - } - - - function _compile_include_tag($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - - if (empty($attrs['file'])) { - $this->_syntax_error("missing 'file' attribute in include tag"); - } else - $attrs['file'] = $this->_dequote($attrs['file']); - - if (count($attrs) > 1) { - $include_func_name = uniqid("_include_"); - $include_file_name = $this->compile_dir.'/'.$attrs['file']; - - foreach ($attrs as $arg_name => $arg_value) { - if ($arg_name == 'file') continue; - if (is_bool($arg_value)) - $arg_value = $arg_value ? 'true' : 'false'; - $arg_list[] = "'$arg_name' => $arg_value"; - } - - return "\n"; - } else - return 'compile_dir.'/'.$attrs['file'].'.php"; ?>'; - } - - function _compile_section_start($tag_args) - { - $attrs = $this->_parse_attrs($tag_args); - - $output = "_syntax_error("missing section name"); - } - - $output .= "unset(\$_sections[$section_name]);\n"; - $section_props = "\$_sections[$section_name]['properties']"; - - foreach ($attrs as $attr_name => $attr_value) { - switch ($attr_name) { - case 'loop': - $output .= "{$section_props}['loop'] = is_array($attr_value) ? count($attr_value) : $attr_value;\n"; - break; - - case 'show': - if (is_bool($attr_value)) - $attr_value = $attr_value ? 'true' : 'false'; - $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; - break; - - default: - $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; - break; - } - } - - if (isset($attrs['loop'])) { - $loop_check_code = "{$section_props}['loop'] > 0 && "; - } else { - $output .= "{$section_props}['loop'] = 1;\n"; - } - - if (isset($attrs['show'])) { - $show_check_code = "{$section_props}['show'] && "; - } else { - $output .= "{$section_props}['show'] = {$section_props}['loop'] > 0;\n"; - } - - $output .= "if ($loop_check_code $show_check_code true): "; - - $output .= " - for ({$section_props}['index'] = 0; - {$section_props}['index'] < {$section_props}['loop']; - {$section_props}['index']++):\n"; - $output .= "{$section_props}['rownum'] = {$section_props}['index'] + 1;\n"; - - $output .= "?>\n"; - - return $output; - } - - function _compile_if_tag($tag_args, $elseif = false) - { - /* Tokenize args for 'if' tag. */ - preg_match_all('/(?: - "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | # match all double quoted strings allowed escaped double quotes - \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | # match all single quoted strings allowed escaped single quotes - [()] | # match parentheses - [^"\'\s()]+ # match any other token that is not any of the above - )/x', $tag_args, $match); - $tokens = $match[0]; - - $this->_parse_vars_props($tokens); - - $is_arg_stack = array(); - - for ($i = 0; $i < count($tokens); $i++) { - $token = &$tokens[$i]; - switch ($token) { - case 'eq': - $token = '=='; - break; - - case 'ne': - case 'neq': - $token = '!='; - break; - - case 'lt': - $token = '<'; - break; - - case 'le': - case 'lte': - $token = '<='; - break; - - case 'gt': - $token = '>'; - break; - - case 'ge': - case 'gte': - $token = '>='; - break; - - case 'and': - $token = '&&'; - break; - - case 'or': - $token = '||'; - break; - - case 'not': - $token = '!'; - break; - - case 'mod': - $token = '%'; - break; - - case '(': - array_push($is_arg_stack, $i); - break; - - case 'is': - /* If last token was a ')', we operate on the parenthesized - expression. The start of the expression is on the stack. - Otherwise, we operate on the last encountered token. */ - if ($tokens[$i-1] == ')') - $is_arg_start = array_pop($is_arg_stack); - else - $is_arg_start = $i-1; - /* Construct the argument for 'is' expression, so it knows - what to operate on. */ - $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); - - /* Pass all tokens from next one until the end to the - 'is' expression parsing function. The function will - return modified tokens, where the first one is the result - of the 'is' expression and the rest are the tokens it - didn't touch. */ - $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); - - /* Replace the old tokens with the new ones. */ - array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); - - /* Adjust argument start so that it won't change from the - current position for the next iteration. */ - $i = $is_arg_start; - break; - } - } - - if ($elseif) - return ''; - else - return ''; - } - - function _parse_is_expr($is_arg, $tokens) - { - $expr_end = 0; - - if (($first_token = array_shift($tokens)) == 'not') { - $negate_expr = true; - $expr_type = array_shift($tokens); - } else - $expr_type = $first_token; - - switch ($expr_type) { - case 'even': - if ($tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!(($is_arg / $expr_arg) % $expr_arg)"; - } - else - $expr = "!($is_arg % 2)"; - break; - - case 'odd': - if ($tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "(($is_arg / $expr_arg) % $expr_arg)"; - } - else - $expr = "($is_arg % 2)"; - break; - - case 'div': - if ($tokens[$expr_end] == 'by') { - $expr_end++; - $expr_arg = $tokens[$expr_end++]; - $expr = "!($is_arg % $expr_arg)"; - } else { - $this->_syntax_error("expecting 'by' after 'div'"); - } - break; - - default: - $this->_syntax_error("unknown 'is' expression - '$expr_type'"); - break; - } - - if ($negate_expr) { - $expr = "!($expr)"; - } - - array_splice($tokens, 0, $expr_end, $expr); - - return $tokens; - } - - function _parse_attrs($tag_args, $quote = true) - { - /* Tokenize tag attributes. */ - preg_match_all('/(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | - \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | (?>[^"\'=\s]+) - )+ | - [=] - /x', $tag_args, $match); - $tokens = $match[0]; - $var_delims = array('$', '#', '%'); - - $attrs = array(); - /* Parse state: - 0 - expecting attribute name - 1 - expecting '=' - 2 - expecting attribute value (not '=') */ - $state = 0; - - foreach ($tokens as $token) { - switch ($state) { - case 0: - /* If the token is a valid identifier, we set attribute name - and go to state 1. */ - if (preg_match('!^\w+$!', $token)) { - $attr_name = $token; - $state = 1; - } else - $this->_syntax_error("invalid attribute name - '$token'"); - break; - - case 1: - /* If the token is '=', then we go to state 2. */ - if ($token == '=') { - $state = 2; - } else - $this->_syntax_error("expecting '=' after attribute name"); - break; - - case 2: - /* If token is not '=', we set the attribute value and go to - state 0. */ - if ($token != '=') { - /* We booleanize the token if it's a non-quoted possible - boolean value. */ - if (preg_match('!^(on|yes|true)$!', $token)) - $token = true; - else if (preg_match('!^(off|no|false)$!', $token)) - $token = false; - /* If the token is not variable (doesn't start with - '$', '#', or '%') and not enclosed in single or - double quotes we single-quote it. */ - else if ($quote && !in_array($token{0}, $var_delims) && - !(($token{0} == '"' || $token[0] == "'") && - $token{strlen($token)-1} == $token{0})) - $token = "'".$token."'"; - - $attrs[$attr_name] = $token; - $state = 0; - } else - $this->_syntax_error("'=' cannot be an attribute value"); - break; - } - } - - $this->_parse_vars_props($attrs); - - return $attrs; - } - - function _preg_grep($pattern, $array) - { - $result = array(); - - foreach ($array as $key => $entry) { - if (preg_match($pattern, $entry)) - $result[$key] = $entry; - } - - return $result; - } - - function _parse_vars_props(&$tokens) - { - $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; - - /* preg_grep() was fixed to return keys properly in 4.0.4 and later. To - allow people to use older versions of PHP we emulate preg_grep() and - use the version check to see what function to call. */ - if (strnatcmp(PHP_VERSION, '4.0.4') >= 0) { - $var_exprs = preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - $conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - $sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - } else { - $var_exprs = $this->_preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - $conf_var_exprs = $this->_preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - $sect_prop_exprs = $this->_preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); - } - - if (count($var_exprs)) { - foreach ($var_exprs as $expr_index => $var_expr) { - $tokens[$expr_index] = $this->_parse_var($var_expr); - } - } - - if (count($conf_var_exprs)) { - foreach ($conf_var_exprs as $expr_index => $var_expr) { - $tokens[$expr_index] = $this->_parse_conf_var($var_expr); - } - } - - if (count($sect_prop_exprs)) { - foreach ($sect_prop_exprs as $expr_index => $section_prop_expr) { - $tokens[$expr_index] = $this->_parse_section_prop($section_prop_expr); - } - } - } - - function _parse_var($var_expr) - { - list($var_ref, $modifiers) = explode('|', substr($var_expr, 1), 2); - - $sections = explode('/', $var_ref); - $props = explode('.', array_pop($sections)); - $var_name = array_shift($props); - - $output = "\$$var_name"; - - foreach ($sections as $section) { - $output .= "[\$_sections['$section']['properties']['index']]"; - } - foreach ($props as $prop) { - $output .= "['$prop']"; - } - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - function _parse_conf_var($conf_var_expr) - { - list($var_ref, $modifiers) = explode('|', $conf_var_expr, 2); - - $var_name = substr($var_ref, 1, -1); - - $output = "\$_config['$var_name']"; - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - function _parse_section_prop($section_prop_expr) - { - list($var_ref, $modifiers) = explode('|', $section_prop_expr, 2); - - preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); - $section_name = $match[1]; - $prop_name = $match[2]; - - $output = "\$_sections['$section_name']['properties']['$prop_name']"; - - $this->_parse_modifiers($output, $modifiers); - - return $output; - } - - function _parse_modifiers(&$output, $modifier_string) - { - $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; - preg_match_all('!\|@?(\w+)((?::(?:'. $qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $match); - list(, $modifiers, $modifier_arg_strings) = $match; - - for ($i = 0; $i < count($modifiers); $i++) { - $modifier_name = $modifiers[$i]; - preg_match_all('!:(' . $qstr_regexp . '|[^|]+)!', $modifier_arg_strings[$i], $match); - $modifier_args = $match[1]; - - if ($modifier_name{0} == '@') { - $map_array = 'false'; - $modifier_name = substr($modifier_name, 1); - } else - $map_array = 'true'; - - /* - * First we lookup the modifier function name in the registered - * modifiers table. - */ - $mod_func_name = $this->custom_mods[$modifier_name]; - - /* - * If we don't find that modifier there, we assume it's just a PHP - * function name. - */ - if (!isset($mod_func_name)) - $mod_func_name = $modifier_name; - - $this->_parse_vars_props($modifier_args); - - if (count($modifier_args) > 0) - $modifier_args = ', '.implode(', ', $modifier_args); - else - $modifier_args = ''; - - $output = "_smarty_mod_handler('$mod_func_name', $map_array, $output$modifier_args)"; - } - } - + function _process_cached_inserts($results) + { + preg_match_all('!'.$this->_smarty_md5.'{insert_cache (.*)}'.$this->_smarty_md5.'!Uis', + $results, $match); + list($cached_inserts, $insert_args) = $match; + + for ($i = 0; $i < count($cached_inserts); $i++) { + $attrs = $this->_parse_attrs($insert_args[$i], false); + $name = $this->_dequote($attrs['name']); + + if (empty($name)) { + $this->_syntax_error("missing insert name"); + } + + $arg_list = array(); + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'name') continue; + $arg_list[$arg_name] = $arg_value; + } + + $function_name = 'insert_' . $name; + $replace = $function_name($arg_list); + + $results = str_replace($cached_inserts[$i], $replace, $results); + } + + return $results; + } + + function _compile_tag($template_tag) + { + /* Matched comment. */ + if ($template_tag{0} == '*' && $template_tag{strlen($template_tag)-1} == '*') + return ""; + + $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + + /* Split tag into two parts: command and the arguments. */ + preg_match('/^( + (?: ' . $qstr_regexp . ' | (?>[^"\'\s]+))+ + ) + (?:\s+(.*))? + /xs', $template_tag, $match); + list(, $tag_command, $tag_args) = $match; + + /* If the tag name matches a variable or section property definition, + we simply process it. */ + if (preg_match('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // if a variable + preg_match('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command) || // or a configuration variable + preg_match('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tag_command)) { // or a section property + settype($tag_command, 'array'); + $this->_parse_vars_props($tag_command); + return ""; + } + + switch ($tag_command) { + case 'include': + return $this->_compile_include_tag($tag_args); + + case 'if': + return $this->_compile_if_tag($tag_args); + + case 'else': + return ''; + + case 'elseif': + return $this->_compile_if_tag($tag_args, true); + + case '/if': + return ''; + + case 'ldelim': + return $this->left_delimiter; + + case 'rdelim': + return $this->right_delimiter; + + case 'section': + array_push($this->_sectionelse_stack, false); + return $this->_compile_section_start($tag_args); + + case 'sectionelse': + $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true; + return ""; + + case '/section': + if (array_pop($this->_sectionelse_stack)) + return ""; + else + return ""; + + case 'config_load': + return $this->_compile_config_load_tag($tag_args); + + case 'strip': + case '/strip': + return $this->left_delimiter.$tag_command.$this->right_delimiter; + + case 'literal': + list (,$literal_block) = each($this->_literal_blocks); + $this->_current_line_no += substr_count($literal_block, "\n"); + return $literal_block; + + case 'insert': + return $this->_compile_insert_tag($tag_args); + + default: + if (isset($this->custom_funcs[$tag_command])) { + return $this->_compile_custom_tag($tag_command, $tag_args); + } else { + $this->_syntax_error("unknown tag - '$tag_command'", E_USER_WARNING); + return ""; + } + } + } + + function _compile_custom_tag($tag_command, $tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $function = $this->custom_funcs[$tag_command]; + foreach ($attrs as $arg_name => $arg_value) { + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + return ""; + } + + function _compile_insert_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + $name = substr($attrs['name'], 1, -1); + + if (empty($name)) { + $this->_syntax_error("missing insert name"); + } + + if($this->caching) + return $this->_smarty_md5."{insert_cache $tag_args}".$this->_smarty_md5; + + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'name') continue; + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + return ""; + } + + function _compile_config_load_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in config_load tag"); + } + + $output = "config_dir."');\n" . + "}\n" . + "\$_config = array_merge((array)\$_config, \$_conf_obj->get(".$attrs['file']."));\n"; + + if (!empty($attrs['section'])) + $output .= '$_config = array_merge((array)$_config, $_conf_obj->get('.$attrs['file'].', '.$attrs['section'].')); '; + + $output .= '?>'; + + return $output; + } + + + function _compile_include_tag($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + if (empty($attrs['file'])) { + $this->_syntax_error("missing 'file' attribute in include tag"); + } else + $attrs['file'] = $this->_dequote($attrs['file']); + + if (count($attrs) > 1) { + $include_func_name = uniqid("_include_"); + $include_file_name = $this->compile_dir.'/'.$attrs['file']; + + foreach ($attrs as $arg_name => $arg_value) { + if ($arg_name == 'file') continue; + if (is_bool($arg_value)) + $arg_value = $arg_value ? 'true' : 'false'; + $arg_list[] = "'$arg_name' => $arg_value"; + } + + return "\n"; + } else + return 'compile_dir.'/'.$attrs['file'].'.php"; ?>'; + } + + function _compile_section_start($tag_args) + { + $attrs = $this->_parse_attrs($tag_args); + + $output = "_syntax_error("missing section name"); + } + + $output .= "unset(\$_sections[$section_name]);\n"; + $section_props = "\$_sections[$section_name]['properties']"; + + foreach ($attrs as $attr_name => $attr_value) { + switch ($attr_name) { + case 'loop': + $output .= "{$section_props}['loop'] = is_array($attr_value) ? count($attr_value) : $attr_value;\n"; + break; + + case 'show': + if (is_bool($attr_value)) + $attr_value = $attr_value ? 'true' : 'false'; + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; + break; + + default: + $output .= "{$section_props}['$attr_name'] = $attr_value;\n"; + break; + } + } + + if (isset($attrs['loop'])) { + $loop_check_code = "{$section_props}['loop'] > 0 && "; + } else { + $output .= "{$section_props}['loop'] = 1;\n"; + } + + if (isset($attrs['show'])) { + $show_check_code = "{$section_props}['show'] && "; + } else { + $output .= "{$section_props}['show'] = {$section_props}['loop'] > 0;\n"; + } + + $output .= "if ($loop_check_code $show_check_code true): "; + + $output .= " + for ({$section_props}['index'] = 0; + {$section_props}['index'] < {$section_props}['loop']; + {$section_props}['index']++):\n"; + $output .= "{$section_props}['rownum'] = {$section_props}['index'] + 1;\n"; + + $output .= "?>\n"; + + return $output; + } + + function _compile_if_tag($tag_args, $elseif = false) + { + /* Tokenize args for 'if' tag. */ + preg_match_all('/(?: + "[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | # match all double quoted strings allowed escaped double quotes + \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | # match all single quoted strings allowed escaped single quotes + [()] | # match parentheses + [^"\'\s()]+ # match any other token that is not any of the above + )/x', $tag_args, $match); + $tokens = $match[0]; + + $this->_parse_vars_props($tokens); + + $is_arg_stack = array(); + + for ($i = 0; $i < count($tokens); $i++) { + $token = &$tokens[$i]; + switch ($token) { + case 'eq': + $token = '=='; + break; + + case 'ne': + case 'neq': + $token = '!='; + break; + + case 'lt': + $token = '<'; + break; + + case 'le': + case 'lte': + $token = '<='; + break; + + case 'gt': + $token = '>'; + break; + + case 'ge': + case 'gte': + $token = '>='; + break; + + case 'and': + $token = '&&'; + break; + + case 'or': + $token = '||'; + break; + + case 'not': + $token = '!'; + break; + + case 'mod': + $token = '%'; + break; + + case '(': + array_push($is_arg_stack, $i); + break; + + case 'is': + /* If last token was a ')', we operate on the parenthesized + expression. The start of the expression is on the stack. + Otherwise, we operate on the last encountered token. */ + if ($tokens[$i-1] == ')') + $is_arg_start = array_pop($is_arg_stack); + else + $is_arg_start = $i-1; + /* Construct the argument for 'is' expression, so it knows + what to operate on. */ + $is_arg = implode(' ', array_slice($tokens, $is_arg_start, $i - $is_arg_start)); + + /* Pass all tokens from next one until the end to the + 'is' expression parsing function. The function will + return modified tokens, where the first one is the result + of the 'is' expression and the rest are the tokens it + didn't touch. */ + $new_tokens = $this->_parse_is_expr($is_arg, array_slice($tokens, $i+1)); + + /* Replace the old tokens with the new ones. */ + array_splice($tokens, $is_arg_start, count($tokens), $new_tokens); + + /* Adjust argument start so that it won't change from the + current position for the next iteration. */ + $i = $is_arg_start; + break; + } + } + + if ($elseif) + return ''; + else + return ''; + } + + function _parse_is_expr($is_arg, $tokens) + { + $expr_end = 0; + + if (($first_token = array_shift($tokens)) == 'not') { + $negate_expr = true; + $expr_type = array_shift($tokens); + } else + $expr_type = $first_token; + + switch ($expr_type) { + case 'even': + if ($tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!(($is_arg / $expr_arg) % $expr_arg)"; + } + else + $expr = "!($is_arg % 2)"; + break; + + case 'odd': + if ($tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "(($is_arg / $expr_arg) % $expr_arg)"; + } + else + $expr = "($is_arg % 2)"; + break; + + case 'div': + if ($tokens[$expr_end] == 'by') { + $expr_end++; + $expr_arg = $tokens[$expr_end++]; + $expr = "!($is_arg % $expr_arg)"; + } else { + $this->_syntax_error("expecting 'by' after 'div'"); + } + break; + + default: + $this->_syntax_error("unknown 'is' expression - '$expr_type'"); + break; + } + + if ($negate_expr) { + $expr = "!($expr)"; + } + + array_splice($tokens, 0, $expr_end, $expr); + + return $tokens; + } + + function _parse_attrs($tag_args, $quote = true) + { + /* Tokenize tag attributes. */ + preg_match_all('/(?:"[^"\\\\]*(?:\\\\.[^"\\\\]*)*" | + \'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\' | (?>[^"\'=\s]+) + )+ | + [=] + /x', $tag_args, $match); + $tokens = $match[0]; + $var_delims = array('$', '#', '%'); + + $attrs = array(); + /* Parse state: + 0 - expecting attribute name + 1 - expecting '=' + 2 - expecting attribute value (not '=') */ + $state = 0; + + foreach ($tokens as $token) { + switch ($state) { + case 0: + /* If the token is a valid identifier, we set attribute name + and go to state 1. */ + if (preg_match('!^\w+$!', $token)) { + $attr_name = $token; + $state = 1; + } else + $this->_syntax_error("invalid attribute name - '$token'"); + break; + + case 1: + /* If the token is '=', then we go to state 2. */ + if ($token == '=') { + $state = 2; + } else + $this->_syntax_error("expecting '=' after attribute name"); + break; + + case 2: + /* If token is not '=', we set the attribute value and go to + state 0. */ + if ($token != '=') { + /* We booleanize the token if it's a non-quoted possible + boolean value. */ + if (preg_match('!^(on|yes|true)$!', $token)) + $token = true; + else if (preg_match('!^(off|no|false)$!', $token)) + $token = false; + /* If the token is not variable (doesn't start with + '$', '#', or '%') and not enclosed in single or + double quotes we single-quote it. */ + else if ($quote && !in_array($token{0}, $var_delims) && + !(($token{0} == '"' || $token[0] == "'") && + $token{strlen($token)-1} == $token{0})) + $token = "'".$token."'"; + + $attrs[$attr_name] = $token; + $state = 0; + } else + $this->_syntax_error("'=' cannot be an attribute value"); + break; + } + } + + $this->_parse_vars_props($attrs); + + return $attrs; + } + + function _preg_grep($pattern, $array) + { + $result = array(); + + foreach ($array as $key => $entry) { + if (preg_match($pattern, $entry)) + $result[$key] = $entry; + } + + return $result; + } + + function _parse_vars_props(&$tokens) + { + $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + + /* preg_grep() was fixed to return keys properly in 4.0.4 and later. To + allow people to use older versions of PHP we emulate preg_grep() and + use the version check to see what function to call. */ + if (strnatcmp(PHP_VERSION, '4.0.4') >= 0) { + $var_exprs = preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + $conf_var_exprs = preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + $sect_prop_exprs = preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + } else { + $var_exprs = $this->_preg_grep('!^\$(\w+/)*\w+(?>\.\w+)*(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + $conf_var_exprs = $this->_preg_grep('!^#(\w+)#(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + $sect_prop_exprs = $this->_preg_grep('!^%\w+\.\w+%(?>\|@?\w+(:(' . $qstr_regexp . '|[^|]+))?)*$!', $tokens); + } + + if (count($var_exprs)) { + foreach ($var_exprs as $expr_index => $var_expr) { + $tokens[$expr_index] = $this->_parse_var($var_expr); + } + } + + if (count($conf_var_exprs)) { + foreach ($conf_var_exprs as $expr_index => $var_expr) { + $tokens[$expr_index] = $this->_parse_conf_var($var_expr); + } + } + + if (count($sect_prop_exprs)) { + foreach ($sect_prop_exprs as $expr_index => $section_prop_expr) { + $tokens[$expr_index] = $this->_parse_section_prop($section_prop_expr); + } + } + } + + function _parse_var($var_expr) + { + list($var_ref, $modifiers) = explode('|', substr($var_expr, 1), 2); + + $sections = explode('/', $var_ref); + $props = explode('.', array_pop($sections)); + $var_name = array_shift($props); + + $output = "\$$var_name"; + + foreach ($sections as $section) { + $output .= "[\$_sections['$section']['properties']['index']]"; + } + foreach ($props as $prop) { + $output .= "['$prop']"; + } + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + function _parse_conf_var($conf_var_expr) + { + list($var_ref, $modifiers) = explode('|', $conf_var_expr, 2); + + $var_name = substr($var_ref, 1, -1); + + $output = "\$_config['$var_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + function _parse_section_prop($section_prop_expr) + { + list($var_ref, $modifiers) = explode('|', $section_prop_expr, 2); + + preg_match('!%(\w+)\.(\w+)%!', $var_ref, $match); + $section_name = $match[1]; + $prop_name = $match[2]; + + $output = "\$_sections['$section_name']['properties']['$prop_name']"; + + $this->_parse_modifiers($output, $modifiers); + + return $output; + } + + function _parse_modifiers(&$output, $modifier_string) + { + $qstr_regexp = '"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\''; + preg_match_all('!\|@?(\w+)((?::(?:'. $qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $match); + list(, $modifiers, $modifier_arg_strings) = $match; + + for ($i = 0; $i < count($modifiers); $i++) { + $modifier_name = $modifiers[$i]; + preg_match_all('!:(' . $qstr_regexp . '|[^|]+)!', $modifier_arg_strings[$i], $match); + $modifier_args = $match[1]; + + if ($modifier_name{0} == '@') { + $map_array = 'false'; + $modifier_name = substr($modifier_name, 1); + } else + $map_array = 'true'; + + /* + * First we lookup the modifier function name in the registered + * modifiers table. + */ + $mod_func_name = $this->custom_mods[$modifier_name]; + + /* + * If we don't find that modifier there, we assume it's just a PHP + * function name. + */ + if (!isset($mod_func_name)) + $mod_func_name = $modifier_name; + + $this->_parse_vars_props($modifier_args); + + if (count($modifier_args) > 0) + $modifier_args = ', '.implode(', ', $modifier_args); + else + $modifier_args = ''; + + $output = "_smarty_mod_handler('$mod_func_name', $map_array, $output$modifier_args)"; + } + } + /*======================================================================*\ - Function: _dequote - Purpose: Remove starting and ending quotes from the string + Function: _dequote + Purpose: Remove starting and ending quotes from the string \*======================================================================*/ - function _dequote($string) - { - if (($string{0} == "'" || $string{0} == '"') && - $string{strlen($string)-1} == $string{0}) - return substr($string, 1, -1); - else - return $string; - } + function _dequote($string) + { + if (($string{0} == "'" || $string{0} == '"') && + $string{strlen($string)-1} == $string{0}) + return substr($string, 1, -1); + else + return $string; + } - + /*======================================================================*\ - Function: _read_file() - Purpose: read in a file + Function: _read_file() + Purpose: read in a file \*======================================================================*/ - function _read_file($filename) - { - if(!($fd = fopen($filename, 'r'))) { - $this->_set_error_msg("problem reading '$filename.'"); - return false; - } - $contents = fread($fd, filesize($filename)); - fclose($fd); - return $contents; - } + function _read_file($filename) + { + if(!($fd = fopen($filename, 'r'))) { + $this->_set_error_msg("problem reading '$filename.'"); + return false; + } + $contents = fread($fd, filesize($filename)); + fclose($fd); + return $contents; + } /*======================================================================*\ - Function: _write_file() - Purpose: write out a file + Function: _write_file() + Purpose: write out a file \*======================================================================*/ - function _write_file($filename,$contents) - { - if(!($fd = fopen($filename, 'w'))) { - $this->_set_error_msg("problem writing '$filename.'"); - return false; - } - fwrite($fd, $contents); - fclose($fd); - return true; - } + function _write_file($filename,$contents) + { + if(!($fd = fopen($filename, 'w'))) { + $this->_set_error_msg("problem writing '$filename.'"); + return false; + } + fwrite($fd, $contents); + fclose($fd); + return true; + } /*======================================================================*\ - Function: _set_error_msg() - Purpose: set the error message + Function: _set_error_msg() + Purpose: set the error message \*======================================================================*/ - function _set_error_msg($error_msg) - { - $this->_error_msg="smarty error: $error_msg"; - return true; - } + function _set_error_msg($error_msg) + { + $this->_error_msg="smarty error: $error_msg"; + return true; + } /*======================================================================*\ - Function: _syntax_error - Purpose: display Smarty syntax error + Function: _syntax_error + Purpose: display Smarty syntax error \*======================================================================*/ - function _syntax_error($error_msg, $error_type = E_USER_ERROR) - { - trigger_error("Smarty: [in " . $this->_current_file . " line " . - $this->_current_line_no . "]: syntax error: $error_msg", $error_type); - } + function _syntax_error($error_msg, $error_type = E_USER_ERROR) + { + trigger_error("Smarty: [in " . $this->_current_file . " line " . + $this->_current_line_no . "]: syntax error: $error_msg", $error_type); + } } +/* vim: set expandtab: */ + ?>