From 94d8eb634c53fea341b849bf13f9224e70db2d16 Mon Sep 17 00:00:00 2001 From: Andreas Gohr Date: Mon, 11 Sep 2006 13:22:29 +0200 Subject: [PATCH] Smarty update to 2.6.14 darcs-hash:20060911112229-6e07b-79732307f41ddcb3ce6389cf3e7cf09f884acce3.gz --- smarty/Config_File.class.php | 152 ++-- smarty/Smarty.class.php | 316 ++++---- smarty/Smarty_Compiler.class.php | 703 +++++++++++------- smarty/core/core.is_secure.php | 59 -- smarty/core/core.write_compiled_include.php | 59 -- smarty/debug.tpl | 2 +- .../core.assemble_plugin_filepath.php | 11 +- .../core.assign_smarty_interface.php | 0 .../core.create_dir_structure.php | 2 +- .../core.display_debug_console.php | 3 +- .../core.get_include_path.php | 2 +- .../core.get_microtime.php | 0 .../core.get_php_resource.php | 4 +- smarty/internals/core.is_secure.php | 59 ++ .../{core => internals}/core.is_trusted.php | 5 +- .../{core => internals}/core.load_plugins.php | 0 .../core.load_resource_plugin.php | 0 .../core.process_cached_inserts.php | 8 +- .../core.process_compiled_include.php | 5 + .../core.read_cache_file.php | 20 +- smarty/{core => internals}/core.rm_auto.php | 4 +- smarty/{core => internals}/core.rmdir.php | 1 - .../core.run_insert_handler.php | 6 +- .../core.smarty_include_php.php | 2 +- .../core.write_cache_file.php | 39 +- .../internals/core.write_compiled_include.php | 91 +++ .../core.write_compiled_resource.php | 4 +- .../{core => internals}/core.write_file.php | 20 +- smarty/plugins/block.textformat.php | 108 +-- smarty/plugins/compiler.assign.php | 40 + smarty/plugins/function.assign_debug_info.php | 3 +- smarty/plugins/function.config_load.php | 124 +-- smarty/plugins/function.counter.php | 44 +- smarty/plugins/function.cycle.php | 47 +- smarty/plugins/function.debug.php | 8 +- smarty/plugins/function.eval.php | 1 + smarty/plugins/function.fetch.php | 344 ++++----- smarty/plugins/function.html_checkboxes.php | 186 ++--- smarty/plugins/function.html_image.php | 45 +- smarty/plugins/function.html_options.php | 154 ++-- smarty/plugins/function.html_radios.php | 194 ++--- smarty/plugins/function.html_select_date.php | 210 ++++-- smarty/plugins/function.html_select_time.php | 33 +- smarty/plugins/function.html_table.php | 34 +- smarty/plugins/function.mailto.php | 189 ++--- smarty/plugins/function.math.php | 12 +- smarty/plugins/function.popup.php | 134 ++-- smarty/plugins/function.popup_init.php | 13 +- smarty/plugins/modifier.capitalize.php | 22 +- smarty/plugins/modifier.cat.php | 4 +- smarty/plugins/modifier.count_characters.php | 1 + smarty/plugins/modifier.count_paragraphs.php | 1 + smarty/plugins/modifier.count_sentences.php | 1 + smarty/plugins/modifier.count_words.php | 1 + smarty/plugins/modifier.csv.php | 3 +- smarty/plugins/modifier.date_format.php | 22 +- smarty/plugins/modifier.debug_print_var.php | 14 +- smarty/plugins/modifier.default.php | 1 + smarty/plugins/modifier.escape.php | 89 ++- smarty/plugins/modifier.indent.php | 3 +- smarty/plugins/modifier.lower.php | 3 +- smarty/plugins/modifier.nl2br.php | 2 +- smarty/plugins/modifier.noteparser.php | 2 +- smarty/plugins/modifier.regex_replace.php | 8 +- smarty/plugins/modifier.replace.php | 1 + smarty/plugins/modifier.spacify.php | 1 + smarty/plugins/modifier.string_format.php | 1 + smarty/plugins/modifier.strip.php | 4 +- smarty/plugins/modifier.strip_tags.php | 1 + smarty/plugins/modifier.truncate.php | 25 +- smarty/plugins/modifier.upper.php | 3 +- smarty/plugins/modifier.wordwrap.php | 3 +- .../plugins/outputfilter.trimwhitespace.php | 50 +- .../plugins/shared.escape_special_chars.php | 13 +- smarty/plugins/shared.make_timestamp.php | 37 +- 75 files changed, 2181 insertions(+), 1635 deletions(-) delete mode 100644 smarty/core/core.is_secure.php delete mode 100644 smarty/core/core.write_compiled_include.php rename smarty/{core => internals}/core.assemble_plugin_filepath.php (81%) rename smarty/{core => internals}/core.assign_smarty_interface.php (100%) rename smarty/{core => internals}/core.create_dir_structure.php (97%) rename smarty/{core => internals}/core.display_debug_console.php (91%) rename smarty/{core => internals}/core.get_include_path.php (91%) rename smarty/{core => internals}/core.get_microtime.php (100%) rename smarty/{core => internals}/core.get_php_resource.php (92%) create mode 100644 smarty/internals/core.is_secure.php rename smarty/{core => internals}/core.is_trusted.php (92%) rename smarty/{core => internals}/core.load_plugins.php (100%) rename smarty/{core => internals}/core.load_resource_plugin.php (100%) rename smarty/{core => internals}/core.process_cached_inserts.php (84%) rename smarty/{core => internals}/core.process_compiled_include.php (84%) rename smarty/{core => internals}/core.read_cache_file.php (85%) rename smarty/{core => internals}/core.rm_auto.php (92%) rename smarty/{core => internals}/core.rmdir.php (93%) rename smarty/{core => internals}/core.run_insert_handler.php (89%) rename smarty/{core => internals}/core.smarty_include_php.php (94%) rename smarty/{core => internals}/core.write_cache_file.php (60%) create mode 100644 smarty/internals/core.write_compiled_include.php rename smarty/{core => internals}/core.write_compiled_resource.php (84%) rename smarty/{core => internals}/core.write_file.php (58%) create mode 100644 smarty/plugins/compiler.assign.php diff --git a/smarty/Config_File.class.php b/smarty/Config_File.class.php index f0297cd..622c0e8 100644 --- a/smarty/Config_File.class.php +++ b/smarty/Config_File.class.php @@ -17,21 +17,16 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * You may contact the author of Config_File by e-mail at: - * {@link andrei@php.net} - * - * The latest version of Config_File can be obtained from: - * http://smarty.php.net/ - * * @link http://smarty.php.net/ - * @version 2.6.0 - * @copyright Copyright: 2001-2003 ispi of Lincoln, Inc. + * @version 2.6.14 + * @copyright Copyright: 2001-2005 New Digital Group, Inc. * @author Andrei Zmievski * @access public * @package Smarty */ -/* $Id: Config_File.class.php,v 1.1.1.1 2004/01/13 16:02:46 gohr Exp $ */ +/* $Id: Config_File.class.php,v 1.84 2006/01/18 19:02:52 mohrt Exp $ */ + /** * Config file reading class * @package Smarty @@ -110,7 +105,7 @@ class Config_File { * @param string $var_name (optional) variable to get info for * @return string|array a value or array of values */ - function &get($file_name, $section_name = NULL, $var_name = NULL) + function get($file_name, $section_name = NULL, $var_name = NULL) { if (empty($file_name)) { $this->_trigger_error_msg('Empty config file name'); @@ -245,75 +240,104 @@ class Config_File { return false; } - $contents = fread($fp, filesize($config_file)); + $contents = ($size = filesize($config_file)) ? fread($fp, $size) : ''; fclose($fp); - if($this->fix_newlines) { - // fix mac/dos formatted newlines - $contents = preg_replace('!\r\n?!',"\n",$contents); - } - - $config_data = array(); - - /* replace all multi-line values by placeholders */ - if (preg_match_all('/"""(.*)"""/Us', $contents, $match)) { - $_triple_quotes = $match[1]; - $_i = 0; - $contents = preg_replace('/""".*"""/Use', '"\x1b\x1b\x1b".$_i++."\x1b\x1b\x1b"', $contents); - } else { - $_triple_quotes = null; - } - - /* Get global variables first. */ - if ($contents{0} != '[' && preg_match("/^(.*?)(\n\[|\Z)/s", $contents, $match)) - $config_data["vars"] = $this->_parse_config_block($match[1], $_triple_quotes); - - /* Get section variables. */ - $config_data["sections"] = array(); - preg_match_all("/^\[(.*?)\]/m", $contents, $match); - foreach ($match[1] as $section) { - if ($section{0} == '.' && !$this->read_hidden) - continue; - if (preg_match("/\[".preg_quote($section, '/')."\](.*?)(\n\[|\Z)/s", $contents, $match)) - if ($section{0} == '.') - $section = substr($section, 1); - $config_data["sections"][$section]["vars"] = $this->_parse_config_block($match[1], $_triple_quotes); - } - - $this->_config_data[$config_file] = $config_data; - + $this->_config_data[$config_file] = $this->parse_contents($contents); return true; } - /**#@+ @access private */ /** - * @var string $config_block + * Store the contents of a file manually. + * + * @param string $config_file file name of the related contents + * @param string $contents the file-contents to parse */ - function _parse_config_block($config_block, $triple_quotes) + function set_file_contents($config_file, $contents) { - $vars = array(); + $this->_config_data[$config_file] = $this->parse_contents($contents); + return true; + } - /* First we grab the multi-line values. */ - if (preg_match_all("/^([^=\n]+)=\s*\x1b\x1b\x1b(\d+)\x1b\x1b\x1b\s*$/ms", $config_block, $match, PREG_SET_ORDER)) { - for ($i = 0; $i < count($match); $i++) { - $this->_set_config_var($vars, trim($match[$i][1]), $triple_quotes[$match[$i][2]], false); - } - $config_block = preg_replace("/^[^=\n]+=\s*\x1b\x1b\x1b\d+\x1b\x1b\x1b\s*$/ms", "", $config_block); + /** + * parse the source of a configuration file manually. + * + * @param string $contents the file-contents to parse + */ + function parse_contents($contents) + { + if($this->fix_newlines) { + // fix mac/dos formatted newlines + $contents = preg_replace('!\r\n?!', "\n", $contents); } + $config_data = array(); + $config_data['sections'] = array(); + $config_data['vars'] = array(); + + /* reference to fill with data */ + $vars =& $config_data['vars']; + + /* parse file line by line */ + preg_match_all('!^.*\r?\n?!m', $contents, $match); + $lines = $match[0]; + for ($i=0, $count=count($lines); $i<$count; $i++) { + $line = $lines[$i]; + if (empty($line)) continue; + + if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { + /* section found */ + if (substr($match[1], 0, 1) == '.') { + /* hidden section */ + if ($this->read_hidden) { + $section_name = substr($match[1], 1); + } else { + /* break reference to $vars to ignore hidden section */ + unset($vars); + $vars = array(); + continue; + } + } else { + $section_name = $match[1]; + } + if (!isset($config_data['sections'][$section_name])) + $config_data['sections'][$section_name] = array('vars' => array()); + $vars =& $config_data['sections'][$section_name]['vars']; + continue; + } - $config_lines = preg_split("/\n+/", $config_block); - - foreach ($config_lines as $line) { - if (preg_match("/^\s*(\.?\w+)\s*=(.*)/", $line, $match)) { - $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', trim($match[2])); - $this->_set_config_var($vars, trim($match[1]), $var_value, $this->booleanize); + if (preg_match('/^\s*(\.?\w+)\s*=\s*(.*)/s', $line, $match)) { + /* variable found */ + $var_name = rtrim($match[1]); + if (strpos($match[2], '"""') === 0) { + /* handle multiline-value */ + $lines[$i] = substr($match[2], 3); + $var_value = ''; + while ($i<$count) { + if (($pos = strpos($lines[$i], '"""')) === false) { + $var_value .= $lines[$i++]; + } else { + /* end of multiline-value */ + $var_value .= substr($lines[$i], 0, $pos); + break; + } + } + $booleanize = false; + + } else { + /* handle simple value */ + $var_value = preg_replace('/^([\'"])(.*)\1$/', '\2', rtrim($match[2])); + $booleanize = $this->booleanize; + + } + $this->_set_config_var($vars, $var_name, $var_value, $booleanize); } + /* else unparsable line / means it is a comment / means ignore it */ } - - return $vars; + return $config_data; } + /**#@+ @access private */ /** * @param array &$container * @param string $var_name @@ -323,7 +347,7 @@ class Config_File { */ function _set_config_var(&$container, $var_name, $var_value, $booleanize) { - if ($var_name{0} == '.') { + if (substr($var_name, 0, 1) == '.') { if (!$this->read_hidden) return; else diff --git a/smarty/Smarty.class.php b/smarty/Smarty.class.php index 7388dc3..47ec24e 100644 --- a/smarty/Smarty.class.php +++ b/smarty/Smarty.class.php @@ -22,28 +22,15 @@ * Smarty mailing list. Send a blank e-mail to * smarty-general-subscribe@lists.php.net * - * You may contact the authors of Smarty by e-mail at: - * monte@ispi.net - * andrei@php.net - * - * Or, write to: - * Monte Ohrt - * Director of Technology, ispi - * 237 S. 70th suite 220 - * Lincoln, NE 68510 - * - * The latest version of Smarty can be obtained from: - * http://smarty.php.net/ - * * @link http://smarty.php.net/ - * @copyright 2001-2003 ispi of Lincoln, Inc. - * @author Monte Ohrt + * @copyright 2001-2005 New Digital Group, Inc. + * @author Monte Ohrt * @author Andrei Zmievski * @package Smarty - * @version 2.6.0 + * @version 2.6.14 */ -/* $Id: Smarty.class.php,v 1.1.1.1 2004/01/13 16:02:46 gohr Exp $ */ +/* $Id: Smarty.class.php,v 1.524 2006/01/18 19:02:52 mohrt Exp $ */ /** * DIR_SEP isn't used anymore, but third party apps might @@ -62,6 +49,10 @@ if (!defined('SMARTY_DIR')) { define('SMARTY_DIR', dirname(__FILE__) . DIRECTORY_SEPARATOR); } +if (!defined('SMARTY_CORE_DIR')) { + define('SMARTY_CORE_DIR', SMARTY_DIR . 'internals' . DIRECTORY_SEPARATOR); +} + define('SMARTY_PHP_PASSTHRU', 0); define('SMARTY_PHP_QUOTE', 1); define('SMARTY_PHP_REMOVE', 2); @@ -113,6 +104,13 @@ class Smarty */ var $debugging = false; + /** + * When set, smarty does uses this value as error_reporting-level. + * + * @var boolean + */ + var $error_reporting = null; + /** * This is the path to the debug console template. If not set, * the default one will be used. @@ -234,11 +232,11 @@ class Smarty 'isset', 'empty', 'count', 'sizeof', 'in_array', 'is_array', - 'true','false'), + 'true', 'false', 'null'), 'INCLUDE_ANY' => false, 'PHP_TAGS' => false, 'MODIFIER_FUNCS' => array('count'), - 'ALLOW_CONSTANTS' => false + 'ALLOW_CONSTANTS' => false ); /** @@ -270,7 +268,7 @@ class Smarty * * @var string */ - var $request_vars_order = "EGPCS"; + var $request_vars_order = 'EGPCS'; /** * Indicates wether $HTTP_*_VARS[] (request_use_auto_globals=false) @@ -280,7 +278,7 @@ class Smarty * * @var boolean */ - var $request_use_auto_globals = false; + var $request_use_auto_globals = true; /** * Set this if you want different sets of compiled files for the same @@ -300,7 +298,7 @@ class Smarty * @var boolean * */ - var $use_sub_dirs = true; + var $use_sub_dirs = false; /** * This is a list of the modifiers to apply to all template variables. @@ -332,23 +330,6 @@ class Smarty */ var $cache_handler_func = null; - /** - * These are the variables from the globals array that are - * assigned to all templates automatically. This isn't really - * necessary any more, you can use the $smarty var to access them - * directly. - * - * @var array - */ - var $global_assign = array('HTTP_SERVER_VARS' => array('SCRIPT_NAME')); - - /** - * The value of "undefined". Leave it alone :-) - * - * @var null - */ - var $undefined = null; - /** * This indicates which filters are automatically loaded into Smarty. * @@ -422,13 +403,6 @@ class Smarty * There should be no need to touch anything below this line. * @access private */ - /** - * error messages. true/false - * - * @var boolean - */ - var $_error_msg = false; - /** * where assigned template vars are kept * @@ -490,7 +464,7 @@ class Smarty * * @var string */ - var $_version = '2.6.0'; + var $_version = '2.6.14'; /** * current template inclusion depth @@ -590,32 +564,13 @@ class Smarty /**#@-*/ /** * The class constructor. - * - * @uses $global_assign uses {@link assign()} to assign each corresponding - * value from $GLOBALS to the template vars */ function Smarty() { - foreach ($this->global_assign as $key => $var_name) { - if (is_array($var_name)) { - foreach ($var_name as $var) { - if (isset($GLOBALS[$key][$var])) { - $this->assign($var, $GLOBALS[$key][$var]); - } else { - $this->assign($var, $this->undefined); - } - } - } else { - if (isset($GLOBALS[$var_name])) { - $this->assign($var_name, $GLOBALS[$var_name]); - } else { - $this->assign($var_name, $this->undefined); - } - } - } + $this->assign('SCRIPT_NAME', isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] + : @$GLOBALS['HTTP_SERVER_VARS']['SCRIPT_NAME']); } - /** * assigns values to template variables * @@ -959,7 +914,7 @@ class Smarty switch ($type) { case 'output': $_params = array('plugins' => array(array($type . 'filter', $name, null, null, false))); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php'); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); smarty_core_load_plugins($_params, $this); break; @@ -986,10 +941,10 @@ class Smarty if (!isset($compile_id)) $compile_id = $this->compile_id; - if (!isset($tpl_file)) - $compile_id = null; + if (!isset($tpl_file)) + $compile_id = null; - $_auto_id = $this->_get_auto_id($cache_id, $compile_id); + $_auto_id = $this->_get_auto_id($cache_id, $compile_id); if (!empty($this->cache_handler_func)) { return call_user_func_array($this->cache_handler_func, @@ -999,7 +954,7 @@ class Smarty 'auto_source' => $tpl_file, 'auto_id' => $_auto_id, 'exp_time' => $exp_time); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rm_auto.php'); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); return smarty_core_rm_auto($_params, $this); } @@ -1014,18 +969,7 @@ class Smarty */ function clear_all_cache($exp_time = null) { - if (!empty($this->cache_handler_func)) { - $dummy = null; - call_user_func_array($this->cache_handler_func, - array('clear', &$this, &$dummy, null, null, null, $exp_time)); - } else { - $_params = array('auto_base' => $this->cache_dir, - 'auto_source' => null, - 'auto_id' => null, - 'exp_time' => $exp_time); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rm_auto.php'); - return smarty_core_rm_auto($_params, $this); - } + return $this->clear_cache(null, null, null, $exp_time); } @@ -1050,7 +994,7 @@ class Smarty 'cache_id' => $cache_id, 'compile_id' => $compile_id ); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.read_cache_file.php'); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); return smarty_core_read_cache_file($_params, $this); } @@ -1084,7 +1028,7 @@ class Smarty 'auto_id' => $compile_id, 'exp_time' => $exp_time, 'extensions' => array('.inc', '.php')); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rm_auto.php'); + require_once(SMARTY_CORE_DIR . 'core.rm_auto.php'); return smarty_core_rm_auto($_params, $this); } @@ -1111,9 +1055,12 @@ class Smarty { if(!isset($name)) { return $this->_tpl_vars; - } - if(isset($this->_tpl_vars[$name])) { + } elseif(isset($this->_tpl_vars[$name])) { return $this->_tpl_vars[$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; } } @@ -1130,6 +1077,10 @@ class Smarty return $this->_config[0]['vars']; } else if(isset($this->_config[0]['vars'][$name])) { return $this->_config[0]['vars'][$name]; + } else { + // var non-existant, return valid reference + $_tmp = null; + return $_tmp; } } @@ -1168,19 +1119,34 @@ class Smarty function fetch($resource_name, $cache_id = null, $compile_id = null, $display = false) { static $_cache_info = array(); - - $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(error_reporting() & ~E_NOTICE); - - if (!$this->debugging && $this->debugging_ctrl == 'URL' - && @strstr($GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING'], $this->_smarty_debug_id)) { - // enable debugging from URL - $this->debugging = true; + + $_smarty_old_error_level = $this->debugging ? error_reporting() : error_reporting(isset($this->error_reporting) + ? $this->error_reporting : error_reporting() & ~E_NOTICE); + + if (!$this->debugging && $this->debugging_ctrl == 'URL') { + $_query_string = $this->request_use_auto_globals ? $_SERVER['QUERY_STRING'] : $GLOBALS['HTTP_SERVER_VARS']['QUERY_STRING']; + if (@strstr($_query_string, $this->_smarty_debug_id)) { + if (@strstr($_query_string, $this->_smarty_debug_id . '=on')) { + // enable debugging for this browser session + @setcookie('SMARTY_DEBUG', true); + $this->debugging = true; + } elseif (@strstr($_query_string, $this->_smarty_debug_id . '=off')) { + // disable debugging for this browser session + @setcookie('SMARTY_DEBUG', false); + $this->debugging = false; + } else { + // enable debugging for this page + $this->debugging = true; + } + } else { + $this->debugging = (bool)($this->request_use_auto_globals ? @$_COOKIE['SMARTY_DEBUG'] : @$GLOBALS['HTTP_COOKIE_VARS']['SMARTY_DEBUG']); + } } if ($this->debugging) { // capture time for debugging info $_params = array(); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $_debug_start_time = smarty_core_get_microtime($_params, $this); $this->_smarty_debug_info[] = array('type' => 'template', 'filename' => $resource_name, @@ -1205,20 +1171,20 @@ class Smarty 'compile_id' => $compile_id, 'results' => null ); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.read_cache_file.php'); + require_once(SMARTY_CORE_DIR . 'core.read_cache_file.php'); if (smarty_core_read_cache_file($_params, $this)) { $_smarty_results = $_params['results']; - if (@count($this->_cache_info['insert_tags'])) { + if (!empty($this->_cache_info['insert_tags'])) { $_params = array('plugins' => $this->_cache_info['insert_tags']); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php'); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); smarty_core_load_plugins($_params, $this); $_params = array('results' => $_smarty_results); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.process_cached_inserts.php'); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); $_smarty_results = smarty_core_process_cached_inserts($_params, $this); } - if (@count($this->_cache_info['cache_serials'])) { + if (!empty($this->_cache_info['cache_serials'])) { $_params = array('results' => $_smarty_results); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.process_compiled_include.php'); + require_once(SMARTY_CORE_DIR . 'core.process_compiled_include.php'); $_smarty_results = smarty_core_process_compiled_include($_params, $this); } @@ -1228,24 +1194,25 @@ class Smarty { // capture time for debugging info $_params = array(); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $_debug_start_time; - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.display_debug_console.php'); + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); $_smarty_results .= smarty_core_display_debug_console($_params, $this); } if ($this->cache_modified_check) { - $_last_modified_date = @substr($GLOBALS['HTTP_SERVER_VARS']['HTTP_IF_MODIFIED_SINCE'], 0, strpos($GLOBALS['HTTP_SERVER_VARS']['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); + $_server_vars = ($this->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; + $_last_modified_date = @substr($_server_vars['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_server_vars['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); $_gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; if (@count($this->_cache_info['insert_tags']) == 0 && !$this->_cache_serials && $_gmt_mtime == $_last_modified_date) { if (php_sapi_name()=='cgi') - header("Status: 304 Not Modified"); + header('Status: 304 Not Modified'); else - header("HTTP/1.1 304 Not Modified"); + header('HTTP/1.1 304 Not Modified'); } else { - header("Last-Modified: ".$_gmt_mtime); + header('Last-Modified: '.$_gmt_mtime); echo $_smarty_results; } } else { @@ -1263,8 +1230,8 @@ class Smarty } } else { $this->_cache_info['template'][$resource_name] = true; - if ($this->cache_modified_check) { - header("Last-Modified: ".gmdate('D, d M Y H:i:s', time()).' GMT'); + if ($this->cache_modified_check && $display) { + header('Last-Modified: '.gmdate('D, d M Y H:i:s', time()).' GMT'); } } } @@ -1310,9 +1277,9 @@ class Smarty 'cache_id' => $cache_id, 'compile_id' => $compile_id, 'results' => $_smarty_results); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_cache_file.php'); + require_once(SMARTY_CORE_DIR . 'core.write_cache_file.php'); smarty_core_write_cache_file($_params, $this); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.process_cached_inserts.php'); + require_once(SMARTY_CORE_DIR . 'core.process_cached_inserts.php'); $_smarty_results = smarty_core_process_cached_inserts($_params, $this); if ($this->_cache_serials) { @@ -1331,9 +1298,9 @@ class Smarty if ($this->debugging) { // capture time for debugging info $_params = array(); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $this->_smarty_debug_info[$_included_tpls_idx]['exec_time'] = (smarty_core_get_microtime($_params, $this) - $_debug_start_time); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.display_debug_console.php'); + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); echo smarty_core_display_debug_console($_params, $this); } error_reporting($_smarty_old_error_level); @@ -1399,7 +1366,7 @@ class Smarty function _get_plugin_filepath($type, $name) { $_params = array('type' => $type, 'name' => $name); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.assemble_plugin_filepath.php'); + require_once(SMARTY_CORE_DIR . 'core.assemble_plugin_filepath.php'); return smarty_core_assemble_plugin_filepath($_params, $this); } @@ -1419,7 +1386,7 @@ class Smarty } else { // get file source and timestamp $_params = array('resource_name' => $resource_name, 'get_source'=>false); - if (!$this->_fetch_resource_info($_params, $this)) { + if (!$this->_fetch_resource_info($_params)) { return false; } if ($_params['resource_timestamp'] <= filemtime($compile_path)) { @@ -1452,23 +1419,21 @@ class Smarty } $_source_content = $_params['source_content']; - $_resource_timestamp = $_params['resource_timestamp']; $_cache_include = substr($compile_path, 0, -4).'.inc'; if ($this->_compile_source($resource_name, $_source_content, $_compiled_content, $_cache_include)) { // if a _cache_serial was set, we also have to write an include-file: if ($this->_cache_include_info) { - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_compiled_include.php'); - smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content)), $this); + require_once(SMARTY_CORE_DIR . 'core.write_compiled_include.php'); + smarty_core_write_compiled_include(array_merge($this->_cache_include_info, array('compiled_content'=>$_compiled_content, 'resource_name'=>$resource_name)), $this); } - $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content, 'resource_timestamp' => $_resource_timestamp); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_compiled_resource.php'); + $_params = array('compile_path'=>$compile_path, 'compiled_content' => $_compiled_content); + require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php'); smarty_core_write_compiled_resource($_params, $this); return true; } else { - $this->trigger_error($smarty_compiler->_error_msg); return false; } @@ -1508,6 +1473,7 @@ class Smarty $smarty_compiler->secure_dir = $this->secure_dir; $smarty_compiler->security_settings = $this->security_settings; $smarty_compiler->trusted_dir = $this->trusted_dir; + $smarty_compiler->use_sub_dirs = $this->use_sub_dirs; $smarty_compiler->_reg_objects = &$this->_reg_objects; $smarty_compiler->_plugins = &$this->_plugins; $smarty_compiler->_tpl_vars = &$this->_tpl_vars; @@ -1516,7 +1482,9 @@ class Smarty $smarty_compiler->_config = $this->_config; $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; - $smarty_compiler->_cache_serial = null; + if (isset($cache_include_path) && isset($this->_cache_serials[$cache_include_path])) { + $smarty_compiler->_cache_serial = $this->_cache_serials[$cache_include_path]; + } $smarty_compiler->_cache_include = $cache_include_path; @@ -1571,6 +1539,8 @@ class Smarty $_params = array('resource_name' => $params['resource_name']) ; if (isset($params['resource_base_path'])) $_params['resource_base_path'] = $params['resource_base_path']; + else + $_params['resource_base_path'] = $this->template_dir; if ($this->_parse_resource_name($_params)) { $_resource_type = $_params['resource_type']; @@ -1621,7 +1591,7 @@ class Smarty $this->trigger_error('unable to read resource: "' . $params['resource_name'] . '"'); } } else if ($_return && $this->security) { - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.is_secure.php'); + require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); if (!smarty_core_is_secure($_params, $this)) { if (!$params['quiet']) $this->trigger_error('(secure mode) accessing "' . $params['resource_name'] . '" is not allowed'); @@ -1666,16 +1636,10 @@ class Smarty } if ($params['resource_type'] == 'file') { - if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/", $params['resource_name'])) { + if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $params['resource_name'])) { // relative pathname to $params['resource_base_path'] // use the first directory where the file is found - if (isset($params['resource_base_path'])) { - $_resource_base_path = (array)$params['resource_base_path']; - } else { - $_resource_base_path = (array)$this->template_dir; - $_resource_base_path[] = '.'; - } - foreach ($_resource_base_path as $_curr_path) { + foreach ((array)$params['resource_base_path'] as $_curr_path) { $_fullpath = $_curr_path . DIRECTORY_SEPARATOR . $params['resource_name']; if (file_exists($_fullpath) && is_file($_fullpath)) { $params['resource_name'] = $_fullpath; @@ -1683,17 +1647,20 @@ class Smarty } // didn't find the file, try include_path $_params = array('file_path' => $_fullpath); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php'); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); if(smarty_core_get_include_path($_params, $this)) { $params['resource_name'] = $_params['new_file_path']; return true; } } return false; + } else { + /* absolute path */ + return file_exists($params['resource_name']); } } elseif (empty($this->_plugins['resource'][$params['resource_type']])) { $_params = array('type' => $params['resource_type']); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_resource_plugin.php'); + require_once(SMARTY_CORE_DIR . 'core.load_resource_plugin.php'); smarty_core_load_resource_plugin($_params, $this); } @@ -1731,8 +1698,8 @@ class Smarty */ function _dequote($string) { - if (($string{0} == "'" || $string{0} == '"') && - $string{strlen($string)-1} == $string{0}) + if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') && + substr($string, -1) == substr($string, 0, 1)) return substr($string, 1, -1); else return $string; @@ -1740,47 +1707,23 @@ class Smarty /** - * read in a file from line $start for $lines. - * read the entire file if $start and $lines are null. + * read in a file * * @param string $filename - * @param integer $start - * @param integer $lines * @return string */ - function _read_file($filename, $start=null, $lines=null) + function _read_file($filename) { - if (!($fd = @fopen($filename, 'r'))) { - return false; - } - flock($fd, LOCK_SH); - if ($start == null && $lines == null) { - // read the entire file - $contents = fread($fd, filesize($filename)); - } else { - if ( $start > 1 ) { - // skip the first lines before $start - for ($loop=1; $loop < $start; $loop++) { - fgets($fd, 65536); - } - } - if ( $lines == null ) { - // read the rest of the file - while (!feof($fd)) { - $contents .= fgets($fd, 65536); - } - } else { - // read up to $lines lines - for ($loop=0; $loop < $lines; $loop++) { - $contents .= fgets($fd, 65536); - if (feof($fd)) { - break; - } - } + if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) { + $contents = ''; + while (!feof($fd)) { + $contents .= fread($fd, 8192); } + fclose($fd); + return $contents; + } else { + return false; } - fclose($fd); - return $contents; } /** @@ -1796,16 +1739,7 @@ class Smarty function _get_auto_filename($auto_base, $auto_source = null, $auto_id = null) { $_compile_dir_sep = $this->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; - - if(@is_dir($auto_base)) { - $_return = $auto_base . DIRECTORY_SEPARATOR; - } else { - // auto_base not found, try include_path - $_params = array('file_path' => $auto_base); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php'); - smarty_core_get_include_path($_params, $this); - $_return = isset($_params['new_file_path']) ? $_params['new_file_path'] . DIRECTORY_SEPARATOR : null; - } + $_return = $auto_base . DIRECTORY_SEPARATOR; if(isset($auto_id)) { // make auto_id safe for directory names @@ -1817,11 +1751,12 @@ class Smarty if(isset($auto_source)) { // make source name safe for filename $_filename = urlencode(basename($auto_source)); - $_crc32 = crc32($auto_source) . $_compile_dir_sep; + $_crc32 = sprintf('%08X', crc32($auto_source)); // prepend %% to avoid name conflicts with // with $params['auto_id'] names - $_crc32 = '%%' . substr($_crc32,0,3) . $_compile_dir_sep . '%%' . $_crc32; - $_return .= $_crc32 . $_filename; + $_crc32 = substr($_crc32, 0, 2) . $_compile_dir_sep . + substr($_crc32, 0, 3) . $_compile_dir_sep . $_crc32; + $_return .= '%%' . $_crc32 . '%%' . $_filename; } return $_return; @@ -1876,13 +1811,12 @@ class Smarty if(isset($file) && isset($line)) { $info = ' ('.basename($file).", line $line)"; } else { - $info = null; + $info = ''; } if (isset($tpl_line) && isset($tpl_file)) { - trigger_error("Smarty error: [in " . $tpl_file . " line " . - $tpl_line . "]: $error_msg$info", $error_type); + $this->trigger_error('[in ' . $tpl_file . ' line ' . $tpl_line . "]: $error_msg$info", $error_type); } else { - trigger_error("Smarty error: $error_msg$info", $error_type); + $this->trigger_error($error_msg . $info, $error_type); } } @@ -1914,7 +1848,7 @@ class Smarty { if ($this->debugging) { $_params = array(); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $debug_start_time = smarty_core_get_microtime($_params, $this); $this->_smarty_debug_info[] = array('type' => 'template', 'filename' => $params['smarty_include_tpl_file'], @@ -1945,7 +1879,7 @@ class Smarty if ($this->debugging) { // capture time for debugging info $_params = array(); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $this->_smarty_debug_info[$included_tpls_idx]['exec_time'] = smarty_core_get_microtime($_params, $this) - $debug_start_time; } @@ -1965,7 +1899,7 @@ class Smarty if ($this->_cache_including) { /* return next set of cache_attrs */ - $_return =& current($_cache_attrs); + $_return = current($_cache_attrs); next($_cache_attrs); return $_return; diff --git a/smarty/Smarty_Compiler.class.php b/smarty/Smarty_Compiler.class.php index e7ee4a8..cbcbddb 100644 --- a/smarty/Smarty_Compiler.class.php +++ b/smarty/Smarty_Compiler.class.php @@ -18,28 +18,15 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * You may contact the authors of Smarty by e-mail at: - * monte@ispi.net - * andrei@php.net - * - * Or, write to: - * Monte Ohrt - * Director of Technology, ispi - * 237 S. 70th suite 220 - * Lincoln, NE 68510 - * - * The latest version of Smarty can be obtained from: - * http://smarty.php.net/ - * * @link http://smarty.php.net/ - * @author Monte Ohrt + * @author Monte Ohrt * @author Andrei Zmievski - * @version 2.6.0 - * @copyright 2001-2003 ispi of Lincoln, Inc. + * @version 2.6.14 + * @copyright 2001-2005 New Digital Group, Inc. * @package Smarty */ -/* $Id: Smarty_Compiler.class.php,v 1.1.1.1 2004/01/13 16:02:46 gohr Exp $ */ +/* $Id: Smarty_Compiler.class.php,v 1.381 2006/05/25 14:46:18 boots Exp $ */ /** * Template compiling class @@ -51,10 +38,7 @@ class Smarty_Compiler extends Smarty { /**#@+ * @access private */ - var $_sectionelse_stack = array(); // keeps track of whether section had 'else' part - var $_foreachelse_stack = array(); // keeps track of whether foreach had 'else' part - var $_literal_blocks = array(); // keeps literal template blocks - var $_php_blocks = array(); // keeps php code blocks + var $_folded_blocks = array(); // keeps folded template blocks var $_current_file = null; // the current template being compiled var $_current_line_no = 1; // line number for error messages var $_capture_stack = array(); // keeps track of nested capture buffers @@ -65,7 +49,9 @@ class Smarty_Compiler extends Smarty { var $_si_qstr_regexp = null; var $_qstr_regexp = null; var $_func_regexp = null; + var $_reg_obj_regexp = null; var $_var_bracket_regexp = null; + var $_num_const_regexp = null; var $_dvar_guts_regexp = null; var $_dvar_regexp = null; var $_cvar_regexp = null; @@ -113,6 +99,12 @@ class Smarty_Compiler extends Smarty { // [$bar] $this->_var_bracket_regexp = '\[\$?[\w\.]+\]'; + // matches numerical constants + // 30 + // -12 + // 13.22 + $this->_num_const_regexp = '(?:\-?\d+(?:\.\d+)?)'; + // matches $ vars (not objects): // $foo // $foo.bar @@ -121,11 +113,10 @@ class Smarty_Compiler extends Smarty { // $foo[$bar] // $foo[5][blah] // $foo[5].bar[$foobar][4] - $this->_dvar_math_regexp = '[\+\-\*\/\%]'; + $this->_dvar_math_regexp = '(?:[\+\*\/\%]|(?:-(?!>)))'; $this->_dvar_math_var_regexp = '[\$\w\.\+\-\*\/\%\d\>\[\]]'; - $this->_dvar_num_var_regexp = '\-?\d+(?:\.\d+)?' . $this->_dvar_math_var_regexp; $this->_dvar_guts_regexp = '\w+(?:' . $this->_var_bracket_regexp - . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:\-?\d+(?:\.\d+)?|' . $this->_dvar_math_var_regexp . ')*)?'; + . ')*(?:\.\$?\w+(?:' . $this->_var_bracket_regexp . ')*)*(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?'; $this->_dvar_regexp = '\$' . $this->_dvar_guts_regexp; // matches config vars: @@ -150,7 +141,7 @@ class Smarty_Compiler extends Smarty { // "text" $this->_var_regexp = '(?:' . $this->_avar_regexp . '|' . $this->_qstr_regexp . ')'; - // matches valid object call (no objects allowed in parameters): + // matches valid object call (one level of object nesting allowed in parameters): // $foo->bar // $foo->bar() // $foo->bar("text") @@ -158,13 +149,20 @@ class Smarty_Compiler extends Smarty { // $foo->bar($foo, "foo") // $foo->bar->foo() // $foo->bar->foo->bar() + // $foo->bar($foo->bar) + // $foo->bar($foo->bar()) + // $foo->bar($foo->bar($blah,$foo,44,"foo",$foo[0].bar)) $this->_obj_ext_regexp = '\->(?:\$?' . $this->_dvar_guts_regexp . ')'; - $this->_obj_params_regexp = '\((?:\w+|' - . $this->_var_regexp . '(?:\s*,\s*(?:(?:\w+|' - . $this->_var_regexp . ')))*)?\)'; + $this->_obj_restricted_param_regexp = '(?:' + . '(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')(?:' . $this->_obj_ext_regexp . '(?:\((?:(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . ')' + . '(?:\s*,\s*(?:' . $this->_var_regexp . '|' . $this->_num_const_regexp . '))*)?\))?)*)'; + $this->_obj_single_param_regexp = '(?:\w+|' . $this->_obj_restricted_param_regexp . '(?:\s*,\s*(?:(?:\w+|' + . $this->_var_regexp . $this->_obj_restricted_param_regexp . ')))*)'; + $this->_obj_params_regexp = '\((?:' . $this->_obj_single_param_regexp + . '(?:\s*,\s*' . $this->_obj_single_param_regexp . ')*)?\)'; $this->_obj_start_regexp = '(?:' . $this->_dvar_regexp . '(?:' . $this->_obj_ext_regexp . ')+)'; - $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?)'; - + $this->_obj_call_regexp = '(?:' . $this->_obj_start_regexp . '(?:' . $this->_obj_params_regexp . ')?(?:' . $this->_dvar_math_regexp . '(?:' . $this->_num_const_regexp . '|' . $this->_dvar_math_var_regexp . ')*)?)'; + // matches valid modifier syntax: // |foo // |@foo @@ -173,7 +171,7 @@ class Smarty_Compiler extends Smarty { // |foo:"bar":$foobar // |foo|bar // |foo:$foo->bar - $this->_mod_regexp = '(?:\|@?\w+(?::(?>-?\w+|' + $this->_mod_regexp = '(?:\|@?\w+(?::(?:\w+|' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_avar_regexp . '|' . $this->_qstr_regexp .'))*)'; // matches valid function name: @@ -195,7 +193,7 @@ class Smarty_Compiler extends Smarty { // "text"|bar // $foo->bar $this->_param_regexp = '(?:\s*(?:' . $this->_obj_call_regexp . '|' - . $this->_var_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; + . $this->_var_regexp . '|' . $this->_num_const_regexp . '|\w+)(?>' . $this->_mod_regexp . '*)\s*)'; // matches valid parenthesised function parameters: // @@ -239,8 +237,11 @@ class Smarty_Compiler extends Smarty { $this->_current_file = $resource_name; $this->_current_line_no = 1; - $ldq = preg_quote($this->left_delimiter, '!'); - $rdq = preg_quote($this->right_delimiter, '!'); + $ldq = preg_quote($this->left_delimiter, '~'); + $rdq = preg_quote($this->right_delimiter, '~'); + + /* un-hide hidden xml open tags */ + $source_content = preg_replace("~<({$ldq}(.*?){$rdq})[?]~s", '< \\1', $source_content); // run template source through prefilter functions if (count($this->_plugins['prefilter']) > 0) { @@ -256,33 +257,31 @@ class Smarty_Compiler extends Smarty { } } - /* Annihilate the comments. */ - $source_content = preg_replace("!({$ldq})\*(.*?)\*({$rdq})!se", - "'\\1*'.str_repeat(\"\n\", substr_count('\\2', \"\n\")) .'*\\3'", - $source_content); + /* fetch all special blocks */ + $search = "~{$ldq}\*(.*?)\*{$rdq}|{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}|{$ldq}\s*php\s*{$rdq}(.*?){$ldq}\s*/php\s*{$rdq}~s"; - /* Pull out the literal blocks. */ - preg_match_all("!{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}!s", $source_content, $_match); - $this->_literal_blocks = $_match[1]; - $source_content = preg_replace("!{$ldq}\s*literal\s*{$rdq}(.*?){$ldq}\s*/literal\s*{$rdq}!s", - $this->_quote_replace($this->left_delimiter.'literal'.$this->right_delimiter), $source_content); + preg_match_all($search, $source_content, $match, PREG_SET_ORDER); + $this->_folded_blocks = $match; + reset($this->_folded_blocks); - /* Pull out the php code blocks. */ - preg_match_all("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", $source_content, $_match); - $this->_php_blocks = $_match[1]; - $source_content = preg_replace("!{$ldq}php{$rdq}(.*?){$ldq}/php{$rdq}!s", - $this->_quote_replace($this->left_delimiter.'php'.$this->right_delimiter), $source_content); + /* replace special blocks by "{php}" */ + $source_content = preg_replace($search.'e', "'" + . $this->_quote_replace($this->left_delimiter) . 'php' + . "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'" + . $this->_quote_replace($this->right_delimiter) + . "'" + , $source_content); /* Gather all template tags. */ - preg_match_all("!{$ldq}\s*(.*?)\s*{$rdq}!s", $source_content, $_match); + preg_match_all("~{$ldq}\s*(.*?)\s*{$rdq}~s", $source_content, $_match); $template_tags = $_match[1]; /* Split content by template tags to obtain non-template content. */ - $text_blocks = preg_split("!{$ldq}.*?{$rdq}!s", $source_content); + $text_blocks = preg_split("~{$ldq}.*?{$rdq}~s", $source_content); /* loop through text blocks */ for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { /* match anything resembling php tags */ - if (preg_match_all('!(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?php[\"\']?)!is', $text_blocks[$curr_tb], $sp_match)) { + if (preg_match_all('~(<\?(?:\w+|=)?|\?>|language\s*=\s*[\"\']?php[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) { /* replace tags with placeholders to prevent recursive replacements */ $sp_match[1] = array_unique($sp_match[1]); usort($sp_match[1], '_smarty_sort_length'); @@ -302,7 +301,7 @@ class Smarty_Compiler extends Smarty { $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '', $text_blocks[$curr_tb]); } else { /* SMARTY_PHP_ALLOW, but echo non php starting tags */ - $sp_match[1][$curr_sp] = preg_replace('%(<\?(?!php|=|$))%i', ''."\n", $sp_match[1][$curr_sp]); + $sp_match[1][$curr_sp] = preg_replace('~(<\?(?!php|=|$))~i', ''."\n", $sp_match[1][$curr_sp]); $text_blocks[$curr_tb] = str_replace('%%%SMARTYSP'.$curr_sp.'%%%', $sp_match[1][$curr_sp], $text_blocks[$curr_tb]); } } @@ -316,32 +315,56 @@ class Smarty_Compiler extends Smarty { $compiled_tags[] = $this->_compile_tag($template_tags[$i]); $this->_current_line_no += substr_count($template_tags[$i], "\n"); } + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = end($this->_tag_stack); + $this->_syntax_error("unclosed tag \{$_open_tag} (opened line $_line_no).", E_USER_ERROR, __FILE__, __LINE__); + return; + } + /* Reformat $text_blocks between 'strip' and '/strip' tags, + removing spaces, tabs and newlines. */ + $strip = false; + for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { + if ($compiled_tags[$i] == '{strip}') { + $compiled_tags[$i] = ''; + $strip = true; + /* remove leading whitespaces */ + $text_blocks[$i + 1] = ltrim($text_blocks[$i + 1]); + } + if ($strip) { + /* strip all $text_blocks before the next '/strip' */ + for ($j = $i + 1; $j < $for_max; $j++) { + /* remove leading and trailing whitespaces of each line */ + $text_blocks[$j] = preg_replace('![\t ]*[\r\n]+[\t ]*!', '', $text_blocks[$j]); + if ($compiled_tags[$j] == '{/strip}') { + /* remove trailing whitespaces from the last text_block */ + $text_blocks[$j] = rtrim($text_blocks[$j]); + } + $text_blocks[$j] = ""\'", "\\"=>"\\\\")) . "'; ?>"; + if ($compiled_tags[$j] == '{/strip}') { + $compiled_tags[$j] = "\n"; /* slurped by php, but necessary + if a newline is following the closing strip-tag */ + $strip = false; + $i = $j; + break; + } + } + } + } $compiled_content = ''; /* Interleave the compiled contents and text blocks to get the final result. */ for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { if ($compiled_tags[$i] == '') { // tag result empty, remove first newline from following text block - $text_blocks[$i+1] = preg_replace('!^(\r\n|\r|\n)!', '', $text_blocks[$i+1]); + $text_blocks[$i+1] = preg_replace('~^(\r\n|\r|\n)~', '', $text_blocks[$i+1]); } $compiled_content .= $text_blocks[$i].$compiled_tags[$i]; } $compiled_content .= $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_content, $_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, $for_max = count($strip_tags); $i < $for_max; $i++) - $compiled_content = preg_replace("!{$ldq}strip{$rdq}.*?{$ldq}/strip{$rdq}!s", - $this->_quote_replace($strip_tags_modified[$i]), - $compiled_content, 1); - } - // remove \n from the end of the file, if any - if (($_len=strlen($compiled_content)) && ($compiled_content{$_len - 1} == "\n" )) { + if (strlen($compiled_content) && (substr($compiled_content, -1) == "\n") ) { $compiled_content = substr($compiled_content, 0, -1); } @@ -350,7 +373,7 @@ class Smarty_Compiler extends Smarty { } // remove unnecessary close/open tags - $compiled_content = preg_replace('!\?>\n?<\?php!', '', $compiled_content); + $compiled_content = preg_replace('~\?>\n?<\?php~', '', $compiled_content); // run compiled template through postfilter functions if (count($this->_plugins['postfilter']) > 0) { @@ -376,24 +399,23 @@ class Smarty_Compiler extends Smarty { $_plugins_params = "array('plugins' => array("; foreach ($this->_plugin_info as $plugin_type => $plugins) { foreach ($plugins as $plugin_name => $plugin_info) { - $_plugins_params .= "array('$plugin_type', '$plugin_name', '$plugin_info[0]', $plugin_info[1], "; + $_plugins_params .= "array('$plugin_type', '$plugin_name', '" . strtr($plugin_info[0], array("'" => "\\'", "\\" => "\\\\")) . "', $plugin_info[1], "; $_plugins_params .= $plugin_info[2] ? 'true),' : 'false),'; } } $_plugins_params .= '))'; - $plugins_code = "\n"; + $plugins_code = "\n"; $template_header .= $plugins_code; $this->_plugin_info = array(); $this->_plugins_code = $plugins_code; } if ($this->_init_smarty_vars) { - $template_header .= "\n"; + $template_header .= "\n"; $this->_init_smarty_vars = false; } $compiled_content = $template_header . $compiled_content; - return true; } @@ -406,33 +428,29 @@ class Smarty_Compiler extends Smarty { function _compile_tag($template_tag) { /* Matched comment. */ - if ($template_tag{0} == '*' && $template_tag{strlen($template_tag) - 1} == '*') + if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*') return ''; - + /* Split tag into two three parts: command, command modifiers and the arguments. */ - if(! preg_match('/^(?:(' . $this->_obj_call_regexp . '|' . $this->_var_regexp + if(! preg_match('~^(?:(' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '|\/?' . $this->_reg_obj_regexp . '|\/?' . $this->_func_regexp . ')(' . $this->_mod_regexp . '*)) (?:\s+(.*))?$ - /xs', $template_tag, $match)) { + ~xs', $template_tag, $match)) { $this->_syntax_error("unrecognized tag: $template_tag", E_USER_ERROR, __FILE__, __LINE__); } - + $tag_command = $match[1]; $tag_modifier = isset($match[2]) ? $match[2] : null; $tag_args = isset($match[3]) ? $match[3] : null; - if (preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$!', $tag_command)) { + if (preg_match('~^' . $this->_num_const_regexp . '|' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '$~', $tag_command)) { /* tag name is a variable or object */ - $_return = $this->_parse_var_props($tag_command . $tag_modifier, $this->_parse_attrs($tag_args)); - if(isset($_tag_attrs['assign'])) { - return "assign('" . $this->_dequote($_tag_attrs['assign']) . "', $_return ); ?>\n"; - } else { - return "" . $this->_additional_newline; - } + $_return = $this->_parse_var_props($tag_command . $tag_modifier); + return "" . $this->_additional_newline; } /* If the tag name is a registered object, we process it. */ - if (preg_match('!^\/?' . $this->_reg_obj_regexp . '$!', $tag_command)) { + if (preg_match('~^\/?' . $this->_reg_obj_regexp . '$~', $tag_command)) { return $this->_compile_registered_object_tag($tag_command, $this->_parse_attrs($tag_args), $tag_modifier); } @@ -444,15 +462,27 @@ class Smarty_Compiler extends Smarty { return $this->_compile_include_php_tag($tag_args); case 'if': + $this->_push_tag('if'); return $this->_compile_if_tag($tag_args); case 'else': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {else}', E_USER_ERROR, __FILE__, __LINE__); + else + $this->_push_tag('else'); return ''; case 'elseif': + list($_open_tag) = end($this->_tag_stack); + if ($_open_tag != 'if' && $_open_tag != 'elseif') + $this->_syntax_error('unexpected {elseif}', E_USER_ERROR, __FILE__, __LINE__); + if ($_open_tag == 'if') + $this->_push_tag('elseif'); return $this->_compile_if_tag($tag_args, true); case '/if': + $this->_pop_tag('if'); return ''; case 'capture': @@ -468,62 +498,76 @@ class Smarty_Compiler extends Smarty { return $this->right_delimiter; case 'section': - array_push($this->_sectionelse_stack, false); + $this->_push_tag('section'); return $this->_compile_section_start($tag_args); case 'sectionelse': - $this->_sectionelse_stack[count($this->_sectionelse_stack)-1] = true; + $this->_push_tag('sectionelse'); return ""; + break; case '/section': - if (array_pop($this->_sectionelse_stack)) + $_open_tag = $this->_pop_tag('section'); + if ($_open_tag == 'sectionelse') return ""; else return ""; case 'foreach': - array_push($this->_foreachelse_stack, false); + $this->_push_tag('foreach'); return $this->_compile_foreach_start($tag_args); break; case 'foreachelse': - $this->_foreachelse_stack[count($this->_foreachelse_stack)-1] = true; - return ""; + $this->_push_tag('foreachelse'); + return ""; case '/foreach': - if (array_pop($this->_foreachelse_stack)) - return ""; + $_open_tag = $this->_pop_tag('foreach'); + if ($_open_tag == 'foreachelse') + return ""; else - return ""; + return ""; + break; case 'strip': case '/strip': - if ($tag_command{0}=='/') { + if (substr($tag_command, 0, 1)=='/') { + $this->_pop_tag('strip'); if (--$this->_strip_depth==0) { /* outermost closing {/strip} */ $this->_additional_newline = "\n"; - return $this->left_delimiter.$tag_command.$this->right_delimiter; + return '{' . $tag_command . '}'; } } else { + $this->_push_tag('strip'); if ($this->_strip_depth++==0) { /* outermost opening {strip} */ $this->_additional_newline = ""; - return $this->left_delimiter.$tag_command.$this->right_delimiter; + return '{' . $tag_command . '}'; } } return ''; - case 'literal': - list (,$literal_block) = each($this->_literal_blocks); - $this->_current_line_no += substr_count($literal_block, "\n"); - return "" . $this->_additional_newline; - case 'php': - if ($this->security && !$this->security_settings['PHP_TAGS']) { - $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__); - return; + /* handle folded tags replaced by {php} */ + list(, $block) = each($this->_folded_blocks); + $this->_current_line_no += substr_count($block[0], "\n"); + /* the number of matched elements in the regexp in _compile_file() + determins the type of folded tag that was found */ + switch (count($block)) { + case 2: /* comment */ + return ''; + + case 3: /* literal */ + return ""\'", "\\"=>"\\\\")) . "'; ?>" . $this->_additional_newline; + + case 4: /* php */ + if ($this->security && !$this->security_settings['PHP_TAGS']) { + $this->_syntax_error("(secure mode) php tags not permitted", E_USER_WARNING, __FILE__, __LINE__); + return; + } + return ''; } - list (,$php_block) = each($this->_php_blocks); - $this->_current_line_no += substr_count($php_block, "\n"); - return ''; + break; case 'insert': return $this->_compile_insert_tag($tag_args); @@ -533,9 +577,12 @@ class Smarty_Compiler extends Smarty { return $output; } else if ($this->_compile_block_tag($tag_command, $tag_args, $tag_modifier, $output)) { return $output; + } else if ($this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier, $output)) { + return $output; } else { - return $this->_compile_custom_tag($tag_command, $tag_args, $tag_modifier); + $this->_syntax_error("unrecognized tag '$tag_command'", E_USER_ERROR, __FILE__, __LINE__); } + } } @@ -620,7 +667,7 @@ class Smarty_Compiler extends Smarty { */ function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output) { - if ($tag_command{0} == '/') { + if (substr($tag_command, 0, 1) == '/') { $start_tag = false; $tag_command = substr($tag_command, 1); } else @@ -674,20 +721,26 @@ class Smarty_Compiler extends Smarty { */ $this->_add_plugin('block', $tag_command); + if ($start_tag) + $this->_push_tag($tag_command); + else + $this->_pop_tag($tag_command); + if ($start_tag) { $output = '_push_cacheable_state('block', $tag_command); $attrs = $this->_parse_attrs($tag_args); - $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs=''); - $output .= "$_cache_attrs\$_params = \$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); '; - $output .= $this->_compile_plugin_call('block', $tag_command).'($_params[1], null, $this, $_block_repeat=true); unset($_params);'; + $_cache_attrs=''; + $arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs); + $output .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); '; + $output .= '$_block_repeat=true;' . $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat);'; $output .= 'while ($_block_repeat) { ob_start(); ?>'; } else { - $output = '_block_content = ob_get_contents(); ob_end_clean(); '; - $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $this->_block_content, $this, $_block_repeat=false)'; + $output = '_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)'; if ($tag_modifier != '') { $this->_parse_modifiers($_out_tag_text, $tag_modifier); } - $output .= 'echo '.$_out_tag_text.'; } '; + $output .= '$_block_repeat=false;echo ' . $_out_tag_text . '; } '; $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>'; } @@ -703,25 +756,69 @@ class Smarty_Compiler extends Smarty { * @param string $tag_modifier * @return string */ - function _compile_custom_tag($tag_command, $tag_args, $tag_modifier) + function _compile_custom_tag($tag_command, $tag_args, $tag_modifier, &$output) { + $found = false; + $have_function = true; + + /* + * First we check if the custom function has already been registered + * or loaded from a plugin file. + */ + if (isset($this->_plugins['function'][$tag_command])) { + $found = true; + $plugin_func = $this->_plugins['function'][$tag_command][0]; + if (!is_callable($plugin_func)) { + $message = "custom function '$tag_command' is not implemented"; + $have_function = false; + } + } + /* + * Otherwise we need to load plugin file and look for the function + * inside it. + */ + else if ($plugin_file = $this->_get_plugin_filepath('function', $tag_command)) { + $found = true; + + include_once $plugin_file; + + $plugin_func = 'smarty_function_' . $tag_command; + if (!function_exists($plugin_func)) { + $message = "plugin function $plugin_func() not found in $plugin_file\n"; + $have_function = false; + } else { + $this->_plugins['function'][$tag_command] = array($plugin_func, null, null, null, true); + + } + } + + if (!$found) { + return false; + } else if (!$have_function) { + $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); + return true; + } + + /* declare plugin to be loaded on display of the template that + we compile right now */ $this->_add_plugin('function', $tag_command); $_cacheable_state = $this->_push_cacheable_state('function', $tag_command); $attrs = $this->_parse_attrs($tag_args); - $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs=''); + $_cache_attrs = ''; + $arg_list = $this->_compile_arg_list('function', $tag_command, $attrs, $_cache_attrs); - $_return = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)"; + $output = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', $arg_list)."), \$this)"; if($tag_modifier != '') { - $this->_parse_modifiers($_return, $tag_modifier); + $this->_parse_modifiers($output, $tag_modifier); } - if($_return != '') { - $_return = '_pop_cacheable_state('function', $tag_command) . "?>" . $this->_additional_newline; } - return $_return; + return true; } /** @@ -734,7 +831,7 @@ class Smarty_Compiler extends Smarty { */ function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier) { - if ($tag_command{0} == '/') { + if (substr($tag_command, 0, 1) == '/') { $start_tag = false; $tag_command = substr($tag_command, 1); } else { @@ -773,22 +870,22 @@ class Smarty_Compiler extends Smarty { $postfix = ''; $newline = ''; if(!is_object($this->_reg_objects[$object][0])) { - $this->_trigger_fatal_error("registered '$object' is not an object"); + $this->_trigger_fatal_error("registered '$object' is not an object" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); } elseif(!empty($this->_reg_objects[$object][1]) && !in_array($obj_comp, $this->_reg_objects[$object][1])) { - $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'"); + $this->_trigger_fatal_error("'$obj_comp' is not a registered component of object '$object'", $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); } elseif(method_exists($this->_reg_objects[$object][0], $obj_comp)) { // method if(in_array($obj_comp, $this->_reg_objects[$object][3])) { // block method if ($start_tag) { $prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); "; - $prefix .= "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat=true); "; + $prefix .= "\$_block_repeat=true; \$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], null, \$this, \$_block_repeat); "; $prefix .= "while (\$_block_repeat) { ob_start();"; $return = null; $postfix = ''; - } else { - $prefix = "\$this->_obj_block_content = ob_get_contents(); ob_end_clean(); "; - $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$this->_obj_block_content, \$this, \$_block_repeat=false)"; + } else { + $prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); \$_block_repeat=false;"; + $return = "\$this->_reg_objects['$object'][0]->$obj_comp(\$this->_tag_stack[count(\$this->_tag_stack)-1][1], \$_obj_block_content, \$this, \$_block_repeat)"; $postfix = "} array_pop(\$this->_tag_stack);"; } } else { @@ -849,7 +946,7 @@ class Smarty_Compiler extends Smarty { $_params = "array('args' => array(".implode(', ', (array)$arg_list)."))"; - return "" . $this->_additional_newline; + return "" . $this->_additional_newline; } /** @@ -922,6 +1019,7 @@ class Smarty_Compiler extends Smarty { $assign_var = (empty($attrs['assign'])) ? '' : $this->_dequote($attrs['assign']); $once_var = (empty($attrs['once']) || $attrs['once']=='false') ? 'false' : 'true'; + $arg_list = array(); foreach($attrs as $arg_name => $arg_value) { if($arg_name != 'file' AND $arg_name != 'once' AND $arg_name != 'assign') { if(is_bool($arg_value)) @@ -930,9 +1028,9 @@ class Smarty_Compiler extends Smarty { } } - $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', (array)$arg_list)."))"; + $_params = "array('smarty_file' => " . $attrs['file'] . ", 'smarty_assign' => '$assign_var', 'smarty_once' => $once_var, 'smarty_include_vars' => array(".implode(',', $arg_list)."))"; - return "" . $this->_additional_newline; + return "" . $this->_additional_newline; } @@ -953,7 +1051,7 @@ class Smarty_Compiler extends Smarty { $this->_syntax_error("missing section name", E_USER_ERROR, __FILE__, __LINE__); } - $output .= "if (isset(\$this->_sections[$section_name])) unset(\$this->_sections[$section_name]);\n"; + $output .= "unset(\$this->_sections[$section_name]);\n"; $section_props = "\$this->_sections[$section_name]"; foreach ($attrs as $attr_name => $attr_value) { @@ -1053,50 +1151,45 @@ class Smarty_Compiler extends Smarty { $arg_list = array(); if (empty($attrs['from'])) { - $this->_syntax_error("missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); + return $this->_syntax_error("foreach: missing 'from' attribute", E_USER_ERROR, __FILE__, __LINE__); } + $from = $attrs['from']; if (empty($attrs['item'])) { - $this->_syntax_error("missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); + return $this->_syntax_error("foreach: missing 'item' attribute", E_USER_ERROR, __FILE__, __LINE__); } - - $from = $attrs['from']; $item = $this->_dequote($attrs['item']); - if (isset($attrs['name'])) - $name = $attrs['name']; - - $output = '_foreach[$name])) unset(\$this->_foreach[$name]);\n"; - $foreach_props = "\$this->_foreach[$name]"; + if (!preg_match('~^\w+$~', $item)) { + return $this->_syntax_error("'foreach: item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); } - $key_part = ''; - - foreach ($attrs as $attr_name => $attr_value) { - switch ($attr_name) { - case 'key': - $key = $this->_dequote($attrs['key']); - $key_part = "\$this->_tpl_vars['$key'] => "; - break; - - case 'name': - $output .= "{$foreach_props}['$attr_name'] = $attr_value;\n"; - break; + if (isset($attrs['key'])) { + $key = $this->_dequote($attrs['key']); + if (!preg_match('~^\w+$~', $key)) { + return $this->_syntax_error("foreach: 'key' must to be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); } + $key_part = "\$this->_tpl_vars['$key'] => "; + } else { + $key = null; + $key_part = ''; } + if (isset($attrs['name'])) { + $name = $attrs['name']; + } else { + $name = null; + } + + $output = ' 0;\n"; - $output .= "if ({$foreach_props}['show']):\n"; - $output .= "{$foreach_props}['iteration'] = 0;\n"; + $foreach_props = "\$this->_foreach[$name]"; + $output .= "{$foreach_props} = array('total' => count(\$_from), 'iteration' => 0);\n"; + $output .= "if ({$foreach_props}['total'] > 0):\n"; $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; $output .= " {$foreach_props}['iteration']++;\n"; - $output .= " {$foreach_props}['first'] = ({$foreach_props}['iteration'] == 1);\n"; - $output .= " {$foreach_props}['last'] = ({$foreach_props}['iteration'] == {$foreach_props}['total']);\n"; } else { - $output .= "if (count(\$_from = (array)$from)):\n"; + $output .= "if (count(\$_from)):\n"; $output .= " foreach (\$_from as $key_part\$this->_tpl_vars['$item']):\n"; } $output .= '?>'; @@ -1152,16 +1245,23 @@ class Smarty_Compiler extends Smarty { { /* Tokenize args for 'if' tag. */ - preg_match_all('/(?> + preg_match_all('~(?> ' . $this->_obj_call_regexp . '(?:' . $this->_mod_regexp . '*)? | # valid object call ' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)? | # var or quoted string \-?0[xX][0-9a-fA-F]+|\-?\d+(?:\.\d+)?|\.\d+|!==|===|==|!=|<>|<<|>>|<=|>=|\&\&|\|\||\(|\)|,|\!|\^|=|\&|\~|<|>|\||\%|\+|\-|\/|\*|\@ | # valid non-word token \b\w+\b | # valid word token \S+ # anything else - )/x', $tag_args, $match); + )~x', $tag_args, $match); $tokens = $match[0]; + if(empty($tokens)) { + $_error_msg = $elseif ? "'elseif'" : "'if'"; + $_error_msg .= ' statement requires arguments'; + $this->_syntax_error($_error_msg, E_USER_ERROR, __FILE__, __LINE__); + } + + // make sure we have balanced parenthesis $token_count = array_count_values($tokens); if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { @@ -1278,13 +1378,16 @@ class Smarty_Compiler extends Smarty { break; default: - if(preg_match('!^' . $this->_func_regexp . '$!', $token) ) { + if(preg_match('~^' . $this->_func_regexp . '$~', $token) ) { // function call if($this->security && !in_array($token, $this->security_settings['IF_FUNCS'])) { $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); } - } elseif(preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$!', $token)) { + } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { + // variable function call + $this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); + } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) { // object or variable $token = $this->_parse_var_props($token); } elseif(is_numeric($token)) { @@ -1356,21 +1459,21 @@ class Smarty_Compiler extends Smarty { switch ($expr_type) { case 'even': - if (@$tokens[$expr_end] == 'by') { + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { $expr_end++; $expr_arg = $tokens[$expr_end++]; - $expr = "!(($is_arg / $expr_arg) % " . $this->_parse_var_props($expr_arg) . ")"; + $expr = "!(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; } else - $expr = "!($is_arg % 2)"; + $expr = "!(1 & $is_arg)"; break; case 'odd': - if (@$tokens[$expr_end] == 'by') { + if (isset($tokens[$expr_end]) && $tokens[$expr_end] == 'by') { $expr_end++; $expr_arg = $tokens[$expr_end++]; - $expr = "(($is_arg / $expr_arg) % ". $this->_parse_var_props($expr_arg) . ")"; + $expr = "(1 & ($is_arg / " . $this->_parse_var_props($expr_arg) . "))"; } else - $expr = "($is_arg % 2)"; + $expr = "(1 & $is_arg)"; break; case 'div': @@ -1408,10 +1511,10 @@ class Smarty_Compiler extends Smarty { { /* Tokenize tag attributes. */ - preg_match_all('/(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+) + preg_match_all('~(?:' . $this->_obj_call_regexp . '|' . $this->_qstr_regexp . ' | (?>[^"\'=\s]+) )+ | [=] - /x', $tag_args, $match); + ~x', $tag_args, $match); $tokens = $match[0]; $attrs = array(); @@ -1426,7 +1529,7 @@ class Smarty_Compiler extends Smarty { case 0: /* If the token is a valid identifier, we set attribute name and go to state 1. */ - if (preg_match('!^\w+$!', $token)) { + if (preg_match('~^\w+$~', $token)) { $attr_name = $token; $state = 1; } else @@ -1447,15 +1550,15 @@ class Smarty_Compiler extends Smarty { if ($token != '=') { /* We booleanize the token if it's a non-quoted possible boolean value. */ - if (preg_match('!^(on|yes|true)$!', $token)) { + if (preg_match('~^(on|yes|true)$~', $token)) { $token = 'true'; - } else if (preg_match('!^(off|no|false)$!', $token)) { + } else if (preg_match('~^(off|no|false)$~', $token)) { $token = 'false'; } else if ($token == 'null') { $token = 'null'; - } else if (preg_match('!^-?([0-9]+|0[xX][0-9a-fA-F]+)$!', $token)) { + } else if (preg_match('~^' . $this->_num_const_regexp . '|0[xX][0-9a-fA-F]+$~', $token)) { /* treat integer literally */ - } else if (!preg_match('!^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$!', $token)) { + } else if (!preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . ')*$~', $token)) { /* treat as a string, double-quote it escaping quotes */ $token = '"'.addslashes($token).'"'; } @@ -1507,42 +1610,52 @@ class Smarty_Compiler extends Smarty { { $val = trim($val); - if(preg_match('!^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$!', $val, $match)) { - // $ variable or object - $return = $this->_parse_var($match[1]); - if($match[2] != '') { - $this->_parse_modifiers($return, $match[2]); - } - return $return; + if(preg_match('~^(' . $this->_obj_call_regexp . '|' . $this->_dvar_regexp . ')(' . $this->_mod_regexp . '*)$~', $val, $match)) { + // $ variable or object + $return = $this->_parse_var($match[1]); + $modifiers = $match[2]; + if (!empty($this->default_modifiers) && !preg_match('~(^|\|)smarty:nodefaults($|\|)~',$modifiers)) { + $_default_mod_string = implode('|',(array)$this->default_modifiers); + $modifiers = empty($modifiers) ? $_default_mod_string : $_default_mod_string . '|' . $modifiers; } - elseif(preg_match('!^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) { + $this->_parse_modifiers($return, $modifiers); + return $return; + } elseif (preg_match('~^' . $this->_db_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { // double quoted text - preg_match('!^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$!', $val, $match); + preg_match('~^(' . $this->_db_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); $return = $this->_expand_quoted_text($match[1]); if($match[2] != '') { $this->_parse_modifiers($return, $match[2]); } return $return; } - elseif(preg_match('!^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) { + elseif(preg_match('~^' . $this->_num_const_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { + // numerical constant + preg_match('~^(' . $this->_num_const_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); + if($match[2] != '') { + $this->_parse_modifiers($match[1], $match[2]); + return $match[1]; + } + } + elseif(preg_match('~^' . $this->_si_qstr_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { // single quoted text - preg_match('!^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$!', $val, $match); + preg_match('~^(' . $this->_si_qstr_regexp . ')('. $this->_mod_regexp . '*)$~', $val, $match); if($match[2] != '') { $this->_parse_modifiers($match[1], $match[2]); return $match[1]; } } - elseif(preg_match('!^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) { + elseif(preg_match('~^' . $this->_cvar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { // config var return $this->_parse_conf_var($val); } - elseif(preg_match('!^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$!', $val)) { + elseif(preg_match('~^' . $this->_svar_regexp . '(?:' . $this->_mod_regexp . '*)$~', $val)) { // section var return $this->_parse_section_prop($val); } elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) { // literal string - return $this->_expand_quoted_text('"' . $val .'"'); + return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"'); } return $val; } @@ -1556,19 +1669,19 @@ class Smarty_Compiler extends Smarty { function _expand_quoted_text($var_expr) { // if contains unescaped $, expand it - if(preg_match_all('%(?:\`(?_dvar_guts_regexp . '\`)|(?:(?_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?_parse_var(str_replace('`','',$_var)) . ')."', $var_expr); } - $_return = preg_replace('%\.""|(?_dvar_math_regexp.'|'.$this->_qstr_regexp.')!', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE); + $_math_vars = preg_split('~('.$this->_dvar_math_regexp.'|'.$this->_qstr_regexp.')~', $var_expr, -1, PREG_SPLIT_DELIM_CAPTURE); if(count($_math_vars) > 1) { $_first_var = ""; $_complete_var = ""; + $_output = ""; // simple check if there is any math, to stop recursion (due to modifiers with "xx % yy" as parameter) foreach($_math_vars as $_k => $_math_var) { $_math_var = $_math_vars[$_k]; if(!empty($_math_var) || is_numeric($_math_var)) { // hit a math operator, so process the stuff which came before it - if(preg_match('!^' . $this->_dvar_math_regexp . '$!', $_math_var)) { + if(preg_match('~^' . $this->_dvar_math_regexp . '$~', $_math_var)) { $_has_math = true; if(!empty($_complete_var) || is_numeric($_complete_var)) { $_output .= $this->_parse_var($_complete_var); @@ -1607,23 +1721,13 @@ class Smarty_Compiler extends Smarty { $_complete_var = ""; } else { - // fetch multiple -> (like $foo->bar->baz ) which wouldn't get fetched else, because it would only get $foo->bar and treat the ->baz as "-" ">baz" then - for($_i = $_k + 1; $_i <= count($_math_vars); $_i += 2) { - // fetch -> because it gets splitted at - and move it back together - if( /* prevent notice */ (isset($_math_vars[$_i]) && isset($_math_vars[$_i+1])) && ($_math_vars[$_i] === '-' && $_math_vars[$_i+1]{0} === '>')) { - $_math_var .= $_math_vars[$_i].$_math_vars[$_i+1]; - $_math_vars[$_i] = $_math_vars[$_i+1] = ''; - } else { - break; - } - } $_complete_var .= $_math_var; } } } if($_has_math) { if(!empty($_complete_var) || is_numeric($_complete_var)) - $_output .= $this->_parse_var($_complete_var, true); + $_output .= $this->_parse_var($_complete_var); // get the modifiers working (only the last var from math + modifier is left) $var_expr = $_complete_var; @@ -1631,15 +1735,16 @@ class Smarty_Compiler extends Smarty { } // prevent cutting of first digit in the number (we _definitly_ got a number if the first char is a digit) - if(is_numeric($var_expr{0})) + if(is_numeric(substr($var_expr, 0, 1))) $_var_ref = $var_expr; else $_var_ref = substr($var_expr, 1); - + if(!$_has_math) { + // get [foo] and .foo and ->foo and (...) pieces - preg_match_all('!(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+!', $_var_ref, $match); - + preg_match_all('~(?:^\w+)|' . $this->_obj_params_regexp . '|(?:' . $this->_var_bracket_regexp . ')|->\$?\w+|\.\$?\w+|\S+~', $_var_ref, $match); + $_indexes = $match[0]; $_var_name = array_shift($_indexes); @@ -1656,7 +1761,7 @@ class Smarty_Compiler extends Smarty { $_var_name = substr(array_shift($_indexes), 1); $_output = "\$this->_smarty_vars['$_var_name']"; } - } elseif(is_numeric($_var_name) && is_numeric($var_expr{0})) { + } elseif(is_numeric($_var_name) && is_numeric(substr($var_expr, 0, 1))) { // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers if(count($_indexes) > 0) { @@ -1669,11 +1774,11 @@ class Smarty_Compiler extends Smarty { } foreach ($_indexes as $_index) { - if ($_index{0} == '[') { + if (substr($_index, 0, 1) == '[') { $_index = substr($_index, 1, -1); if (is_numeric($_index)) { $_output .= "[$_index]"; - } elseif ($_index{0} == '$') { + } elseif (substr($_index, 0, 1) == '$') { if (strpos($_index, '.') !== false) { $_output .= '[' . $this->_parse_var($_index) . ']'; } else { @@ -1685,8 +1790,8 @@ class Smarty_Compiler extends Smarty { $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index'; $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]"; } - } else if ($_index{0} == '.') { - if ($_index{1} == '$') + } else if (substr($_index, 0, 1) == '.') { + if (substr($_index, 1, 1) == '$') $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]"; else $_output .= "['" . substr($_index, 1) . "']"; @@ -1695,7 +1800,7 @@ class Smarty_Compiler extends Smarty { $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__); } elseif($this->security && substr($_index, 2, 1) == '_') { $this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); - } elseif ($_index{2} == '$') { + } elseif (substr($_index, 2, 1) == '$') { if ($this->security) { $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); } else { @@ -1704,7 +1809,7 @@ class Smarty_Compiler extends Smarty { } else { $_output .= $_index; } - } elseif ($_index{0} == '(') { + } elseif (substr($_index, 0, 1) == '(') { $_index = $this->_parse_parenth_args($_index); $_output .= $_index; } else { @@ -1724,13 +1829,14 @@ class Smarty_Compiler extends Smarty { */ function _parse_parenth_args($parenth_args) { - preg_match_all('!' . $this->_param_regexp . '!',$parenth_args, $match); - $match = $match[0]; - rsort($match); - reset($match); - $orig_vals = $match; + preg_match_all('~' . $this->_param_regexp . '~',$parenth_args, $match); + $orig_vals = $match = $match[0]; $this->_parse_vars_props($match); - return str_replace($orig_vals, $match, $parenth_args); + $replace = array(); + for ($i = 0, $count = count($match); $i < $count; $i++) { + $replace[$orig_vals[$i]] = $match[$i]; + } + return strtr($parenth_args, $replace); } /** @@ -1786,7 +1892,7 @@ class Smarty_Compiler extends Smarty { */ function _parse_modifiers(&$output, $modifier_string) { - preg_match_all('!\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)!', '|' . $modifier_string, $_match); + preg_match_all('~\|(@?\w+)((?>:(?:'. $this->_qstr_regexp . '|[^|]+))*)~', '|' . $modifier_string, $_match); list(, $_modifiers, $modifier_arg_strings) = $_match; for ($_i = 0, $_for_max = count($_modifiers); $_i < $_for_max; $_i++) { @@ -1797,35 +1903,35 @@ class Smarty_Compiler extends Smarty { continue; } - preg_match_all('!:(' . $this->_qstr_regexp . '|[^:]+)!', $modifier_arg_strings[$_i], $_match); + preg_match_all('~:(' . $this->_qstr_regexp . '|[^:]+)~', $modifier_arg_strings[$_i], $_match); $_modifier_args = $_match[1]; - if ($_modifier_name{0} == '@') { + if (substr($_modifier_name, 0, 1) == '@') { $_map_array = false; $_modifier_name = substr($_modifier_name, 1); } else { $_map_array = true; } - $this->_add_plugin('modifier', $_modifier_name); if (empty($this->_plugins['modifier'][$_modifier_name]) && !$this->_get_plugin_filepath('modifier', $_modifier_name) && function_exists($_modifier_name)) { if ($this->security && !in_array($_modifier_name, $this->security_settings['MODIFIER_FUNCS'])) { - $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $_tpl_file, $_tpl_line, __FILE__, __LINE__); + $this->_trigger_fatal_error("[plugin] (secure mode) modifier '$_modifier_name' is not allowed" , $this->_current_file, $this->_current_line_no, __FILE__, __LINE__); } else { $this->_plugins['modifier'][$_modifier_name] = array($_modifier_name, null, null, false); } } + $this->_add_plugin('modifier', $_modifier_name); $this->_parse_vars_props($_modifier_args); if($_modifier_name == 'default') { // supress notifications of default modifier vars and args - if($output{0} == '$') { + if(substr($output, 0, 1) == '$') { $output = '@' . $output; } - if(isset($_modifier_args[0]) && $_modifier_args[0]{0} == '$') { + if(isset($_modifier_args[0]) && substr($_modifier_args[0], 0, 1) == '$') { $_modifier_args[0] = '@' . $_modifier_args[0]; } } @@ -1877,7 +1983,7 @@ class Smarty_Compiler extends Smarty { /* Extract the reference name. */ $_ref = substr($indexes[0], 1); foreach($indexes as $_index_no=>$_index) { - if ($_index{0} != '.' && $_index_no<2 || !preg_match('!^(\.|\[|->)!', $_index)) { + if (substr($_index, 0, 1) != '.' && $_index_no<2 || !preg_match('~^(\.|\[|->)~', $_index)) { $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__); } } @@ -1889,13 +1995,41 @@ class Smarty_Compiler extends Smarty { break; case 'foreach': + array_shift($indexes); + $_var = $this->_parse_var_props(substr($indexes[0], 1)); + $_propname = substr($indexes[1], 1); + $_max_index = 1; + switch ($_propname) { + case 'index': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration']-1)"; + break; + + case 'first': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] <= 1)"; + break; + + case 'last': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['iteration'] == \$this->_foreach[$_var]['total'])"; + break; + + case 'show': + array_shift($indexes); + $compiled_ref = "(\$this->_foreach[$_var]['total'] > 0)"; + break; + + default: + unset($_max_index); + $compiled_ref = "\$this->_foreach[$_var]"; + } + break; + case 'section': array_shift($indexes); $_var = $this->_parse_var_props(substr($indexes[0], 1)); - if ($_ref == 'foreach') - $compiled_ref = "\$this->_foreach[$_var]"; - else - $compiled_ref = "\$this->_sections[$_var]"; + $compiled_ref = "\$this->_sections[$_var]"; break; case 'get': @@ -1949,17 +2083,34 @@ class Smarty_Compiler extends Smarty { break; case 'const': + if ($this->security && !$this->security_settings['ALLOW_CONSTANTS']) { + $this->_syntax_error("(secure mode) constants not permitted", + E_USER_WARNING, __FILE__, __LINE__); + return; + } array_shift($indexes); - $_val = $this->_parse_var_props(substr($indexes[0],1)); - $compiled_ref = '@constant(' . $_val . ')'; + if (preg_match('!^\.\w+$!', $indexes[0])) { + $compiled_ref = '@' . substr($indexes[0], 1); + } else { + $_val = $this->_parse_var_props(substr($indexes[0], 1)); + $compiled_ref = '@constant(' . $_val . ')'; + } $_max_index = 1; break; case 'config': $compiled_ref = "\$this->_config[0]['vars']"; - $_max_index = 2; + $_max_index = 3; break; + case 'ldelim': + $compiled_ref = "'$this->left_delimiter'"; + break; + + case 'rdelim': + $compiled_ref = "'$this->right_delimiter'"; + break; + default: $this->_syntax_error('$smarty.' . $_ref . ' is an unknown reference', E_USER_ERROR, __FILE__, __LINE__); break; @@ -2014,7 +2165,7 @@ class Smarty_Compiler extends Smarty { if ($prefilter === false) { unset($this->_plugins['prefilter'][$filter_name]); $_params = array('plugins' => array(array('prefilter', $filter_name, null, null, false))); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php'); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); smarty_core_load_plugins($_params, $this); } } @@ -2024,7 +2175,7 @@ class Smarty_Compiler extends Smarty { if ($postfilter === false) { unset($this->_plugins['postfilter'][$filter_name]); $_params = array('plugins' => array(array('postfilter', $filter_name, null, null, false))); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.load_plugins.php'); + require_once(SMARTY_CORE_DIR . 'core.load_plugins.php'); smarty_core_load_plugins($_params, $this); } } @@ -2040,7 +2191,7 @@ class Smarty_Compiler extends Smarty { */ function _quote_replace($string) { - return preg_replace('![\\$]\d!', '\\\\\\0', $string); + return strtr($string, array('\\' => '\\\\', '$' => '\\$')); } /** @@ -2053,13 +2204,7 @@ class Smarty_Compiler extends Smarty { */ function _syntax_error($error_msg, $error_type = E_USER_ERROR, $file=null, $line=null) { - if(isset($file) && isset($line)) { - $info = ' ('.basename($file).", line $line)"; - } else { - $info = null; - } - trigger_error('Smarty: [in ' . $this->_current_file . ' line ' . - $this->_current_line_no . "]: syntax error: $error_msg$info", $error_type); + $this->_trigger_fatal_error("syntax error: $error_msg", $this->_current_file, $this->_current_line_no, $file, $line, $error_type); } @@ -2074,9 +2219,9 @@ class Smarty_Compiler extends Smarty { if ($_cacheable || 0<$this->_cacheable_state++) return ''; if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty')); - $_ret = 'if ($this->caching) { echo \'{nocache:' + $_ret = 'if ($this->caching && !$this->_cache_including) { echo \'{nocache:' . $this->_cache_serial . '#' . $this->_nocache_count - . '}\';}'; + . '}\'; };'; return $_ret; } @@ -2091,9 +2236,57 @@ class Smarty_Compiler extends Smarty { $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; if ($_cacheable || --$this->_cacheable_state>0) return ''; - return 'if ($this->caching) { echo \'{/nocache:' + return 'if ($this->caching && !$this->_cache_including) { echo \'{/nocache:' . $this->_cache_serial . '#' . ($this->_nocache_count++) - . '}\';}'; + . '}\'; };'; + } + + + /** + * push opening tag-name, file-name and line-number on the tag-stack + * @param string the opening tag's name + */ + function _push_tag($open_tag) + { + array_push($this->_tag_stack, array($open_tag, $this->_current_line_no)); + } + + /** + * pop closing tag-name + * raise an error if this stack-top doesn't match with the closing tag + * @param string the closing tag's name + * @return string the opening tag's name + */ + function _pop_tag($close_tag) + { + $message = ''; + if (count($this->_tag_stack)>0) { + list($_open_tag, $_line_no) = array_pop($this->_tag_stack); + if ($close_tag == $_open_tag) { + return $_open_tag; + } + if ($close_tag == 'if' && ($_open_tag == 'else' || $_open_tag == 'elseif' )) { + return $this->_pop_tag($close_tag); + } + if ($close_tag == 'section' && $_open_tag == 'sectionelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($close_tag == 'foreach' && $_open_tag == 'foreachelse') { + $this->_pop_tag($close_tag); + return $_open_tag; + } + if ($_open_tag == 'else' || $_open_tag == 'elseif') { + $_open_tag = 'if'; + } elseif ($_open_tag == 'sectionelse') { + $_open_tag = 'section'; + } elseif ($_open_tag == 'foreachelse') { + $_open_tag = 'foreach'; + } + $message = " expected {/$_open_tag} (opened line $_line_no)."; + } + $this->_syntax_error("mismatched tag {/$close_tag}.$message", + E_USER_ERROR, __FILE__, __LINE__); } } diff --git a/smarty/core/core.is_secure.php b/smarty/core/core.is_secure.php deleted file mode 100644 index 877886b..0000000 --- a/smarty/core/core.is_secure.php +++ /dev/null @@ -1,59 +0,0 @@ -security || $smarty->security_settings['INCLUDE_ANY']) { - return true; - } - - $_smarty_secure = false; - if ($params['resource_type'] == 'file') { - if($check_template_dir) { - if (!in_array($smarty->template_dir, $smarty->secure_dir)) - // add template_dir to secure_dir array - array_unshift($smarty->secure_dir, $smarty->template_dir); - $check_template_dir = false; - } - if (!empty($smarty->secure_dir)) { - $_rp = realpath($params['resource_name']); - foreach ((array)$smarty->secure_dir as $curr_dir) { - if ( !empty($curr_dir) && is_readable ($curr_dir)) { - $_cd = realpath($curr_dir); - if (strncmp($_rp, $_cd, strlen($_cd)) == 0 - && $_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) { - $_smarty_secure = true; - break; - } - } - } - } - } else { - // resource is not on local file system - $_smarty_secure = call_user_func_array( - $smarty->_plugins['resource'][$params['resource_type']][0][2], - array($params['resource_name'], &$_smarty_secure, &$smarty)); - } - - return $_smarty_secure; -} - -/* vim: set expandtab: */ - -?> diff --git a/smarty/core/core.write_compiled_include.php b/smarty/core/core.write_compiled_include.php deleted file mode 100644 index 9c6a491..0000000 --- a/smarty/core/core.write_compiled_include.php +++ /dev/null @@ -1,59 +0,0 @@ -caching\) \{ echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\';\}'; - $_tag_end = 'if \(\$this->caching\) \{ echo \'\{/nocache\:(\\2)#(\\3)\}\';\}'; - - preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us', - $params['compiled_content'], $_match_source, PREG_SET_ORDER); - - // no nocache-parts found: done - if (count($_match_source)==0) return; - - // convert the matched php-code to functions - $_include_compiled = "_cache_serials[$_compile_path] = $params['cache_serial']; - $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>"; - - $_include_compiled .= $params['plugins_code']; - $_include_compiled .= "\n"; - - $_params = array('filename' => $_compile_path, - 'contents' => $_include_compiled, 'create_dirs' => true); - - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_file.php'); - smarty_core_write_file($_params, $smarty); - return true; -} - - -?> diff --git a/smarty/debug.tpl b/smarty/debug.tpl index 01265fb..7f1c9d4 100644 --- a/smarty/debug.tpl +++ b/smarty/debug.tpl @@ -36,7 +36,7 @@ var title = 'Console_' + self.name; {rdelim} _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes"); - _smarty_console.document.write("Smarty Debug Console_"+self.name+""); + _smarty_console.document.write("Smarty Debug Console_"+self.name+""); _smarty_console.document.write(""); _smarty_console.document.write(""); _smarty_console.document.write(""); diff --git a/smarty/core/core.assemble_plugin_filepath.php b/smarty/internals/core.assemble_plugin_filepath.php similarity index 81% rename from smarty/core/core.assemble_plugin_filepath.php rename to smarty/internals/core.assemble_plugin_filepath.php index ec44f8e..690d3dd 100644 --- a/smarty/core/core.assemble_plugin_filepath.php +++ b/smarty/internals/core.assemble_plugin_filepath.php @@ -14,8 +14,12 @@ */ function smarty_core_assemble_plugin_filepath($params, &$smarty) { + static $_filepaths_cache = array(); $_plugin_filename = $params['type'] . '.' . $params['name'] . '.php'; + if (isset($_filepaths_cache[$_plugin_filename])) { + return $_filepaths_cache[$_plugin_filename]; + } $_return = false; foreach ((array)$smarty->plugins_dir as $_plugin_dir) { @@ -46,14 +50,15 @@ function smarty_core_assemble_plugin_filepath($params, &$smarty) $_plugin_filepath = $_plugin_dir . DIRECTORY_SEPARATOR . $_plugin_filename; $_params = array('file_path' => $_plugin_filepath); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php'); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); if(smarty_core_get_include_path($_params, $smarty)) { - return $_params['new_file_path']; + $_return = $_params['new_file_path']; + break; } } } } - + $_filepaths_cache[$_plugin_filename] = $_return; return $_return; } diff --git a/smarty/core/core.assign_smarty_interface.php b/smarty/internals/core.assign_smarty_interface.php similarity index 100% rename from smarty/core/core.assign_smarty_interface.php rename to smarty/internals/core.assign_smarty_interface.php diff --git a/smarty/core/core.create_dir_structure.php b/smarty/internals/core.create_dir_structure.php similarity index 97% rename from smarty/core/core.create_dir_structure.php rename to smarty/internals/core.create_dir_structure.php index 999cf59..3eecc49 100644 --- a/smarty/core/core.create_dir_structure.php +++ b/smarty/internals/core.create_dir_structure.php @@ -22,7 +22,7 @@ function smarty_core_create_dir_structure($params, &$smarty) /* unix-style paths */ $_dir = $params['dir']; $_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY); - $_new_dir = ($_dir{0}=='/') ? '/' : getcwd().'/'; + $_new_dir = (substr($_dir, 0, 1)=='/') ? '/' : getcwd().'/'; if($_use_open_basedir = !empty($_open_basedir_ini)) { $_open_basedirs = explode(':', $_open_basedir_ini); } diff --git a/smarty/core/core.display_debug_console.php b/smarty/internals/core.display_debug_console.php similarity index 91% rename from smarty/core/core.display_debug_console.php rename to smarty/internals/core.display_debug_console.php index c509ff7..1a80f39 100644 --- a/smarty/core/core.display_debug_console.php +++ b/smarty/internals/core.display_debug_console.php @@ -23,8 +23,9 @@ function smarty_core_display_debug_console($params, &$smarty) // set path to debug template from SMARTY_DIR $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl'; if($smarty->security && is_file($smarty->debug_tpl)) { - $smarty->secure_dir[] = dirname(realpath($smarty->debug_tpl)); + $smarty->secure_dir[] = realpath($smarty->debug_tpl); } + $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl'; } $_ldelim_orig = $smarty->left_delimiter; diff --git a/smarty/core/core.get_include_path.php b/smarty/internals/core.get_include_path.php similarity index 91% rename from smarty/core/core.get_include_path.php rename to smarty/internals/core.get_include_path.php index eb7188c..4343241 100644 --- a/smarty/core/core.get_include_path.php +++ b/smarty/internals/core.get_include_path.php @@ -31,7 +31,7 @@ function smarty_core_get_include_path(&$params, &$smarty) } } foreach ($_path_array as $_include_path) { - if (file_exists($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) { + if (@is_readable($_include_path . DIRECTORY_SEPARATOR . $params['file_path'])) { $params['new_file_path'] = $_include_path . DIRECTORY_SEPARATOR . $params['file_path']; return true; } diff --git a/smarty/core/core.get_microtime.php b/smarty/internals/core.get_microtime.php similarity index 100% rename from smarty/core/core.get_microtime.php rename to smarty/internals/core.get_microtime.php diff --git a/smarty/core/core.get_php_resource.php b/smarty/internals/core.get_php_resource.php similarity index 92% rename from smarty/core/core.get_php_resource.php rename to smarty/internals/core.get_php_resource.php index 8121acf..786d4e7 100644 --- a/smarty/core/core.get_php_resource.php +++ b/smarty/internals/core.get_php_resource.php @@ -32,7 +32,7 @@ function smarty_core_get_php_resource(&$params, &$smarty) } else { // test for file in include_path $_params = array('file_path' => $params['resource_name']); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php'); + require_once(SMARTY_CORE_DIR . 'core.get_include_path.php'); if(smarty_core_get_include_path($_params, $smarty)) { $_include_path = $_params['new_file_path']; $_readable = true; @@ -56,7 +56,7 @@ function smarty_core_get_php_resource(&$params, &$smarty) if ($_readable) { if ($smarty->security) { - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.is_trusted.php'); + require_once(SMARTY_CORE_DIR . 'core.is_trusted.php'); if (!smarty_core_is_trusted($params, $smarty)) { $smarty->$_error_funcc('(secure mode) ' . $params['resource_type'] . ':' . $params['resource_name'] . ' is not trusted'); return false; diff --git a/smarty/internals/core.is_secure.php b/smarty/internals/core.is_secure.php new file mode 100644 index 0000000..d54abd4 --- /dev/null +++ b/smarty/internals/core.is_secure.php @@ -0,0 +1,59 @@ +security || $smarty->security_settings['INCLUDE_ANY']) { + return true; + } + + if ($params['resource_type'] == 'file') { + $_rp = realpath($params['resource_name']); + if (isset($params['resource_base_path'])) { + foreach ((array)$params['resource_base_path'] as $curr_dir) { + if ( ($_cd = realpath($curr_dir)) !== false && + strncmp($_rp, $_cd, strlen($_cd)) == 0 && + substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { + return true; + } + } + } + if (!empty($smarty->secure_dir)) { + foreach ((array)$smarty->secure_dir as $curr_dir) { + if ( ($_cd = realpath($curr_dir)) !== false) { + if($_cd == $_rp) { + return true; + } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 && + substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) { + return true; + } + } + } + } + } else { + // resource is not on local file system + return call_user_func_array( + $smarty->_plugins['resource'][$params['resource_type']][0][2], + array($params['resource_name'], &$smarty)); + } + + return false; +} + +/* vim: set expandtab: */ + +?> diff --git a/smarty/core/core.is_trusted.php b/smarty/internals/core.is_trusted.php similarity index 92% rename from smarty/core/core.is_trusted.php rename to smarty/internals/core.is_trusted.php index c90e3ef..4299731 100644 --- a/smarty/core/core.is_trusted.php +++ b/smarty/internals/core.is_trusted.php @@ -5,9 +5,6 @@ * @subpackage plugins */ -/**#@+ - * @access private - */ /** * determines if a resource is trusted or not * @@ -28,7 +25,7 @@ function smarty_core_is_trusted($params, &$smarty) if (!empty($curr_dir) && is_readable ($curr_dir)) { $_cd = realpath($curr_dir); if (strncmp($_rp, $_cd, strlen($_cd)) == 0 - && $_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) { + && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) { $_smarty_trusted = true; break; } diff --git a/smarty/core/core.load_plugins.php b/smarty/internals/core.load_plugins.php similarity index 100% rename from smarty/core/core.load_plugins.php rename to smarty/internals/core.load_plugins.php diff --git a/smarty/core/core.load_resource_plugin.php b/smarty/internals/core.load_resource_plugin.php similarity index 100% rename from smarty/core/core.load_resource_plugin.php rename to smarty/internals/core.load_resource_plugin.php diff --git a/smarty/core/core.process_cached_inserts.php b/smarty/internals/core.process_cached_inserts.php similarity index 84% rename from smarty/core/core.process_cached_inserts.php rename to smarty/internals/core.process_cached_inserts.php index 0e368fd..1d78edd 100644 --- a/smarty/core/core.process_cached_inserts.php +++ b/smarty/internals/core.process_cached_inserts.php @@ -20,7 +20,7 @@ function smarty_core_process_cached_inserts($params, &$smarty) for ($i = 0, $for_max = count($cached_inserts); $i < $for_max; $i++) { if ($smarty->debugging) { $_params = array(); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $debug_start_time = smarty_core_get_microtime($_params, $smarty); } @@ -29,7 +29,7 @@ function smarty_core_process_cached_inserts($params, &$smarty) if (isset($args['script'])) { $_params = array('resource_name' => $smarty->_dequote($args['script'])); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_php_resource.php'); + require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); if(!smarty_core_get_php_resource($_params, $smarty)) { return false; } @@ -52,10 +52,10 @@ function smarty_core_process_cached_inserts($params, &$smarty) $replace = ''; } - $params['results'] = str_replace($cached_inserts[$i], $replace, $params['results']); + $params['results'] = substr_replace($params['results'], $replace, strpos($params['results'], $cached_inserts[$i]), strlen($cached_inserts[$i])); if ($smarty->debugging) { $_params = array(); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $smarty->_smarty_debug_info[] = array('type' => 'insert', 'filename' => 'insert_'.$name, 'depth' => $smarty->_inclusion_depth, diff --git a/smarty/core/core.process_compiled_include.php b/smarty/internals/core.process_compiled_include.php similarity index 84% rename from smarty/core/core.process_compiled_include.php rename to smarty/internals/core.process_compiled_include.php index 3e1d4c1..d539423 100644 --- a/smarty/core/core.process_compiled_include.php +++ b/smarty/internals/core.process_compiled_include.php @@ -20,6 +20,11 @@ function smarty_core_process_compiled_include($params, &$smarty) $smarty->_cache_including = true; $_return = $params['results']; + + foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { + $smarty->_include($_include_file_path, true); + } + foreach ($smarty->_cache_serials as $_include_file_path=>$_cache_serial) { $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s', array(&$smarty, '_process_compiled_include_callback'), diff --git a/smarty/core/core.read_cache_file.php b/smarty/internals/core.read_cache_file.php similarity index 85% rename from smarty/core/core.read_cache_file.php rename to smarty/internals/core.read_cache_file.php index 2ab4281..c60e113 100644 --- a/smarty/core/core.read_cache_file.php +++ b/smarty/internals/core.read_cache_file.php @@ -48,10 +48,11 @@ function smarty_core_read_cache_file(&$params, &$smarty) return false; } - $cache_split = explode("\n", $params['results'], 2); - $cache_header = $cache_split[0]; - - $_cache_info = unserialize($cache_header); + $_contents = $params['results']; + $_info_start = strpos($_contents, "\n") + 1; + $_info_len = (int)substr($_contents, 0, $_info_start - 1); + $_cache_info = unserialize(substr($_contents, $_info_start, $_info_len)); + $params['results'] = substr($_contents, $_info_start + $_info_len); if ($smarty->caching == 2 && isset ($_cache_info['expires'])){ // caching by expiration time @@ -89,17 +90,6 @@ function smarty_core_read_cache_file(&$params, &$smarty) } } - foreach ($_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) { - if (empty($smarty->_cache_serials[$_include_file_path])) { - $smarty->_include($_include_file_path, true); - } - - if ($smarty->_cache_serials[$_include_file_path] != $_cache_serial) { - /* regenerate */ - return false; - } - } - $params['results'] = $cache_split[1]; $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info); $smarty->_cache_info = $_cache_info; diff --git a/smarty/core/core.rm_auto.php b/smarty/internals/core.rm_auto.php similarity index 92% rename from smarty/core/core.rm_auto.php rename to smarty/internals/core.rm_auto.php index b7cdaf8..b251f64 100644 --- a/smarty/core/core.rm_auto.php +++ b/smarty/internals/core.rm_auto.php @@ -28,7 +28,7 @@ function smarty_core_rm_auto($params, &$smarty) 'level' => 0, 'exp_time' => $params['exp_time'] ); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rmdir.php'); + require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); $_res = smarty_core_rmdir($_params, $smarty); } else { $_tname = $smarty->_get_auto_filename($params['auto_base'], $params['auto_source'], $params['auto_id']); @@ -47,7 +47,7 @@ function smarty_core_rm_auto($params, &$smarty) 'level' => 1, 'exp_time' => $params['exp_time'] ); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rmdir.php'); + require_once(SMARTY_CORE_DIR . 'core.rmdir.php'); $_res = smarty_core_rmdir($_params, $smarty); } else { // remove matching file names diff --git a/smarty/core/core.rmdir.php b/smarty/internals/core.rmdir.php similarity index 93% rename from smarty/core/core.rmdir.php rename to smarty/internals/core.rmdir.php index 38df822..2166c44 100644 --- a/smarty/core/core.rmdir.php +++ b/smarty/internals/core.rmdir.php @@ -32,7 +32,6 @@ function smarty_core_rmdir($params, &$smarty) 'level' => $params['level'] + 1, 'exp_time' => $params['exp_time'] ); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.rmdir.php'); smarty_core_rmdir($_params, $smarty); } else { diff --git a/smarty/core/core.run_insert_handler.php b/smarty/internals/core.run_insert_handler.php similarity index 89% rename from smarty/core/core.run_insert_handler.php rename to smarty/internals/core.run_insert_handler.php index aa391ab..71c3845 100644 --- a/smarty/core/core.run_insert_handler.php +++ b/smarty/internals/core.run_insert_handler.php @@ -14,7 +14,7 @@ function smarty_core_run_insert_handler($params, &$smarty) { - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); if ($smarty->debugging) { $_params = array(); $_debug_start_time = smarty_core_get_microtime($_params, $smarty); @@ -34,7 +34,7 @@ function smarty_core_run_insert_handler($params, &$smarty) } else { if (isset($params['args']['script'])) { $_params = array('resource_name' => $smarty->_dequote($params['args']['script'])); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_php_resource.php'); + require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); if(!smarty_core_get_php_resource($_params, $smarty)) { return false; } @@ -51,7 +51,7 @@ function smarty_core_run_insert_handler($params, &$smarty) $_content = $_funcname($params['args'], $smarty); if ($smarty->debugging) { $_params = array(); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php'); + require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); $smarty->_smarty_debug_info[] = array('type' => 'insert', 'filename' => 'insert_'.$params['args']['name'], 'depth' => $smarty->_inclusion_depth, diff --git a/smarty/core/core.smarty_include_php.php b/smarty/internals/core.smarty_include_php.php similarity index 94% rename from smarty/core/core.smarty_include_php.php rename to smarty/internals/core.smarty_include_php.php index 4b31648..30c6e76 100644 --- a/smarty/core/core.smarty_include_php.php +++ b/smarty/internals/core.smarty_include_php.php @@ -21,7 +21,7 @@ function smarty_core_smarty_include_php($params, &$smarty) { $_params = array('resource_name' => $params['smarty_file']); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_php_resource.php'); + require_once(SMARTY_CORE_DIR . 'core.get_php_resource.php'); smarty_core_get_php_resource($_params, $smarty); $_smarty_resource_type = $_params['resource_type']; $_smarty_php_resource = $_params['php_resource']; diff --git a/smarty/core/core.write_cache_file.php b/smarty/internals/core.write_cache_file.php similarity index 60% rename from smarty/core/core.write_cache_file.php rename to smarty/internals/core.write_cache_file.php index 7429ad9..72f785b 100644 --- a/smarty/core/core.write_cache_file.php +++ b/smarty/internals/core.write_cache_file.php @@ -31,16 +31,39 @@ function smarty_core_write_cache_file($params, &$smarty) $smarty->_cache_info['expires'] = -1; } - // collapse {nocache...}-tags - $params['results'] = preg_replace('!((\{nocache\:([0-9a-f]{32})#(\d+)\})' - .'.*' - .'{/nocache\:\\3#\\4\})!Us' - ,'\\2' - ,$params['results']); + // collapse nocache.../nocache-tags + if (preg_match_all('!\{(/?)nocache\:[0-9a-f]{32}#\d+\}!', $params['results'], $match, PREG_PATTERN_ORDER)) { + // remove everything between every pair of outermost noache.../nocache-tags + // and replace it by a single nocache-tag + // this new nocache-tag will be replaced by dynamic contents in + // smarty_core_process_compiled_includes() on a cache-read + + $match_count = count($match[0]); + $results = preg_split('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!', $params['results'], -1, PREG_SPLIT_DELIM_CAPTURE); + + $level = 0; + $j = 0; + for ($i=0, $results_count = count($results); $i < $results_count && $j < $match_count; $i++) { + if ($results[$i] == $match[0][$j]) { + // nocache tag + if ($match[1][$j]) { // closing tag + $level--; + unset($results[$i]); + } else { // opening tag + if ($level++ > 0) unset($results[$i]); + } + $j++; + } elseif ($level > 0) { + unset($results[$i]); + } + } + $params['results'] = implode('', $results); + } $smarty->_cache_info['cache_serials'] = $smarty->_cache_serials; // prepend the cache header info into cache file - $params['results'] = serialize($smarty->_cache_info)."\n".$params['results']; + $_cache_info = serialize($smarty->_cache_info); + $params['results'] = strlen($_cache_info) . "\n" . $_cache_info . $params['results']; if (!empty($smarty->cache_handler_func)) { // use cache_handler function @@ -62,7 +85,7 @@ function smarty_core_write_cache_file($params, &$smarty) $_auto_id = $smarty->_get_auto_id($params['cache_id'], $params['compile_id']); $_cache_file = $smarty->_get_auto_filename($smarty->cache_dir, $params['tpl_file'], $_auto_id); $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_file.php'); + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); smarty_core_write_file($_params, $smarty); return true; } diff --git a/smarty/internals/core.write_compiled_include.php b/smarty/internals/core.write_compiled_include.php new file mode 100644 index 0000000..3a78094 --- /dev/null +++ b/smarty/internals/core.write_compiled_include.php @@ -0,0 +1,91 @@ +caching && \!\$this->_cache_including\) \{ echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; \};'; + $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\) \{ echo \'\{/nocache\:(\\2)#(\\3)\}\'; \};'; + + preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us', + $params['compiled_content'], $_match_source, PREG_SET_ORDER); + + // no nocache-parts found: done + if (count($_match_source)==0) return; + + // convert the matched php-code to functions + $_include_compiled = "_version.", created on ".strftime("%Y-%m-%d %H:%M:%S")."\n"; + $_include_compiled .= " compiled from " . strtr(urlencode($params['resource_name']), array('%2F'=>'/', '%3A'=>':')) . " */\n\n"; + + $_compile_path = $params['include_file_path']; + + $smarty->_cache_serials[$_compile_path] = $params['cache_serial']; + $_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$params['cache_serial']."';\n\n?>"; + + $_include_compiled .= $params['plugins_code']; + $_include_compiled .= "= 5.0) ? '_smarty' : 'this'; + for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) { + $_match =& $_match_source[$_i]; + $source = $_match[4]; + if ($this_varname == '_smarty') { + /* rename $this to $_smarty in the sourcecode */ + $tokens = token_get_all('\n"; + + $_params = array('filename' => $_compile_path, + 'contents' => $_include_compiled, 'create_dirs' => true); + + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); + smarty_core_write_file($_params, $smarty); + return true; +} + + +?> diff --git a/smarty/core/core.write_compiled_resource.php b/smarty/internals/core.write_compiled_resource.php similarity index 84% rename from smarty/core/core.write_compiled_resource.php rename to smarty/internals/core.write_compiled_resource.php index 09b50d3..b902eff 100644 --- a/smarty/core/core.write_compiled_resource.php +++ b/smarty/internals/core.write_compiled_resource.php @@ -10,7 +10,6 @@ * * @param string $compile_path * @param string $compiled_content - * @param integer $resource_timestamp * @return true */ function smarty_core_write_compiled_resource($params, &$smarty) @@ -26,9 +25,8 @@ function smarty_core_write_compiled_resource($params, &$smarty) } $_params = array('filename' => $params['compile_path'], 'contents' => $params['compiled_content'], 'create_dirs' => true); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_file.php'); + require_once(SMARTY_CORE_DIR . 'core.write_file.php'); smarty_core_write_file($_params, $smarty); - touch($params['compile_path'], $params['resource_timestamp']); return true; } diff --git a/smarty/core/core.write_file.php b/smarty/internals/core.write_file.php similarity index 58% rename from smarty/core/core.write_file.php rename to smarty/internals/core.write_file.php index c92454d..09e1698 100644 --- a/smarty/core/core.write_file.php +++ b/smarty/internals/core.write_file.php @@ -19,22 +19,28 @@ function smarty_core_write_file($params, &$smarty) if ($params['create_dirs']) { $_params = array('dir' => $_dirname); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.create_dir_structure.php'); + require_once(SMARTY_CORE_DIR . 'core.create_dir_structure.php'); smarty_core_create_dir_structure($_params, $smarty); } // write to tmp file, then rename it to avoid // file locking race condition - $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid(''); - - if (!($fd = @fopen($_tmp_file, 'w'))) { - $smarty->trigger_error("problem writing temporary file '$_tmp_file'"); - return false; + $_tmp_file = tempnam($_dirname, 'wrt'); + + if (!($fd = @fopen($_tmp_file, 'wb'))) { + $_tmp_file = $_dirname . DIRECTORY_SEPARATOR . uniqid('wrt'); + if (!($fd = @fopen($_tmp_file, 'wb'))) { + $smarty->trigger_error("problem writing temporary file '$_tmp_file'"); + return false; + } } fwrite($fd, $params['contents']); fclose($fd); - if(file_exists($params['filename'])) { + + // Delete the file if it allready exists (this is needed on Win, + // because it cannot overwrite files with rename() + if (file_exists($params['filename'])) { @unlink($params['filename']); } @rename($_tmp_file, $params['filename']); diff --git a/smarty/plugins/block.textformat.php b/smarty/plugins/block.textformat.php index 7ddccc7..8cd010a 100644 --- a/smarty/plugins/block.textformat.php +++ b/smarty/plugins/block.textformat.php @@ -23,59 +23,79 @@ * indent_char: string (" ") * wrap_boundary: boolean (true) * + * @author Monte Ohrt * @param string contents of the block * @param Smarty clever simulation of a method * @return string string $content re-formatted */ function smarty_block_textformat($params, $content, &$smarty) { - $style = null; - $indent = 0; - $indent_first = 0; - $indent_char = ' '; - $wrap = 80; - $wrap_char = "\n"; - $wrap_cut = false; - $assign = null; - - if($content == null) { - return true; - } + if (is_null($content)) { + return; + } - extract($params); + $style = null; + $indent = 0; + $indent_first = 0; + $indent_char = ' '; + $wrap = 80; + $wrap_char = "\n"; + $wrap_cut = false; + $assign = null; + + foreach ($params as $_key => $_val) { + switch ($_key) { + case 'style': + case 'indent_char': + case 'wrap_char': + case 'assign': + $$_key = (string)$_val; + break; - if($style == 'email') { - $wrap = 72; - } - - // split into paragraphs - $paragraphs = preg_split('![\r\n][\r\n]!',$content); - $output = ''; + case 'indent': + case 'indent_first': + case 'wrap': + $$_key = (int)$_val; + break; + + case 'wrap_cut': + $$_key = (bool)$_val; + break; + + default: + $smarty->trigger_error("textformat: unknown attribute '$_key'"); + } + } + + if ($style == 'email') { + $wrap = 72; + } + + // split into paragraphs + $_paragraphs = preg_split('![\r\n][\r\n]!',$content); + $_output = ''; + + for($_x = 0, $_y = count($_paragraphs); $_x < $_y; $_x++) { + if ($_paragraphs[$_x] == '') { + continue; + } + // convert mult. spaces & special chars to single space + $_paragraphs[$_x] = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'), array(' ',''), $_paragraphs[$_x]); + // indent first line + if($indent_first > 0) { + $_paragraphs[$_x] = str_repeat($indent_char, $indent_first) . $_paragraphs[$_x]; + } + // wordwrap sentences + $_paragraphs[$_x] = wordwrap($_paragraphs[$_x], $wrap - $indent, $wrap_char, $wrap_cut); + // indent lines + if($indent > 0) { + $_paragraphs[$_x] = preg_replace('!^!m', str_repeat($indent_char, $indent), $_paragraphs[$_x]); + } + } + $_output = implode($wrap_char . $wrap_char, $_paragraphs); + + return $assign ? $smarty->assign($assign, $_output) : $_output; - foreach($paragraphs as $paragraph) { - if($paragraph == '') { - continue; - } - // convert mult. spaces & special chars to single space - $paragraph = preg_replace(array('!\s+!','!(^\s+)|(\s+$)!'),array(' ',''),$paragraph); - // indent first line - if($indent_first > 0) { - $paragraph = str_repeat($indent_char,$indent_first) . $paragraph; - } - // wordwrap sentences - $paragraph = wordwrap($paragraph, $wrap - $indent, $wrap_char, $wrap_cut); - // indent lines - if($indent > 0) { - $paragraph = preg_replace('!^!m',str_repeat($indent_char,$indent),$paragraph); - } - $output .= $paragraph . $wrap_char . $wrap_char; - } - - if($assign != null) { - $smarty->assign($assign,$output); - } else { - return $output; - } } /* vim: set expandtab: */ diff --git a/smarty/plugins/compiler.assign.php b/smarty/plugins/compiler.assign.php new file mode 100644 index 0000000..be17298 --- /dev/null +++ b/smarty/plugins/compiler.assign.php @@ -0,0 +1,40 @@ + + * Name: assign
+ * Purpose: assign a value to a template variable + * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign} + * (Smarty online manual) + * @author Monte Ohrt (initial author) + * @auther messju mohr (conversion to compiler function) + * @param string containing var-attribute and value-attribute + * @param Smarty_Compiler + */ +function smarty_compiler_assign($tag_attrs, &$compiler) +{ + $_params = $compiler->_parse_attrs($tag_attrs); + + if (!isset($_params['var'])) { + $compiler->_syntax_error("assign: missing 'var' parameter", E_USER_WARNING); + return; + } + + if (!isset($_params['value'])) { + $compiler->_syntax_error("assign: missing 'value' parameter", E_USER_WARNING); + return; + } + + return "\$this->assign({$_params['var']}, {$_params['value']});"; +} + +/* vim: set expandtab: */ + +?> diff --git a/smarty/plugins/function.assign_debug_info.php b/smarty/plugins/function.assign_debug_info.php index c281ce8..6540498 100644 --- a/smarty/plugins/function.assign_debug_info.php +++ b/smarty/plugins/function.assign_debug_info.php @@ -11,6 +11,7 @@ * Type: function
* Name: assign_debug_info
* Purpose: assign debug info to the template
+ * @author Monte Ohrt * @param array unused in this plugin, this plugin uses {@link Smarty::$_config}, * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info} * @param Smarty @@ -24,7 +25,7 @@ function smarty_function_assign_debug_info($params, &$smarty) ksort($config_vars); $smarty->assign("_debug_config_keys", array_keys($config_vars)); $smarty->assign("_debug_config_vals", array_values($config_vars)); - } + } $included_templates = $smarty->_smarty_debug_info; diff --git a/smarty/plugins/function.config_load.php b/smarty/plugins/function.config_load.php index 12b7462..db89f63 100644 --- a/smarty/plugins/function.config_load.php +++ b/smarty/plugins/function.config_load.php @@ -13,6 +13,8 @@ * Purpose: load config file vars * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load} * (Smarty online manual) + * @author Monte Ohrt + * @author messju mohr (added use of resources) * @param array Format: *
  * array('file' => required config file name,
@@ -25,77 +27,87 @@
 function smarty_function_config_load($params, &$smarty)
 {
         if ($smarty->debugging) {
-			$_params = array();
-            require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
             $_debug_start_time = smarty_core_get_microtime($_params, $smarty);
         }
 
-		$_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
-		$_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
-		$_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
-		$_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
+        $_file = isset($params['file']) ? $smarty->_dequote($params['file']) : null;
+        $_section = isset($params['section']) ? $smarty->_dequote($params['section']) : null;
+        $_scope = isset($params['scope']) ? $smarty->_dequote($params['scope']) : 'global';
+        $_global = isset($params['global']) ? $smarty->_dequote($params['global']) : false;
 
         if (!isset($_file) || strlen($_file) == 0) {
-            $smarty->_syntax_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
+            $smarty->trigger_error("missing 'file' attribute in config_load tag", E_USER_ERROR, __FILE__, __LINE__);
         }
 
         if (isset($_scope)) {
             if ($_scope != 'local' &&
                 $_scope != 'parent' &&
                 $_scope != 'global') {
-                $smarty->_syntax_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
+                $smarty->trigger_error("invalid 'scope' attribute value", E_USER_ERROR, __FILE__, __LINE__);
             }
         } else {
             if ($_global) {
                 $_scope = 'parent';
-			} else {
+            } else {
                 $_scope = 'local';
-			}
-        }		
-			
-        if(@is_dir($smarty->config_dir)) {
-            $_config_dir = $smarty->config_dir;            
-        } else {
-            // config_dir not found, try include_path
-			$_params = array('file_path' => $smarty->config_dir);
-			require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_include_path.php');
-            smarty_core_get_include_path($_params, $smarty);
-			$_config_dir = $_params['new_file_path'];
+            }
         }
 
-		$_file_path = $_config_dir . DIRECTORY_SEPARATOR . $_file;
-        if (isset($_section)) 
+        $_params = array('resource_name' => $_file,
+                         'resource_base_path' => $smarty->config_dir,
+                         'get_source' => false);
+        $smarty->_parse_resource_name($_params);
+        $_file_path = $_params['resource_type'] . ':' . $_params['resource_name'];
+        if (isset($_section))
             $_compile_file = $smarty->_get_compile_path($_file_path.'|'.$_section);
         else
             $_compile_file = $smarty->_get_compile_path($_file_path);
-		
-		if($smarty->force_compile
-				|| !file_exists($_compile_file)
-				|| ($smarty->compile_check
-					&& !$smarty->_is_compiled($_file_path, $_compile_file))) {
-			// compile config file
-        	if(!is_object($smarty->_conf_obj)) {
-            	require_once SMARTY_DIR . $smarty->config_class . '.class.php';
-            	$smarty->_conf_obj = new $smarty->config_class($_config_dir);
-            	$smarty->_conf_obj->overwrite = $smarty->config_overwrite;
-            	$smarty->_conf_obj->booleanize = $smarty->config_booleanize;
-            	$smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
-            	$smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
-            	$smarty->_conf_obj->set_path = $_config_dir;
-        	}
-        	$_config_vars = array_merge($smarty->_conf_obj->get($_file),
-                	$smarty->_conf_obj->get($_file, $_section));
-			if(function_exists('var_export')) {
-				$_output = '';
-			} else {
-				$_output = ''\\\'', '\\'=>'\\\\')) . '\'); ?>';
-			}
-			$_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => filemtime($_file_path)));
-			require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.write_compiled_resource.php');
-			smarty_core_write_compiled_resource($_params, $smarty);
-		} else {
+
+        if($smarty->force_compile || !file_exists($_compile_file)) {
+            $_compile = true;
+        } elseif ($smarty->compile_check) {
+            $_params = array('resource_name' => $_file,
+                             'resource_base_path' => $smarty->config_dir,
+                             'get_source' => false);
+            $_compile = $smarty->_fetch_resource_info($_params) &&
+                $_params['resource_timestamp'] > filemtime($_compile_file);
+        } else {
+            $_compile = false;
+        }
+
+        if($_compile) {
+            // compile config file
+            if(!is_object($smarty->_conf_obj)) {
+                require_once SMARTY_DIR . $smarty->config_class . '.class.php';
+                $smarty->_conf_obj = new $smarty->config_class();
+                $smarty->_conf_obj->overwrite = $smarty->config_overwrite;
+                $smarty->_conf_obj->booleanize = $smarty->config_booleanize;
+                $smarty->_conf_obj->read_hidden = $smarty->config_read_hidden;
+                $smarty->_conf_obj->fix_newlines = $smarty->config_fix_newlines;
+            }
+
+            $_params = array('resource_name' => $_file,
+                             'resource_base_path' => $smarty->config_dir,
+                             $_params['get_source'] = true);
+            if (!$smarty->_fetch_resource_info($_params)) {
+                return;
+            }
+            $smarty->_conf_obj->set_file_contents($_file, $_params['source_content']);
+            $_config_vars = array_merge($smarty->_conf_obj->get($_file),
+                    $smarty->_conf_obj->get($_file, $_section));
+            if(function_exists('var_export')) {
+                $_output = '';
+            } else {
+                $_output = ''\\\'', '\\'=>'\\\\')) . '\'); ?>';
+            }
+            $_params = (array('compile_path' => $_compile_file, 'compiled_content' => $_output, 'resource_timestamp' => $_params['resource_timestamp']));
+            require_once(SMARTY_CORE_DIR . 'core.write_compiled_resource.php');
+            smarty_core_write_compiled_resource($_params, $smarty);
+        } else {
             include($_compile_file);
-		}
+        }
 
         if ($smarty->caching) {
             $smarty->_cache_info['config'][$_file] = true;
@@ -103,26 +115,26 @@ function smarty_function_config_load($params, &$smarty)
 
         $smarty->_config[0]['vars'] = @array_merge($smarty->_config[0]['vars'], $_config_vars);
         $smarty->_config[0]['files'][$_file] = true;
-        
+
         if ($_scope == 'parent') {
                 $smarty->_config[1]['vars'] = @array_merge($smarty->_config[1]['vars'], $_config_vars);
                 $smarty->_config[1]['files'][$_file] = true;
         } else if ($_scope == 'global') {
             for ($i = 1, $for_max = count($smarty->_config); $i < $for_max; $i++) {
-                    $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
-                    $smarty->_config[$i]['files'][$_file] = true;
+                $smarty->_config[$i]['vars'] = @array_merge($smarty->_config[$i]['vars'], $_config_vars);
+                $smarty->_config[$i]['files'][$_file] = true;
             }
         }
-		
+
         if ($smarty->debugging) {
-			$_params = array();
-			require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.get_microtime.php');
+            $_params = array();
+            require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');
             $smarty->_smarty_debug_info[] = array('type'      => 'config',
                                                 'filename'  => $_file.' ['.$_section.'] '.$_scope,
                                                 'depth'     => $smarty->_inclusion_depth,
                                                 'exec_time' => smarty_core_get_microtime($_params, $smarty) - $_debug_start_time);
         }
-	
+
 }
 
 /* vim: set expandtab: */
