Update smarty for admin to 2.6.28

This commit is contained in:
botanic 2014-09-13 13:09:48 -07:00
parent 9ee1faeb42
commit 62567d313a
55 changed files with 5229 additions and 4882 deletions

View file

@ -17,15 +17,19 @@
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
* @link http://smarty.php.net/ * For questions, help, comments, discussion, etc., please join the
* @version 2.6.9 * Smarty mailing list. Send a blank e-mail to
* smarty-discussion-subscribe@googlegroups.com
*
* @link http://www.smarty.net/
* @version 2.6.25-dev
* @copyright Copyright: 2001-2005 New Digital Group, Inc. * @copyright Copyright: 2001-2005 New Digital Group, Inc.
* @author Andrei Zmievski <andrei@php.net> * @author Andrei Zmievski <andrei@php.net>
* @access public * @access public
* @package Smarty * @package Smarty
*/ */
/* $Id: Config_File.class.php,v 1.1 2006/05/29 16:38:21 powles Exp $ */ /* $Id: Config_File.class.php 3149 2009-05-23 20:59:25Z monte.ohrt $ */
/** /**
* Config file reading class * Config file reading class
@ -105,7 +109,7 @@ class Config_File {
* @param string $var_name (optional) variable to get info for * @param string $var_name (optional) variable to get info for
* @return string|array a value or array of values * @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)) { if (empty($file_name)) {
$this->_trigger_error_msg('Empty config file name'); $this->_trigger_error_msg('Empty config file name');
@ -285,9 +289,9 @@ class Config_File {
$line = $lines[$i]; $line = $lines[$i];
if (empty($line)) continue; if (empty($line)) continue;
if ( $line{0} == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) { if ( substr($line, 0, 1) == '[' && preg_match('!^\[(.*?)\]!', $line, $match) ) {
/* section found */ /* section found */
if ($match[1]{0} == '.') { if (substr($match[1], 0, 1) == '.') {
/* hidden section */ /* hidden section */
if ($this->read_hidden) { if ($this->read_hidden) {
$section_name = substr($match[1], 1); $section_name = substr($match[1], 1);
@ -347,7 +351,7 @@ class Config_File {
*/ */
function _set_config_var(&$container, $var_name, $var_value, $booleanize) function _set_config_var(&$container, $var_name, $var_value, $booleanize)
{ {
if ($var_name{0} == '.') { if (substr($var_name, 0, 1) == '.') {
if (!$this->read_hidden) if (!$this->read_hidden)
return; return;
else else

View file

@ -20,17 +20,17 @@
* *
* For questions, help, comments, discussion, etc., please join the * For questions, help, comments, discussion, etc., please join the
* Smarty mailing list. Send a blank e-mail to * Smarty mailing list. Send a blank e-mail to
* smarty-general-subscribe@lists.php.net * smarty-discussion-subscribe@googlegroups.com
* *
* @link http://smarty.php.net/ * @link http://www.smarty.net/
* @copyright 2001-2005 New Digital Group, Inc. * @copyright 2001-2005 New Digital Group, Inc.
* @author Monte Ohrt <monte at ohrt dot com> * @author Monte Ohrt <monte at ohrt dot com>
* @author Andrei Zmievski <andrei@php.net> * @author Andrei Zmievski <andrei@php.net>
* @package Smarty * @package Smarty
* @version 2.6.9 * @version 2.6.28
*/ */
/* $Id: Smarty.class.php,v 1.1 2006/05/29 16:38:21 powles Exp $ */ /* $Id: Smarty.class.php 4660 2012-09-24 20:05:15Z uwe.tews@googlemail.com $ */
/** /**
* DIR_SEP isn't used anymore, but third party apps might * DIR_SEP isn't used anymore, but third party apps might
@ -107,7 +107,7 @@ class Smarty
/** /**
* When set, smarty does uses this value as error_reporting-level. * When set, smarty does uses this value as error_reporting-level.
* *
* @var boolean * @var integer
*/ */
var $error_reporting = null; var $error_reporting = null;
@ -236,7 +236,8 @@ class Smarty
'INCLUDE_ANY' => false, 'INCLUDE_ANY' => false,
'PHP_TAGS' => false, 'PHP_TAGS' => false,
'MODIFIER_FUNCS' => array('count'), 'MODIFIER_FUNCS' => array('count'),
'ALLOW_CONSTANTS' => false 'ALLOW_CONSTANTS' => false,
'ALLOW_SUPER_GLOBALS' => true
); );
/** /**
@ -464,7 +465,7 @@ class Smarty
* *
* @var string * @var string
*/ */
var $_version = '2.6.9'; var $_version = '2.6.28';
/** /**
* current template inclusion depth * current template inclusion depth
@ -838,69 +839,66 @@ class Smarty
* Registers a prefilter function to apply * Registers a prefilter function to apply
* to a template before compiling * to a template before compiling
* *
* @param string $function name of PHP function to register * @param callback $function
*/ */
function register_prefilter($function) function register_prefilter($function)
{ {
$_name = (is_array($function)) ? $function[1] : $function; $this->_plugins['prefilter'][$this->_get_filter_name($function)]
$this->_plugins['prefilter'][$_name]
= array($function, null, null, false); = array($function, null, null, false);
} }
/** /**
* Unregisters a prefilter function * Unregisters a prefilter function
* *
* @param string $function name of PHP function * @param callback $function
*/ */
function unregister_prefilter($function) function unregister_prefilter($function)
{ {
unset($this->_plugins['prefilter'][$function]); unset($this->_plugins['prefilter'][$this->_get_filter_name($function)]);
} }
/** /**
* Registers a postfilter function to apply * Registers a postfilter function to apply
* to a compiled template after compilation * to a compiled template after compilation
* *
* @param string $function name of PHP function to register * @param callback $function
*/ */
function register_postfilter($function) function register_postfilter($function)
{ {
$_name = (is_array($function)) ? $function[1] : $function; $this->_plugins['postfilter'][$this->_get_filter_name($function)]
$this->_plugins['postfilter'][$_name]
= array($function, null, null, false); = array($function, null, null, false);
} }
/** /**
* Unregisters a postfilter function * Unregisters a postfilter function
* *
* @param string $function name of PHP function * @param callback $function
*/ */
function unregister_postfilter($function) function unregister_postfilter($function)
{ {
unset($this->_plugins['postfilter'][$function]); unset($this->_plugins['postfilter'][$this->_get_filter_name($function)]);
} }
/** /**
* Registers an output filter function to apply * Registers an output filter function to apply
* to a template output * to a template output
* *
* @param string $function name of PHP function * @param callback $function
*/ */
function register_outputfilter($function) function register_outputfilter($function)
{ {
$_name = (is_array($function)) ? $function[1] : $function; $this->_plugins['outputfilter'][$this->_get_filter_name($function)]
$this->_plugins['outputfilter'][$_name]
= array($function, null, null, false); = array($function, null, null, false);
} }
/** /**
* Unregisters an outputfilter function * Unregisters an outputfilter function
* *
* @param string $function name of PHP function * @param callback $function
*/ */
function unregister_outputfilter($function) function unregister_outputfilter($function)
{ {
unset($this->_plugins['outputfilter'][$function]); unset($this->_plugins['outputfilter'][$this->_get_filter_name($function)]);
} }
/** /**
@ -1055,9 +1053,12 @@ class Smarty
{ {
if(!isset($name)) { if(!isset($name)) {
return $this->_tpl_vars; return $this->_tpl_vars;
} } elseif(isset($this->_tpl_vars[$name])) {
if(isset($this->_tpl_vars[$name])) {
return $this->_tpl_vars[$name]; return $this->_tpl_vars[$name];
} else {
// var non-existant, return valid reference
$_tmp = null;
return $_tmp;
} }
} }
@ -1074,6 +1075,10 @@ class Smarty
return $this->_config[0]['vars']; return $this->_config[0]['vars'];
} else if(isset($this->_config[0]['vars'][$name])) { } else if(isset($this->_config[0]['vars'][$name])) {
return $this->_config[0]['vars'][$name]; return $this->_config[0]['vars'][$name];
} else {
// var non-existant, return valid reference
$_tmp = null;
return $_tmp;
} }
} }
@ -1085,7 +1090,8 @@ class Smarty
*/ */
function trigger_error($error_msg, $error_type = E_USER_WARNING) function trigger_error($error_msg, $error_type = E_USER_WARNING)
{ {
trigger_error("Smarty error: $error_msg", $error_type); $msg = htmlentities($error_msg);
trigger_error("Smarty error: $msg", $error_type);
} }
@ -1544,7 +1550,7 @@ class Smarty
$params['source_content'] = $this->_read_file($_resource_name); $params['source_content'] = $this->_read_file($_resource_name);
} }
$params['resource_timestamp'] = filemtime($_resource_name); $params['resource_timestamp'] = filemtime($_resource_name);
$_return = is_file($_resource_name); $_return = is_file($_resource_name) && is_readable($_resource_name);
break; break;
default: default:
@ -1691,8 +1697,8 @@ class Smarty
*/ */
function _dequote($string) function _dequote($string)
{ {
if (($string{0} == "'" || $string{0} == '"') && if ((substr($string, 0, 1) == "'" || substr($string, 0, 1) == '"') &&
$string{strlen($string)-1} == $string{0}) substr($string, -1) == substr($string, 0, 1))
return substr($string, 1, -1); return substr($string, 1, -1);
else else
return $string; return $string;
@ -1707,8 +1713,11 @@ class Smarty
*/ */
function _read_file($filename) function _read_file($filename)
{ {
if ( file_exists($filename) && ($fd = @fopen($filename, 'rb')) ) { if ( file_exists($filename) && is_readable($filename) && ($fd = @fopen($filename, 'rb')) ) {
$contents = ($size = filesize($filename)) ? fread($fd, $size) : ''; $contents = '';
while (!feof($fd)) {
$contents .= fread($fd, 8192);
}
fclose($fd); fclose($fd);
return $contents; return $contents;
} else { } else {
@ -1889,7 +1898,7 @@ class Smarty
if ($this->_cache_including) { if ($this->_cache_including) {
/* return next set of cache_attrs */ /* return next set of cache_attrs */
$_return =& current($_cache_attrs); $_return = current($_cache_attrs);
next($_cache_attrs); next($_cache_attrs);
return $_return; return $_return;
@ -1925,6 +1934,25 @@ class Smarty
{ {
return eval($code); return eval($code);
} }
/**
* Extracts the filter name from the given callback
*
* @param callback $function
* @return string
*/
function _get_filter_name($function)
{
if (is_array($function)) {
$_class_name = (is_object($function[0]) ?
get_class($function[0]) : $function[0]);
return $_class_name . '_' . $function[1];
}
else {
return $function;
}
}
/**#@-*/ /**#@-*/
} }

View file

@ -21,12 +21,12 @@
* @link http://smarty.php.net/ * @link http://smarty.php.net/
* @author Monte Ohrt <monte at ohrt dot com> * @author Monte Ohrt <monte at ohrt dot com>
* @author Andrei Zmievski <andrei@php.net> * @author Andrei Zmievski <andrei@php.net>
* @version 2.6.9 * @version 2.6.25-dev
* @copyright 2001-2005 New Digital Group, Inc. * @copyright 2001-2005 New Digital Group, Inc.
* @package Smarty * @package Smarty
*/ */
/* $Id: Smarty_Compiler.class.php,v 1.1 2006/05/29 16:38:21 powles Exp $ */ /* $Id: Smarty_Compiler.class.php 4779 2013-09-30 19:14:32Z Uwe.Tews@googlemail.com $ */
/** /**
* Template compiling class * Template compiling class
@ -262,11 +262,11 @@ class Smarty_Compiler extends Smarty {
reset($this->_folded_blocks); reset($this->_folded_blocks);
/* replace special blocks by "{php}" */ /* replace special blocks by "{php}" */
$source_content = preg_replace($search.'e', "'" $source_content = preg_replace_callback($search, create_function ('$matches', "return '"
. $this->_quote_replace($this->left_delimiter) . 'php' . $this->_quote_replace($this->left_delimiter) . 'php'
. "' . str_repeat(\"\n\", substr_count('\\0', \"\n\")) .'" . "' . str_repeat(\"\n\", substr_count('\$matches[1]', \"\n\")) .'"
. $this->_quote_replace($this->right_delimiter) . $this->_quote_replace($this->right_delimiter)
. "'" . "';")
, $source_content); , $source_content);
/* Gather all template tags. */ /* Gather all template tags. */
@ -278,7 +278,7 @@ class Smarty_Compiler extends Smarty {
/* loop through text blocks */ /* loop through text blocks */
for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) { for ($curr_tb = 0, $for_max = count($text_blocks); $curr_tb < $for_max; $curr_tb++) {
/* match anything resembling php tags */ /* 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*[\"\']?\s*php\s*[\"\']?)~is', $text_blocks[$curr_tb], $sp_match)) {
/* replace tags with placeholders to prevent recursive replacements */ /* replace tags with placeholders to prevent recursive replacements */
$sp_match[1] = array_unique($sp_match[1]); $sp_match[1] = array_unique($sp_match[1]);
usort($sp_match[1], '_smarty_sort_length'); usort($sp_match[1], '_smarty_sort_length');
@ -350,18 +350,31 @@ class Smarty_Compiler extends Smarty {
} }
$compiled_content = ''; $compiled_content = '';
$tag_guard = '%%%SMARTYOTG' . md5(uniqid(rand(), true)) . '%%%';
/* Interleave the compiled contents and text blocks to get the final result. */ /* Interleave the compiled contents and text blocks to get the final result. */
for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) { for ($i = 0, $for_max = count($compiled_tags); $i < $for_max; $i++) {
if ($compiled_tags[$i] == '') { if ($compiled_tags[$i] == '') {
// tag result empty, remove first newline from following text block // 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]; // replace legit PHP tags with placeholder
$text_blocks[$i] = str_replace('<?', $tag_guard, $text_blocks[$i]);
$compiled_tags[$i] = str_replace('<?', $tag_guard, $compiled_tags[$i]);
$compiled_content .= $text_blocks[$i] . $compiled_tags[$i];
} }
$compiled_content .= $text_blocks[$i]; $compiled_content .= str_replace('<?', $tag_guard, $text_blocks[$i]);
// escape php tags created by interleaving
$compiled_content = str_replace('<?', "<?php echo '<?' ?>\n", $compiled_content);
$compiled_content = preg_replace("~(?<!')language\s*=\s*[\"\']?\s*php\s*[\"\']?~", "<?php echo 'language=php' ?>\n", $compiled_content);
// recover legit tags
$compiled_content = str_replace($tag_guard, '<?', $compiled_content);
// remove \n from the end of the file, if any // 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); $compiled_content = substr($compiled_content, 0, -1);
} }
@ -369,9 +382,6 @@ class Smarty_Compiler extends Smarty {
$compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content; $compiled_content = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $compiled_content;
} }
// remove unnecessary close/open tags
$compiled_content = preg_replace('~\?>\n?<\?php~', '', $compiled_content);
// run compiled template through postfilter functions // run compiled template through postfilter functions
if (count($this->_plugins['postfilter']) > 0) { if (count($this->_plugins['postfilter']) > 0) {
foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) { foreach ($this->_plugins['postfilter'] as $filter_name => $postfilter) {
@ -425,7 +435,7 @@ class Smarty_Compiler extends Smarty {
function _compile_tag($template_tag) function _compile_tag($template_tag)
{ {
/* Matched comment. */ /* Matched comment. */
if ($template_tag{0} == '*' && $template_tag{strlen($template_tag) - 1} == '*') if (substr($template_tag, 0, 1) == '*' && substr($template_tag, -1) == '*')
return ''; return '';
/* Split tag into two three parts: command, command modifiers and the arguments. */ /* Split tag into two three parts: command, command modifiers and the arguments. */
@ -529,7 +539,7 @@ class Smarty_Compiler extends Smarty {
case 'strip': case 'strip':
case '/strip': case '/strip':
if ($tag_command{0}=='/') { if (substr($tag_command, 0, 1)=='/') {
$this->_pop_tag('strip'); $this->_pop_tag('strip');
if (--$this->_strip_depth==0) { /* outermost closing {/strip} */ if (--$this->_strip_depth==0) { /* outermost closing {/strip} */
$this->_additional_newline = "\n"; $this->_additional_newline = "\n";
@ -664,7 +674,7 @@ class Smarty_Compiler extends Smarty {
*/ */
function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output) function _compile_block_tag($tag_command, $tag_args, $tag_modifier, &$output)
{ {
if ($tag_command{0} == '/') { if (substr($tag_command, 0, 1) == '/') {
$start_tag = false; $start_tag = false;
$tag_command = substr($tag_command, 1); $tag_command = substr($tag_command, 1);
} else } else
@ -726,17 +736,18 @@ class Smarty_Compiler extends Smarty {
if ($start_tag) { if ($start_tag) {
$output = '<?php ' . $this->_push_cacheable_state('block', $tag_command); $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
$arg_list = $this->_compile_arg_list('block', $tag_command, $attrs, $_cache_attrs=''); $_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 .= "$_cache_attrs\$this->_tag_stack[] = array('$tag_command', array(".implode(',', $arg_list).')); ';
$output .= $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], null, $this, $_block_repeat=true);'; $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(); ?>'; $output .= 'while ($_block_repeat) { ob_start(); ?>';
} else { } else {
$output = '<?php $_block_content = ob_get_contents(); ob_end_clean(); '; $output = '<?php $_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], $_block_content, $this, $_block_repeat=false)'; $_out_tag_text = $this->_compile_plugin_call('block', $tag_command).'($this->_tag_stack[count($this->_tag_stack)-1][1], $_block_content, $this, $_block_repeat)';
if ($tag_modifier != '') { if ($tag_modifier != '') {
$this->_parse_modifiers($_out_tag_text, $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) . '?>'; $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
} }
@ -801,7 +812,8 @@ class Smarty_Compiler extends Smarty {
$_cacheable_state = $this->_push_cacheable_state('function', $tag_command); $_cacheable_state = $this->_push_cacheable_state('function', $tag_command);
$attrs = $this->_parse_attrs($tag_args); $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);
$output = $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 != '') { if($tag_modifier != '') {
@ -826,7 +838,7 @@ class Smarty_Compiler extends Smarty {
*/ */
function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier) function _compile_registered_object_tag($tag_command, $attrs, $tag_modifier)
{ {
if ($tag_command{0} == '/') { if (substr($tag_command, 0, 1) == '/') {
$start_tag = false; $start_tag = false;
$tag_command = substr($tag_command, 1); $tag_command = substr($tag_command, 1);
} else { } else {
@ -857,7 +869,7 @@ class Smarty_Compiler extends Smarty {
// traditional argument format // traditional argument format
$args = implode(',', array_values($attrs)); $args = implode(',', array_values($attrs));
if (empty($args)) { if (empty($args)) {
$args = 'null'; $args = '';
} }
} }
@ -874,13 +886,13 @@ class Smarty_Compiler extends Smarty {
// block method // block method
if ($start_tag) { if ($start_tag) {
$prefix = "\$this->_tag_stack[] = array('$obj_comp', $args); "; $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();"; $prefix .= "while (\$_block_repeat) { ob_start();";
$return = null; $return = null;
$postfix = ''; $postfix = '';
} else { } else {
$prefix = "\$_obj_block_content = ob_get_contents(); ob_end_clean(); "; $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=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);"; $postfix = "} array_pop(\$this->_tag_stack);";
} }
} else { } else {
@ -922,7 +934,11 @@ class Smarty_Compiler extends Smarty {
$name = $this->_dequote($attrs['name']); $name = $this->_dequote($attrs['name']);
if (empty($name)) { if (empty($name)) {
$this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__); return $this->_syntax_error("missing insert name", E_USER_ERROR, __FILE__, __LINE__);
}
if (!preg_match('~^\w+$~', $name)) {
return $this->_syntax_error("'insert: 'name' must be an insert function name", E_USER_ERROR, __FILE__, __LINE__);
} }
if (!empty($attrs['script'])) { if (!empty($attrs['script'])) {
@ -1155,7 +1171,7 @@ class Smarty_Compiler extends Smarty {
} }
$item = $this->_dequote($attrs['item']); $item = $this->_dequote($attrs['item']);
if (!preg_match('~^\w+$~', $item)) { if (!preg_match('~^\w+$~', $item)) {
return $this->_syntax_error("'foreach: item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__); return $this->_syntax_error("foreach: 'item' must be a variable name (literal string)", E_USER_ERROR, __FILE__, __LINE__);
} }
if (isset($attrs['key'])) { if (isset($attrs['key'])) {
@ -1206,23 +1222,21 @@ class Smarty_Compiler extends Smarty {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
if ($start) { if ($start) {
if (isset($attrs['name'])) $buffer = isset($attrs['name']) ? $attrs['name'] : "'default'";
$buffer = $attrs['name']; $assign = isset($attrs['assign']) ? $attrs['assign'] : null;
else $append = isset($attrs['append']) ? $attrs['append'] : null;
$buffer = "'default'";
if (isset($attrs['assign']))
$assign = $attrs['assign'];
else
$assign = null;
$output = "<?php ob_start(); ?>"; $output = "<?php ob_start(); ?>";
$this->_capture_stack[] = array($buffer, $assign); $this->_capture_stack[] = array($buffer, $assign, $append);
} else { } else {
list($buffer, $assign) = array_pop($this->_capture_stack); list($buffer, $assign, $append) = array_pop($this->_capture_stack);
$output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); "; $output = "<?php \$this->_smarty_vars['capture'][$buffer] = ob_get_contents(); ";
if (isset($assign)) { if (isset($assign)) {
$output .= " \$this->assign($assign, ob_get_contents());"; $output .= " \$this->assign($assign, ob_get_contents());";
} }
if (isset($append)) {
$output .= " \$this->append($append, ob_get_contents());";
}
$output .= "ob_end_clean(); ?>"; $output .= "ob_end_clean(); ?>";
} }
@ -1250,6 +1264,13 @@ class Smarty_Compiler extends Smarty {
$tokens = $match[0]; $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 // make sure we have balanced parenthesis
$token_count = array_count_values($tokens); $token_count = array_count_values($tokens);
if(isset($token_count['(']) && $token_count['('] != $token_count[')']) { if(isset($token_count['(']) && $token_count['('] != $token_count[')']) {
@ -1342,9 +1363,14 @@ class Smarty_Compiler extends Smarty {
/* If last token was a ')', we operate on the parenthesized /* If last token was a ')', we operate on the parenthesized
expression. The start of the expression is on the stack. expression. The start of the expression is on the stack.
Otherwise, we operate on the last encountered token. */ Otherwise, we operate on the last encountered token. */
if ($tokens[$i-1] == ')') if ($tokens[$i-1] == ')') {
$is_arg_start = array_pop($is_arg_stack); $is_arg_start = array_pop($is_arg_stack);
else if ($is_arg_start != 0) {
if (preg_match('~^' . $this->_func_regexp . '$~', $tokens[$is_arg_start-1])) {
$is_arg_start--;
}
}
} else
$is_arg_start = $i-1; $is_arg_start = $i-1;
/* Construct the argument for 'is' expression, so it knows /* Construct the argument for 'is' expression, so it knows
what to operate on. */ what to operate on. */
@ -1372,7 +1398,7 @@ class Smarty_Compiler extends Smarty {
!in_array($token, $this->security_settings['IF_FUNCS'])) { !in_array($token, $this->security_settings['IF_FUNCS'])) {
$this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); $this->_syntax_error("(secure mode) '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__);
} }
} elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') { } elseif(preg_match('~^' . $this->_var_regexp . '$~', $token) && (strpos('+-*/^%&|', substr($token, -1)) === false) && isset($tokens[$i+1]) && $tokens[$i+1] == '(') {
// variable function call // variable function call
$this->_syntax_error("variable function call '$token' not allowed in if statement", E_USER_ERROR, __FILE__, __LINE__); $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)) { } elseif(preg_match('~^' . $this->_obj_call_regexp . '|' . $this->_var_regexp . '(?:' . $this->_mod_regexp . '*)$~', $token)) {
@ -1643,7 +1669,7 @@ class Smarty_Compiler extends Smarty {
} }
elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) { elseif(!in_array($val, $this->_permitted_tokens) && !is_numeric($val)) {
// literal string // literal string
return $this->_expand_quoted_text('"' . $val .'"'); return $this->_expand_quoted_text('"' . strtr($val, array('\\' => '\\\\', '"' => '\\"')) .'"');
} }
return $val; return $val;
} }
@ -1659,11 +1685,11 @@ class Smarty_Compiler extends Smarty {
// if contains unescaped $, expand it // if contains unescaped $, expand it
if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) { if(preg_match_all('~(?:\`(?<!\\\\)\$' . $this->_dvar_guts_regexp . '(?:' . $this->_obj_ext_regexp . ')*\`)|(?:(?<!\\\\)\$\w+(\[[a-zA-Z0-9]+\])*)~', $var_expr, $_match)) {
$_match = $_match[0]; $_match = $_match[0];
rsort($_match); $_replace = array();
reset($_match);
foreach($_match as $_var) { foreach($_match as $_var) {
$var_expr = str_replace ($_var, '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."', $var_expr); $_replace[$_var] = '".(' . $this->_parse_var(str_replace('`','',$_var)) . ')."';
} }
$var_expr = strtr($var_expr, $_replace);
$_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr); $_return = preg_replace('~\.""|(?<!\\\\)""\.~', '', $var_expr);
} else { } else {
$_return = $var_expr; $_return = $var_expr;
@ -1723,7 +1749,7 @@ 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) // 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; $_var_ref = $var_expr;
else else
$_var_ref = substr($var_expr, 1); $_var_ref = substr($var_expr, 1);
@ -1749,7 +1775,7 @@ class Smarty_Compiler extends Smarty {
$_var_name = substr(array_shift($_indexes), 1); $_var_name = substr(array_shift($_indexes), 1);
$_output = "\$this->_smarty_vars['$_var_name']"; $_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 // because . is the operator for accessing arrays thru inidizes we need to put it together again for floating point numbers
if(count($_indexes) > 0) if(count($_indexes) > 0)
{ {
@ -1762,11 +1788,11 @@ class Smarty_Compiler extends Smarty {
} }
foreach ($_indexes as $_index) { foreach ($_indexes as $_index) {
if ($_index{0} == '[') { if (substr($_index, 0, 1) == '[') {
$_index = substr($_index, 1, -1); $_index = substr($_index, 1, -1);
if (is_numeric($_index)) { if (is_numeric($_index)) {
$_output .= "[$_index]"; $_output .= "[$_index]";
} elseif ($_index{0} == '$') { } elseif (substr($_index, 0, 1) == '$') {
if (strpos($_index, '.') !== false) { if (strpos($_index, '.') !== false) {
$_output .= '[' . $this->_parse_var($_index) . ']'; $_output .= '[' . $this->_parse_var($_index) . ']';
} else { } else {
@ -1778,8 +1804,8 @@ class Smarty_Compiler extends Smarty {
$_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index'; $_var_section_prop = isset($_var_parts[1]) ? $_var_parts[1] : 'index';
$_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]"; $_output .= "[\$this->_sections['$_var_section']['$_var_section_prop']]";
} }
} else if ($_index{0} == '.') { } else if (substr($_index, 0, 1) == '.') {
if ($_index{1} == '$') if (substr($_index, 1, 1) == '$')
$_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]"; $_output .= "[\$this->_tpl_vars['" . substr($_index, 2) . "']]";
else else
$_output .= "['" . substr($_index, 1) . "']"; $_output .= "['" . substr($_index, 1) . "']";
@ -1788,7 +1814,7 @@ class Smarty_Compiler extends Smarty {
$this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__); $this->_syntax_error('call to internal object members is not allowed', E_USER_ERROR, __FILE__, __LINE__);
} elseif($this->security && substr($_index, 2, 1) == '_') { } elseif($this->security && substr($_index, 2, 1) == '_') {
$this->_syntax_error('(secure) call to private object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); $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) { if ($this->security) {
$this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__); $this->_syntax_error('(secure) call to dynamic object member is not allowed', E_USER_ERROR, __FILE__, __LINE__);
} else { } else {
@ -1797,7 +1823,7 @@ class Smarty_Compiler extends Smarty {
} else { } else {
$_output .= $_index; $_output .= $_index;
} }
} elseif ($_index{0} == '(') { } elseif (substr($_index, 0, 1) == '(') {
$_index = $this->_parse_parenth_args($_index); $_index = $this->_parse_parenth_args($_index);
$_output .= $_index; $_output .= $_index;
} else { } else {
@ -1894,7 +1920,7 @@ class Smarty_Compiler extends Smarty {
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]; $_modifier_args = $_match[1];
if ($_modifier_name{0} == '@') { if (substr($_modifier_name, 0, 1) == '@') {
$_map_array = false; $_map_array = false;
$_modifier_name = substr($_modifier_name, 1); $_modifier_name = substr($_modifier_name, 1);
} else { } else {
@ -1916,10 +1942,10 @@ class Smarty_Compiler extends Smarty {
if($_modifier_name == 'default') { if($_modifier_name == 'default') {
// supress notifications of default modifier vars and args // supress notifications of default modifier vars and args
if($output{0} == '$') { if(substr($output, 0, 1) == '$') {
$output = '@' . $output; $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]; $_modifier_args[0] = '@' . $_modifier_args[0];
} }
} }
@ -1971,7 +1997,7 @@ class Smarty_Compiler extends Smarty {
/* Extract the reference name. */ /* Extract the reference name. */
$_ref = substr($indexes[0], 1); $_ref = substr($indexes[0], 1);
foreach($indexes as $_index_no=>$_index) { 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__); $this->_syntax_error('$smarty' . implode('', array_slice($indexes, 0, 2)) . ' is an invalid reference', E_USER_ERROR, __FILE__, __LINE__);
} }
} }
@ -2021,27 +2047,57 @@ class Smarty_Compiler extends Smarty {
break; break;
case 'get': case 'get':
$compiled_ref = ($this->request_use_auto_globals) ? '$_GET' : "\$GLOBALS['HTTP_GET_VARS']"; if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
$this->_syntax_error("(secure mode) super global access not permitted",
E_USER_WARNING, __FILE__, __LINE__);
return;
}
$compiled_ref = "\$_GET";
break; break;
case 'post': case 'post':
$compiled_ref = ($this->request_use_auto_globals) ? '$_POST' : "\$GLOBALS['HTTP_POST_VARS']"; if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
$this->_syntax_error("(secure mode) super global access not permitted",
E_USER_WARNING, __FILE__, __LINE__);
return;
}
$compiled_ref = "\$_POST";
break; break;
case 'cookies': case 'cookies':
$compiled_ref = ($this->request_use_auto_globals) ? '$_COOKIE' : "\$GLOBALS['HTTP_COOKIE_VARS']"; if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
$this->_syntax_error("(secure mode) super global access not permitted",
E_USER_WARNING, __FILE__, __LINE__);
return;
}
$compiled_ref = "\$_COOKIE";
break; break;
case 'env': case 'env':
$compiled_ref = ($this->request_use_auto_globals) ? '$_ENV' : "\$GLOBALS['HTTP_ENV_VARS']"; if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
$this->_syntax_error("(secure mode) super global access not permitted",
E_USER_WARNING, __FILE__, __LINE__);
return;
}
$compiled_ref = "\$_ENV";
break; break;
case 'server': case 'server':
$compiled_ref = ($this->request_use_auto_globals) ? '$_SERVER' : "\$GLOBALS['HTTP_SERVER_VARS']"; if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
$this->_syntax_error("(secure mode) super global access not permitted",
E_USER_WARNING, __FILE__, __LINE__);
return;
}
$compiled_ref = "\$_SERVER";
break; break;
case 'session': case 'session':
$compiled_ref = ($this->request_use_auto_globals) ? '$_SESSION' : "\$GLOBALS['HTTP_SESSION_VARS']"; if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
$this->_syntax_error("(secure mode) super global access not permitted",
E_USER_WARNING, __FILE__, __LINE__);
return;
}
$compiled_ref = "\$_SESSION";
break; break;
/* /*
@ -2049,8 +2105,13 @@ class Smarty_Compiler extends Smarty {
* compiler. * compiler.
*/ */
case 'request': case 'request':
if ($this->security && !$this->security_settings['ALLOW_SUPER_GLOBALS']) {
$this->_syntax_error("(secure mode) super global access not permitted",
E_USER_WARNING, __FILE__, __LINE__);
return;
}
if ($this->request_use_auto_globals) { if ($this->request_use_auto_globals) {
$compiled_ref = '$_REQUEST'; $compiled_ref = "\$_REQUEST";
break; break;
} else { } else {
$this->_init_smarty_vars = true; $this->_init_smarty_vars = true;
@ -2061,7 +2122,7 @@ class Smarty_Compiler extends Smarty {
return null; return null;
case 'template': case 'template':
$compiled_ref = "'$this->_current_file'"; $compiled_ref = "'" . addslashes($this->_current_file) . "'";
$_max_index = 1; $_max_index = 1;
break; break;
@ -2207,9 +2268,9 @@ class Smarty_Compiler extends Smarty {
if ($_cacheable if ($_cacheable
|| 0<$this->_cacheable_state++) return ''; || 0<$this->_cacheable_state++) return '';
if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty')); if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
$_ret = 'if ($this->caching && !$this->_cache_including) { echo \'{nocache:' $_ret = 'if ($this->caching && !$this->_cache_including): echo \'{nocache:'
. $this->_cache_serial . '#' . $this->_nocache_count . $this->_cache_serial . '#' . $this->_nocache_count
. '}\';}'; . '}\'; endif;';
return $_ret; return $_ret;
} }
@ -2224,9 +2285,9 @@ class Smarty_Compiler extends Smarty {
$_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4]; $_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
if ($_cacheable if ($_cacheable
|| --$this->_cacheable_state>0) return ''; || --$this->_cacheable_state>0) return '';
return 'if ($this->caching && !$this->_cache_including) { echo \'{/nocache:' return 'if ($this->caching && !$this->_cache_including): echo \'{/nocache:'
. $this->_cache_serial . '#' . ($this->_nocache_count++) . $this->_cache_serial . '#' . ($this->_nocache_count++)
. '}\';}'; . '}\'; endif;';
} }

View file

@ -1,64 +1,157 @@
{* Smarty *} {* Smarty *}
{* debug.tpl, last updated version 2.1.0 *}
{* debug.tpl, last updated version 2.0.1 *}
{assign_debug_info} {assign_debug_info}
{capture assign=debug_output}
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Smarty Debug Console</title>
{literal}
<style type="text/css">
/* <![CDATA[ */
body, h1, h2, td, th, p {
font-family: sans-serif;
font-weight: normal;
font-size: 0.9em;
margin: 1px;
padding: 0;
}
h1 {
margin: 0;
text-align: left;
padding: 2px;
background-color: #f0c040;
color: black;
font-weight: bold;
font-size: 1.2em;
}
h2 {
background-color: #9B410E;
color: white;
text-align: left;
font-weight: bold;
padding: 2px;
border-top: 1px solid black;
}
body {
background: black;
}
p, table, div {
background: #f0ead8;
}
p {
margin: 0;
font-style: italic;
text-align: center;
}
table {
width: 100%;
}
th, td {
font-family: monospace;
vertical-align: top;
text-align: left;
width: 50%;
}
td {
color: green;
}
.odd {
background-color: #eeeeee;
}
.even {
background-color: #fafafa;
}
.exectime {
font-size: 0.8em;
font-style: italic;
}
#table_assigned_vars th {
color: blue;
}
#table_config_vars th {
color: maroon;
}
/* ]]> */
</style>
{/literal}
</head>
<body>
<h1>Smarty Debug Console</h1>
<h2>included templates &amp; config files (load time in seconds)</h2>
<div>
{section name=templates loop=$_debug_tpls}
{section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}
<font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>
{$_debug_tpls[templates].filename|escape:html}</font>
{if isset($_debug_tpls[templates].exec_time)}
<span class="exectime">
({$_debug_tpls[templates].exec_time|string_format:"%.5f"})
{if %templates.index% eq 0}(total){/if}
</span>
{/if}
<br />
{sectionelse}
<p>no templates included</p>
{/section}
</div>
<h2>assigned template variables</h2>
<table id="table_assigned_vars">
{section name=vars loop=$_debug_keys}
<tr class="{cycle values="odd,even"}">
<th>{ldelim}${$_debug_keys[vars]|escape:'html'}{rdelim}</th>
<td>{$_debug_vals[vars]|@debug_print_var}</td></tr>
{sectionelse}
<tr><td><p>no template variables assigned</p></td></tr>
{/section}
</table>
<h2>assigned config file variables (outer template scope)</h2>
<table id="table_config_vars">
{section name=config_vars loop=$_debug_config_keys}
<tr class="{cycle values="odd,even"}">
<th>{ldelim}#{$_debug_config_keys[config_vars]|escape:'html'}#{rdelim}</th>
<td>{$_debug_config_vals[config_vars]|@debug_print_var}</td></tr>
{sectionelse}
<tr><td><p>no config vars assigned</p></td></tr>
{/section}
</table>
</body>
</html>
{/capture}
{if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"} {if isset($_smarty_debug_output) and $_smarty_debug_output eq "html"}
<table border=0 width=100%> {$debug_output}
<tr bgcolor=#cccccc><th colspan=2>Smarty Debug Console</th></tr>
<tr bgcolor=#cccccc><td colspan=2><b>included templates & config files (load time in seconds):</b></td></tr>
{section name=templates loop=$_debug_tpls}
<tr bgcolor={if %templates.index% is even}#eeeeee{else}#fafafa{/if}><td colspan=2><tt>{section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}<font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>{$_debug_tpls[templates].filename|escape:html}</font>{if isset($_debug_tpls[templates].exec_time)} <font size=-1><i>({$_debug_tpls[templates].exec_time|string_format:"%.5f"}){if %templates.index% eq 0} (total){/if}</i></font>{/if}</tt></td></tr>
{sectionelse}
<tr bgcolor=#eeeeee><td colspan=2><tt><i>no templates included</i></tt></td></tr>
{/section}
<tr bgcolor=#cccccc><td colspan=2><b>assigned template variables:</b></td></tr>
{section name=vars loop=$_debug_keys}
<tr bgcolor={if %vars.index% is even}#eeeeee{else}#fafafa{/if}><td valign=top><tt><font color=blue>{ldelim}${$_debug_keys[vars]}{rdelim}</font></tt></td><td nowrap><tt><font color=green>{$_debug_vals[vars]|@debug_print_var}</font></tt></td></tr>
{sectionelse}
<tr bgcolor=#eeeeee><td colspan=2><tt><i>no template variables assigned</i></tt></td></tr>
{/section}
<tr bgcolor=#cccccc><td colspan=2><b>assigned config file variables (outer template scope):</b></td></tr>
{section name=config_vars loop=$_debug_config_keys}
<tr bgcolor={if %config_vars.index% is even}#eeeeee{else}#fafafa{/if}><td valign=top><tt><font color=maroon>{ldelim}#{$_debug_config_keys[config_vars]}#{rdelim}</font></tt></td><td><tt><font color=green>{$_debug_config_vals[config_vars]|@debug_print_var}</font></tt></td></tr>
{sectionelse}
<tr bgcolor=#eeeeee><td colspan=2><tt><i>no config vars assigned</i></tt></td></tr>
{/section}
</table>
</BODY></HTML>
{else} {else}
<SCRIPT language=javascript> <script type="text/javascript">
if( self.name == '' ) {ldelim} // <![CDATA[
var title = 'Console'; if ( self.name == '' ) {ldelim}
{rdelim} var title = 'Console';
else {ldelim} {rdelim}
var title = 'Console_' + self.name; else {ldelim}
{rdelim} var title = 'Console_' + self.name;
_smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes"); {rdelim}
_smarty_console.document.write("<HTML><HEAD><TITLE>Smarty Debug Console_"+self.name+"</TITLE></HEAD><BODY bgcolor=#ffffff>"); _smarty_console = window.open("",title.value,"width=680,height=600,resizable,scrollbars=yes");
_smarty_console.document.write("<table border=0 width=100%>"); _smarty_console.document.write('{$debug_output|escape:'javascript'}');
_smarty_console.document.write("<tr bgcolor=#cccccc><th colspan=2>Smarty Debug Console</th></tr>"); _smarty_console.document.close();
_smarty_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>included templates & config files (load time in seconds):</b></td></tr>"); // ]]>
{section name=templates loop=$_debug_tpls} </script>
_smarty_console.document.write("<tr bgcolor={if %templates.index% is even}#eeeeee{else}#fafafa{/if}><td colspan=2><tt>{section name=indent loop=$_debug_tpls[templates].depth}&nbsp;&nbsp;&nbsp;{/section}<font color={if $_debug_tpls[templates].type eq "template"}brown{elseif $_debug_tpls[templates].type eq "insert"}black{else}green{/if}>{$_debug_tpls[templates].filename|escape:html|escape:javascript}</font>{if isset($_debug_tpls[templates].exec_time)} <font size=-1><i>({$_debug_tpls[templates].exec_time|string_format:"%.5f"}){if %templates.index% eq 0} (total){/if}</i></font>{/if}</tt></td></tr>");
{sectionelse}
_smarty_console.document.write("<tr bgcolor=#eeeeee><td colspan=2><tt><i>no templates included</i></tt></td></tr>");
{/section}
_smarty_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>assigned template variables:</b></td></tr>");
{section name=vars loop=$_debug_keys}
_smarty_console.document.write("<tr bgcolor={if %vars.index% is even}#eeeeee{else}#fafafa{/if}><td valign=top><tt><font color=blue>{ldelim}${$_debug_keys[vars]}{rdelim}</font></tt></td><td nowrap><tt><font color=green>{$_debug_vals[vars]|@debug_print_var|escape:javascript}</font></tt></td></tr>");
{sectionelse}
_smarty_console.document.write("<tr bgcolor=#eeeeee><td colspan=2><tt><i>no template variables assigned</i></tt></td></tr>");
{/section}
_smarty_console.document.write("<tr bgcolor=#cccccc><td colspan=2><b>assigned config file variables (outer template scope):</b></td></tr>");
{section name=config_vars loop=$_debug_config_keys}
_smarty_console.document.write("<tr bgcolor={if %config_vars.index% is even}#eeeeee{else}#fafafa{/if}><td valign=top><tt><font color=maroon>{ldelim}#{$_debug_config_keys[config_vars]}#{rdelim}</font></tt></td><td><tt><font color=green>{$_debug_config_vals[config_vars]|@debug_print_var|escape:javascript}</font></tt></td></tr>");
{sectionelse}
_smarty_console.document.write("<tr bgcolor=#eeeeee><td colspan=2><tt><i>no config vars assigned</i></tt></td></tr>");
{/section}
_smarty_console.document.write("</table>");
_smarty_console.document.write("</BODY></HTML>");
_smarty_console.document.close();
</SCRIPT>
{/if} {/if}

View file

@ -22,7 +22,7 @@ function smarty_core_create_dir_structure($params, &$smarty)
/* unix-style paths */ /* unix-style paths */
$_dir = $params['dir']; $_dir = $params['dir'];
$_dir_parts = preg_split('!/+!', $_dir, -1, PREG_SPLIT_NO_EMPTY); $_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)) { if($_use_open_basedir = !empty($_open_basedir_ini)) {
$_open_basedirs = explode(':', $_open_basedir_ini); $_open_basedirs = explode(':', $_open_basedir_ini);
} }

View file

@ -23,7 +23,7 @@ function smarty_core_display_debug_console($params, &$smarty)
// set path to debug template from SMARTY_DIR // set path to debug template from SMARTY_DIR
$smarty->debug_tpl = SMARTY_DIR . 'debug.tpl'; $smarty->debug_tpl = SMARTY_DIR . 'debug.tpl';
if($smarty->security && is_file($smarty->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'; $smarty->debug_tpl = 'file:' . SMARTY_DIR . 'debug.tpl';
} }

View file

@ -27,17 +27,20 @@ function smarty_core_is_secure($params, &$smarty)
foreach ((array)$params['resource_base_path'] as $curr_dir) { foreach ((array)$params['resource_base_path'] as $curr_dir) {
if ( ($_cd = realpath($curr_dir)) !== false && if ( ($_cd = realpath($curr_dir)) !== false &&
strncmp($_rp, $_cd, strlen($_cd)) == 0 && strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
$_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) { substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
return true; return true;
} }
} }
} }
if (!empty($smarty->secure_dir)) { if (!empty($smarty->secure_dir)) {
foreach ((array)$smarty->secure_dir as $curr_dir) { foreach ((array)$smarty->secure_dir as $curr_dir) {
if ( ($_cd = realpath($curr_dir)) !== false && if ( ($_cd = realpath($curr_dir)) !== false) {
strncmp($_rp, $_cd, strlen($_cd)) == 0 && if($_cd == $_rp) {
$_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) { return true;
return true; } elseif (strncmp($_rp, $_cd, strlen($_cd)) == 0 &&
substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR) {
return true;
}
} }
} }
} }

View file

@ -25,7 +25,7 @@ function smarty_core_is_trusted($params, &$smarty)
if (!empty($curr_dir) && is_readable ($curr_dir)) { if (!empty($curr_dir) && is_readable ($curr_dir)) {
$_cd = realpath($curr_dir); $_cd = realpath($curr_dir);
if (strncmp($_rp, $_cd, strlen($_cd)) == 0 if (strncmp($_rp, $_cd, strlen($_cd)) == 0
&& $_rp{strlen($_cd)} == DIRECTORY_SEPARATOR ) { && substr($_rp, strlen($_cd), 1) == DIRECTORY_SEPARATOR ) {
$_smarty_trusted = true; $_smarty_trusted = true;
break; break;
} }

View file

@ -52,7 +52,7 @@ function smarty_core_process_cached_inserts($params, &$smarty)
$replace = ''; $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) { if ($smarty->debugging) {
$_params = array(); $_params = array();
require_once(SMARTY_CORE_DIR . 'core.get_microtime.php'); require_once(SMARTY_CORE_DIR . 'core.get_microtime.php');

View file

@ -20,7 +20,12 @@ function smarty_core_process_compiled_include($params, &$smarty)
$smarty->_cache_including = true; $smarty->_cache_including = true;
$_return = $params['results']; $_return = $params['results'];
foreach ($smarty->_cache_serials as $_include_file_path=>$_cache_serial) {
foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
$smarty->_include($_include_file_path, true);
}
foreach ($smarty->_cache_info['cache_serials'] as $_include_file_path=>$_cache_serial) {
$_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s', $_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
array(&$smarty, '_process_compiled_include_callback'), array(&$smarty, '_process_compiled_include_callback'),
$_return); $_return);

View file

@ -90,16 +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;
}
}
$content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info); $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $_cache_info);
$smarty->_cache_info = $_cache_info; $smarty->_cache_info = $_cache_info;

View file

@ -32,7 +32,6 @@ function smarty_core_rmdir($params, &$smarty)
'level' => $params['level'] + 1, 'level' => $params['level'] + 1,
'exp_time' => $params['exp_time'] 'exp_time' => $params['exp_time']
); );
require_once(SMARTY_CORE_DIR . 'core.rmdir.php');
smarty_core_rmdir($_params, $smarty); smarty_core_rmdir($_params, $smarty);
} }
else { else {

View file

@ -68,7 +68,7 @@ function smarty_core_write_cache_file($params, &$smarty)
if (!empty($smarty->cache_handler_func)) { if (!empty($smarty->cache_handler_func)) {
// use cache_handler function // use cache_handler function
call_user_func_array($smarty->cache_handler_func, call_user_func_array($smarty->cache_handler_func,
array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], null)); array('write', &$smarty, &$params['results'], $params['tpl_file'], $params['cache_id'], $params['compile_id'], $smarty->_cache_info['expires']));
} else { } else {
// use local cache file // use local cache file

View file

@ -15,8 +15,8 @@
function smarty_core_write_compiled_include($params, &$smarty) function smarty_core_write_compiled_include($params, &$smarty)
{ {
$_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\) \{ echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\';\}'; $_tag_start = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{nocache\:('.$params['cache_serial'].')#(\d+)\}\'; endif;';
$_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\) \{ echo \'\{/nocache\:(\\2)#(\\3)\}\';\}'; $_tag_end = 'if \(\$this->caching && \!\$this->_cache_including\)\: echo \'\{/nocache\:(\\2)#(\\3)\}\'; endif;';
preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us', preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
$params['compiled_content'], $_match_source, PREG_SET_ORDER); $params['compiled_content'], $_match_source, PREG_SET_ORDER);

View file

@ -23,8 +23,7 @@ function smarty_core_write_file($params, &$smarty)
smarty_core_create_dir_structure($_params, $smarty); smarty_core_create_dir_structure($_params, $smarty);
} }
// write to tmp file, then rename it to avoid // write to tmp file, then rename it to avoid file locking race condition
// file locking race condition
$_tmp_file = tempnam($_dirname, 'wrt'); $_tmp_file = tempnam($_dirname, 'wrt');
if (!($fd = @fopen($_tmp_file, 'wb'))) { if (!($fd = @fopen($_tmp_file, 'wb'))) {
@ -38,12 +37,13 @@ function smarty_core_write_file($params, &$smarty)
fwrite($fd, $params['contents']); fwrite($fd, $params['contents']);
fclose($fd); fclose($fd);
// Delete the file if it allready exists (this is needed on Win, if (DIRECTORY_SEPARATOR == '\\' || !@rename($_tmp_file, $params['filename'])) {
// because it cannot overwrite files with rename() // On platforms and filesystems that cannot overwrite with rename()
if (file_exists($params['filename'])) { // delete the file before renaming it -- because windows always suffers
// this, it is short-circuited to avoid the initial rename() attempt
@unlink($params['filename']); @unlink($params['filename']);
@rename($_tmp_file, $params['filename']);
} }
@rename($_tmp_file, $params['filename']);
@chmod($params['filename'], $smarty->_file_perms); @chmod($params['filename'], $smarty->_file_perms);
return true; return true;

View file

@ -23,6 +23,7 @@
* indent_char: string (" ") * indent_char: string (" ")
* wrap_boundary: boolean (true) * wrap_boundary: boolean (true)
* </pre> * </pre>
* @author Monte Ohrt <monte at ohrt dot com>
* @param string contents of the block * @param string contents of the block
* @param Smarty clever simulation of a method * @param Smarty clever simulation of a method
* @return string string $content re-formatted * @return string string $content re-formatted

View file

@ -13,6 +13,8 @@
* Purpose: assign a value to a template variable * Purpose: assign a value to a template variable
* @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign} * @link http://smarty.php.net/manual/en/language.custom.functions.php#LANGUAGE.FUNCTION.ASSIGN {assign}
* (Smarty online manual) * (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com> (initial author)
* @author messju mohr <messju at lammfellpuschen dot de> (conversion to compiler function)
* @param string containing var-attribute and value-attribute * @param string containing var-attribute and value-attribute
* @param Smarty_Compiler * @param Smarty_Compiler
*/ */

View file

@ -11,6 +11,7 @@
* Type: function<br> * Type: function<br>
* Name: assign_debug_info<br> * Name: assign_debug_info<br>
* Purpose: assign debug info to the template<br> * Purpose: assign debug info to the template<br>
* @author Monte Ohrt <monte at ohrt dot com>
* @param array unused in this plugin, this plugin uses {@link Smarty::$_config}, * @param array unused in this plugin, this plugin uses {@link Smarty::$_config},
* {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info} * {@link Smarty::$_tpl_vars} and {@link Smarty::$_smarty_debug_info}
* @param Smarty * @param Smarty

View file

@ -13,6 +13,8 @@
* Purpose: load config file vars * Purpose: load config file vars
* @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load} * @link http://smarty.php.net/manual/en/language.function.config.load.php {config_load}
* (Smarty online manual) * (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @author messju mohr <messju at lammfellpuschen dot de> (added use of resources)
* @param array Format: * @param array Format:
* <pre> * <pre>
* array('file' => required config file name, * array('file' => required config file name,

View file

@ -12,6 +12,7 @@
* Type: function<br> * Type: function<br>
* Name: counter<br> * Name: counter<br>
* Purpose: print out a counter value * Purpose: print out a counter value
* @author Monte Ohrt <monte at ohrt dot com>
* @link http://smarty.php.net/manual/en/language.function.counter.php {counter} * @link http://smarty.php.net/manual/en/language.function.counter.php {counter}
* (Smarty online manual) * (Smarty online manual)
* @param array parameters * @param array parameters

View file

@ -63,7 +63,11 @@ function smarty_function_cycle($params, &$smarty)
$cycle_vars[$name]['values'] = $params['values']; $cycle_vars[$name]['values'] = $params['values'];
} }
$cycle_vars[$name]['delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : ','; if (isset($params['delimiter'])) {
$cycle_vars[$name]['delimiter'] = $params['delimiter'];
} elseif (!isset($cycle_vars[$name]['delimiter'])) {
$cycle_vars[$name]['delimiter'] = ',';
}
if(is_array($cycle_vars[$name]['values'])) { if(is_array($cycle_vars[$name]['values'])) {
$cycle_array = $cycle_vars[$name]['values']; $cycle_array = $cycle_vars[$name]['values'];

View file

@ -14,6 +14,7 @@
* Purpose: evaluate a template variable as a template<br> * Purpose: evaluate a template variable as a template<br>
* @link http://smarty.php.net/manual/en/language.function.eval.php {eval} * @link http://smarty.php.net/manual/en/language.function.eval.php {eval}
* (Smarty online manual) * (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array * @param array
* @param Smarty * @param Smarty
*/ */

View file

@ -14,6 +14,7 @@
* Purpose: fetch file, web or ftp data and display results * Purpose: fetch file, web or ftp data and display results
* @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch} * @link http://smarty.php.net/manual/en/language.function.fetch.php {fetch}
* (Smarty online manual) * (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array * @param array
* @param Smarty * @param Smarty
* @return string|null if the assign parameter is passed, Smarty assigns the * @return string|null if the assign parameter is passed, Smarty assigns the
@ -180,12 +181,12 @@ function smarty_function_fetch($params, &$smarty)
$content .= fgets($fp,4096); $content .= fgets($fp,4096);
} }
fclose($fp); fclose($fp);
$csplit = split("\r\n\r\n",$content,2); $csplit = preg_split("!\r\n\r\n!",$content,2);
$content = $csplit[1]; $content = $csplit[1];
if(!empty($params['assign_headers'])) { if(!empty($params['assign_headers'])) {
$smarty->assign($params['assign_headers'],split("\r\n",$csplit[0])); $smarty->assign($params['assign_headers'],preg_split("!\r\n!",$csplit[0]));
} }
} }
} else { } else {

View file

@ -19,9 +19,10 @@
* - width = image width (optional, default actual width) * - width = image width (optional, default actual width)
* - basedir = base directory for absolute paths, default * - basedir = base directory for absolute paths, default
* is environment variable DOCUMENT_ROOT * is environment variable DOCUMENT_ROOT
* - path_prefix = prefix for path output (optional, default empty)
* *
* Examples: {html_image file="images/masthead.gif"} * Examples: {html_image file="/images/masthead.gif"}
* Output: <img src="images/masthead.gif" width=400 height=23> * Output: <img src="/images/masthead.gif" width=400 height=23>
* @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image} * @link http://smarty.php.net/manual/en/language.function.html.image.php {html_image}
* (Smarty online manual) * (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com> * @author Monte Ohrt <monte at ohrt dot com>
@ -44,6 +45,7 @@ function smarty_function_html_image($params, &$smarty)
$extra = ''; $extra = '';
$prefix = ''; $prefix = '';
$suffix = ''; $suffix = '';
$path_prefix = '';
$server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; $server_vars = ($smarty->request_use_auto_globals) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
$basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : ''; $basedir = isset($server_vars['DOCUMENT_ROOT']) ? $server_vars['DOCUMENT_ROOT'] : '';
foreach($params as $_key => $_val) { foreach($params as $_key => $_val) {
@ -52,6 +54,7 @@ function smarty_function_html_image($params, &$smarty)
case 'height': case 'height':
case 'width': case 'width':
case 'dpi': case 'dpi':
case 'path_prefix':
case 'basedir': case 'basedir':
$$_key = $_val; $$_key = $_val;
break; break;
@ -92,13 +95,7 @@ function smarty_function_html_image($params, &$smarty)
} }
if(!isset($params['width']) || !isset($params['height'])) { if(!isset($params['width']) || !isset($params['height'])) {
if ($smarty->security && if(!$_image_data = @getimagesize($_image_path)) {
($_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);
} elseif (!$_image_data = @getimagesize($_image_path)) {
if(!file_exists($_image_path)) { if(!file_exists($_image_path)) {
$smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE); $smarty->trigger_error("html_image: unable to find '$_image_path'", E_USER_NOTICE);
return; return;
@ -110,6 +107,12 @@ function smarty_function_html_image($params, &$smarty)
return; return;
} }
} }
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);
}
if(!isset($params['width'])) { if(!isset($params['width'])) {
$width = $_image_data[0]; $width = $_image_data[0];
@ -131,7 +134,7 @@ function smarty_function_html_image($params, &$smarty)
$height = round($height * $_resize); $height = round($height * $_resize);
} }
return $prefix . '<img src="'.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix; return $prefix . '<img src="'.$path_prefix.$file.'" alt="'.$alt.'" width="'.$width.'" height="'.$height.'"'.$extra.' />' . $suffix;
} }
/* vim: set expandtab: */ /* vim: set expandtab: */

View file

@ -17,11 +17,11 @@
* - options (required if no values supplied) - associative array * - options (required if no values supplied) - associative array
* - selected (optional) - string default not set * - selected (optional) - string default not set
* - output (required if not options supplied) - array * - output (required if not options supplied) - array
* - disabled (optional) - string default not set (added by Yogin)
* Purpose: Prints the list of <option> tags generated from * Purpose: Prints the list of <option> tags generated from
* the passed parameters * the passed parameters
* @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image} * @link http://smarty.php.net/manual/en/language.function.html.options.php {html_image}
* (Smarty online manual) * (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array * @param array
* @param Smarty * @param Smarty
* @return string * @return string
@ -35,7 +35,6 @@ function smarty_function_html_options($params, &$smarty)
$values = null; $values = null;
$options = null; $options = null;
$selected = array(); $selected = array();
$disabled = array();
$output = null; $output = null;
$extra = ''; $extra = '';
@ -59,11 +58,6 @@ function smarty_function_html_options($params, &$smarty)
$$_key = array_map('strval', array_values((array)$_val)); $$_key = array_map('strval', array_values((array)$_val));
break; break;
case 'disabled':
$$_key = array_map('strval', array_values((array)$_val));
break;
default: default:
if(!is_array($_val)) { if(!is_array($_val)) {
$extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';
@ -82,13 +76,13 @@ function smarty_function_html_options($params, &$smarty)
if (isset($options)) { if (isset($options)) {
foreach ($options as $_key=>$_val) foreach ($options as $_key=>$_val)
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $disabled); $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
} else { } else {
foreach ($values as $_i=>$_key) { foreach ($values as $_i=>$_key) {
$_val = isset($output[$_i]) ? $output[$_i] : ''; $_val = isset($output[$_i]) ? $output[$_i] : '';
$_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected, $disabled); $_html_result .= smarty_function_html_options_optoutput($_key, $_val, $selected);
} }
} }
@ -101,27 +95,23 @@ function smarty_function_html_options($params, &$smarty)
} }
function smarty_function_html_options_optoutput($key, $value, $selected, $disabled) { function smarty_function_html_options_optoutput($key, $value, $selected) {
if(!is_array($value)) { if(!is_array($value)) {
$_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' . $_html_result = '<option label="' . smarty_function_escape_special_chars($value) . '" value="' .
smarty_function_escape_special_chars($key) . '"'; smarty_function_escape_special_chars($key) . '"';
if (in_array((string)$key, $selected)) if (in_array((string)$key, $selected))
$_html_result .= ' selected="selected"'; $_html_result .= ' selected="selected"';
if (in_array((string)$key, $disabled))
$_html_result .= ' disabled';
$_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n"; $_html_result .= '>' . smarty_function_escape_special_chars($value) . '</option>' . "\n";
} else { } else {
$_html_result = smarty_function_html_options_optgroup($key, $value, $selected, $disabled); $_html_result = smarty_function_html_options_optgroup($key, $value, $selected);
} }
return $_html_result; return $_html_result;
} }
function smarty_function_html_options_optgroup($key, $values, $selected, $disabled) { function smarty_function_html_options_optgroup($key, $values, $selected) {
$optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n"; $optgroup_html = '<optgroup label="' . smarty_function_escape_special_chars($key) . '">' . "\n";
foreach ($values as $key => $value) { foreach ($values as $key => $value) {
$optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected, $disabled); $optgroup_html .= smarty_function_html_options_optoutput($key, $value, $selected);
} }
$optgroup_html .= "</optgroup>\n"; $optgroup_html .= "</optgroup>\n";
return $optgroup_html; return $optgroup_html;

View file

@ -48,6 +48,7 @@ function smarty_function_html_radios($params, &$smarty)
$selected = null; $selected = null;
$separator = ''; $separator = '';
$labels = true; $labels = true;
$label_ids = false;
$output = null; $output = null;
$extra = ''; $extra = '';
@ -68,6 +69,7 @@ function smarty_function_html_radios($params, &$smarty)
break; break;
case 'labels': case 'labels':
case 'label_ids':
$$_key = (bool)$_val; $$_key = (bool)$_val;
break; break;
@ -106,13 +108,13 @@ function smarty_function_html_radios($params, &$smarty)
if (isset($options)) { if (isset($options)) {
foreach ($options as $_key=>$_val) foreach ($options as $_key=>$_val)
$_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels); $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
} else { } else {
foreach ($values as $_i=>$_key) { foreach ($values as $_i=>$_key) {
$_val = isset($output[$_i]) ? $output[$_i] : ''; $_val = isset($output[$_i]) ? $output[$_i] : '';
$_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels); $_html_result[] = smarty_function_html_radios_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids);
} }
} }
@ -125,19 +127,23 @@ function smarty_function_html_radios($params, &$smarty)
} }
function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels) { function smarty_function_html_radios_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids) {
$_output = ''; $_output = '';
if ($labels) { if ($labels) {
$_id = smarty_function_escape_special_chars($name . '_' . $value); if($label_ids) {
$_output .= '<label for="' . $_id . '">'; $_id = smarty_function_escape_special_chars(preg_replace('![^\w\-\.]!', '_', $name . '_' . $value));
$_output .= '<label for="' . $_id . '">';
} else {
$_output .= '<label>';
}
} }
$_output .= '<input type="radio" name="' $_output .= '<input type="radio" name="'
. smarty_function_escape_special_chars($name) . '" value="' . smarty_function_escape_special_chars($name) . '" value="'
. smarty_function_escape_special_chars($value) . '"'; . smarty_function_escape_special_chars($value) . '"';
if ($labels) $_output .= ' id="' . $_id . '"'; if ($labels && $label_ids) $_output .= ' id="' . $_id . '"';
if ($value==$selected) { if ((string)$value==$selected) {
$_output .= ' checked="checked"'; $_output .= ' checked="checked"';
} }
$_output .= $extra . ' />' . $output; $_output .= $extra . ' />' . $output;

View file

@ -22,18 +22,22 @@
* month values (Gary Loescher) * month values (Gary Loescher)
* - 1.3.1 added support for choosing format for * - 1.3.1 added support for choosing format for
* day values (Marcus Bointon) * day values (Marcus Bointon)
* - 1.3.2 suppport negative timestamps, force year * - 1.3.2 support negative timestamps, force year
* dropdown to include given date unless explicitly set (Monte) * dropdown to include given date unless explicitly set (Monte)
* - 1.3.4 fix behaviour of 0000-00-00 00:00:00 dates to match that
* of 0000-00-00 dates (cybot, boots)
* @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date} * @link http://smarty.php.net/manual/en/language.function.html.select.date.php {html_select_date}
* (Smarty online manual) * (Smarty online manual)
* @version 1.3.2 * @version 1.3.4
* @author Andrei Zmievski * @author Andrei Zmievski
* @author Monte Ohrt <monte at ohrt dot com>
* @param array * @param array
* @param Smarty * @param Smarty
* @return string * @return string
*/ */
function smarty_function_html_select_date($params, &$smarty) function smarty_function_html_select_date($params, &$smarty)
{ {
require_once $smarty->_get_plugin_filepath('shared','escape_special_chars');
require_once $smarty->_get_plugin_filepath('shared','make_timestamp'); require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
require_once $smarty->_get_plugin_filepath('function','html_options'); require_once $smarty->_get_plugin_filepath('function','html_options');
/* Default values. */ /* Default values. */
@ -78,6 +82,7 @@ function smarty_function_html_select_date($params, &$smarty)
$day_empty = null; $day_empty = null;
$month_empty = null; $month_empty = null;
$year_empty = null; $year_empty = null;
$extra_attrs = '';
foreach ($params as $_key=>$_value) { foreach ($params as $_key=>$_value) {
switch ($_key) { switch ($_key) {
@ -119,17 +124,23 @@ function smarty_function_html_select_date($params, &$smarty)
break; break;
default: default:
$smarty->trigger_error("[html_select_date] unknown parameter $_key", E_USER_WARNING); if(!is_array($_value)) {
$extra_attrs .= ' '.$_key.'="'.smarty_function_escape_special_chars($_value).'"';
} else {
$smarty->trigger_error("html_select_date: extra attribute '$_key' cannot be an array", E_USER_NOTICE);
}
break;
} }
} }
if(preg_match('!^-\d+$!',$time)) { if (preg_match('!^-\d+$!', $time)) {
// negative timestamp, use date() // negative timestamp, use date()
$time = date('Y-m-d',$time); $time = date('Y-m-d', $time);
} }
// If $time is not in format yyyy-mm-dd // If $time is not in format yyyy-mm-dd
if (!preg_match('/^\d{0,4}-\d{0,2}-\d{0,2}$/', $time)) { if (preg_match('/^(\d{0,4}-\d{0,2}-\d{0,2})/', $time, $found)) {
$time = $found[1];
} else {
// use smarty_make_timestamp to get an unix timestamp and // use smarty_make_timestamp to get an unix timestamp and
// strftime to make yyyy-mm-dd // strftime to make yyyy-mm-dd
$time = strftime('%Y-%m-%d', smarty_make_timestamp($time)); $time = strftime('%Y-%m-%d', smarty_make_timestamp($time));
@ -167,7 +178,9 @@ function smarty_function_html_select_date($params, &$smarty)
$html_result = $month_result = $day_result = $year_result = ""; $html_result = $month_result = $day_result = $year_result = "";
$field_separator_count = -1;
if ($display_months) { if ($display_months) {
$field_separator_count++;
$month_names = array(); $month_names = array();
$month_values = array(); $month_values = array();
if(isset($month_empty)) { if(isset($month_empty)) {
@ -194,17 +207,18 @@ function smarty_function_html_select_date($params, &$smarty)
if (null !== $all_extra){ if (null !== $all_extra){
$month_result .= ' ' . $all_extra; $month_result .= ' ' . $all_extra;
} }
$month_result .= '>'."\n"; $month_result .= $extra_attrs . '>'."\n";
$month_result .= smarty_function_html_options(array('output' => $month_names, $month_result .= smarty_function_html_options(array('output' => $month_names,
'values' => $month_values, 'values' => $month_values,
'selected' => $a=$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '', 'selected' => (int)$time[1] ? strftime($month_value_format, mktime(0, 0, 0, (int)$time[1], 1, 2000)) : '',
'print_result' => false), 'print_result' => false),
$smarty); $smarty);
$month_result .= '</select>'; $month_result .= '</select>';
} }
if ($display_days) { if ($display_days) {
$field_separator_count++;
$days = array(); $days = array();
if (isset($day_empty)) { if (isset($day_empty)) {
$days[''] = $day_empty; $days[''] = $day_empty;
@ -230,7 +244,7 @@ function smarty_function_html_select_date($params, &$smarty)
if (null !== $day_extra){ if (null !== $day_extra){
$day_result .= ' ' . $day_extra; $day_result .= ' ' . $day_extra;
} }
$day_result .= '>'."\n"; $day_result .= $extra_attrs . '>'."\n";
$day_result .= smarty_function_html_options(array('output' => $days, $day_result .= smarty_function_html_options(array('output' => $days,
'values' => $day_values, 'values' => $day_values,
'selected' => $time[2], 'selected' => $time[2],
@ -240,6 +254,7 @@ function smarty_function_html_select_date($params, &$smarty)
} }
if ($display_years) { if ($display_years) {
$field_separator_count++;
if (null !== $field_array){ if (null !== $field_array){
$year_name = $field_array . '[' . $prefix . 'Year]'; $year_name = $field_array . '[' . $prefix . 'Year]';
} else { } else {
@ -253,7 +268,7 @@ function smarty_function_html_select_date($params, &$smarty)
if (null !== $year_extra){ if (null !== $year_extra){
$year_result .= ' ' . $year_extra; $year_result .= ' ' . $year_extra;
} }
$year_result .= '>'; $year_result .= ' />';
} else { } else {
$years = range((int)$start_year, (int)$end_year); $years = range((int)$start_year, (int)$end_year);
if ($reverse_years) { if ($reverse_years) {
@ -276,7 +291,7 @@ function smarty_function_html_select_date($params, &$smarty)
if (null !== $year_extra){ if (null !== $year_extra){
$year_result .= ' ' . $year_extra; $year_result .= ' ' . $year_extra;
} }
$year_result .= '>'."\n"; $year_result .= $extra_attrs . '>'."\n";
$year_result .= smarty_function_html_options(array('output' => $years, $year_result .= smarty_function_html_options(array('output' => $years,
'values' => $yearvals, 'values' => $yearvals,
'selected' => $time[0], 'selected' => $time[0],
@ -303,7 +318,7 @@ function smarty_function_html_select_date($params, &$smarty)
break; break;
} }
// Add the field seperator // Add the field seperator
if($i != 2) { if($i < $field_separator_count) {
$html_result .= $field_separator; $html_result .= $field_separator;
} }
} }

View file

@ -14,6 +14,8 @@
* Purpose: Prints the dropdowns for time selection * Purpose: Prints the dropdowns for time selection
* @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time} * @link http://smarty.php.net/manual/en/language.function.html.select.time.php {html_select_time}
* (Smarty online manual) * (Smarty online manual)
* @author Roberto Berto <roberto@berto.net>
* @credits Monte Ohrt <monte AT ohrt DOT com>
* @param array * @param array
* @param Smarty * @param Smarty
* @return string * @return string

View file

@ -15,12 +15,15 @@
* Purpose: make an html table from an array of data<br> * Purpose: make an html table from an array of data<br>
* Input:<br> * Input:<br>
* - loop = array to loop through * - loop = array to loop through
* - cols = number of columns * - cols = number of columns, comma separated list of column names
* or array of column names
* - rows = number of rows * - rows = number of rows
* - table_attr = table attributes * - table_attr = table attributes
* - th_attr = table heading attributes (arrays are cycled)
* - tr_attr = table row attributes (arrays are cycled) * - tr_attr = table row attributes (arrays are cycled)
* - td_attr = table cell attributes (arrays are cycled) * - td_attr = table cell attributes (arrays are cycled)
* - trailpad = value to pad trailing cells with * - trailpad = value to pad trailing cells with
* - caption = text for caption element
* - vdir = vertical direction (default: "down", means top-to-bottom) * - vdir = vertical direction (default: "down", means top-to-bottom)
* - hdir = horizontal direction (default: "right", means left-to-right) * - hdir = horizontal direction (default: "right", means left-to-right)
* - inner = inner loop (default "cols": print $loop line by line, * - inner = inner loop (default "cols": print $loop line by line,
@ -31,10 +34,12 @@
* <pre> * <pre>
* {table loop=$data} * {table loop=$data}
* {table loop=$data cols=4 tr_attr='"bgcolor=red"'} * {table loop=$data cols=4 tr_attr='"bgcolor=red"'}
* {table loop=$data cols=4 tr_attr=$colors} * {table loop=$data cols="first,second,third" tr_attr=$colors}
* </pre> * </pre>
* @author Monte Ohrt <monte at ohrt dot com> * @author Monte Ohrt <monte at ohrt dot com>
* @version 1.0 * @author credit to Messju Mohr <messju at lammfellpuschen dot de>
* @author credit to boots <boots dot smarty at yahoo dot com>
* @version 1.1
* @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table} * @link http://smarty.php.net/manual/en/language.function.html.table.php {html_table}
* (Smarty online manual) * (Smarty online manual)
* @param array * @param array
@ -45,13 +50,15 @@ function smarty_function_html_table($params, &$smarty)
{ {
$table_attr = 'border="1"'; $table_attr = 'border="1"';
$tr_attr = ''; $tr_attr = '';
$th_attr = '';
$td_attr = ''; $td_attr = '';
$cols = 3; $cols = $cols_count = 3;
$rows = 3; $rows = 3;
$trailpad = '&nbsp;'; $trailpad = '&nbsp;';
$vdir = 'down'; $vdir = 'down';
$hdir = 'right'; $hdir = 'right';
$inner = 'cols'; $inner = 'cols';
$caption = '';
if (!isset($params['loop'])) { if (!isset($params['loop'])) {
$smarty->trigger_error("html_table: missing 'loop' parameter"); $smarty->trigger_error("html_table: missing 'loop' parameter");
@ -65,6 +72,19 @@ function smarty_function_html_table($params, &$smarty)
break; break;
case 'cols': case 'cols':
if (is_array($_value) && !empty($_value)) {
$cols = $_value;
$cols_count = count($_value);
} elseif (!is_numeric($_value) && is_string($_value) && !empty($_value)) {
$cols = explode(',', $_value);
$cols_count = count($cols);
} elseif (!empty($_value)) {
$cols_count = (int)$_value;
} else {
$cols_count = $cols;
}
break;
case 'rows': case 'rows':
$$_key = (int)$_value; $$_key = (int)$_value;
break; break;
@ -74,11 +94,13 @@ function smarty_function_html_table($params, &$smarty)
case 'hdir': case 'hdir':
case 'vdir': case 'vdir':
case 'inner': case 'inner':
case 'caption':
$$_key = (string)$_value; $$_key = (string)$_value;
break; break;
case 'tr_attr': case 'tr_attr':
case 'td_attr': case 'td_attr':
case 'th_attr':
$$_key = $_value; $$_key = $_value;
break; break;
} }
@ -87,25 +109,42 @@ function smarty_function_html_table($params, &$smarty)
$loop_count = count($loop); $loop_count = count($loop);
if (empty($params['rows'])) { if (empty($params['rows'])) {
/* no rows specified */ /* no rows specified */
$rows = ceil($loop_count/$cols); $rows = ceil($loop_count/$cols_count);
} elseif (empty($params['cols'])) { } elseif (empty($params['cols'])) {
if (!empty($params['rows'])) { if (!empty($params['rows'])) {
/* no cols specified, but rows */ /* no cols specified, but rows */
$cols = ceil($loop_count/$rows); $cols_count = ceil($loop_count/$rows);
} }
} }
$output = "<table $table_attr>\n"; $output = "<table $table_attr>\n";
if (!empty($caption)) {
$output .= '<caption>' . $caption . "</caption>\n";
}
if (is_array($cols)) {
$cols = ($hdir == 'right') ? $cols : array_reverse($cols);
$output .= "<thead><tr>\n";
for ($r=0; $r<$cols_count; $r++) {
$output .= '<th' . smarty_function_html_table_cycle('th', $th_attr, $r) . '>';
$output .= $cols[$r];
$output .= "</th>\n";
}
$output .= "</tr></thead>\n";
}
$output .= "<tbody>\n";
for ($r=0; $r<$rows; $r++) { for ($r=0; $r<$rows; $r++) {
$output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n"; $output .= "<tr" . smarty_function_html_table_cycle('tr', $tr_attr, $r) . ">\n";
$rx = ($vdir == 'down') ? $r*$cols : ($rows-1-$r)*$cols; $rx = ($vdir == 'down') ? $r*$cols_count : ($rows-1-$r)*$cols_count;
for ($c=0; $c<$cols; $c++) { for ($c=0; $c<$cols_count; $c++) {
$x = ($hdir == 'right') ? $rx+$c : $rx+$cols-1-$c; $x = ($hdir == 'right') ? $rx+$c : $rx+$cols_count-1-$c;
if ($inner!='cols') { if ($inner!='cols') {
/* shuffle x to loop over rows*/ /* shuffle x to loop over rows*/
$x = floor($x/$cols) + ($x%$cols)*$rows; $x = floor($x/$cols_count) + ($x%$cols_count)*$rows;
} }
if ($x<$loop_count) { if ($x<$loop_count) {
@ -116,6 +155,7 @@ function smarty_function_html_table($params, &$smarty)
} }
$output .= "</tr>\n"; $output .= "</tr>\n";
} }
$output .= "</tbody>\n";
$output .= "</table>\n"; $output .= "</table>\n";
return $output; return $output;

View file

@ -62,6 +62,8 @@ function smarty_function_mailto($params, &$smarty)
// netscape and mozilla do not decode %40 (@) in BCC field (bug?) // netscape and mozilla do not decode %40 (@) in BCC field (bug?)
// so, don't encode it. // so, don't encode it.
$search = array('%40', '%2C');
$replace = array('@', ',');
$mail_parms = array(); $mail_parms = array();
foreach ($params as $var=>$value) { foreach ($params as $var=>$value) {
switch ($var) { switch ($var) {
@ -69,7 +71,7 @@ function smarty_function_mailto($params, &$smarty)
case 'bcc': case 'bcc':
case 'followupto': case 'followupto':
if (!empty($value)) if (!empty($value))
$mail_parms[] = $var.'='.str_replace('%40','@',rawurlencode($value)); $mail_parms[] = $var.'='.str_replace($search,$replace,rawurlencode($value));
break; break;
case 'subject': case 'subject':

View file

@ -14,6 +14,7 @@
* Purpose: handle math computations in template<br> * Purpose: handle math computations in template<br>
* @link http://smarty.php.net/manual/en/language.function.math.php {math} * @link http://smarty.php.net/manual/en/language.function.math.php {math}
* (Smarty online manual) * (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array * @param array
* @param Smarty * @param Smarty
* @return string * @return string
@ -26,7 +27,8 @@ function smarty_function_math($params, &$smarty)
return; return;
} }
$equation = $params['equation']; // strip out backticks, not necessary for math
$equation = str_replace('`','',$params['equation']);
// make sure parenthesis are balanced // make sure parenthesis are balanced
if (substr_count($equation,"(") != substr_count($equation,")")) { if (substr_count($equation,"(") != substr_count($equation,")")) {
@ -35,7 +37,7 @@ function smarty_function_math($params, &$smarty)
} }
// match all vars in equation, make sure all are passed // match all vars in equation, make sure all are passed
preg_match_all("!(?:0x[a-fA-F0-9]+)|([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', $allowed_funcs = array('int','abs','ceil','cos','exp','floor','log','log10',
'max','min','pi','pow','rand','round','sin','sqrt','srand','tan'); 'max','min','pi','pow','rand','round','sin','sqrt','srand','tan');
@ -57,7 +59,7 @@ function smarty_function_math($params, &$smarty)
$smarty->trigger_error("math: parameter $key: is not numeric"); $smarty->trigger_error("math: parameter $key: is not numeric");
return; return;
} }
$equation = preg_replace("/\b$key\b/",$val, $equation); $equation = preg_replace("/\b$key\b/", " \$params['$key'] ", $equation);
} }
} }

View file

@ -14,6 +14,7 @@
* Purpose: make text pop up in windows via overlib * Purpose: make text pop up in windows via overlib
* @link http://smarty.php.net/manual/en/language.function.popup.php {popup} * @link http://smarty.php.net/manual/en/language.function.popup.php {popup}
* (Smarty online manual) * (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array * @param array
* @param Smarty * @param Smarty
* @return string * @return string
@ -88,6 +89,7 @@ function smarty_function_popup($params, &$smarty)
case 'vauto': case 'vauto':
case 'mouseoff': case 'mouseoff':
case 'followmouse': case 'followmouse':
case 'closeclick':
if ($_value) $append .= ',' . strtoupper($_key); if ($_value) $append .= ',' . strtoupper($_key);
break; break;

View file

@ -14,6 +14,7 @@
* Purpose: initialize overlib * Purpose: initialize overlib
* @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init} * @link http://smarty.php.net/manual/en/language.function.popup.init.php {popup_init}
* (Smarty online manual) * (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array * @param array
* @param Smarty * @param Smarty
* @return string * @return string

View file

@ -14,13 +14,14 @@
* Purpose: capitalize words in the string * Purpose: capitalize words in the string
* @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE * @link http://smarty.php.net/manual/en/language.modifiers.php#LANGUAGE.MODIFIER.CAPITALIZE
* capitalize (Smarty online manual) * capitalize (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @return string * @return string
*/ */
function smarty_modifier_capitalize($string, $uc_digits = false) function smarty_modifier_capitalize($string, $uc_digits = false)
{ {
smarty_modifier_capitalize_ucfirst(null, $uc_digits); smarty_modifier_capitalize_ucfirst(null, $uc_digits);
return preg_replace_callback('!\b\w+\b!', 'smarty_modifier_capitalize_ucfirst', $string); return preg_replace_callback('!\'?\b\w(\w|\')*\b!', 'smarty_modifier_capitalize_ucfirst', $string);
} }
function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null) function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
@ -32,7 +33,7 @@ function smarty_modifier_capitalize_ucfirst($string, $uc_digits = null)
return; return;
} }
if(!preg_match('!\d!',$string[0]) || $_uc_digits) if(substr($string[0],0,1) != "'" && !preg_match("!\d!",$string[0]) || $_uc_digits)
return ucfirst($string[0]); return ucfirst($string[0]);
else else
return $string[0]; return $string[0];

View file

@ -14,6 +14,7 @@
* Purpose: count the number of characters in a text * Purpose: count the number of characters in a text
* @link http://smarty.php.net/manual/en/language.modifier.count.characters.php * @link http://smarty.php.net/manual/en/language.modifier.count.characters.php
* count_characters (Smarty online manual) * count_characters (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param boolean include whitespace in the character count * @param boolean include whitespace in the character count
* @return integer * @return integer

View file

@ -14,6 +14,7 @@
* Purpose: count the number of paragraphs in a text * Purpose: count the number of paragraphs in a text
* @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
* count_paragraphs (Smarty online manual) * count_paragraphs (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @return integer * @return integer
*/ */

View file

@ -14,6 +14,7 @@
* Purpose: count the number of sentences in a text * Purpose: count the number of sentences in a text
* @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php * @link http://smarty.php.net/manual/en/language.modifier.count.paragraphs.php
* count_sentences (Smarty online manual) * count_sentences (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @return integer * @return integer
*/ */

View file

@ -14,6 +14,7 @@
* Purpose: count the number of words in a text * Purpose: count the number of words in a text
* @link http://smarty.php.net/manual/en/language.modifier.count.words.php * @link http://smarty.php.net/manual/en/language.modifier.count.words.php
* count_words (Smarty online manual) * count_words (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @return integer * @return integer
*/ */

View file

@ -8,7 +8,7 @@
/** /**
* Include the {@link shared.make_timestamp.php} plugin * Include the {@link shared.make_timestamp.php} plugin
*/ */
require_once $smarty->_get_plugin_filepath('shared','make_timestamp'); require_once $smarty->_get_plugin_filepath('shared', 'make_timestamp');
/** /**
* Smarty date_format modifier plugin * Smarty date_format modifier plugin
* *
@ -21,26 +21,36 @@ require_once $smarty->_get_plugin_filepath('shared','make_timestamp');
* - default_date: default date if $string is empty * - default_date: default date if $string is empty
* @link http://smarty.php.net/manual/en/language.modifier.date.format.php * @link http://smarty.php.net/manual/en/language.modifier.date.format.php
* date_format (Smarty online manual) * date_format (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param string * @param string
* @param string * @param string
* @return string|void * @return string|void
* @uses smarty_make_timestamp() * @uses smarty_make_timestamp()
*/ */
function smarty_modifier_date_format($string, $format="%b %e, %Y", $default_date=null) function smarty_modifier_date_format($string, $format = '%b %e, %Y', $default_date = '')
{ {
if (substr(PHP_OS,0,3) == 'WIN') { if ($string != '') {
$_win_from = array ('%e', '%T', '%D'); $timestamp = smarty_make_timestamp($string);
$_win_to = array ('%#d', '%H:%M:%S', '%m/%d/%y'); } elseif ($default_date != '') {
$format = str_replace($_win_from, $_win_to, $format); $timestamp = smarty_make_timestamp($default_date);
}
if($string != '') {
return strftime($format, smarty_make_timestamp($string));
} elseif (isset($default_date) && $default_date != '') {
return strftime($format, smarty_make_timestamp($default_date));
} else { } else {
return; return;
} }
if (DIRECTORY_SEPARATOR == '\\') {
$_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T');
$_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S');
if (strpos($format, '%e') !== false) {
$_win_from[] = '%e';
$_win_to[] = sprintf('%\' 2d', date('j', $timestamp));
}
if (strpos($format, '%l') !== false) {
$_win_from[] = '%l';
$_win_to[] = sprintf('%\' 2d', date('h', $timestamp));
}
$format = str_replace($_win_from, $_win_to, $format);
}
return strftime($format, $timestamp);
} }
/* vim: set expandtab: */ /* vim: set expandtab: */

View file

@ -14,6 +14,7 @@
* Purpose: formats variable contents for display in the console * Purpose: formats variable contents for display in the console
* @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php * @link http://smarty.php.net/manual/en/language.modifier.debug.print.var.php
* debug_print_var (Smarty online manual) * debug_print_var (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param array|object * @param array|object
* @param integer * @param integer
* @param integer * @param integer
@ -21,33 +22,66 @@
*/ */
function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40) function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
{ {
$_replace = array("\n"=>'<i>&#92;n</i>', "\r"=>'<i>&#92;r</i>', "\t"=>'<i>&#92;t</i>'); $_replace = array(
if (is_array($var)) { "\n" => '<i>\n</i>',
$results = "<b>Array (".count($var).")</b>"; "\r" => '<i>\r</i>',
foreach ($var as $curr_key => $curr_val) { "\t" => '<i>\t</i>'
$return = smarty_modifier_debug_print_var($curr_val, $depth+1, $length); );
$results .= "<br>".str_repeat('&nbsp;', $depth*2)."<b>".strtr($curr_key, $_replace)."</b> =&gt; $return";
} switch (gettype($var)) {
} else if (is_object($var)) { case 'array' :
$object_vars = get_object_vars($var); $results = '<b>Array (' . count($var) . ')</b>';
$results = "<b>".get_class($var)." Object (".count($object_vars).")</b>"; foreach ($var as $curr_key => $curr_val) {
foreach ($object_vars as $curr_key => $curr_val) { $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
$return = smarty_modifier_debug_print_var($curr_val, $depth+1, $length); . '<b>' . strtr($curr_key, $_replace) . '</b> =&gt; '
$results .= "<br>".str_repeat('&nbsp;', $depth*2)."<b>$curr_key</b> =&gt; $return"; . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
} $depth--;
} else if (is_resource($var)) { }
$results = '<i>'.(string)$var.'</i>'; break;
} else if (empty($var) && $var != "0") { case 'object' :
$results = '<i>empty</i>'; $object_vars = get_object_vars($var);
} else { $results = '<b>' . get_class($var) . ' Object (' . count($object_vars) . ')</b>';
if (strlen($var) > $length ) { foreach ($object_vars as $curr_key => $curr_val) {
$results = substr($var, 0, $length-3).'...'; $results .= '<br>' . str_repeat('&nbsp;', $depth * 2)
} else { . '<b> -&gt;' . strtr($curr_key, $_replace) . '</b> = '
$results = $var; . smarty_modifier_debug_print_var($curr_val, ++$depth, $length);
} $depth--;
$results = htmlspecialchars($results); }
$results = strtr($results, $_replace); break;
case 'boolean' :
case 'NULL' :
case 'resource' :
if (true === $var) {
$results = 'true';
} elseif (false === $var) {
$results = 'false';
} elseif (null === $var) {
$results = 'null';
} else {
$results = htmlspecialchars((string) $var);
}
$results = '<i>' . $results . '</i>';
break;
case 'integer' :
case 'float' :
$results = htmlspecialchars((string) $var);
break;
case 'string' :
$results = strtr($var, $_replace);
if (strlen($var) > $length ) {
$results = substr($var, 0, $length - 3) . '...';
}
$results = htmlspecialchars('"' . $results . '"');
break;
case 'unknown type' :
default :
$results = strtr((string) $var, $_replace);
if (strlen($results) > $length ) {
$results = substr($results, 0, $length - 3) . '...';
}
$results = htmlspecialchars($results);
} }
return $results; return $results;
} }

View file

@ -14,6 +14,7 @@
* Purpose: designate default value for empty variables * Purpose: designate default value for empty variables
* @link http://smarty.php.net/manual/en/language.modifier.default.php * @link http://smarty.php.net/manual/en/language.modifier.default.php
* default (Smarty online manual) * default (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param string * @param string
* @return string * @return string

View file

@ -14,22 +14,26 @@
* Purpose: Escape the string according to escapement type * Purpose: Escape the string according to escapement type
* @link http://smarty.php.net/manual/en/language.modifier.escape.php * @link http://smarty.php.net/manual/en/language.modifier.escape.php
* escape (Smarty online manual) * escape (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param html|htmlall|url|quotes|hex|hexentity|javascript * @param html|htmlall|url|quotes|hex|hexentity|javascript
* @return string * @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) { switch ($esc_type) {
case 'html': case 'html':
return htmlspecialchars($string, ENT_QUOTES); return htmlspecialchars($string, ENT_QUOTES, $char_set);
case 'htmlall': case 'htmlall':
return htmlentities($string, ENT_QUOTES); return htmlentities($string, ENT_QUOTES, $char_set);
case 'url': case 'url':
return rawurlencode($string); return rawurlencode($string);
case 'urlpathinfo':
return str_replace('%2F','/',rawurlencode($string));
case 'quotes': case 'quotes':
// escape unescaped single quotes // escape unescaped single quotes
return preg_replace("%(?<!\\\\)'%", "\\'", $string); return preg_replace("%(?<!\\\\)'%", "\\'", $string);
@ -68,13 +72,13 @@ function smarty_modifier_escape($string, $esc_type = 'html')
// escape non-standard chars, such as ms document quotes // escape non-standard chars, such as ms document quotes
$_res = ''; $_res = '';
for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) { for($_i = 0, $_len = strlen($string); $_i < $_len; $_i++) {
$_ord = ord($string{$_i}); $_ord = ord(substr($string, $_i, 1));
// non-standard char, escape it // non-standard char, escape it
if($_ord >= 126){ if($_ord >= 126){
$_res .= '&#' . $_ord . ';'; $_res .= '&#' . $_ord . ';';
} }
else { else {
$_res .= $string{$_i}; $_res .= substr($string, $_i, 1);
} }
} }
return $_res; return $_res;

View file

@ -14,6 +14,7 @@
* Purpose: indent lines of text * Purpose: indent lines of text
* @link http://smarty.php.net/manual/en/language.modifier.indent.php * @link http://smarty.php.net/manual/en/language.modifier.indent.php
* indent (Smarty online manual) * indent (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param integer * @param integer
* @param string * @param string

View file

@ -14,6 +14,7 @@
* Purpose: convert string to lowercase * Purpose: convert string to lowercase
* @link http://smarty.php.net/manual/en/language.modifier.lower.php * @link http://smarty.php.net/manual/en/language.modifier.lower.php
* lower (Smarty online manual) * lower (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @return string * @return string
*/ */

View file

@ -11,9 +11,10 @@
* *
* Type: modifier<br> * Type: modifier<br>
* Name: regex_replace<br> * Name: regex_replace<br>
* Purpose: regular epxression search/replace * Purpose: regular expression search/replace
* @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php
* regex_replace (Smarty online manual) * regex_replace (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param string|array * @param string|array
* @param string|array * @param string|array
@ -21,13 +22,27 @@
*/ */
function smarty_modifier_regex_replace($string, $search, $replace) function smarty_modifier_regex_replace($string, $search, $replace)
{ {
if (preg_match('!\W(\w+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) { if(is_array($search)) {
/* remove eval-modifier from $search */ foreach($search as $idx => $s)
$search = substr($search, 0, -strlen($match[1])) . str_replace('e', '', $match[1]); $search[$idx] = _smarty_regex_replace_check($s);
} else {
$search = _smarty_regex_replace_check($search);
} }
return preg_replace($search, $replace, $string); return preg_replace($search, $replace, $string);
} }
function _smarty_regex_replace_check($search)
{
if (($pos = strpos($search,"\0")) !== false)
$search = substr($search,0,$pos);
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 $search;
}
/* vim: set expandtab: */ /* vim: set expandtab: */
?> ?>

View file

@ -14,6 +14,7 @@
* Purpose: simple search/replace * Purpose: simple search/replace
* @link http://smarty.php.net/manual/en/language.modifier.replace.php * @link http://smarty.php.net/manual/en/language.modifier.replace.php
* replace (Smarty online manual) * replace (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param string * @param string
* @param string * @param string

View file

@ -14,6 +14,7 @@
* Purpose: add spaces between characters in a string * Purpose: add spaces between characters in a string
* @link http://smarty.php.net/manual/en/language.modifier.spacify.php * @link http://smarty.php.net/manual/en/language.modifier.spacify.php
* spacify (Smarty online manual) * spacify (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param string * @param string
* @return string * @return string

View file

@ -14,6 +14,7 @@
* Purpose: format strings via sprintf * Purpose: format strings via sprintf
* @link http://smarty.php.net/manual/en/language.modifier.string.format.php * @link http://smarty.php.net/manual/en/language.modifier.string.format.php
* string_format (Smarty online manual) * string_format (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param string * @param string
* @return string * @return string

View file

@ -14,6 +14,7 @@
* Purpose: strip html tags from text * Purpose: strip html tags from text
* @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php * @link http://smarty.php.net/manual/en/language.modifier.strip.tags.php
* strip_tags (Smarty online manual) * strip_tags (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param boolean * @param boolean
* @return string * @return string

View file

@ -13,29 +13,36 @@
* Name: truncate<br> * Name: truncate<br>
* Purpose: Truncate a string to a certain length if necessary, * Purpose: Truncate a string to a certain length if necessary,
* optionally splitting in the middle of a word, and * optionally splitting in the middle of a word, and
* appending the $etc string. * appending the $etc string or inserting $etc into the middle.
* @link http://smarty.php.net/manual/en/language.modifier.truncate.php * @link http://smarty.php.net/manual/en/language.modifier.truncate.php
* truncate (Smarty online manual) * truncate (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param integer * @param integer
* @param string * @param string
* @param boolean * @param boolean
* @param boolean
* @return string * @return string
*/ */
function smarty_modifier_truncate($string, $length = 80, $etc = '...', function smarty_modifier_truncate($string, $length = 80, $etc = '...',
$break_words = false) $break_words = false, $middle = false)
{ {
if ($length == 0) if ($length == 0)
return ''; return '';
if (strlen($string) > $length) { if (strlen($string) > $length) {
$length -= strlen($etc); $length -= min($length, strlen($etc));
if (!$break_words) if (!$break_words && !$middle) {
$string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1)); $string = preg_replace('/\s+?(\S+)?$/', '', substr($string, 0, $length+1));
}
return substr($string, 0, $length).$etc; if(!$middle) {
} else return substr($string, 0, $length) . $etc;
} else {
return substr($string, 0, $length/2) . $etc . substr($string, -$length/2);
}
} else {
return $string; return $string;
}
} }
/* vim: set expandtab: */ /* vim: set expandtab: */

View file

@ -14,6 +14,7 @@
* Purpose: convert string to uppercase * Purpose: convert string to uppercase
* @link http://smarty.php.net/manual/en/language.modifier.upper.php * @link http://smarty.php.net/manual/en/language.modifier.upper.php
* upper (Smarty online manual) * upper (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @return string * @return string
*/ */

View file

@ -14,6 +14,7 @@
* Purpose: wrap a string of text at a given length * Purpose: wrap a string of text at a given length
* @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php
* wordwrap (Smarty online manual) * wordwrap (Smarty online manual)
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @param integer * @param integer
* @param string * @param string

View file

@ -28,35 +28,35 @@
function smarty_outputfilter_trimwhitespace($source, &$smarty) function smarty_outputfilter_trimwhitespace($source, &$smarty)
{ {
// Pull out the script blocks // Pull out the script blocks
preg_match_all("!<script[^>]+>.*?</script>!is", $source, $match); preg_match_all("!<script[^>]*?>.*?</script>!is", $source, $match);
$_script_blocks = $match[0]; $_script_blocks = $match[0];
$source = preg_replace("!<script[^>]+>.*?</script>!is", $source = preg_replace("!<script[^>]*?>.*?</script>!is",
'@@@SMARTY:TRIM:SCRIPT@@@', $source); '@@@SMARTY:TRIM:SCRIPT@@@', $source);
// Pull out the pre blocks // Pull out the pre blocks
preg_match_all("!<pre>.*?</pre>!is", $source, $match); preg_match_all("!<pre[^>]*?>.*?</pre>!is", $source, $match);
$_pre_blocks = $match[0]; $_pre_blocks = $match[0];
$source = preg_replace("!<pre>.*?</pre>!is", $source = preg_replace("!<pre[^>]*?>.*?</pre>!is",
'@@@SMARTY:TRIM:PRE@@@', $source); '@@@SMARTY:TRIM:PRE@@@', $source);
// Pull out the textarea blocks // Pull out the textarea blocks
preg_match_all("!<textarea[^>]+>.*?</textarea>!is", $source, $match); preg_match_all("!<textarea[^>]*?>.*?</textarea>!is", $source, $match);
$_textarea_blocks = $match[0]; $_textarea_blocks = $match[0];
$source = preg_replace("!<textarea[^>]+>.*?</textarea>!is", $source = preg_replace("!<textarea[^>]*?>.*?</textarea>!is",
'@@@SMARTY:TRIM:TEXTAREA@@@', $source); '@@@SMARTY:TRIM:TEXTAREA@@@', $source);
// remove all leading spaces, tabs and carriage returns NOT // remove all leading spaces, tabs and carriage returns NOT
// preceeded by a php close tag. // preceeded by a php close tag.
$source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source)); $source = trim(preg_replace('/((?<!\?>)\n)[\s]+/m', '\1', $source));
// replace script blocks // replace textarea blocks
smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source); smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source);
// replace pre blocks // replace pre blocks
smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source); smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:PRE@@@",$_pre_blocks, $source);
// replace textarea blocks // replace script blocks
smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:TEXTAREA@@@",$_textarea_blocks, $source); smarty_outputfilter_trimwhitespace_replace("@@@SMARTY:TRIM:SCRIPT@@@",$_script_blocks, $source);
return $source; return $source;
} }

View file

@ -12,6 +12,7 @@
* Function: smarty_function_escape_special_chars<br> * Function: smarty_function_escape_special_chars<br>
* Purpose: used by other smarty functions to escape * Purpose: used by other smarty functions to escape
* special chars except for already escaped ones * special chars except for already escaped ones
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @return string * @return string
*/ */

View file

@ -10,32 +10,35 @@
* Function: smarty_make_timestamp<br> * Function: smarty_make_timestamp<br>
* Purpose: used by other smarty functions to make a timestamp * Purpose: used by other smarty functions to make a timestamp
* from a string. * from a string.
* @author Monte Ohrt <monte at ohrt dot com>
* @param string * @param string
* @return string * @return string
*/ */
function smarty_make_timestamp($string) function smarty_make_timestamp($string)
{ {
if(empty($string)) { if(empty($string)) {
$string = "now"; // use "now":
$time = 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();
}
} }
$time = strtotime($string); return $time;
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));
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: */ /* vim: set expandtab: */