diff --git a/smarty/plugins/function.counter.php b/smarty/plugins/function.counter.php
index 2536c14..1f26db5 100644
--- a/smarty/plugins/function.counter.php
+++ b/smarty/plugins/function.counter.php
@@ -12,6 +12,7 @@
  * Type:     function
* Name: counter
* Purpose: print out a counter value + * @author Monte Ohrt * @link http://smarty.php.net/manual/en/language.function.counter.php {counter} * (Smarty online manual) * @param array parameters @@ -22,16 +23,7 @@ function smarty_function_counter($params, &$smarty) { static $counters = array(); - extract($params); - - if (!isset($name)) { - if(isset($id)) { - $name = $id; - } else { - $name = "default"; - } - } - + $name = (isset($params['name'])) ? $params['name'] : 'default'; if (!isset($counters[$name])) { $counters[$name] = array( 'start'=>1, @@ -42,45 +34,45 @@ function smarty_function_counter($params, &$smarty) } $counter =& $counters[$name]; - if (isset($start)) { - $counter['start'] = $counter['count'] = $start; + if (isset($params['start'])) { + $counter['start'] = $counter['count'] = (int)$params['start']; } - if (!empty($assign)) { - $counter['assign'] = $assign; + if (!empty($params['assign'])) { + $counter['assign'] = $params['assign']; } if (isset($counter['assign'])) { $smarty->assign($counter['assign'], $counter['count']); } - if (isset($print)) { - $print = (bool)$print; + if (isset($params['print'])) { + $print = (bool)$params['print']; } else { $print = empty($counter['assign']); } if ($print) { $retval = $counter['count']; - } else { - $retval = null; - } + } else { + $retval = null; + } - if (isset($skip)) { - $counter['skip'] = $skip; + if (isset($params['skip'])) { + $counter['skip'] = $params['skip']; } - if (isset($direction)) { - $counter['direction'] = $direction; + if (isset($params['direction'])) { + $counter['direction'] = $params['direction']; } if ($counter['direction'] == "down") $counter['count'] -= $counter['skip']; else $counter['count'] += $counter['skip']; - - return $retval; - + + return $retval; + } /* vim: set expandtab: */ diff --git a/smarty/plugins/function.cycle.php b/smarty/plugins/function.cycle.php index d5909a6..fe78bb8 100644 --- a/smarty/plugins/function.cycle.php +++ b/smarty/plugins/function.cycle.php @@ -23,7 +23,7 @@ * - delimiter = the value delimiter, default is "," * - assign = boolean, assigns to template var instead of * printed. - * + * * Examples:
*
  * {cycle values="#eeeeee,#d0d0d0d"}
@@ -32,7 +32,7 @@
  * 
* @link http://smarty.php.net/manual/en/language.function.cycle.php {cycle} * (Smarty online manual) - * @author Monte Ohrt + * @author Monte Ohrt * @author credit to Mark Priatel * @author credit to Gerard * @author credit to Jason Sweat @@ -45,23 +45,10 @@ function smarty_function_cycle($params, &$smarty) { static $cycle_vars; - extract($params); - - if (empty($name)) { - $name = 'default'; - } - - if (!isset($print)) { - $print = true; - } - - if (!isset($advance)) { - $advance = true; - } - - if (!isset($reset)) { - $reset = false; - } + $name = (empty($params['name'])) ? 'default' : $params['name']; + $print = (isset($params['print'])) ? (bool)$params['print'] : true; + $advance = (isset($params['advance'])) ? (bool)$params['advance'] : true; + $reset = (isset($params['reset'])) ? (bool)$params['reset'] : false; if (!in_array('values', array_keys($params))) { if(!isset($cycle_vars[$name]['values'])) { @@ -70,31 +57,27 @@ function smarty_function_cycle($params, &$smarty) } } else { if(isset($cycle_vars[$name]['values']) - && $cycle_vars[$name]['values'] != $values ) { + && $cycle_vars[$name]['values'] != $params['values'] ) { $cycle_vars[$name]['index'] = 0; } - $cycle_vars[$name]['values'] = $values; + $cycle_vars[$name]['values'] = $params['values']; } - if (isset($delimiter)) { - $cycle_vars[$name]['delimiter'] = $delimiter; - } elseif (!isset($cycle_vars[$name]['delimiter'])) { - $cycle_vars[$name]['delimiter'] = ','; - } + $cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ','; - if(!is_array($cycle_vars[$name]['values'])) { - $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']); + if(is_array($cycle_vars[$name]['values'])) { + $cycle_array = $cycle_vars[$name]['values']; } else { - $cycle_array = $cycle_vars[$name]['values']; + $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']); } if(!isset($cycle_vars[$name]['index']) || $reset ) { $cycle_vars[$name]['index'] = 0; } - if (isset($assign)) { + if (isset($params['assign'])) { $print = false; - $smarty->assign($assign, $cycle_array[$cycle_vars[$name]['index']]); + $smarty->assign($params['assign'], $cycle_array[$cycle_vars[$name]['index']]); } if($print) { @@ -105,7 +88,7 @@ function smarty_function_cycle($params, &$smarty) if($advance) { if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) { - $cycle_vars[$name]['index'] = 0; + $cycle_vars[$name]['index'] = 0; } else { $cycle_vars[$name]['index']++; } diff --git a/smarty/plugins/function.debug.php b/smarty/plugins/function.debug.php index 2452d62..4345230 100644 --- a/smarty/plugins/function.debug.php +++ b/smarty/plugins/function.debug.php @@ -15,7 +15,7 @@ * Purpose: popup debug window * @link http://smarty.php.net/manual/en/language.function.debug.php {debug} * (Smarty online manual) - * @author Monte Ohrt + * @author Monte Ohrt * @version 1.0 * @param array * @param Smarty @@ -23,10 +23,10 @@ */ function smarty_function_debug($params, &$smarty) { - if($params['output']) { - $smarty->assign('_smarty_debug_output',$params['output']); + if (isset($params['output'])) { + $smarty->assign('_smarty_debug_output', $params['output']); } - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.display_debug_console.php'); + require_once(SMARTY_CORE_DIR . 'core.display_debug_console.php'); return smarty_core_display_debug_console(null, $smarty); } diff --git a/smarty/plugins/function.eval.php b/smarty/plugins/function.eval.php index 3a4b8b2..ff0472d 100644 --- a/smarty/plugins/function.eval.php +++ b/smarty/plugins/function.eval.php @@ -14,6 +14,7 @@ * Purpose: evaluate a template variable as a template
* @link http://smarty.php.net/manual/en/language.function.eval.php {eval} * (Smarty online manual) + * @author Monte Ohrt * @param array * @param Smarty */ diff --git a/smarty/plugins/function.fetch.php b/smarty/plugins/function.fetch.php index b013b8c..81b1bfc 100644 --- a/smarty/plugins/function.fetch.php +++ b/smarty/plugins/function.fetch.php @@ -14,6 +14,7 @@ * Purpose: fetch file, web or ftp data and display results * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch} * (Smarty online manual) + * @author Monte Ohrt * @param array * @param Smarty * @return string|null if the assign parameter is passed, Smarty assigns the @@ -26,183 +27,186 @@ function smarty_function_fetch($params, &$smarty) return; } + $content = ''; if ($smarty->security && !preg_match('!^(http|ftp)://!i', $params['file'])) { - $_params = array('resource_type' => 'file', 'resource_name' => $params['file']); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.is_secure.php'); - if(!smarty_core_is_secure($_params, $smarty)) { + $_params = array('resource_type' => 'file', 'resource_name' => $params['file']); + require_once(SMARTY_CORE_DIR . 'core.is_secure.php'); + if(!smarty_core_is_secure($_params, $smarty)) { $smarty->_trigger_fatal_error('[plugin] (secure mode) fetch \'' . $params['file'] . '\' is not allowed'); - return; - } - - // fetch the file - if($fp = @fopen($params['file'],'r')) { - while(!feof($fp)) { - $content .= fgets ($fp,4096); - } - fclose($fp); - } else { + return; + } + + // fetch the file + if($fp = @fopen($params['file'],'r')) { + while(!feof($fp)) { + $content .= fgets ($fp,4096); + } + fclose($fp); + } else { $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] . '\''); - return; - } + return; + } } else { - // not a local file - if(preg_match('!^http://!i',$params['file'])) { - // http fetch - if($uri_parts = parse_url($params['file'])) { - // set defaults - $host = $server_name = $uri_parts['host']; - $timeout = 30; - $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; - $agent = "Smarty Template Engine ".$smarty->_version; - $referer = ""; - $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; - $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; - $_is_proxy = false; - if(empty($uri_parts['port'])) { - $port = 80; - } else { - $port = $uri_parts['port']; - } - if(empty($uri_parts['user'])) { - $user = ''; - } - // loop through parameters, setup headers - foreach($params as $param_key => $param_value) { - switch($param_key) { - case "file": - case "assign": - case "assign_headers": - break; - case "user": - if(!empty($param_value)) { - $user = $param_value; - } - break; - case "pass": - if(!empty($param_value)) { - $pass = $param_value; - } - break; - case "accept": - if(!empty($param_value)) { - $accept = $param_value; - } - break; - case "header": - if(!empty($param_value)) { - if(!preg_match('![\w\d-]+: .+!',$param_value)) { - $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'"); - return; - } else { - $extra_headers[] = $param_value; - } - } - break; - case "proxy_host": - if(!empty($param_value)) { - $proxy_host = $param_value; - } - break; - case "proxy_port": - if(!preg_match('!\D!', $param_value)) { - $proxy_port = (int) $param_value; - } else { - $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); - return; - } - break; - case "agent": - if(!empty($param_value)) { - $agent = $param_value; - } - break; - case "referer": - if(!empty($param_value)) { - $referer = $param_value; - } - break; - case "timeout": - if(!preg_match('!\D!', $param_value)) { - $timeout = (int) $param_value; - } else { - $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); - return; - } - break; - default: - $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'"); - return; - } - } - if(!empty($proxy_host) && !empty($proxy_port)) { - $_is_proxy = true; - $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout); - } else { - $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout); - } + // not a local file + if(preg_match('!^http://!i',$params['file'])) { + // http fetch + if($uri_parts = parse_url($params['file'])) { + // set defaults + $host = $server_name = $uri_parts['host']; + $timeout = 30; + $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; + $agent = "Smarty Template Engine ".$smarty->_version; + $referer = ""; + $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; + $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; + $_is_proxy = false; + if(empty($uri_parts['port'])) { + $port = 80; + } else { + $port = $uri_parts['port']; + } + if(!empty($uri_parts['user'])) { + $user = $uri_parts['user']; + } + if(!empty($uri_parts['pass'])) { + $pass = $uri_parts['pass']; + } + // loop through parameters, setup headers + foreach($params as $param_key => $param_value) { + switch($param_key) { + case "file": + case "assign": + case "assign_headers": + break; + case "user": + if(!empty($param_value)) { + $user = $param_value; + } + break; + case "pass": + if(!empty($param_value)) { + $pass = $param_value; + } + break; + case "accept": + if(!empty($param_value)) { + $accept = $param_value; + } + break; + case "header": + if(!empty($param_value)) { + if(!preg_match('![\w\d-]+: .+!',$param_value)) { + $smarty->_trigger_fatal_error("[plugin] invalid header format '".$param_value."'"); + return; + } else { + $extra_headers[] = $param_value; + } + } + break; + case "proxy_host": + if(!empty($param_value)) { + $proxy_host = $param_value; + } + break; + case "proxy_port": + if(!preg_match('!\D!', $param_value)) { + $proxy_port = (int) $param_value; + } else { + $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); + return; + } + break; + case "agent": + if(!empty($param_value)) { + $agent = $param_value; + } + break; + case "referer": + if(!empty($param_value)) { + $referer = $param_value; + } + break; + case "timeout": + if(!preg_match('!\D!', $param_value)) { + $timeout = (int) $param_value; + } else { + $smarty->_trigger_fatal_error("[plugin] invalid value for attribute '".$param_key."'"); + return; + } + break; + default: + $smarty->_trigger_fatal_error("[plugin] unrecognized attribute '".$param_key."'"); + return; + } + } + if(!empty($proxy_host) && !empty($proxy_port)) { + $_is_proxy = true; + $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout); + } else { + $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout); + } - if(!$fp) { - $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)"); - return; - } else { - if($_is_proxy) { - fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n"); - } else { - fputs($fp, "GET $uri HTTP/1.0\r\n"); - } - if(!empty($host)) { - fputs($fp, "Host: $host\r\n"); - } - if(!empty($accept)) { - fputs($fp, "Accept: $accept\r\n"); - } - if(!empty($agent)) { - fputs($fp, "User-Agent: $agent\r\n"); - } - if(!empty($referer)) { - fputs($fp, "Referer: $referer\r\n"); - } - if(isset($extra_headers) && is_array($extra_headers)) { - foreach($extra_headers as $curr_header) { - fputs($fp, $curr_header."\r\n"); - } - } - if(!empty($user) && !empty($pass)) { - fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n"); - } + if(!$fp) { + $smarty->_trigger_fatal_error("[plugin] unable to fetch: $errstr ($errno)"); + return; + } else { + if($_is_proxy) { + fputs($fp, 'GET ' . $params['file'] . " HTTP/1.0\r\n"); + } else { + fputs($fp, "GET $uri HTTP/1.0\r\n"); + } + if(!empty($host)) { + fputs($fp, "Host: $host\r\n"); + } + if(!empty($accept)) { + fputs($fp, "Accept: $accept\r\n"); + } + if(!empty($agent)) { + fputs($fp, "User-Agent: $agent\r\n"); + } + if(!empty($referer)) { + fputs($fp, "Referer: $referer\r\n"); + } + if(isset($extra_headers) && is_array($extra_headers)) { + foreach($extra_headers as $curr_header) { + fputs($fp, $curr_header."\r\n"); + } + } + if(!empty($user) && !empty($pass)) { + fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n"); + } - $content = ''; - fputs($fp, "\r\n"); - while(!feof($fp)) { - $content .= fgets($fp,4096); - } - fclose($fp); - $csplit = split("\r\n\r\n",$content,2); + fputs($fp, "\r\n"); + while(!feof($fp)) { + $content .= fgets($fp,4096); + } + fclose($fp); + $csplit = split("\r\n\r\n",$content,2); - $content = $csplit[1]; - - if(!empty($params['assign_headers'])) { - $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0])); - } - } - } else { - $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax"); - return; - } - } else { - // ftp fetch - if($fp = @fopen($params['file'],'r')) { - while(!feof($fp)) { - $content .= fgets ($fp,4096); - } - fclose($fp); - } else { - $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\''); - return; - } - } - - } + $content = $csplit[1]; + + if(!empty($params['assign_headers'])) { + $smarty->assign($params['assign_headers'],split("\r\n",$csplit[0])); + } + } + } else { + $smarty->_trigger_fatal_error("[plugin] unable to parse URL, check syntax"); + return; + } + } else { + // ftp fetch + if($fp = @fopen($params['file'],'r')) { + while(!feof($fp)) { + $content .= fgets ($fp,4096); + } + fclose($fp); + } else { + $smarty->_trigger_fatal_error('[plugin] fetch cannot read file \'' . $params['file'] .'\''); + return; + } + } + + } if (!empty($params['assign'])) { diff --git a/smarty/plugins/function.html_checkboxes.php b/smarty/plugins/function.html_checkboxes.php index c146fc1..ed8ad7f 100644 --- a/smarty/plugins/function.html_checkboxes.php +++ b/smarty/plugins/function.html_checkboxes.php @@ -20,7 +20,8 @@ * - options (optional) - associative array * - checked (optional) - array default not set * - separator (optional) - ie
or   - * - output (optional) - without this one the buttons don't have names + * - output (optional) - the output next to each checkbox + * - assign (optional) - assign the output as an array to this variable * Examples: *
  * {html_checkboxes values=$ids output=$names}
@@ -30,7 +31,7 @@
  * @link http://smarty.php.net/manual/en/language.function.html.checkboxes.php {html_checkboxes}
  *      (Smarty online manual)
  * @author     Christopher Kvarme 
- * @author credits to Monte Ohrt 
+ * @author credits to Monte Ohrt 
  * @version    1.0
  * @param array
  * @param Smarty
@@ -39,97 +40,104 @@
  */
 function smarty_function_html_checkboxes($params, &$smarty)
 {
-   require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
-
-   $name = 'checkbox';
-   $values = null;
-   $options = null;
-   $selected = null;
-   $separator = '';
-   $labels = true;
-   $output = null;
- 
-   $extra = '';
-   
-   foreach($params as $_key => $_val) {
-      switch($_key) {
-      case 'name':
-      case 'separator':
-         $$_key = $_val;
-         break;
-
-      case 'labels':
-         $$_key = (bool)$_val;
-         break;
-
-      case 'options':
-         $$_key = (array)$_val;
-         break;
-
-      case 'values':
-      case 'output':
-         $$_key = array_values((array)$_val);
-	 break;
-
-      case 'checked':
-      case 'selected':
-         $selected = array_values((array)$_val);
-         break;
-
-      case 'checkboxes':
-         $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
-         $options = (array)$_val;
-         break;
-
-      default:
-		if(!is_array($_val)) {
-			$extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
-		} else {
-			$smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
-		}
-         break;
-      }
-   }
-
-   if (!isset($options) && !isset($values))
-      return ''; /* raise error here? */
-
-   settype($selected, 'array');
-   $_html_result = '';
-
-   if (is_array($options)) {
-
-      foreach ($options as $_key=>$_val)
-         $_html_result .= smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
-
-
-   } else {
-      foreach ($values as $_i=>$_key) {
-         $_val = isset($output[$_i]) ? $output[$_i] : '';
-         $_html_result .= smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
-      }
-
-   }
-
-   return $_html_result;
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+
+    $name = 'checkbox';
+    $values = null;
+    $options = null;
+    $selected = null;
+    $separator = '';
+    $labels = true;
+    $output = null;
+
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = $_val;
+                break;
+
+            case 'labels':
+                $$_key = (bool)$_val;
+                break;
+
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'checked':
+            case 'selected':
+                $selected = array_map('strval', array_values((array)$_val));
+                break;
+
+            case 'checkboxes':
+                $smarty->trigger_error('html_checkboxes: the use of the "checkboxes" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array)$_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    settype($selected, 'array');
+    $_html_result = array();
+
+    if (isset($options)) {
+
+        foreach ($options as $_key=>$_val)
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+
+
+    } else {
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+        }
+
+    }
+
+    if(!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n",$_html_result);
+    }
 
 }
 
 function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels) {
-   $_output = '';
-   if ($labels) $_output .= '';
-   $_output .=  $separator . "\n";
-
-   return $_output;
+    $_output = '';
+    if ($labels) $_output .= '';
+    $_output .=  $separator;
+
+    return $_output;
 }
 
 ?>
diff --git a/smarty/plugins/function.html_image.php b/smarty/plugins/function.html_image.php
index 2fcdb4e..9abae72 100644
--- a/smarty/plugins/function.html_image.php
+++ b/smarty/plugins/function.html_image.php
@@ -15,17 +15,17 @@
  * Purpose:  format HTML tags for the image
* Input:
* - file = file (and path) of image (required) - * - border = border width (optional, default 0) * - height = image height (optional, default actual height) - * - image =image width (optional, default actual width) + * - width = image width (optional, default actual width) * - basedir = base directory for absolute paths, default * is environment variable DOCUMENT_ROOT + * - path_prefix = prefix for path output (optional, default empty) * - * Examples: {html_image file="images/masthead.gif"} - * Output: + * Examples: {html_image file="/images/masthead.gif"} + * Output: * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image} * (Smarty online manual) - * @author Monte Ohrt + * @author Monte Ohrt * @author credits to Duda - wrote first image function * in repository, helped with lots of functionality * @version 1.0 @@ -40,27 +40,21 @@ function smarty_function_html_image($params, &$smarty) $alt = ''; $file = ''; - $border = 0; $height = ''; $width = ''; $extra = ''; $prefix = ''; $suffix = ''; - $basedir = isset($GLOBALS['HTTP_SERVER_VARS']['DOCUMENT_ROOT']) - ? $GLOBALS['HTTP_SERVER_VARS']['DOCUMENT_ROOT'] : ''; - if(strstr($GLOBALS['HTTP_SERVER_VARS']['HTTP_USER_AGENT'], 'Mac')) { - $dpi_default = 72; - } else { - $dpi_default = 96; - } - + $path_prefix = ''; + $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; + $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : ''; foreach($params as $_key => $_val) { switch($_key) { case 'file': - case 'border': case 'height': case 'width': case 'dpi': + case 'path_prefix': case 'basedir': $$_key = $_val; break; @@ -99,7 +93,7 @@ function smarty_function_html_image($params, &$smarty) } else { $_image_path = $file; } - + if(!isset($params['width']) || !isset($params['height'])) { if(!$_image_data = @getimagesize($_image_path)) { if(!file_exists($_image_path)) { @@ -113,13 +107,13 @@ function smarty_function_html_image($params, &$smarty) return; } } - $_params = array('resource_type' => 'file', 'resource_name' => $_image_path); - require_once(SMARTY_DIR . 'core' . DIRECTORY_SEPARATOR . 'core.is_secure.php'); - if(!$smarty->security && !smarty_core_is_secure($_params, $smarty)) { + if ($smarty->security && + ($_params = array('resource_type' => 'file', 'resource_name' => $_image_path)) && + (require_once(SMARTY_CORE_DIR . 'core.is_secure.php')) && + (!smarty_core_is_secure($_params, $smarty)) ) { $smarty->trigger_error("html_image: (secure) '$_image_path' not in secure directory", E_USER_NOTICE); - return; - } - + } + if(!isset($params['width'])) { $width = $_image_data[0]; } @@ -130,12 +124,17 @@ function smarty_function_html_image($params, &$smarty) } if(isset($params['dpi'])) { + if(strstr($server_vars['HTTP_USER_AGENT'], 'Mac')) { + $dpi_default = 72; + } else { + $dpi_default = 96; + } $_resize = $dpi_default/$params['dpi']; $width = round($width * $_resize); $height = round($height * $_resize); } - return $prefix . ''.$alt.'' . $suffix; + return $prefix . ''.$alt.'' . $suffix; } /* vim: set expandtab: */ diff --git a/smarty/plugins/function.html_options.php b/smarty/plugins/function.html_options.php index 1b10653..cebadde 100644 --- a/smarty/plugins/function.html_options.php +++ b/smarty/plugins/function.html_options.php @@ -21,6 +21,7 @@ * the passed parameters * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image} * (Smarty online manual) + * @author Monte Ohrt * @param array * @param Smarty * @return string @@ -28,89 +29,92 @@ */ function smarty_function_html_options($params, &$smarty) { - require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); - - $name = null; - $values = null; - $options = null; - $selected = array(); - $output = null; - - $extra = ''; - - foreach($params as $_key => $_val) { - switch($_key) { - case 'name': - $$_key = (string)$_val; - break; - - case 'options': - $$_key = (array)$_val; - break; - - case 'selected': - case 'values': - case 'output': - $$_key = array_values((array)$_val); - break; - - default: - if(!is_array($_val)) { - $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; - } else { - $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE); - } - break; - } - } - - if (!isset($options) && !isset($values)) - return ''; /* raise error here? */ - - $_html_result = ''; - - if (is_array($options)) { - - foreach ($options as $_key=>$_val) - $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected); + require_once $smarty->_get_plugin_filepath('shared','escape_special_chars'); - } else { - - foreach ((array)$values as $_i=>$_key) { - $_val = isset($output[$_i]) ? $output[$_i] : ''; - $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected); - } - - } - - if(!empty($name)) { - $_html_result = '' . "\n"; - } - - return $_html_result; + $name = null; + $values = null; + $options = null; + $selected = array(); + $output = null; + + $extra = ''; + + foreach($params as $_key => $_val) { + switch($_key) { + case 'name': + $$_key = (string)$_val; + break; + + case 'options': + $$_key = (array)$_val; + break; + + case 'values': + case 'output': + $$_key = array_values((array)$_val); + break; + + case 'selected': + $$_key = array_map('strval', array_values((array)$_val)); + break; + + default: + if(!is_array($_val)) { + $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + } else { + $smarty->trigger_error("html_options: extra attribute '$_key' cannot be an array", E_USER_NOTICE); + } + break; + } + } + + if (!isset($options) && !isset($values)) + return ''; /* raise error here? */ + + $_html_result = ''; + + if (isset($options)) { + + foreach ($options as $_key=>$_val) + $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected); + + } else { + + foreach ($values as $_i=>$_key) { + $_val = isset($output[$_i]) ? $output[$_i] : ''; + $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected); + } + + } + + if(!empty($name)) { + $_html_result = '' . "\n"; + } + + return $_html_result; } function smarty_function_html_options_optoutput($key, $value, $selected) { - if(!is_array($value)) { - $_html_result = '' . "\n"; - foreach ($values as $key => $value) { - $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected); - } - $optgroup_html .= "\n"; - return $optgroup_html; + $optgroup_html = '' . "\n"; + foreach ($values as $key => $value) { + $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected); + } + $optgroup_html .= "\n"; + return $optgroup_html; } /* vim: set expandtab: */ diff --git a/smarty/plugins/function.html_radios.php b/smarty/plugins/function.html_radios.php index b80e9bc..7503cfa 100644 --- a/smarty/plugins/function.html_radios.php +++ b/smarty/plugins/function.html_radios.php @@ -20,7 +20,8 @@ * - options (optional) - associative array * - checked (optional) - array default not set * - separator (optional) - ie
or   - * - output (optional) - without this one the buttons don't have names + * - output (optional) - the output next to each radio button + * - assign (optional) - assign the output as an array to this variable * Examples: *
  * {html_radios values=$ids output=$names}
@@ -30,7 +31,7 @@
  * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios}
  *      (Smarty online manual)
  * @author     Christopher Kvarme 
- * @author credits to Monte Ohrt 
+ * @author credits to Monte Ohrt 
  * @version    1.0
  * @param array
  * @param Smarty
@@ -39,100 +40,117 @@
  */
 function smarty_function_html_radios($params, &$smarty)
 {
-   require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
+    require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
    
-   $name = 'radio';
-   $values = null;
-   $options = null;
-   $selected = null;
-   $separator = '';
-   $labels = true;
-   $output = null;
-   $extra = '';
-
-   foreach($params as $_key => $_val) {
-		switch($_key) {
-		case 'name':
-		case 'separator':
-		    $$_key = (string)$_val;
-		    break;
-
-		case 'checked':
-		case 'selected':
-			if(is_array($_val)) {
-				$smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
-			} else {
-				$selected = (string)$_val;
-			}
-			break;
-
-        case 'labels':
-            $$_key = (bool)$_val;
-            break;
-
-		case 'options':
-			$$_key = (array)$_val;
-			break;
-
-		case 'values':
-		case 'output':
-			$$_key = array_values((array)$_val);
-			break;
-
-		case 'radios':
-			$smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
-			$options = (array)$_val;
-			break;
-
-
-		default:
-			if(!is_array($_val)) {
-				$extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
-			} else {
-				$smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
-			}
-			break;
-		}
-   }
-
-   if (!isset($options) && !isset($values))
-      return ''; /* raise error here? */
-
-   $_html_result = '';
-
-   if (isset($options) && is_array($options)) {
+    $name = 'radio';
+    $values = null;
+    $options = null;
+    $selected = null;
+    $separator = '';
+    $labels = true;
+    $label_ids = false;
+    $output = null;
+    $extra = '';
+
+    foreach($params as $_key => $_val) {
+        switch($_key) {
+            case 'name':
+            case 'separator':
+                $$_key = (string)$_val;
+                break;
+
+            case 'checked':
+            case 'selected':
+                if(is_array($_val)) {
+                    $smarty->trigger_error('html_radios: the "' . $_key . '" attribute cannot be an array', E_USER_WARNING);
+                } else {
+                    $selected = (string)$_val;
+                }
+                break;
+
+            case 'labels':
+            case 'label_ids':
+                $$_key = (bool)$_val;
+                break;
+
+            case 'options':
+                $$_key = (array)$_val;
+                break;
+
+            case 'values':
+            case 'output':
+                $$_key = array_values((array)$_val);
+                break;
+
+            case 'radios':
+                $smarty->trigger_error('html_radios: the use of the "radios" attribute is deprecated, use "options" instead', E_USER_WARNING);
+                $options = (array)$_val;
+                break;
+
+            case 'assign':
+                break;
+
+            default:
+                if(!is_array($_val)) {
+                    $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
+                } else {
+                    $smarty->trigger_error("html_radios: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
+                }
+                break;
+        }
+    }
+
+    if (!isset($options) && !isset($values))
+        return ''; /* raise error here? */
+
+    $_html_result = array();
+
+    if (isset($options)) {
+
+        foreach ($options as $_key=>$_val)
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+
+    } else {
+
+        foreach ($values as $_i=>$_key) {
+            $_val = isset($output[$_i]) ? $output[$_i] : '';
+            $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
+        }
+
+    }
+
+    if(!empty($params['assign'])) {
+        $smarty->assign($params['assign'], $_html_result);
+    } else {
+        return implode("\n",$_html_result);
+    }
 
-      foreach ((array)$options as $_key=>$_val)
-	 $_html_result .= smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
-
-   } else {
+}
 
-      foreach ((array)$values as $_i=>$_key) {
-	 $_val = isset($output[$_i]) ? $output[$_i] : '';
-	 $_html_result .= smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels);
+function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
+    $_output = '';
+    if ($labels) {
+      if($label_ids) {
+          $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
+          $_output .= '
Smarty Debug Console
included templates & config files (load time in seconds):
\n"; return $output; diff --git a/smarty/plugins/function.mailto.php b/smarty/plugins/function.mailto.php index f6e3de0..64c122c 100644 --- a/smarty/plugins/function.mailto.php +++ b/smarty/plugins/function.mailto.php @@ -20,6 +20,7 @@ * - encode = (optional) can be one of: * * none : no encoding (default) * * javascript : encode with javascript + * * javascript_charcode : encode with javascript charcode * * hex : encode with hexidecimal (no javascript) * - cc = (optional) address(es) to carbon copy * - bcc = (optional) address(es) to blind carbon copy @@ -27,7 +28,7 @@ * - newsgroups = (optional) newsgroup(s) to post to * - followupto = (optional) address(es) to follow up to * - extra = (optional) extra tags for the href link - * + * * Examples: *
  * {mailto address="me@domain.com"}
@@ -40,99 +41,121 @@
  * @link http://smarty.php.net/manual/en/language.function.mailto.php {mailto}
  *          (Smarty online manual)
  * @version  1.2
- * @author	 Monte Ohrt 
- * @author credits to Jason Sweat (added cc, bcc and subject functionality)
- * @param array
- * @param Smarty
- * @return string
+ * @author   Monte Ohrt 
+ * @author   credits to Jason Sweat (added cc, bcc and subject functionality)
+ * @param    array
+ * @param    Smarty
+ * @return   string
  */
 function smarty_function_mailto($params, &$smarty)
 {
     $extra = '';
-    extract($params);
 
-    if (empty($address)) {
+    if (empty($params['address'])) {
         $smarty->trigger_error("mailto: missing 'address' parameter");
         return;
+    } else {
+        $address = $params['address'];
     }
-	
-    if (empty($text)) {
-		$text = $address;
+
+    $text = $address;
+
+    // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
+    // so, don't encode it.
+    $mail_parms = array();
+    foreach ($params as $var=>$value) {
+        switch ($var) {
+            case 'cc':
+            case 'bcc':
+            case 'followupto':
+                if (!empty($value))
+                    $mail_parms[] = $var.'='.str_replace('%40','@',rawurlencode($value));
+                break;
+                
+            case 'subject':
+            case 'newsgroups':
+                $mail_parms[] = $var.'='.rawurlencode($value);
+                break;
+
+            case 'extra':
+            case 'text':
+                $$var = $value;
+
+            default:
+        }
     }
-	
-	// netscape and mozilla do not decode %40 (@) in BCC field (bug?)
-	// so, don't encode it.
-	
-	$mail_parms = array();
-	if (!empty($cc)) {
-		$mail_parms[] = 'cc='.str_replace('%40','@',rawurlencode($cc));
-	}
-	
-	if (!empty($bcc)) {
-		$mail_parms[] = 'bcc='.str_replace('%40','@',rawurlencode($bcc));
-	}
-	
-	if (!empty($subject)) {
-		$mail_parms[] = 'subject='.rawurlencode($subject);
-	}
-
-	if (!empty($newsgroups)) {
-		$mail_parms[] = 'newsgroups='.rawurlencode($newsgroups);
-	}
-
-	if (!empty($followupto)) {
-		$mail_parms[] = 'followupto='.str_replace('%40','@',rawurlencode($followupto));
-	}
-	
+
     $mail_parm_vals = '';
-	for ($i=0; $itrigger_error("mailto: 'encode' parameter must be none, javascript or hex");
-        return;		
-	}
-	
-	if ($encode == 'javascript' ) {
-		$string = 'document.write(\''.$text.'\');';
-		
-		for ($x=0; $x < strlen($string); $x++) {
-			$js_encode .= '%' . bin2hex($string[$x]);
-		}
-	
-		return '';
-		
-	} elseif ($encode == 'hex') {
-
-		preg_match('!^(.*)(\?.*)$!',$address,$match);
-		if(!empty($match[2])) {
-        	$smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
-        	return;						
-		}  
-		for ($x=0; $x < strlen($address); $x++) {
-			if(preg_match('!\w!',$address[$x])) {
-				$address_encode .= '%' . bin2hex($address[$x]);
-			} else {
-				$address_encode .= $address[$x];				
-			}
-		}
-		for ($x=0; $x < strlen($text); $x++) {
-			$text_encode .= '&#x' . bin2hex($text[$x]).';';
-		}
-		
-		return ''.$text_encode.'';
-		
-	} else {
-		// no encoding		
-		return ''.$text.'';
-
-	}
-	
+        return;
+    }
+
+    if ($encode == 'javascript' ) {
+        $string = 'document.write(\''.$text.'\');';
+
+        $js_encode = '';
+        for ($x=0; $x < strlen($string); $x++) {
+            $js_encode .= '%' . bin2hex($string[$x]);
+        }
+
+        return '';
+
+    } elseif ($encode == 'javascript_charcode' ) {
+        $string = ''.$text.'';
+
+        for($x = 0, $y = strlen($string); $x < $y; $x++ ) {
+            $ord[] = ord($string[$x]);   
+        }
+
+        $_ret = "\n";
+        
+        return $_ret;
+        
+        
+    } elseif ($encode == 'hex') {
+
+        preg_match('!^(.*)(\?.*)$!',$address,$match);
+        if(!empty($match[2])) {
+            $smarty->trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.");
+            return;
+        }
+        $address_encode = '';
+        for ($x=0; $x < strlen($address); $x++) {
+            if(preg_match('!\w!',$address[$x])) {
+                $address_encode .= '%' . bin2hex($address[$x]);
+            } else {
+                $address_encode .= $address[$x];
+            }
+        }
+        $text_encode = '';
+        for ($x=0; $x < strlen($text); $x++) {
+            $text_encode .= '&#x' . bin2hex($text[$x]).';';
+        }
+
+        $mailto = "mailto:";
+        return ''.$text_encode.'';
+
+    } else {
+        // no encoding
+        return ''.$text.'';
+
+    }
+
 }
 
 /* vim: set expandtab: */
diff --git a/smarty/plugins/function.math.php b/smarty/plugins/function.math.php
index c080d4d..71672fe 100644
--- a/smarty/plugins/function.math.php
+++ b/smarty/plugins/function.math.php
@@ -14,6 +14,7 @@
  * Purpose:  handle math computations in template
* @link http://smarty.php.net/manual/en/language.function.math.php {math} * (Smarty online manual) + * @author Monte Ohrt * @param array * @param Smarty * @return string @@ -35,12 +36,13 @@ function smarty_function_math($params, &$smarty) } // match all vars in equation, make sure all are passed - preg_match_all("!\!(0x)([a-zA-Z][a-zA-Z0-9_]*)!",$equation, $match); + preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]+)!",$equation, $match); $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10', 'max','min','pi','pow','rand','round','sin','sqrt','srand','tan'); - foreach($match[2] as $curr_var) { - if (!in_array($curr_var,array_keys($params)) && !in_array($curr_var, $allowed_funcs)) { - $smarty->trigger_error("math: parameter $curr_var not passed as argument"); + + foreach($match[1] as $curr_var) { + if ($curr_var && !in_array($curr_var, array_keys($params)) && !in_array($curr_var, $allowed_funcs)) { + $smarty->trigger_error("math: function call $curr_var not allowed"); return; } } @@ -56,7 +58,7 @@ function smarty_function_math($params, &$smarty) $smarty->trigger_error("math: parameter $key: is not numeric"); return; } - $equation = preg_replace("/\b$key\b/",$val, $equation); + $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation); } } diff --git a/smarty/plugins/function.popup.php b/smarty/plugins/function.popup.php index d1030a7..3a76b78 100644 --- a/smarty/plugins/function.popup.php +++ b/smarty/plugins/function.popup.php @@ -14,13 +14,89 @@ * Purpose: make text pop up in windows via overlib * @link http://smarty.php.net/manual/en/language.function.popup.php {popup} * (Smarty online manual) + * @author Monte Ohrt * @param array * @param Smarty * @return string */ function smarty_function_popup($params, &$smarty) { - extract($params); + $append = ''; + foreach ($params as $_key=>$_value) { + switch ($_key) { + case 'text': + case 'trigger': + case 'function': + case 'inarray': + $$_key = (string)$_value; + if ($_key == 'function' || $_key == 'inarray') + $append .= ',' . strtoupper($_key) . ",'$_value'"; + break; + + case 'caption': + case 'closetext': + case 'status': + $append .= ',' . strtoupper($_key) . ",'" . str_replace("'","\'",$_value) . "'"; + break; + + case 'fgcolor': + case 'bgcolor': + case 'textcolor': + case 'capcolor': + case 'closecolor': + case 'textfont': + case 'captionfont': + case 'closefont': + case 'fgbackground': + case 'bgbackground': + case 'caparray': + case 'capicon': + case 'background': + case 'frame': + $append .= ',' . strtoupper($_key) . ",'$_value'"; + break; + + case 'textsize': + case 'captionsize': + case 'closesize': + case 'width': + case 'height': + case 'border': + case 'offsetx': + case 'offsety': + case 'snapx': + case 'snapy': + case 'fixx': + case 'fixy': + case 'padx': + case 'pady': + case 'timeout': + case 'delay': + $append .= ',' . strtoupper($_key) . ",$_value"; + break; + + case 'sticky': + case 'left': + case 'right': + case 'center': + case 'above': + case 'below': + case 'noclose': + case 'autostatus': + case 'autostatuscap': + case 'fullhtml': + case 'hauto': + case 'vauto': + case 'mouseoff': + case 'followmouse': + case 'closeclick': + if ($_value) $append .= ',' . strtoupper($_key); + break; + + default: + $smarty->trigger_error("[popup] unknown parameter $_key", E_USER_WARNING); + } + } if (empty($text) && !isset($inarray) && empty($function)) { $smarty->trigger_error("overlib: attribute 'text' or 'inarray' or 'function' required"); @@ -30,56 +106,12 @@ function smarty_function_popup($params, &$smarty) if (empty($trigger)) { $trigger = "onmouseover"; } $retval = $trigger . '="return overlib(\''.preg_replace(array("!'!","![\r\n]!"),array("\'",'\r'),$text).'\''; - if ($sticky) { $retval .= ",STICKY"; } - if (!empty($caption)) { $retval .= ",CAPTION,'".str_replace("'","\'",$caption)."'"; } - if (!empty($fgcolor)) { $retval .= ",FGCOLOR,'$fgcolor'"; } - if (!empty($bgcolor)) { $retval .= ",BGCOLOR,'$bgcolor'"; } - if (!empty($textcolor)) { $retval .= ",TEXTCOLOR,'$textcolor'"; } - if (!empty($capcolor)) { $retval .= ",CAPCOLOR,'$capcolor'"; } - if (!empty($closecolor)) { $retval .= ",CLOSECOLOR,'$closecolor'"; } - if (!empty($textfont)) { $retval .= ",TEXTFONT,'$textfont'"; } - if (!empty($captionfont)) { $retval .= ",CAPTIONFONT,'$captionfont'"; } - if (!empty($closefont)) { $retval .= ",CLOSEFONT,'$closefont'"; } - if (!empty($textsize)) { $retval .= ",TEXTSIZE,$textsize"; } - if (!empty($captionsize)) { $retval .= ",CAPTIONSIZE,$captionsize"; } - if (!empty($closesize)) { $retval .= ",CLOSESIZE,$closesize"; } - if (!empty($width)) { $retval .= ",WIDTH,$width"; } - if (!empty($height)) { $retval .= ",HEIGHT,$height"; } - if (!empty($left)) { $retval .= ",LEFT"; } - if (!empty($right)) { $retval .= ",RIGHT"; } - if (!empty($center)) { $retval .= ",CENTER"; } - if (!empty($above)) { $retval .= ",ABOVE"; } - if (!empty($below)) { $retval .= ",BELOW"; } - if (isset($border)) { $retval .= ",BORDER,$border"; } - if (isset($offsetx)) { $retval .= ",OFFSETX,$offsetx"; } - if (isset($offsety)) { $retval .= ",OFFSETY,$offsety"; } - if (!empty($fgbackground)) { $retval .= ",FGBACKGROUND,'$fgbackground'"; } - if (!empty($bgbackground)) { $retval .= ",BGBACKGROUND,'$bgbackground'"; } - if (!empty($closetext)) { $retval .= ",CLOSETEXT,'".str_replace("'","\'",$closetext)."'"; } - if (!empty($noclose)) { $retval .= ",NOCLOSE"; } - if (!empty($status)) { $retval .= ",STATUS,'".str_replace("'","\'",$status)."'"; } - if (!empty($autostatus)) { $retval .= ",AUTOSTATUS"; } - if (!empty($autostatuscap)) { $retval .= ",AUTOSTATUSCAP"; } - if (isset($inarray)) { $retval .= ",INARRAY,'$inarray'"; } - if (isset($caparray)) { $retval .= ",CAPARRAY,'$caparray'"; } - if (!empty($capicon)) { $retval .= ",CAPICON,'$capicon'"; } - if (!empty($snapx)) { $retval .= ",SNAPX,$snapx"; } - if (!empty($snapy)) { $retval .= ",SNAPY,$snapy"; } - if (isset($fixx)) { $retval .= ",FIXX,$fixx"; } - if (isset($fixy)) { $retval .= ",FIXY,$fixy"; } - if (!empty($background)) { $retval .= ",BACKGROUND,'$background'"; } - if (!empty($padx)) { $retval .= ",PADX,$padx"; } - if (!empty($pady)) { $retval .= ",PADY,$pady"; } - if (!empty($fullhtml)) { $retval .= ",FULLHTML"; } - if (!empty($frame)) { $retval .= ",FRAME,'$frame'"; } - if (isset($timeout)) { $retval .= ",TIMEOUT,$timeout"; } - if (!empty($function)) { $retval .= ",FUNCTION,'$function'"; } - if (isset($delay)) { $retval .= ",DELAY,$delay"; } - if (!empty($hauto)) { $retval .= ",HAUTO"; } - if (!empty($vauto)) { $retval .= ",VAUTO"; } - $retval .= ');" onmouseout="nd();"'; - - return $retval; + $retval .= $append . ');"'; + if ($trigger == 'onmouseover') + $retval .= ' onmouseout="nd();"'; + + + return $retval; } /* vim: set expandtab: */ diff --git a/smarty/plugins/function.popup_init.php b/smarty/plugins/function.popup_init.php index d9b42bd..93cb454 100644 --- a/smarty/plugins/function.popup_init.php +++ b/smarty/plugins/function.popup_init.php @@ -14,20 +14,21 @@ * Purpose: initialize overlib * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init} * (Smarty online manual) + * @author Monte Ohrt * @param array * @param Smarty * @return string */ function smarty_function_popup_init($params, &$smarty) { - $zindex = 1000; - + $zindex = 1000; + if (!empty($params['zindex'])) { - $zindex = $params['zindex']; - } - + $zindex = $params['zindex']; + } + if (!empty($params['src'])) { - return '' . "\n" + return '' . "\n" . '' . "\n"; } else { $smarty->trigger_error("popup_init: missing src parameter"); diff --git a/smarty/plugins/modifier.capitalize.php b/smarty/plugins/modifier.capitalize.php index 41d63ed..bca951a 100644 --- a/smarty/plugins/modifier.capitalize.php +++ b/smarty/plugins/modifier.capitalize.php @@ -14,12 +14,30 @@ * Purpose: capitalize words in the string * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE * capitalize (Smarty online manual) + * @author Monte Ohrt * @param string * @return string */ -function smarty_modifier_capitalize($string) +function smarty_modifier_capitalize($string, $uc_digits = false) { - return ucwords($string); + smarty_modifier_capitalize_ucfirst(null, $uc_digits); + return preg_replace_callback('!\b\w+\b!', 'smarty_modifier_capitalize_ucfirst', $string); } +function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null) +{ + static $_uc_digits = false; + + if(isset($uc_digits)) { + $_uc_digits = $uc_digits; + return; + } + + if(!preg_match('!\d!',$string[0]) || $_uc_digits) + return ucfirst($string[0]); + else + return $string[0]; +} + + ?> diff --git a/smarty/plugins/modifier.cat.php b/smarty/plugins/modifier.cat.php index 8dc7324..2e37940 100644 --- a/smarty/plugins/modifier.cat.php +++ b/smarty/plugins/modifier.cat.php @@ -17,7 +17,7 @@ * Example: {$var|cat:"foo"} * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat * (Smarty online manual) - * @author Monte Ohrt + * @author Monte Ohrt * @version 1.0 * @param string * @param string @@ -25,7 +25,7 @@ */ function smarty_modifier_cat($string, $cat) { - return $string . $cat; + return $string . $cat; } /* vim: set expandtab: */ diff --git a/smarty/plugins/modifier.count_characters.php b/smarty/plugins/modifier.count_characters.php index 49ce655..5ed9a87 100644 --- a/smarty/plugins/modifier.count_characters.php +++ b/smarty/plugins/modifier.count_characters.php @@ -14,6 +14,7 @@ * Purpose: count the number of characters in a text * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php * count_characters (Smarty online manual) + * @author Monte Ohrt * @param string * @param boolean include whitespace in the character count * @return integer diff --git a/smarty/plugins/modifier.count_paragraphs.php b/smarty/plugins/modifier.count_paragraphs.php index 6a9833c..e0e274d 100644 --- a/smarty/plugins/modifier.count_paragraphs.php +++ b/smarty/plugins/modifier.count_paragraphs.php @@ -14,6 +14,7 @@ * Purpose: count the number of paragraphs in a text * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php * count_paragraphs (Smarty online manual) + * @author Monte Ohrt * @param string * @return integer */ diff --git a/smarty/plugins/modifier.count_sentences.php b/smarty/plugins/modifier.count_sentences.php index 0c210f0..f66ea17 100644 --- a/smarty/plugins/modifier.count_sentences.php +++ b/smarty/plugins/modifier.count_sentences.php @@ -14,6 +14,7 @@ * Purpose: count the number of sentences in a text * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php * count_sentences (Smarty online manual) + * @author Monte Ohrt * @param string * @return integer */ diff --git a/smarty/plugins/modifier.count_words.php b/smarty/plugins/modifier.count_words.php index 42c8a74..9d339f5 100644 --- a/smarty/plugins/modifier.count_words.php +++ b/smarty/plugins/modifier.count_words.php @@ -14,6 +14,7 @@ * Purpose: count the number of words in a text * @link http://smarty.php.net/manual/en/language.modifier.count.words.php * count_words (Smarty online manual) + * @author Monte Ohrt * @param string * @return integer */ diff --git a/smarty/plugins/modifier.csv.php b/smarty/plugins/modifier.csv.php index 145c41b..4c715c4 100644 --- a/smarty/plugins/modifier.csv.php +++ b/smarty/plugins/modifier.csv.php @@ -12,12 +12,13 @@ * Type: modifier
* Name: csv
* Purpose: format string for CSV output + * @author Andreas Gohr * @param string * @return string */ function smarty_modifier_csv($string) { - return '"'.strtr(trim($string),'"','""').'"'; + return '"'.strtr(trim($string),'"','""').'"'; } ?> diff --git a/smarty/plugins/modifier.date_format.php b/smarty/plugins/modifier.date_format.php index dbe26a5..523c144 100644 --- a/smarty/plugins/modifier.date_format.php +++ b/smarty/plugins/modifier.date_format.php @@ -11,7 +11,7 @@ require_once $smarty->_get_plugin_filepath('shared','make_timestamp'); /** * Smarty date_format modifier plugin - * + * * Type: modifier
* Name: date_format
* Purpose: format datestamps via strftime
@@ -21,6 +21,7 @@ require_once $smarty->_get_plugin_filepath('shared','make_timestamp'); * - default_date: default date if $string is empty * @link http://smarty.php.net/manual/en/language.modifier.date.format.php * date_format (Smarty online manual) + * @author Monte Ohrt * @param string * @param string * @param string @@ -29,13 +30,18 @@ require_once $smarty->_get_plugin_filepath('shared','make_timestamp'); */ function smarty_modifier_date_format($string, $format="%b %e, %Y", $default_date=null) { - if($string != '') { - return strftime($format, smarty_make_timestamp($string)); - } elseif (isset($default_date) && $default_date != '') { - return strftime($format, smarty_make_timestamp($default_date)); - } else { - return; - } + if (substr(PHP_OS,0,3) == 'WIN') { + $_win_from = array ('%e', '%T', '%D'); + $_win_to = array ('%#d', '%H:%M:%S', '%m/%d/%y'); + $format = str_replace($_win_from, $_win_to, $format); + } + if($string != '') { + return strftime($format, smarty_make_timestamp($string)); + } elseif (isset($default_date) && $default_date != '') { + return strftime($format, smarty_make_timestamp($default_date)); + } else { + return; + } } /* vim: set expandtab: */ diff --git a/smarty/plugins/modifier.debug_print_var.php b/smarty/plugins/modifier.debug_print_var.php index 3528311..d28956a 100644 --- a/smarty/plugins/modifier.debug_print_var.php +++ b/smarty/plugins/modifier.debug_print_var.php @@ -14,6 +14,7 @@ * Purpose: formats variable contents for display in the console * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php * debug_print_var (Smarty online manual) + * @author Monte Ohrt * @param array|object * @param integer * @param integer @@ -21,14 +22,13 @@ */ function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40) { - $_replace = array("\n"=>'\n', "\r"=>'\r', "\t"=>'\t'); + $_replace = array("\n"=>'\n', "\r"=>'\r', "\t"=>'\t'); if (is_array($var)) { $results = "Array (".count($var).")"; foreach ($var as $curr_key => $curr_val) { $return = smarty_modifier_debug_print_var($curr_val, $depth+1, $length); $results .= "
".str_repeat(' ', $depth*2)."".strtr($curr_key, $_replace)." => $return"; } - return $results; } else if (is_object($var)) { $object_vars = get_object_vars($var); $results = "".get_class($var)." Object (".count($object_vars).")"; @@ -36,11 +36,11 @@ function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40) $return = smarty_modifier_debug_print_var($curr_val, $depth+1, $length); $results .= "
".str_repeat(' ', $depth*2)."$curr_key => $return"; } - return $results; + } else if (is_resource($var)) { + $results = ''.(string)$var.''; + } else if (empty($var) && $var != "0") { + $results = 'empty'; } else { - if (empty($var) && $var != "0") { - return 'empty'; - } if (strlen($var) > $length ) { $results = substr($var, 0, $length-3).'...'; } else { @@ -48,8 +48,8 @@ function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40) } $results = htmlspecialchars($results); $results = strtr($results, $_replace); - return $results; } + return $results; } /* vim: set expandtab: */ diff --git a/smarty/plugins/modifier.default.php b/smarty/plugins/modifier.default.php index 8268e39..70011fd 100644 --- a/smarty/plugins/modifier.default.php +++ b/smarty/plugins/modifier.default.php @@ -14,6 +14,7 @@ * Purpose: designate default value for empty variables * @link http://smarty.php.net/manual/en/language.modifier.default.php * default (Smarty online manual) + * @author Monte Ohrt * @param string * @param string * @return string diff --git a/smarty/plugins/modifier.escape.php b/smarty/plugins/modifier.escape.php index dc7bae2..a2f52b2 100644 --- a/smarty/plugins/modifier.escape.php +++ b/smarty/plugins/modifier.escape.php @@ -14,71 +14,80 @@ * Purpose: Escape the string according to escapement type * @link http://smarty.php.net/manual/en/language.modifier.escape.php * escape (Smarty online manual) + * @author Monte Ohrt * @param string * @param html|htmlall|url|quotes|hex|hexentity|javascript * @return string */ -function smarty_modifier_escape($string, $esc_type = 'html') +function smarty_modifier_escape($string, $esc_type = 'html', $char_set = 'ISO-8859-1') { switch ($esc_type) { case 'html': - return htmlspecialchars($string, ENT_QUOTES); + return htmlspecialchars($string, ENT_QUOTES, $char_set); case 'htmlall': - return htmlentities($string, ENT_QUOTES); + return htmlentities($string, ENT_QUOTES, $char_set); case 'url': - return urlencode($string); + return rawurlencode($string); + case 'urlpathinfo': + return str_replace('%2F','/',rawurlencode($string)); + case 'quotes': // escape unescaped single quotes return preg_replace("%(?'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n')); + // escape quotes and backslashes, newlines, etc. + return strtr($string, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n',''<\/')); + + case 'mail': + // safe way to display e-mail address on a web page + return str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $string); + + case 'nonstd': + // escape non-standard chars, such as ms document quotes + $_res = ''; + for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) { + $_ord = ord(substr($string, $_i, 1)); + // non-standard char, escape it + if($_ord >= 126){ + $_res .= '&#' . $_ord . ';'; + } + else { + $_res .= substr($string, $_i, 1); + } + } + return $_res; default: return $string; } } -function smarty_modifier_escape_qp_enc( $input = "") { - $hex = array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'); - $escape = "="; - $linlen = strlen($input); - $newline = ''; - for($i = 0; $i < $linlen; $i++) { - $c = substr( $input, $i, 1 ); - $dec = ord( $c ); - if( ($dec == 61) || ($dec < 32 ) || ($dec > 126) ){ - $h2 = floor($dec/16); - $h1 = floor($dec%16); - $c = $escape.$hex["$h2"].$hex["$h1"]; - } - $newline .= $c; - } - return $newline; -} - /* vim: set expandtab: */ ?> diff --git a/smarty/plugins/modifier.indent.php b/smarty/plugins/modifier.indent.php index 552c3e1..394147a 100644 --- a/smarty/plugins/modifier.indent.php +++ b/smarty/plugins/modifier.indent.php @@ -14,6 +14,7 @@ * Purpose: indent lines of text * @link http://smarty.php.net/manual/en/language.modifier.indent.php * indent (Smarty online manual) + * @author Monte Ohrt * @param string * @param integer * @param string @@ -21,7 +22,7 @@ */ function smarty_modifier_indent($string,$chars=4,$char=" ") { - return preg_replace('!^!m',str_repeat($char,$chars),$string); + return preg_replace('!^!m',str_repeat($char,$chars),$string); } ?> diff --git a/smarty/plugins/modifier.lower.php b/smarty/plugins/modifier.lower.php index ee37423..20e7a8d 100644 --- a/smarty/plugins/modifier.lower.php +++ b/smarty/plugins/modifier.lower.php @@ -14,12 +14,13 @@ * Purpose: convert string to lowercase * @link http://smarty.php.net/manual/en/language.modifier.lower.php * lower (Smarty online manual) + * @author Monte Ohrt * @param string * @return string */ function smarty_modifier_lower($string) { - return strtolower($string); + return strtolower($string); } ?> diff --git a/smarty/plugins/modifier.nl2br.php b/smarty/plugins/modifier.nl2br.php index 5a9b744..d6fabff 100644 --- a/smarty/plugins/modifier.nl2br.php +++ b/smarty/plugins/modifier.nl2br.php @@ -21,7 +21,7 @@ * @link http://smarty.php.net/manual/en/language.modifier.nl2br.php * nl2br (Smarty online manual) * @version 1.0 - * @author Monte Ohrt + * @author Monte Ohrt * @param string * @return string */ diff --git a/smarty/plugins/modifier.noteparser.php b/smarty/plugins/modifier.noteparser.php index 18553ce..0f96f00 100644 --- a/smarty/plugins/modifier.noteparser.php +++ b/smarty/plugins/modifier.noteparser.php @@ -14,7 +14,7 @@ * Date: Feb 26, 2003 * Purpose: Converts plaintext notes to richer HTML (very simple) * Example: {$entry.note|noteparser} - * @author Andreas Gohr + * @author Andreas Gohr * @param string * @return string */ diff --git a/smarty/plugins/modifier.regex_replace.php b/smarty/plugins/modifier.regex_replace.php index b9cc865..d4d2030 100644 --- a/smarty/plugins/modifier.regex_replace.php +++ b/smarty/plugins/modifier.regex_replace.php @@ -11,9 +11,10 @@ * * Type: modifier
* Name: regex_replace
- * Purpose: regular epxression search/replace + * Purpose: regular expression search/replace * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php * regex_replace (Smarty online manual) + * @author Monte Ohrt * @param string * @param string|array * @param string|array @@ -21,6 +22,11 @@ */ function smarty_modifier_regex_replace($string, $search, $replace) { + if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) { + /* remove eval-modifier from $search */ + $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]); + } + return preg_replace($search, $replace, $string); } diff --git a/smarty/plugins/modifier.replace.php b/smarty/plugins/modifier.replace.php index 2a43515..df041c8 100644 --- a/smarty/plugins/modifier.replace.php +++ b/smarty/plugins/modifier.replace.php @@ -14,6 +14,7 @@ * Purpose: simple search/replace * @link http://smarty.php.net/manual/en/language.modifier.replace.php * replace (Smarty online manual) + * @author Monte Ohrt * @param string * @param string * @param string diff --git a/smarty/plugins/modifier.spacify.php b/smarty/plugins/modifier.spacify.php index dad057f..c2423f4 100644 --- a/smarty/plugins/modifier.spacify.php +++ b/smarty/plugins/modifier.spacify.php @@ -14,6 +14,7 @@ * Purpose: add spaces between characters in a string * @link http://smarty.php.net/manual/en/language.modifier.spacify.php * spacify (Smarty online manual) + * @author Monte Ohrt * @param string * @param string * @return string diff --git a/smarty/plugins/modifier.string_format.php b/smarty/plugins/modifier.string_format.php index efd6215..9e051a5 100644 --- a/smarty/plugins/modifier.string_format.php +++ b/smarty/plugins/modifier.string_format.php @@ -14,6 +14,7 @@ * Purpose: format strings via sprintf * @link http://smarty.php.net/manual/en/language.modifier.string.format.php * string_format (Smarty online manual) + * @author Monte Ohrt * @param string * @param string * @return string diff --git a/smarty/plugins/modifier.strip.php b/smarty/plugins/modifier.strip.php index 0db2f8a..cc5c453 100644 --- a/smarty/plugins/modifier.strip.php +++ b/smarty/plugins/modifier.strip.php @@ -17,7 +17,7 @@ * Date: September 25th, 2002 * @link http://smarty.php.net/manual/en/language.modifier.strip.php * strip (Smarty online manual) - * @author Monte Ohrt + * @author Monte Ohrt * @version 1.0 * @param string * @param string @@ -25,7 +25,7 @@ */ function smarty_modifier_strip($text, $replace = ' ') { - return preg_replace('!\s+!', $replace, $text); + return preg_replace('!\s+!', $replace, $text); } /* vim: set expandtab: */ diff --git a/smarty/plugins/modifier.strip_tags.php b/smarty/plugins/modifier.strip_tags.php index 45f1ec1..93011a8 100644 --- a/smarty/plugins/modifier.strip_tags.php +++ b/smarty/plugins/modifier.strip_tags.php @@ -14,6 +14,7 @@ * Purpose: strip html tags from text * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php * strip_tags (Smarty online manual) + * @author Monte Ohrt * @param string * @param boolean * @return string diff --git a/smarty/plugins/modifier.truncate.php b/smarty/plugins/modifier.truncate.php index c82b14a..d96de5f 100644 --- a/smarty/plugins/modifier.truncate.php +++ b/smarty/plugins/modifier.truncate.php @@ -12,30 +12,37 @@ * Type: modifier
* Name: truncate
* Purpose: Truncate a string to a certain length if necessary, - * optionally splitting in the middle of a word, and - * appending the $etc string. + * optionally splitting in the middle of a word, and + * appending the $etc string or inserting $etc into the middle. * @link http://smarty.php.net/manual/en/language.modifier.truncate.php * truncate (Smarty online manual) + * @author Monte Ohrt * @param string * @param integer * @param string * @param boolean + * @param boolean * @return string */ function smarty_modifier_truncate($string, $length = 80, $etc = '...', - $break_words = false) + $break_words = false, $middle = false) { if ($length == 0) return ''; if (strlen($string) > $length) { - $length -= strlen($etc); - if (!$break_words) - $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1)); - - return substr($string, 0, $length).$etc; - } else + $length -= strlen($etc); + if (!$break_words && !$middle) { + $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1)); + } + if(!$middle) { + return substr($string, 0, $length).$etc; + } else { + return substr($string, 0, $length/2) . $etc . substr($string, -$length/2); + } + } else { return $string; + } } /* vim: set expandtab: */ diff --git a/smarty/plugins/modifier.upper.php b/smarty/plugins/modifier.upper.php index 9d9ef35..c12480f 100644 --- a/smarty/plugins/modifier.upper.php +++ b/smarty/plugins/modifier.upper.php @@ -14,12 +14,13 @@ * Purpose: convert string to uppercase * @link http://smarty.php.net/manual/en/language.modifier.upper.php * upper (Smarty online manual) + * @author Monte Ohrt * @param string * @return string */ function smarty_modifier_upper($string) { - return strtoupper($string); + return strtoupper($string); } ?> diff --git a/smarty/plugins/modifier.wordwrap.php b/smarty/plugins/modifier.wordwrap.php index 55b4a1d..ce07181 100644 --- a/smarty/plugins/modifier.wordwrap.php +++ b/smarty/plugins/modifier.wordwrap.php @@ -14,6 +14,7 @@ * Purpose: wrap a string of text at a given length * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php * wordwrap (Smarty online manual) + * @author Monte Ohrt * @param string * @param integer * @param string @@ -22,7 +23,7 @@ */ function smarty_modifier_wordwrap($string,$length=80,$break="\n",$cut=false) { - return wordwrap($string,$length,$break,$cut); + return wordwrap($string,$length,$break,$cut); } ?> diff --git a/smarty/plugins/outputfilter.trimwhitespace.php b/smarty/plugins/outputfilter.trimwhitespace.php index e82acc1..01e35e0 100644 --- a/smarty/plugins/outputfilter.trimwhitespace.php +++ b/smarty/plugins/outputfilter.trimwhitespace.php @@ -16,60 +16,60 @@ * template source after it gets interpreted, cleaning * up code and saving bandwidth. Does not affect * <
>
and blocks.
- * Install: Drop into the plugin directory, call + * Install: Drop into the plugin directory, call * $smarty->load_filter('output','trimwhitespace'); * from application. - * @author Monte Ohrt + * @author Monte Ohrt * @author Contributions from Lars Noschinski * @version 1.3 * @param string * @param Smarty */ - function smarty_outputfilter_trimwhitespace($source, &$smarty) - { +function smarty_outputfilter_trimwhitespace($source, &$smarty) +{ // Pull out the script blocks preg_match_all("!]+>.*?!is", $source, $match); $_script_blocks = $match[0]; $source = preg_replace("!]+>.*?!is", - '@@@SMARTY:TRIM:SCRIPT@@@', $source); + '@@@SMARTY:TRIM:SCRIPT@@@', $source); // Pull out the pre blocks preg_match_all("!
.*?
!is", $source, $match); $_pre_blocks = $match[0]; $source = preg_replace("!
.*?
!is", - '@@@SMARTY:TRIM:PRE@@@', $source); + '@@@SMARTY:TRIM:PRE@@@', $source); // Pull out the textarea blocks preg_match_all("!]+>.*?!is", $source, $match); $_textarea_blocks = $match[0]; $source = preg_replace("!]+>.*?!is", - '@@@SMARTY:TRIM:TEXTAREA@@@', $source); + '@@@SMARTY:TRIM:TEXTAREA@@@', $source); - // remove all leading spaces, tabs and carriage returns NOT - // preceeded by a php close tag. - $source = trim(preg_replace('/((?)\n)[\s]+/m', '\1', $source)); + // remove all leading spaces, tabs and carriage returns NOT + // preceeded by a php close tag. + $source = trim(preg_replace('/((?)\n)[\s]+/m', '\1', $source)); - // replace script blocks - smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source); + // replace script blocks + smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source); - // replace pre blocks - smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source); + // replace pre blocks + smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source); // replace textarea blocks - smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source); + smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source); - return $source; - } + return $source; +} function smarty_outputfilter_trimwhitespace_replace($search_str, $replace, &$subject) { - $_len = strlen($search_str); - $_pos = 0; - for ($_i=0, $_count=count($replace); $_i<$_count; $_i++) - if (($_pos=strpos($subject, $search_str, $_pos))!==false) - $subject = substr_replace($subject, $replace[$_i], $_pos, $_len); - else - break; - + $_len = strlen($search_str); + $_pos = 0; + for ($_i=0, $_count=count($replace); $_i<$_count; $_i++) + if (($_pos=strpos($subject, $search_str, $_pos))!==false) + $subject = substr_replace($subject, $replace[$_i], $_pos, $_len); + else + break; + } ?> diff --git a/smarty/plugins/shared.escape_special_chars.php b/smarty/plugins/shared.escape_special_chars.php index 090ee9c..c07ce31 100644 --- a/smarty/plugins/shared.escape_special_chars.php +++ b/smarty/plugins/shared.escape_special_chars.php @@ -12,17 +12,18 @@ * Function: smarty_function_escape_special_chars
* Purpose: used by other smarty functions to escape * special chars except for already escaped ones + * @author Monte Ohrt * @param string * @return string */ function smarty_function_escape_special_chars($string) { - if(!is_array($string)) { - $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); - $string = htmlspecialchars($string); - $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string); - } - return $string; + if(!is_array($string)) { + $string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string); + $string = htmlspecialchars($string); + $string = str_replace(array('%%%SMARTY_START%%%','%%%SMARTY_END%%%'), array('&',';'), $string); + } + return $string; } /* vim: set expandtab: */ diff --git a/smarty/plugins/shared.make_timestamp.php b/smarty/plugins/shared.make_timestamp.php index acdd777..b42eb11 100644 --- a/smarty/plugins/shared.make_timestamp.php +++ b/smarty/plugins/shared.make_timestamp.php @@ -10,32 +10,35 @@ * Function: smarty_make_timestamp
* Purpose: used by other smarty functions to make a timestamp * from a string. + * @author Monte Ohrt * @param string * @return string */ function smarty_make_timestamp($string) { if(empty($string)) { - $string = "now"; - } - $time = strtotime($string); - if (is_numeric($time) && $time != -1) - return $time; - - // is mysql timestamp format of YYYYMMDDHHMMSS? - if (preg_match('/^\d{14}$/', $string)) { - $time = mktime(substr($string,8,2),substr($string,10,2),substr($string,12,2), - substr($string,4,2),substr($string,6,2),substr($string,0,4)); + // use "now": + $time = time(); - return $time; + } elseif (preg_match('/^\d{14}$/', $string)) { + // it is mysql timestamp format of YYYYMMDDHHMMSS? + $time = mktime(substr($string, 8, 2),substr($string, 10, 2),substr($string, 12, 2), + substr($string, 4, 2),substr($string, 6, 2),substr($string, 0, 4)); + + } elseif (is_numeric($string)) { + // it is a numeric string, we handle it as timestamp + $time = (int)$string; + + } else { + // strtotime should handle it + $time = strtotime($string); + if ($time == -1 || $time === false) { + // strtotime() was not able to parse $string, use "now": + $time = time(); + } } + return $time; - // couldn't recognize it, try to return a time - $time = (int) $string; - if ($time > 0) - return $time; - else - return time(); } /* vim: set expandtab: */ -- 2.39.5